You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by an...@apache.org on 2018/10/24 09:32:17 UTC

[01/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Repository: zookeeper
Updated Branches:
  refs/heads/branch-3.4 f0c868346 -> 7291e47cb


http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/test-github-pr.sh
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/test-github-pr.sh b/zookeeper-server/src/test/resources/test-github-pr.sh
new file mode 100755
index 0000000..e155769
--- /dev/null
+++ b/zookeeper-server/src/test/resources/test-github-pr.sh
@@ -0,0 +1,616 @@
+#!/usr/bin/env bash
+#   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.
+
+
+#set -x
+
+### Setup some variables.
+### GIT_COMMIT and BUILD_URL are set by Hudson if it is run by patch process
+### Read variables from properties file
+. `dirname $0`/test-patch.properties
+
+###############################################################################
+parseArgs() {
+  case "$1" in
+    QABUILD)
+      ### Set QABUILD to true to indicate that this script is being run by Hudson
+      QABUILD=true
+      if [[ $# != 14 ]] ; then
+        echo "ERROR: usage $0 QABUILD <PATCH_DIR> <PS_CMD> <WGET_CMD> <JIRACLI> <GIT_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JIRA_PASSWD> <JAVA5_HOME> <CURL_CMD>"
+        cleanupAndExit 0
+      fi
+      PATCH_DIR=$2
+      PS=$3
+      WGET=$4
+      JIRACLI=$5
+      GIT=$6
+      GREP=$7
+      PATCH=$8
+      FINDBUGS_HOME=$9
+      FORREST_HOME=${10}
+      BASEDIR=${11}
+      JIRA_PASSWD=${12}
+      JAVA5_HOME=${13}
+      CURL=${14}
+      if [ ! -e "$PATCH_DIR" ] ; then
+        mkdir -p $PATCH_DIR
+      fi
+
+      ## Obtain PR number and title
+      PULLREQUEST_ID=${GIT_PR_NUMBER}
+      PULLREQUEST_TITLE="${GIT_PR_TITLE}"
+
+      ## Extract jira number from PR title
+      local prefix=${PULLREQUEST_TITLE%ZOOKEEPER\-[0-9]*}
+      local noprefix=${PULLREQUEST_TITLE#$prefix}
+      local regex='\(ZOOKEEPER-.[0-9]*\)'
+      defect=$(expr "$noprefix" : ${regex})
+
+      echo "Pull request id: ${PULLREQUEST_ID}"
+      echo "Pull request title: ${PULLREQUEST_TITLE}"
+      echo "Defect number: ${defect}"
+
+      JIRA_COMMENT="GitHub Pull Request ${PULLREQUEST_NUMBER} Build
+      "
+      ;;
+    DEVELOPER)
+      ### Set QABUILD to false to indicate that this script is being run by a developer
+      QABUILD=false
+      if [[ $# != 10 ]] ; then
+        echo "ERROR: usage $0 DEVELOPER <GIT_PR_URL> <SCRATCH_DIR> <GIT_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JAVA5_HOME>"
+        cleanupAndExit 0
+      fi
+      PATCH_DIR=$3
+      PATCH_FILE=${PATCH_DIR}/patch
+      curl -L $2.diff > ${PATCH_FILE}
+      ### PATCH_FILE contains the location of the patchfile
+      if [[ ! -e "$PATCH_FILE" ]] ; then
+        echo "Unable to locate the patch file $PATCH_FILE"
+        cleanupAndExit 0
+      fi
+      ### Check if $PATCH_DIR exists. If it does not exist, create a new directory
+      if [[ ! -e "$PATCH_DIR" ]] ; then
+	mkdir "$PATCH_DIR"
+	if [[ $? == 0 ]] ; then
+	  echo "$PATCH_DIR has been created"
+	else
+	  echo "Unable to create $PATCH_DIR"
+	  cleanupAndExit 0
+	fi
+      fi
+      GIT=$4
+      GREP=$5
+      PATCH=$6
+      FINDBUGS_HOME=$7
+      FORREST_HOME=$8
+      BASEDIR=$9
+      JAVA5_HOME=${10}
+      ### Obtain the patch filename to append it to the version number
+      local subject=`grep "Subject:" ${PATCH_FILE}`
+      local length=`expr match ${subject} ZOOKEEPER-[0-9]*`
+      local position=`expr index ${subject} ZOOKEEPER-`
+      defect=${${subject:$position:$length}#ZOOKEEPER-}
+      ;;
+    *)
+      echo "ERROR: usage $0 QABUILD [args] | DEVELOPER [args]"
+      cleanupAndExit 0
+      ;;
+  esac
+}
+
+###############################################################################
+checkout () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Testing patch for pull request ${PULLREQUEST_ID}."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  ### When run by a developer, if the workspace contains modifications, do not continue
+  # Ref http://stackoverflow.com/a/2659808 for details on checking dirty status
+  ${GIT} diff-index --quiet HEAD
+  if [[ $? -ne 0 ]] ; then
+    uncommitted=`${GIT} diff --name-only HEAD`
+    uncommitted="You have the following files with uncommitted changes:${NEWLINE}${uncommitted}"
+  fi
+  untracked="$(${GIT} ls-files --exclude-standard --others)" && test -z "${untracked}"
+  if [[ $? -ne 0 ]] ; then
+    untracked="You have untracked and unignored files:${NEWLINE}${untracked}"
+  fi
+
+  if [[ $QABUILD == "false" ]] ; then
+    if [[ $uncommitted || $untracked ]] ; then
+      echo "ERROR: can't run in a workspace that contains the following modifications"
+      echo ""
+      echo "${uncommitted}"
+      echo ""
+      echo "${untracked}"
+      cleanupAndExit 1
+    fi
+  else
+    # I don't believe we need to do anything here - the jenkins job will
+    # cleanup the environment for us ("cleanup before checkout" action)
+    # on the precommit jenkins job
+    echo
+  fi
+  return $?
+}
+
+###############################################################################
+setup () {
+  ### exit if warnings are NOT defined in the properties file
+  if [ -z "$OK_FINDBUGS_WARNINGS" ] || [[ -z "$OK_JAVADOC_WARNINGS" ]] || [[ -z $OK_RELEASEAUDIT_WARNINGS ]]; then
+    echo "Please define the following properties in test-patch.properties file"
+	 echo  "OK_FINDBUGS_WARNINGS"
+	 echo  "OK_RELEASEAUDIT_WARNINGS"
+	 echo  "OK_JAVADOC_WARNINGS"
+    cleanupAndExit 1
+  fi
+  ### get pull request diff
+  ${CURL} -L ${GIT_PR_URL}.diff > $PATCH_DIR/patch
+
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo " Pre-build trunk to verify trunk stability and javac warnings"
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant  -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1"
+ $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1
+  if [[ $? != 0 ]] ; then
+    echo "Trunk compilation is broken?"
+    cleanupAndExit 1
+  fi
+}
+
+###############################################################################
+### Check for @author tags in the patch
+checkAuthor () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Checking there are no @author tags in the patch."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  authorTags=`$GREP -c -i '@author' $PATCH_DIR/patch`
+  echo "There appear to be $authorTags @author tags in the patch."
+  if [[ $authorTags != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 @author.  The patch appears to contain $authorTags @author tags which the Zookeeper community has agreed to not allow in code contributions."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 @author.  The patch does not contain any @author tags."
+  return 0
+}
+
+###############################################################################
+### Check for tests in the patch
+checkTests () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Checking there are new or changed tests in the patch."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  testReferences=`$GREP -c -i '/test' $PATCH_DIR/patch`
+  echo "There appear to be $testReferences test files referenced in the patch."
+  if [[ $testReferences == 0 ]] ; then
+    if [[ $QABUILD == "true" ]] ; then
+      patchIsDoc=`$GREP -c -i 'title="documentation' $PATCH_DIR/jira`
+      if [[ $patchIsDoc != 0 ]] ; then
+        echo "The patch appears to be a documentation patch that doesn't require tests."
+        JIRA_COMMENT="$JIRA_COMMENT
+
+    +0 tests included.  The patch appears to be a documentation patch that doesn't require tests."
+        return 0
+      fi
+    fi
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 tests included.  The patch doesn't appear to include any new or modified tests.
+                        Please justify why no new tests are needed for this patch.
+                        Also please list what manual steps were performed to verify this patch."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 tests included.  The patch appears to include $testReferences new or modified tests."
+  return 0
+}
+
+###############################################################################
+### Check there are no javadoc warnings
+checkJavadocWarnings () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched javadoc warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt
+  javadocWarnings=`$GREP -o '\[javadoc\] [0-9]* warning' $PATCH_DIR/patchJavadocWarnings.txt | awk '{total += $2} END {print total}'`
+  echo ""
+  echo ""
+  echo "There appear to be $javadocWarnings javadoc warnings generated by the patched build."
+
+  ### if current warnings greater than OK_JAVADOC_WARNINGS
+  if [[ $javadocWarnings > $OK_JAVADOC_WARNINGS ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 javadoc.  The javadoc tool appears to have generated `expr $(($javadocWarnings-$OK_JAVADOC_WARNINGS))` warning messages."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 javadoc.  The javadoc tool did not generate any warning messages."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of Javac warnings
+checkJavacWarnings () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched javac warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1"
+  $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1
+  if [[ $? != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 javac.  The patch appears to cause tar ant target to fail."
+    return 1
+  fi
+  ### Compare trunk and patch javac warning numbers
+  if [[ -f $PATCH_DIR/patchJavacWarnings.txt ]] ; then
+    trunkJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/trunkJavacWarnings.txt | awk '{total += $2} END {print total}'`
+    patchJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/patchJavacWarnings.txt | awk '{total += $2} END {print total}'`
+    echo "There appear to be $trunkJavacWarnings javac compiler warnings before the patch and $patchJavacWarnings javac compiler warnings after applying the patch."
+    if [[ $patchJavacWarnings != "" && $trunkJavacWarnings != "" ]] ; then
+      if [[ $patchJavacWarnings -gt $trunkJavacWarnings ]] ; then
+        JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 javac.  The applied patch generated $patchJavacWarnings javac compiler warnings (more than the trunk's current $trunkJavacWarnings warnings)."
+        return 1
+      fi
+    fi
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 javac.  The applied patch does not increase the total number of javac compiler warnings."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of release audit (RAT) warnings
+checkReleaseAuditWarnings () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched release audit warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1"
+  $ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1
+
+  ### Compare trunk and patch release audit warning numbers
+  if [[ -f $PATCH_DIR/patchReleaseAuditWarnings.txt ]] ; then
+    patchReleaseAuditWarnings=`$GREP -c '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt`
+    echo ""
+    echo ""
+    echo "There appear to be $OK_RELEASEAUDIT_WARNINGS release audit warnings before the patch and $patchReleaseAuditWarnings release audit warnings after applying the patch."
+    if [[ $patchReleaseAuditWarnings != "" && $OK_RELEASEAUDIT_WARNINGS != "" ]] ; then
+      if [[ $patchReleaseAuditWarnings -gt $OK_RELEASEAUDIT_WARNINGS ]] ; then
+        JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 release audit.  The applied patch generated $patchReleaseAuditWarnings release audit warnings (more than the trunk's current $OK_RELEASEAUDIT_WARNINGS warnings)."
+        $GREP '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt > $PATCH_DIR/patchReleaseAuditProblems.txt
+        echo "Lines that start with ????? in the release audit report indicate files that do not have an Apache license header." >> $PATCH_DIR/patchReleaseAuditProblems.txt
+        JIRA_COMMENT_FOOTER="Release audit warnings: $BUILD_URL/artifact/trunk/patchprocess/patchReleaseAuditProblems.txt
+$JIRA_COMMENT_FOOTER"
+        return 1
+      fi
+    fi
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 release audit.  The applied patch does not increase the total number of release audit warnings."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of Checkstyle warnings
+checkStyle () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched checkstyle warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "THIS IS NOT IMPLEMENTED YET"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle
+  JIRA_COMMENT_FOOTER="Checkstyle results: $BUILD_URL/artifact/trunk/build/test/checkstyle-errors.html
+$JIRA_COMMENT_FOOTER"
+  ### TODO: calculate actual patchStyleErrors
+#  patchStyleErrors=0
+#  if [[ $patchStyleErrors != 0 ]] ; then
+#    JIRA_COMMENT="$JIRA_COMMENT
+#
+#    -1 checkstyle.  The patch generated $patchStyleErrors code style errors."
+#    return 1
+#  fi
+#  JIRA_COMMENT="$JIRA_COMMENT
+#
+#    +1 checkstyle.  The patch generated 0 code style errors."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of Findbugs warnings
+checkFindbugsWarnings () {
+  findbugs_version=`${FINDBUGS_HOME}/bin/findbugs -version`
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched Findbugs warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs"
+  $ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs
+  if [ $? != 0 ] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 findbugs.  The patch appears to cause Findbugs (version ${findbugs_version}) to fail."
+    return 1
+  fi
+JIRA_COMMENT_FOOTER="Findbugs warnings: $BUILD_URL/artifact/trunk/build/test/findbugs/newPatchFindbugsWarnings.html
+$JIRA_COMMENT_FOOTER"
+  cp $BASEDIR/build/test/findbugs/*.xml $PATCH_DIR/patchFindbugsWarnings.xml
+  $FINDBUGS_HOME/bin/setBugDatabaseInfo -timestamp "01/01/2000" \
+    $PATCH_DIR/patchFindbugsWarnings.xml \
+    $PATCH_DIR/patchFindbugsWarnings.xml
+  findbugsWarnings=`$FINDBUGS_HOME/bin/filterBugs -first "01/01/2000" $PATCH_DIR/patchFindbugsWarnings.xml \
+    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml | /usr/bin/awk '{print $1}'`
+  $FINDBUGS_HOME/bin/convertXmlToText -html \
+    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml \
+    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html
+  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html $PATCH_DIR/newPatchFindbugsWarnings.html
+  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml $PATCH_DIR/newPatchFindbugsWarnings.xml
+
+  ### if current warnings greater than OK_FINDBUGS_WARNINGS
+  if [[ $findbugsWarnings > $OK_FINDBUGS_WARNINGS ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 findbugs.  The patch appears to introduce `expr $(($findbugsWarnings-$OK_FINDBUGS_WARNINGS))` new Findbugs (version ${findbugs_version}) warnings."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 findbugs.  The patch does not introduce any new Findbugs (version ${findbugs_version}) warnings."
+  return 0
+}
+
+###############################################################################
+### Run the test-core target
+runCoreTests () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Running core tests."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+
+  ### Kill any rogue build processes from the last attempt
+  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
+
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dtest.junit.threads=8 -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dtest.junit.threads=8 -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core
+  if [[ $? != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 core tests.  The patch failed core unit tests."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 core tests.  The patch passed core unit tests."
+  return 0
+}
+
+###############################################################################
+### Run the test-contrib target
+runContribTests () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Running contrib tests."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+
+  ### Kill any rogue build processes from the last attempt
+  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
+
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib
+  if [[ $? != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 contrib tests.  The patch failed contrib unit tests."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 contrib tests.  The patch passed contrib unit tests."
+  return 0
+}
+
+###############################################################################
+### Submit a comment to the defect's Jira
+submitJiraComment () {
+  local result=$1
+  ### Do not output the value of JIRA_COMMENT_FOOTER when run by a developer
+  if [[  $QABUILD == "false" ]] ; then
+    JIRA_COMMENT_FOOTER=""
+  fi
+  if [[ $result == 0 ]] ; then
+    comment="+1 overall.  $JIRA_COMMENT
+
+$JIRA_COMMENT_FOOTER"
+  else
+    comment="-1 overall.  $JIRA_COMMENT
+
+$JIRA_COMMENT_FOOTER"
+  fi
+  ### Output the test result to the console
+  echo "
+
+
+
+$comment"
+
+  if [[ $QABUILD == "true" ]] ; then
+    echo ""
+    echo ""
+    echo "======================================================================"
+    echo "======================================================================"
+    echo "    Adding comment to Jira."
+    echo "======================================================================"
+    echo "======================================================================"
+    echo ""
+    echo ""
+    ### Update Jira with a comment
+    export USER=jenkins
+    $JIRACLI -s https://issues.apache.org/jira -a addcomment -u hadoopqa -p $JIRA_PASSWD --comment "$comment" --issue $defect
+    $JIRACLI -s https://issues.apache.org/jira -a logout -u hadoopqa -p $JIRA_PASSWD
+  fi
+}
+
+###############################################################################
+### Cleanup files
+cleanupAndExit () {
+  local result=$1
+  if [[ $QABUILD == "true" ]] ; then
+    if [ -e "$PATCH_DIR" ] ; then
+      mv $PATCH_DIR $BASEDIR
+    fi
+  fi
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Finished build."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  exit $result
+}
+
+###############################################################################
+###############################################################################
+###############################################################################
+
+JIRA_COMMENT=""
+JIRA_COMMENT_FOOTER="Console output: $BUILD_URL/console
+
+This message is automatically generated."
+
+### Check if arguments to the script have been specified properly or not
+echo "----- Going to parser args -----"
+parseArgs $@
+cd $BASEDIR
+
+echo "----- Parsed args, going to checkout -----"
+checkout
+RESULT=$?
+if [[ $QABUILD == "true" ]] ; then
+  if [[ $RESULT != 0 ]] ; then
+    exit 100
+  fi
+fi
+setup
+checkAuthor
+(( RESULT = RESULT + $? ))
+
+checkTests
+checkTestsResult=$?
+(( RESULT = RESULT + $checkTestsResult ))
+if [[ $checkTestsResult != 0 ]] ; then
+  submitJiraComment 1
+  cleanupAndExit 1
+fi
+checkJavadocWarnings
+(( RESULT = RESULT + $? ))
+checkJavacWarnings
+(( RESULT = RESULT + $? ))
+### Checkstyle not implemented yet
+#checkStyle
+#(( RESULT = RESULT + $? ))
+checkFindbugsWarnings
+(( RESULT = RESULT + $? ))
+checkReleaseAuditWarnings
+(( RESULT = RESULT + $? ))
+### Do not call these when run by a developer
+if [[ $QABUILD == "true" ]] ; then
+  runCoreTests
+  (( RESULT = RESULT + $? ))
+  runContribTests
+  (( RESULT = RESULT + $? ))
+fi
+JIRA_COMMENT_FOOTER="Test results: $BUILD_URL/testReport/
+$JIRA_COMMENT_FOOTER"
+
+submitJiraComment $RESULT
+cleanupAndExit $RESULT

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/test-patch.properties
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/test-patch.properties b/zookeeper-server/src/test/resources/test-patch.properties
new file mode 100644
index 0000000..c467e63
--- /dev/null
+++ b/zookeeper-server/src/test/resources/test-patch.properties
@@ -0,0 +1,18 @@
+# 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.
+
+OK_RELEASEAUDIT_WARNINGS=24
+OK_FINDBUGS_WARNINGS=0
+OK_JAVADOC_WARNINGS=0

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/test-patch.sh
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/test-patch.sh b/zookeeper-server/src/test/resources/test-patch.sh
new file mode 100755
index 0000000..d42789b
--- /dev/null
+++ b/zookeeper-server/src/test/resources/test-patch.sh
@@ -0,0 +1,637 @@
+#!/usr/bin/env bash
+#   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.
+
+
+#set -x
+ulimit -n 1024
+
+### Setup some variables.  
+### SVN_REVISION and BUILD_URL are set by Hudson if it is run by patch process
+### Read variables from properties file
+. `dirname $0`/test-patch.properties
+
+###############################################################################
+parseArgs() {
+  case "$1" in
+    HUDSON)
+      ### Set HUDSON to true to indicate that this script is being run by Hudson
+      HUDSON=true
+      if [[ $# != 15 ]] ; then
+        echo "ERROR: usage $0 HUDSON <PATCH_DIR> <PS_CMD> <WGET_CMD> <JIRACLI> <SVN_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JIRA_PASSWD> <JAVA5_HOME> <CURL_CMD> <DEFECT> "
+        cleanupAndExit 0
+      fi
+      PATCH_DIR=$2
+      PS=$3
+      WGET=$4
+      JIRACLI=$5
+      SVN=$6
+      GREP=$7
+      PATCH=$8
+      FINDBUGS_HOME=$9
+      FORREST_HOME=${10}
+      BASEDIR=${11}
+      JIRA_PASSWD=${12}
+      JAVA5_HOME=${13}
+      CURL=${14}
+      defect=${15}
+		
+      ### Retrieve the defect number
+      if [ -z "$defect" ] ; then
+        echo "Could not determine the patch to test.  Exiting."
+        cleanupAndExit 0
+      fi
+
+      if [ ! -e "$PATCH_DIR" ] ; then
+        mkdir -p $PATCH_DIR 
+      fi
+
+      ;;
+    DEVELOPER)
+      ### Set HUDSON to false to indicate that this script is being run by a developer
+      HUDSON=false
+      if [[ $# != 10 ]] ; then
+        echo "ERROR: usage $0 DEVELOPER <PATCH_FILE> <SCRATCH_DIR> <SVN_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JAVA5_HOME>"
+        cleanupAndExit 0
+      fi
+      ### PATCH_FILE contains the location of the patchfile
+      PATCH_FILE=$2 
+      if [[ ! -e "$PATCH_FILE" ]] ; then
+        echo "Unable to locate the patch file $PATCH_FILE"
+        cleanupAndExit 0
+      fi
+      PATCH_DIR=$3
+      ### Check if $PATCH_DIR exists. If it does not exist, create a new directory
+      if [[ ! -e "$PATCH_DIR" ]] ; then
+	mkdir "$PATCH_DIR"
+	if [[ $? == 0 ]] ; then 
+	  echo "$PATCH_DIR has been created"
+	else
+	  echo "Unable to create $PATCH_DIR"
+	  cleanupAndExit 0
+	fi
+      fi
+      SVN=$4
+      GREP=$5
+      PATCH=$6
+      FINDBUGS_HOME=$7
+      FORREST_HOME=$8
+      BASEDIR=$9
+      JAVA5_HOME=${10}
+      ### Obtain the patch filename to append it to the version number
+      defect=`basename $PATCH_FILE` 
+      ;;
+    *)
+      echo "ERROR: usage $0 HUDSON [args] | DEVELOPER [args]"
+      cleanupAndExit 0
+      ;;
+  esac
+}
+
+###############################################################################
+checkout () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Testing patch for ${defect}."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  ### When run by a developer, if the workspace contains modifications, do not continue
+  status=`$SVN stat --ignore-externals | sed -e '/^X[ ]*/D'`
+  if [[ $HUDSON == "false" ]] ; then
+    if [[ "$status" != "" ]] ; then
+      echo "ERROR: can't run in a workspace that contains the following modifications"
+      echo "$status"
+      cleanupAndExit 1
+    fi
+  else   
+    cd $BASEDIR
+    $SVN revert -R .
+    rm -rf `$SVN status --no-ignore`
+    $SVN update
+  fi
+  return $?
+}
+
+###############################################################################
+setup () {
+  ### Download latest patch file (ignoring .htm and .html) when run from patch process
+  if [[ $HUDSON == "true" ]] ; then
+    $WGET -q -O $PATCH_DIR/jira http://issues.apache.org/jira/browse/$defect
+    if [[ `$GREP -c 'Patch Available' $PATCH_DIR/jira` == 0 ]] ; then
+      echo "$defect is not \"Patch Available\".  Exiting."
+      cleanupAndExit 0
+    fi
+    relativePatchURL=`$GREP -o '"/jira/secure/attachment/[0-9]*/[^"]*' $PATCH_DIR/jira | $GREP -v -e 'htm[l]*$' | sort | tail -1 | $GREP -o '/jira/secure/attachment/[0-9]*/[^"]*'`
+    patchURL="http://issues.apache.org${relativePatchURL}"
+    patchNum=`echo $patchURL | $GREP -o '[0-9]*/' | $GREP -o '[0-9]*'`
+    echo "$defect patch is being downloaded at `date` from"
+    echo "$patchURL"
+    $WGET -q -O $PATCH_DIR/patch $patchURL
+    JIRA_COMMENT="Here are the results of testing the latest attachment 
+  $patchURL
+  against trunk revision ${SVN_REVISION}."
+
+  ### Copy the patch file to $PATCH_DIR
+  else
+    cp $PATCH_FILE $PATCH_DIR/patch
+    if [[ $? == 0 ]] ; then
+      echo "Patch file $PATCH_FILE copied to $PATCH_DIR"
+    else
+      echo "Could not copy $PATCH_FILE to $PATCH_DIR"
+      cleanupAndExit 0
+    fi
+  fi
+  ### exit if warnings are NOT defined in the properties file
+  if [ -z "$OK_FINDBUGS_WARNINGS" ] || [[ -z "$OK_JAVADOC_WARNINGS" ]] || [[ -z $OK_RELEASEAUDIT_WARNINGS ]]; then
+    echo "Please define the following properties in test-patch.properties file"
+	 echo  "OK_FINDBUGS_WARNINGS"
+	 echo  "OK_RELEASEAUDIT_WARNINGS"
+	 echo  "OK_JAVADOC_WARNINGS"
+    cleanupAndExit 1
+  fi
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo " Pre-build trunk to verify trunk stability and javac warnings" 
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant  -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1"
+ $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1
+  if [[ $? != 0 ]] ; then
+    echo "Trunk compilation is broken?"
+    cleanupAndExit 1
+  fi
+}
+
+###############################################################################
+### Check for @author tags in the patch
+checkAuthor () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Checking there are no @author tags in the patch."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  authorTags=`$GREP -c -i '@author' $PATCH_DIR/patch`
+  echo "There appear to be $authorTags @author tags in the patch."
+  if [[ $authorTags != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 @author.  The patch appears to contain $authorTags @author tags which the Zookeeper community has agreed to not allow in code contributions."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 @author.  The patch does not contain any @author tags."
+  return 0
+}
+
+###############################################################################
+### Check for tests in the patch
+checkTests () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Checking there are new or changed tests in the patch."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  testReferences=`$GREP -c -i '/test' $PATCH_DIR/patch`
+  echo "There appear to be $testReferences test files referenced in the patch."
+  if [[ $testReferences == 0 ]] ; then
+    if [[ $HUDSON == "true" ]] ; then
+      patchIsDoc=`$GREP -c -i 'title="documentation' $PATCH_DIR/jira`
+      if [[ $patchIsDoc != 0 ]] ; then
+        echo "The patch appears to be a documentation patch that doesn't require tests."
+        JIRA_COMMENT="$JIRA_COMMENT
+
+    +0 tests included.  The patch appears to be a documentation patch that doesn't require tests."
+        return 0
+      fi
+    fi
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 tests included.  The patch doesn't appear to include any new or modified tests.
+                        Please justify why no new tests are needed for this patch.
+                        Also please list what manual steps were performed to verify this patch."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 tests included.  The patch appears to include $testReferences new or modified tests."
+  return 0
+}
+
+###############################################################################
+### Attempt to apply the patch
+applyPatch () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Applying patch."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  $PATCH -E -p0 < $PATCH_DIR/patch
+  if [[ $? != 0 ]] ; then
+    echo "PATCH APPLICATION FAILED"
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 patch.  The patch command could not apply the patch."
+    return 1
+  fi
+  return 0
+}
+
+###############################################################################
+### Check there are no javadoc warnings
+checkJavadocWarnings () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched javadoc warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt
+  javadocWarnings=`$GREP -o '\[javadoc\] [0-9]* warning' $PATCH_DIR/patchJavadocWarnings.txt | awk '{total += $2} END {print total}'`
+  echo ""
+  echo ""
+  echo "There appear to be $javadocWarnings javadoc warnings generated by the patched build."
+
+  ### if current warnings greater than OK_JAVADOC_WARNINGS
+  if [[ $javadocWarnings > $OK_JAVADOC_WARNINGS ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 javadoc.  The javadoc tool appears to have generated `expr $(($javadocWarnings-$OK_JAVADOC_WARNINGS))` warning messages."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 javadoc.  The javadoc tool did not generate any warning messages."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of Javac warnings
+checkJavacWarnings () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched javac warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1"
+  $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1
+  if [[ $? != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 javac.  The patch appears to cause tar ant target to fail."
+    return 1
+  fi
+  ### Compare trunk and patch javac warning numbers
+  if [[ -f $PATCH_DIR/patchJavacWarnings.txt ]] ; then
+    trunkJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/trunkJavacWarnings.txt | awk '{total += $2} END {print total}'`
+    patchJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/patchJavacWarnings.txt | awk '{total += $2} END {print total}'`
+    echo "There appear to be $trunkJavacWarnings javac compiler warnings before the patch and $patchJavacWarnings javac compiler warnings after applying the patch."
+    if [[ $patchJavacWarnings != "" && $trunkJavacWarnings != "" ]] ; then
+      if [[ $patchJavacWarnings -gt $trunkJavacWarnings ]] ; then
+        JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 javac.  The applied patch generated $patchJavacWarnings javac compiler warnings (more than the trunk's current $trunkJavacWarnings warnings)."
+        return 1
+      fi
+    fi
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 javac.  The applied patch does not increase the total number of javac compiler warnings."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of release audit (RAT) warnings
+checkReleaseAuditWarnings () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched release audit warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1"
+  $ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1
+
+  ### Compare trunk and patch release audit warning numbers
+  if [[ -f $PATCH_DIR/patchReleaseAuditWarnings.txt ]] ; then
+    patchReleaseAuditWarnings=`$GREP -c '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt`
+    echo ""
+    echo ""
+    echo "There appear to be $OK_RELEASEAUDIT_WARNINGS release audit warnings before the patch and $patchReleaseAuditWarnings release audit warnings after applying the patch."
+    if [[ $patchReleaseAuditWarnings != "" && $OK_RELEASEAUDIT_WARNINGS != "" ]] ; then
+      if [[ $patchReleaseAuditWarnings -gt $OK_RELEASEAUDIT_WARNINGS ]] ; then
+        JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 release audit.  The applied patch generated $patchReleaseAuditWarnings release audit warnings (more than the trunk's current $OK_RELEASEAUDIT_WARNINGS warnings)."
+        $GREP '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt > $PATCH_DIR/patchReleaseAuditProblems.txt
+        echo "Lines that start with ????? in the release audit report indicate files that do not have an Apache license header." >> $PATCH_DIR/patchReleaseAuditProblems.txt
+        JIRA_COMMENT_FOOTER="Release audit warnings: $BUILD_URL/artifact/trunk/patchprocess/patchReleaseAuditProblems.txt
+$JIRA_COMMENT_FOOTER"
+        return 1
+      fi
+    fi
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 release audit.  The applied patch does not increase the total number of release audit warnings."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of Checkstyle warnings
+checkStyle () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched checkstyle warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "THIS IS NOT IMPLEMENTED YET"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle
+  JIRA_COMMENT_FOOTER="Checkstyle results: $BUILD_URL/artifact/trunk/build/test/checkstyle-errors.html
+$JIRA_COMMENT_FOOTER"
+  ### TODO: calculate actual patchStyleErrors
+#  patchStyleErrors=0
+#  if [[ $patchStyleErrors != 0 ]] ; then
+#    JIRA_COMMENT="$JIRA_COMMENT
+#
+#    -1 checkstyle.  The patch generated $patchStyleErrors code style errors."
+#    return 1
+#  fi
+#  JIRA_COMMENT="$JIRA_COMMENT
+#
+#    +1 checkstyle.  The patch generated 0 code style errors."
+  return 0
+}
+
+###############################################################################
+### Check there are no changes in the number of Findbugs warnings
+checkFindbugsWarnings () {
+  findbugs_version=`${FINDBUGS_HOME}/bin/findbugs -version`
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Determining number of patched Findbugs warnings."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  echo "$ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs"
+  $ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs
+  if [ $? != 0 ] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 findbugs.  The patch appears to cause Findbugs (version ${findbugs_version}) to fail."
+    return 1
+  fi
+JIRA_COMMENT_FOOTER="Findbugs warnings: $BUILD_URL/artifact/trunk/build/test/findbugs/newPatchFindbugsWarnings.html
+$JIRA_COMMENT_FOOTER"
+  cp $BASEDIR/build/test/findbugs/*.xml $PATCH_DIR/patchFindbugsWarnings.xml
+  $FINDBUGS_HOME/bin/setBugDatabaseInfo -timestamp "01/01/2000" \
+    $PATCH_DIR/patchFindbugsWarnings.xml \
+    $PATCH_DIR/patchFindbugsWarnings.xml
+  findbugsWarnings=`$FINDBUGS_HOME/bin/filterBugs -first "01/01/2000" $PATCH_DIR/patchFindbugsWarnings.xml \
+    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml | /usr/bin/awk '{print $1}'`
+  $FINDBUGS_HOME/bin/convertXmlToText -html \
+    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml \
+    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html
+  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html $PATCH_DIR/newPatchFindbugsWarnings.html
+  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml $PATCH_DIR/newPatchFindbugsWarnings.xml
+
+  ### if current warnings greater than OK_FINDBUGS_WARNINGS
+  if [[ $findbugsWarnings > $OK_FINDBUGS_WARNINGS ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 findbugs.  The patch appears to introduce `expr $(($findbugsWarnings-$OK_FINDBUGS_WARNINGS))` new Findbugs (version ${findbugs_version}) warnings."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 findbugs.  The patch does not introduce any new Findbugs (version ${findbugs_version}) warnings."
+  return 0
+}
+
+###############################################################################
+### Run the test-core target
+runCoreTests () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Running core tests."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  
+  ### Kill any rogue build processes from the last attempt
+  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
+
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core
+  if [[ $? != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 core tests.  The patch failed core unit tests."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 core tests.  The patch passed core unit tests."
+  return 0
+}
+
+###############################################################################
+### Run the test-contrib target
+runContribTests () {
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Running contrib tests."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+
+  ### Kill any rogue build processes from the last attempt
+  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
+
+  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib"
+  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib
+  if [[ $? != 0 ]] ; then
+    JIRA_COMMENT="$JIRA_COMMENT
+
+    -1 contrib tests.  The patch failed contrib unit tests."
+    return 1
+  fi
+  JIRA_COMMENT="$JIRA_COMMENT
+
+    +1 contrib tests.  The patch passed contrib unit tests."
+  return 0
+}
+
+###############################################################################
+### Submit a comment to the defect's Jira
+submitJiraComment () {
+  local result=$1
+  ### Do not output the value of JIRA_COMMENT_FOOTER when run by a developer
+  if [[  $HUDSON == "false" ]] ; then
+    JIRA_COMMENT_FOOTER=""
+  fi
+  if [[ $result == 0 ]] ; then
+    comment="+1 overall.  $JIRA_COMMENT
+
+$JIRA_COMMENT_FOOTER"
+  else
+    comment="-1 overall.  $JIRA_COMMENT
+
+$JIRA_COMMENT_FOOTER"
+  fi
+  ### Output the test result to the console
+  echo "
+
+
+
+$comment"  
+
+  if [[ $HUDSON == "true" ]] ; then
+    echo ""
+    echo ""
+    echo "======================================================================"
+    echo "======================================================================"
+    echo "    Adding comment to Jira."
+    echo "======================================================================"
+    echo "======================================================================"
+    echo ""
+    echo ""
+    ### Update Jira with a comment
+    export USER=hudson
+    $JIRACLI -s https://issues.apache.org/jira -a addcomment -u hadoopqa -p $JIRA_PASSWD --comment "$comment" --issue $defect
+    $JIRACLI -s https://issues.apache.org/jira -a logout -u hadoopqa -p $JIRA_PASSWD
+  fi
+}
+
+###############################################################################
+### Cleanup files
+cleanupAndExit () {
+  local result=$1
+  if [[ $HUDSON == "true" ]] ; then
+    if [ -e "$PATCH_DIR" ] ; then
+      mv $PATCH_DIR $BASEDIR
+    fi
+  fi
+  echo ""
+  echo ""
+  echo "======================================================================"
+  echo "======================================================================"
+  echo "    Finished build."
+  echo "======================================================================"
+  echo "======================================================================"
+  echo ""
+  echo ""
+  exit $result
+}
+
+###############################################################################
+###############################################################################
+###############################################################################
+
+JIRA_COMMENT=""
+JIRA_COMMENT_FOOTER="Console output: $BUILD_URL/console
+
+This message is automatically generated."
+
+### Check if arguments to the script have been specified properly or not
+parseArgs $@
+cd $BASEDIR
+
+checkout
+RESULT=$?
+if [[ $HUDSON == "true" ]] ; then
+  if [[ $RESULT != 0 ]] ; then
+    exit 100
+  fi
+fi
+setup
+checkAuthor
+RESULT=$?
+
+checkTests
+(( RESULT = RESULT + $? ))
+applyPatch
+if [[ $? != 0 ]] ; then
+  submitJiraComment 1
+  cleanupAndExit 1
+fi
+checkJavadocWarnings
+(( RESULT = RESULT + $? ))
+checkJavacWarnings
+(( RESULT = RESULT + $? ))
+### Checkstyle not implemented yet
+#checkStyle
+#(( RESULT = RESULT + $? ))
+checkFindbugsWarnings
+(( RESULT = RESULT + $? ))
+checkReleaseAuditWarnings
+(( RESULT = RESULT + $? ))
+### Do not call these when run by a developer 
+if [[ $HUDSON == "true" ]] ; then
+  runCoreTests
+  (( RESULT = RESULT + $? ))
+  runContribTests
+  (( RESULT = RESULT + $? ))
+fi
+JIRA_COMMENT_FOOTER="Test results: $BUILD_URL/testReport/
+$JIRA_COMMENT_FOOTER"
+
+submitJiraComment $RESULT
+cleanupAndExit $RESULT


[06/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java
new file mode 100644
index 0000000..de26698
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java
@@ -0,0 +1,378 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetSocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.quorum.Election;
+import org.apache.zookeeper.server.quorum.FLELostMessageTest;
+import org.apache.zookeeper.server.quorum.LeaderElection;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.Vote;
+import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LENonTerminateTest extends ZKTestCase {
+    public class MockLeaderElection extends LeaderElection {
+        public MockLeaderElection(QuorumPeer self) {
+            super(self);            
+        }
+
+        /**
+         * Temporary for 3.3.0 - we want to ensure that a round of voting happens
+         * before any of the peers update their votes. The easiest way to do that
+         * is to add a latch that all wait on after counting their votes. 
+         * 
+         * In 3.4.0 we intend to make this class more testable, and therefore
+         * there should be much less duplicated code.
+         * 
+         * JMX bean method calls are removed to reduce noise.
+         */
+        public Vote lookForLeader() throws InterruptedException {            
+            self.setCurrentVote(new Vote(self.getId(),
+                    self.getLastLoggedZxid()));
+            // We are going to look for a leader by casting a vote for ourself
+            byte requestBytes[] = new byte[4];
+            ByteBuffer requestBuffer = ByteBuffer.wrap(requestBytes);
+            byte responseBytes[] = new byte[28];
+            ByteBuffer responseBuffer = ByteBuffer.wrap(responseBytes);
+            /* The current vote for the leader. Initially me! */
+            DatagramSocket s = null;
+            try {
+                s = new DatagramSocket();
+                s.setSoTimeout(200);
+            } catch (SocketException e1) {
+                LOG.error("Socket exception when creating socket for leader election", e1);
+                System.exit(4);
+            }
+            DatagramPacket requestPacket = new DatagramPacket(requestBytes,
+                    requestBytes.length);
+            DatagramPacket responsePacket = new DatagramPacket(responseBytes,
+                    responseBytes.length);
+            int xid = epochGen.nextInt();
+            while (self.isRunning()) {
+                HashMap<InetSocketAddress, Vote> votes =
+                    new HashMap<InetSocketAddress, Vote>(self.getVotingView().size());
+
+                requestBuffer.clear();
+                requestBuffer.putInt(xid);
+                requestPacket.setLength(4);
+                HashSet<Long> heardFrom = new HashSet<Long>();
+                for (QuorumServer server :
+                    self.getVotingView().values())
+                {
+                    LOG.info("Server address: " + server.addr);
+                    try {
+                        requestPacket.setSocketAddress(server.addr);
+                    } catch (IllegalArgumentException e) {
+                        // Sun doesn't include the address that causes this
+                        // exception to be thrown, so we wrap the exception
+                        // in order to capture this critical detail.
+                        throw new IllegalArgumentException(
+                                "Unable to set socket address on packet, msg:"
+                                + e.getMessage() + " with addr:" + server.addr,
+                                e);
+                    }
+
+                    try {
+                        s.send(requestPacket);
+                        responsePacket.setLength(responseBytes.length);
+                        s.receive(responsePacket);
+                        if (responsePacket.getLength() != responseBytes.length) {
+                            LOG.error("Got a short response: "
+                                    + responsePacket.getLength());
+                            continue;
+                        }
+                        responseBuffer.clear();
+                        int recvedXid = responseBuffer.getInt();
+                        if (recvedXid != xid) {
+                            LOG.error("Got bad xid: expected " + xid
+                                    + " got " + recvedXid);
+                            continue;
+                        }
+                        long peerId = responseBuffer.getLong();
+                        heardFrom.add(peerId);
+                        //if(server.id != peerId){
+                        Vote vote = new Vote(responseBuffer.getLong(),
+                                responseBuffer.getLong());
+                        InetSocketAddress addr =
+                            (InetSocketAddress) responsePacket
+                            .getSocketAddress();
+                        votes.put(addr, vote);
+                        //}
+                    } catch (IOException e) {
+                        LOG.warn("Ignoring exception while looking for leader",
+                                e);
+                        // Errors are okay, since hosts may be
+                        // down
+                    }
+                }
+
+                ElectionResult result = countVotes(votes, heardFrom);
+                
+                /**
+                 * This is the only difference from LeaderElection - wait for
+                 * this latch on the first time through this method. This ensures
+                 * that the first round of voting happens before setCurrentVote
+                 * is called below.
+                 */
+                LOG.info("Waiting for first round of voting to complete");
+                latch.countDown();
+                Assert.assertTrue("Thread timed out waiting for latch",
+                        latch.await(10000, TimeUnit.MILLISECONDS));
+                
+                // ZOOKEEPER-569:
+                // If no votes are received for live peers, reset to voting 
+                // for ourselves as otherwise we may hang on to a vote 
+                // for a dead peer                 
+                if (result.numValidVotes == 0) {
+                    self.setCurrentVote(new Vote(self.getId(),
+                            self.getLastLoggedZxid()));
+                } else {
+                    if (result.winner.getId() >= 0) {
+                        self.setCurrentVote(result.vote);
+                        // To do: this doesn't use a quorum verifier
+                        if (result.winningCount > (self.getVotingView().size() / 2)) {
+                            self.setCurrentVote(result.winner);
+                            s.close();
+                            Vote current = self.getCurrentVote();
+                            LOG.info("Found leader: my type is: " + self.getLearnerType());
+                            /*
+                             * We want to make sure we implement the state machine
+                             * correctly. If we are a PARTICIPANT, once a leader
+                             * is elected we can move either to LEADING or 
+                             * FOLLOWING. However if we are an OBSERVER, it is an
+                             * error to be elected as a Leader.
+                             */
+                            if (self.getLearnerType() == LearnerType.OBSERVER) {
+                                if (current.getId() == self.getId()) {
+                                    // This should never happen!
+                                    LOG.error("OBSERVER elected as leader!");
+                                    Thread.sleep(100);
+                                }
+                                else {
+                                    self.setPeerState(ServerState.OBSERVING);
+                                    Thread.sleep(100);
+                                    return current;
+                                }
+                            } else {
+                                self.setPeerState((current.getId() == self.getId())
+                                        ? ServerState.LEADING: ServerState.FOLLOWING);
+                                if (self.getPeerState() == ServerState.FOLLOWING) {
+                                    Thread.sleep(100);
+                                }                            
+                                return current;
+                            }
+                        }
+                    }
+                }
+                Thread.sleep(1000);
+            }
+            return null;
+        }         
+    }
+    
+    public class MockQuorumPeer extends QuorumPeer {
+        public MockQuorumPeer(Map<Long,QuorumServer> quorumPeers, File snapDir,
+                File logDir, int clientPort, int electionAlg,
+                long myid, int tickTime, int initLimit, int syncLimit)
+        throws IOException
+        {
+            super(quorumPeers, snapDir, logDir, electionAlg,
+                    myid,tickTime, initLimit,syncLimit, false,
+                    ServerCnxnFactory.createFactory(clientPort, -1),
+                    new QuorumMaj(countParticipants(quorumPeers)));
+        }
+        
+        protected  Election createElectionAlgorithm(int electionAlgorithm){
+            LOG.info("Returning mocked leader election");
+            return new MockLeaderElection(this);
+        }
+    }
+    
+    
+    protected static final Logger LOG = LoggerFactory.getLogger(FLELostMessageTest.class);
+    
+    int count;
+    HashMap<Long,QuorumServer> peers;
+    File tmpdir[];
+    int port[];   
+   
+    @Before
+    public void setUp() throws Exception {
+        count = 3;
+
+        peers = new HashMap<Long,QuorumServer>(count);
+        tmpdir = new File[count];
+        port = new int[count];
+    }
+
+    static final CountDownLatch latch = new CountDownLatch(2);
+    static final CountDownLatch mockLatch = new CountDownLatch(1);
+
+    class LEThread extends Thread {
+        int i;
+        QuorumPeer peer;
+        
+
+        LEThread(QuorumPeer peer, int i) {
+            this.i = i;
+            this.peer = peer;
+            LOG.info("Constructor: " + getName());
+
+        }
+
+        public void run(){            
+            try{
+                Vote v = null;
+                peer.setPeerState(ServerState.LOOKING);
+                LOG.info("Going to call leader election: " + i);
+                v = peer.getElectionAlg().lookForLeader();
+
+                if (v == null){
+                    Assert.fail("Thread " + i + " got a null vote");
+                }                                
+
+                /*
+                 * A real zookeeper would take care of setting the current vote. Here
+                 * we do it manually.
+                 */
+                peer.setCurrentVote(v);
+
+                LOG.info("Finished election: " + i + ", " + v.getId());
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            LOG.info("Joining");
+        }
+    }
+    
+    /**
+     * This tests ZK-569.
+     * With three peers A, B and C, the following could happen:
+     * 1. Round 1, A,B and C all vote for themselves
+     * 2. Round 2, C dies, A and B vote for C
+     * 3. Because C has died, votes for it are ignored, but A and B never
+     * reset their votes. Hence LE never terminates. ZK-569 fixes this by
+     * resetting votes to themselves if the set of votes for live peers is null.
+     */
+    @Test
+    public void testNonTermination() throws Exception {                
+        LOG.info("TestNonTermination: " + getTestName()+ ", " + count);
+        for(int i = 0; i < count; i++) {
+            int clientport = PortAssignment.unique();
+            peers.put(Long.valueOf(i),
+                      new QuorumServer(i, "127.0.0.1", clientport,
+                                       PortAssignment.unique(), null));
+            tmpdir[i] = ClientBase.createTmpDir();
+            port[i] = clientport;
+        }
+        
+        /*
+         * peer1 and peer2 are A and B in the above example. 
+         */
+        QuorumPeer peer1 = new MockQuorumPeer(peers, tmpdir[0], tmpdir[0], port[0], 0, 0, 2, 2, 2);
+        peer1.startLeaderElection();
+        LEThread thread1 = new LEThread(peer1, 0);
+        
+        QuorumPeer peer2 = new MockQuorumPeer(peers, tmpdir[1], tmpdir[1], port[1], 0, 1, 2, 2, 2);
+        peer2.startLeaderElection();        
+        LEThread thread2 = new LEThread(peer2, 1);
+                            
+        /*
+         * Start mock server.
+         */
+        Thread thread3 = new Thread() { 
+            public void run() {
+                try {
+                    mockServer();
+                } catch (Exception e) {
+                    LOG.error("exception", e);
+                    Assert.fail("Exception when running mocked server " + e);
+                }
+            }
+        };        
+        
+        thread3.start();
+        Assert.assertTrue("mockServer did not start in 5s",
+                mockLatch.await(5000, TimeUnit.MILLISECONDS));
+        thread1.start();
+        thread2.start();
+        /*
+         * Occasionally seen false negatives with a 5s timeout.
+         */
+        thread1.join(15000);
+        thread2.join(15000);
+        thread3.join(15000);
+        if (thread1.isAlive() || thread2.isAlive() || thread3.isAlive()) {
+            Assert.fail("Threads didn't join");
+        }
+    }
+     
+    /**
+     * MockServer plays the role of peer C. Respond to two requests for votes
+     * with vote for self and then Assert.fail. 
+     */
+    void mockServer() throws InterruptedException, IOException {          
+        byte b[] = new byte[36];
+        ByteBuffer responseBuffer = ByteBuffer.wrap(b);
+        DatagramPacket packet = new DatagramPacket(b, b.length);
+        QuorumServer server = peers.get(Long.valueOf(2));
+        DatagramSocket udpSocket = new DatagramSocket(server.addr.getPort());
+        LOG.info("In MockServer");
+        mockLatch.countDown();
+        Vote current = new Vote(2, 1);
+        for (int i=0;i<2;++i) {
+            udpSocket.receive(packet);
+            responseBuffer.rewind();
+            LOG.info("Received " + responseBuffer.getInt() + " " + responseBuffer.getLong() + " " + responseBuffer.getLong());
+            LOG.info("From " + packet.getSocketAddress());
+            responseBuffer.clear();
+            responseBuffer.getInt(); // Skip the xid
+            responseBuffer.putLong(2);
+            
+            responseBuffer.putLong(current.getId());
+            responseBuffer.putLong(current.getZxid());
+            packet.setData(b);
+            udpSocket.send(packet);
+        }
+    }    
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/LETest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/LETest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LETest.java
new file mode 100644
index 0000000..0fd3430
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LETest.java
@@ -0,0 +1,137 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Random;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.server.quorum.LeaderElection;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.Vote;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LETest extends ZKTestCase {
+    private static final Logger LOG = LoggerFactory.getLogger(LETest.class);
+    volatile Vote votes[];
+    volatile boolean leaderDies;
+    volatile long leader = -1;
+    Random rand = new Random();
+    class LEThread extends Thread {
+        LeaderElection le;
+        int i;
+        QuorumPeer peer;
+        LEThread(LeaderElection le, QuorumPeer peer, int i) {
+            this.le = le;
+            this.i = i;
+            this.peer = peer;
+        }
+        public void run() {
+            try {
+                Vote v = null;
+                while(true) {
+                    v = le.lookForLeader();
+                    votes[i] = v;
+                    if (v.getId() == i) {
+                        synchronized(LETest.this) {
+                            if (leaderDies) {
+                                leaderDies = false;
+                                peer.stopLeaderElection();
+                                LOG.info("Leader " + i + " dying");
+                                leader = -2;
+                            } else {
+                                leader = i;
+                            }
+                            LETest.this.notifyAll();
+                        }
+                        break;
+                    }
+                    synchronized(LETest.this) {
+                        if (leader == -1) {
+                            LETest.this.wait();
+                        }
+                        if (leader == v.getId()) {
+                            break;
+                        }
+                    }
+                    Thread.sleep(rand.nextInt(1000));
+                    peer.setCurrentVote(new Vote(peer.getId(), 0));
+                }
+                LOG.info("Thread " + i + " votes " + v);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Test
+    public void testLE() throws Exception {
+        int count = 30;
+        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>(count);
+        ArrayList<LEThread> threads = new ArrayList<LEThread>(count);
+        File tmpdir[] = new File[count];
+        int port[] = new int[count];
+        votes = new Vote[count];
+        for(int i = 0; i < count; i++) {
+            peers.put(Long.valueOf(i),
+                      new QuorumServer(i, "127.0.0.1", PortAssignment.unique(), 0, null));
+            tmpdir[i] = ClientBase.createTmpDir();
+            port[i] = PortAssignment.unique();
+        }
+        LeaderElection le[] = new LeaderElection[count];
+        leaderDies = true;
+        boolean allowOneBadLeader = leaderDies;
+        for(int i = 0; i < le.length; i++) {
+            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i],
+                    port[i], 0, i, 1000, 2, 2);
+            peer.startLeaderElection();
+            le[i] = new LeaderElection(peer);
+            LEThread thread = new LEThread(le[i], peer, i);
+            thread.start();
+            threads.add(thread);
+        }
+        for(int i = 0; i < threads.size(); i++) {
+            threads.get(i).join(15000);
+            if (threads.get(i).isAlive()) {
+                Assert.fail("Threads didn't join");
+            }
+        }
+        long id = votes[0].getId();
+        for(int i = 1; i < votes.length; i++) {
+            if (votes[i] == null) {
+                Assert.fail("Thread " + i + " had a null vote");
+            }
+            if (votes[i].getId() != id) {
+                if (allowOneBadLeader && votes[i].getId() == i) {
+                    allowOneBadLeader = false;
+                } else {
+                    Assert.fail("Thread " + i + " got " + votes[i].getId() + " expected " + id);
+                }
+            }
+        }
+    }    
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java
new file mode 100644
index 0000000..9135307
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java
@@ -0,0 +1,175 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.jute.BinaryInputArchive;
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.jute.Record;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.common.Time;
+import org.apache.zookeeper.server.DataNode;
+import org.apache.zookeeper.server.DataTree;
+import org.apache.zookeeper.server.persistence.FileHeader;
+import org.apache.zookeeper.server.persistence.FileTxnLog;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
+import org.apache.zookeeper.txn.CreateTxn;
+import org.apache.zookeeper.txn.DeleteTxn;
+import org.apache.zookeeper.txn.MultiTxn;
+import org.apache.zookeeper.txn.Txn;
+import org.apache.zookeeper.txn.TxnHeader;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class LoadFromLogNoServerTest extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(LoadFromLogNoServerTest.class);
+
+    /**
+     * For ZOOKEEPER-1046. Verify if cversion and pzxid if incremented
+     * after create/delete failure during restore.
+     */
+    @Test
+    public void testTxnFailure() throws Exception {
+        long count = 1;
+        File tmpDir = ClientBase.createTmpDir();
+        FileTxnSnapLog logFile = new FileTxnSnapLog(tmpDir, tmpDir);
+        DataTree dt = new DataTree();
+        dt.createNode("/test", new byte[0], null, 0, -1, 1, 1);
+        for (count = 1; count <= 3; count++) {
+            dt.createNode("/test/" + count, new byte[0], null, 0, -1, count,
+                    Time.currentElapsedTime());
+        }
+        DataNode zk = dt.getNode("/test");
+
+        // Make create to fail, then verify cversion.
+        LOG.info("Attempting to create " + "/test/" + (count - 1));
+        doOp(logFile, ZooDefs.OpCode.create, "/test/" + (count - 1), dt, zk, -1);
+
+        LOG.info("Attempting to create " + "/test/" + (count - 1));
+        doOp(logFile, ZooDefs.OpCode.create, "/test/" + (count - 1), dt, zk,
+                zk.stat.getCversion() + 1);
+
+        LOG.info("Attempting to create " + "/test/" + (count - 1));
+        doOp(logFile, ZooDefs.OpCode.multi, "/test/" + (count - 1), dt, zk,
+                zk.stat.getCversion() + 1);
+
+        LOG.info("Attempting to create " + "/test/" + (count - 1));
+        doOp(logFile, ZooDefs.OpCode.multi, "/test/" + (count - 1), dt, zk,
+                -1);
+
+        // Make delete fo fail, then verify cversion.
+        // this doesn't happen anymore, we only set the cversion on create
+        // LOG.info("Attempting to delete " + "/test/" + (count + 1));
+        // doOp(logFile, OpCode.delete, "/test/" + (count + 1), dt, zk);
+    }
+
+    /*
+     * Does create/delete depending on the type and verifies
+     * if cversion before the operation is 1 less than cversion afer.
+     */
+    private void doOp(FileTxnSnapLog logFile, int type, String path,
+                      DataTree dt, DataNode parent, int cversion) throws Exception {
+        int lastSlash = path.lastIndexOf('/');
+        String parentName = path.substring(0, lastSlash);
+
+        int prevCversion = parent.stat.getCversion();
+        long prevPzxid = parent.stat.getPzxid();
+        List<String> child = dt.getChildren(parentName, null, null);
+        String childStr = "";
+        for (String s : child) {
+            childStr += s + " ";
+        }
+        LOG.info("Children: " + childStr + " for " + parentName);
+        LOG.info("(cverions, pzxid): " + prevCversion + ", " + prevPzxid);
+
+        Record txn = null;
+        TxnHeader txnHeader = null;
+        if (type == ZooDefs.OpCode.delete) {
+            txn = new DeleteTxn(path);
+            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
+                    Time.currentElapsedTime(), ZooDefs.OpCode.delete);
+        } else if (type == ZooDefs.OpCode.create) {
+            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
+                    Time.currentElapsedTime(), ZooDefs.OpCode.create);
+            txn = new CreateTxn(path, new byte[0], null, false, cversion);
+        }
+        else if (type == ZooDefs.OpCode.multi) {
+            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
+                    Time.currentElapsedTime(), ZooDefs.OpCode.create);
+            txn = new CreateTxn(path, new byte[0], null, false, cversion);
+            ArrayList txnList = new ArrayList();
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+            txn.serialize(boa, "request") ;
+            ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
+            Txn txact = new Txn(ZooDefs.OpCode.create,  bb.array());
+            txnList.add(txact);
+            txn = new MultiTxn(txnList);
+            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
+                    Time.currentElapsedTime(), ZooDefs.OpCode.multi);
+        }
+        logFile.processTransaction(txnHeader, dt, null, txn);
+
+        int newCversion = parent.stat.getCversion();
+        long newPzxid = parent.stat.getPzxid();
+        child = dt.getChildren(parentName, null, null);
+        childStr = "";
+        for (String s : child) {
+            childStr += s + " ";
+        }
+        LOG.info("Children: " + childStr + " for " + parentName);
+        LOG.info("(cverions, pzxid): " +newCversion + ", " + newPzxid);
+        Assert.assertTrue(type + " <cversion, pzxid> verification failed. Expected: <" +
+                        (prevCversion + 1) + ", " + (prevPzxid + 1) + ">, found: <" +
+                        newCversion + ", " + newPzxid + ">",
+                (newCversion == prevCversion + 1 && newPzxid == prevPzxid + 1));
+    }
+
+    /**
+     * Simulates ZOOKEEPER-1069 and verifies that flush() before padLogFile
+     * fixes it.
+     */
+    @Test
+    public void testPad() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+        FileTxnLog txnLog = new FileTxnLog(tmpDir);
+        TxnHeader txnHeader = new TxnHeader(0xabcd, 0x123, 0x123,
+                Time.currentElapsedTime(), ZooDefs.OpCode.create);
+        Record txn = new CreateTxn("/Test", new byte[0], null, false, 1);
+        txnLog.append(txnHeader, txn);
+        FileInputStream in = new FileInputStream(tmpDir.getPath() + "/log." +
+                Long.toHexString(txnHeader.getZxid()));
+        BinaryInputArchive ia  = BinaryInputArchive.getArchive(in);
+        FileHeader header = new FileHeader();
+        header.deserialize(ia, "fileheader");
+        LOG.info("Received magic : " + header.getMagic() +
+                " Expected : " + FileTxnLog.TXNLOG_MAGIC);
+        Assert.assertTrue("Missing magic number ",
+                header.getMagic() == FileTxnLog.TXNLOG_MAGIC);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java
new file mode 100644
index 0000000..dac3910
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java
@@ -0,0 +1,223 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException.NoNodeException;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.persistence.FileTxnLog;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
+import org.apache.zookeeper.server.persistence.TxnLog.TxnIterator;
+import org.apache.zookeeper.txn.TxnHeader;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+public class LoadFromLogTest extends ClientBase {
+    private static final int NUM_MESSAGES = 300;
+    protected static final Logger LOG = LoggerFactory.getLogger(LoadFromLogTest.class);
+
+    // setting up the quorum has a transaction overhead for creating and closing the session
+    private static final int TRANSACTION_OVERHEAD = 2;	
+    private static final int TOTAL_TRANSACTIONS = NUM_MESSAGES + TRANSACTION_OVERHEAD;
+
+    @Before
+     public void setUp() throws Exception {
+                SyncRequestProcessor.setSnapCount(50);
+                super.setUp();
+            }
+
+    /**
+     * test that all transactions from the Log are loaded, and only once
+     * @throws Exception an exception might be thrown here
+     */
+    @Test
+    public void testLoad() throws Exception {
+        ZooKeeper zk = createZKClient(hostPort);
+
+        // generate some transactions that will get logged
+        try {
+            for (int i = 0; i< NUM_MESSAGES; i++) {
+                zk.create("/invalidsnap-" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+            }
+        } finally {
+            zk.close();
+        }
+        stopServer();
+
+        // now verify that the FileTxnLog reads every transaction only once
+        File logDir = new File(tmpDir, FileTxnSnapLog.version + FileTxnSnapLog.VERSION);
+        FileTxnLog txnLog = new FileTxnLog(logDir);
+
+        TxnIterator itr = txnLog.read(0);
+        long expectedZxid = 0;
+        long lastZxid = 0;
+        TxnHeader hdr;
+        do {
+            hdr = itr.getHeader();
+            expectedZxid++;
+            Assert.assertTrue("not the same transaction. lastZxid=" + lastZxid + ", zxid=" + hdr.getZxid(), lastZxid != hdr.getZxid());
+            Assert.assertTrue("excepting next transaction. expected=" + expectedZxid + ", retreived=" + hdr.getZxid(), (hdr.getZxid() == expectedZxid));
+            lastZxid = hdr.getZxid();
+        }while(itr.next());
+	
+        Assert.assertTrue("processed all transactions. " + expectedZxid + " == " + TOTAL_TRANSACTIONS, (expectedZxid == TOTAL_TRANSACTIONS));
+    }
+
+    /**
+     * Test we can restore the snapshot that has data ahead of the zxid
+     * of the snapshot file. 
+     */
+    @Test
+    public void testRestore() throws Exception {
+        ZooKeeper zk = createZKClient(hostPort);
+
+		// generate some transactions
+		String lastPath = null;
+		try {
+			zk.create("/invalidsnap", new byte[0], Ids.OPEN_ACL_UNSAFE,
+					CreateMode.PERSISTENT);
+			for (int i = 0; i < NUM_MESSAGES; i++) {
+				lastPath = zk.create("/invalidsnap/test-", new byte[0],
+						Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+			}
+		} finally {
+			zk.close();
+		}
+		String[] tokens = lastPath.split("-");
+		String expectedPath = "/invalidsnap/test-"
+				+ String.format("%010d",
+                Integer.parseInt(tokens[1]) + 1);
+        ZooKeeperServer zks = getServer(serverFactory);
+		long eZxid = zks.getZKDatabase().getDataTreeLastProcessedZxid();
+		// force the zxid to be behind the content
+		zks.getZKDatabase().setlastProcessedZxid(
+				zks.getZKDatabase().getDataTreeLastProcessedZxid() - 10);
+		LOG.info("Set lastProcessedZxid to "
+				+ zks.getZKDatabase().getDataTreeLastProcessedZxid());
+		// Force snapshot and restore
+		zks.takeSnapshot();
+		zks.shutdown();
+		stopServer();
+
+		startServer();
+		zks = getServer(serverFactory);
+		long fZxid = zks.getZKDatabase().getDataTreeLastProcessedZxid();
+
+		// Verify lastProcessedZxid is set correctly
+		Assert.assertTrue("Restore failed expected zxid=" + eZxid + " found="
+				+ fZxid, fZxid == eZxid);
+        zk = createZKClient(hostPort);
+
+		// Verify correctness of data and whether sequential znode creation 
+		// proceeds correctly after this point
+		String[] children;
+		String path;
+		try {
+			children = zk.getChildren("/invalidsnap", false).toArray(
+					new String[0]);
+			path = zk.create("/invalidsnap/test-", new byte[0],
+					Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+		} finally {
+			zk.close();
+		}
+		LOG.info("Expected " + expectedPath + " found " + path);
+		Assert.assertTrue("Error in sequential znode creation expected "
+				+ expectedPath + " found " + path, path.equals(expectedPath));
+		Assert.assertTrue("Unexpected number of children " + children.length
+				+ " expected " + NUM_MESSAGES,
+				(children.length == NUM_MESSAGES));
+	}
+    
+    /**
+     * Test we can restore a snapshot that has errors and data ahead of the zxid
+     * of the snapshot file. 
+     */
+    @Test
+    public void testRestoreWithTransactionErrors() throws Exception {
+        ZooKeeper zk = createZKClient(hostPort);
+
+        // generate some transactions
+        try {
+            for (int i = 0; i < NUM_MESSAGES; i++) {
+                try {
+                    zk.create("/invaliddir/test-", new byte[0],
+                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+                } catch(NoNodeException e) {
+                    //Expected
+                }
+            }
+        } finally {
+            zk.close();
+        }
+
+        // force the zxid to be behind the content
+        ZooKeeperServer zks = getServer(serverFactory);
+        zks.getZKDatabase().setlastProcessedZxid(
+                zks.getZKDatabase().getDataTreeLastProcessedZxid() - 10);
+        LOG.info("Set lastProcessedZxid to "
+                + zks.getZKDatabase().getDataTreeLastProcessedZxid());
+        
+        // Force snapshot and restore
+        zks.takeSnapshot();
+        zks.shutdown();
+        stopServer();
+
+        zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        startServer();
+   }
+
+    /**
+     * ZOOKEEPER-1573: test restoring a snapshot with deleted txns ahead of the
+     * snapshot file's zxid.
+     */
+    @Test
+    public void testReloadSnapshotWithMissingParent() throws Exception {
+        ZooKeeper zk = createZKClient(hostPort);
+
+        // create transactions to create the snapshot with create/delete pattern
+        zk.create("/a", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        Stat stat = zk.exists("/a", false);
+        long createZxId = stat.getMzxid();
+        zk.create("/a/b", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk.delete("/a/b", -1);
+        zk.delete("/a", -1);
+        // force the zxid to be behind the content
+        ZooKeeperServer zks = getServer(serverFactory);
+        zks.getZKDatabase().setlastProcessedZxid(createZxId);
+        LOG.info("Set lastProcessedZxid to {}", zks.getZKDatabase()
+                .getDataTreeLastProcessedZxid());
+        // Force snapshot and restore
+        zks.takeSnapshot();
+        zks.shutdown();
+        stopServer();
+        startServer();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java
new file mode 100644
index 0000000..0a31ac9
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java
@@ -0,0 +1,139 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.zookeeper.proto.ConnectRequest;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MaxCnxnsTest extends ClientBase {
+    final private int numCnxns = 30;
+    AtomicInteger numConnected = new AtomicInteger(0);
+    String host;
+    int port;
+
+    @Override
+    public void setUp() throws Exception {
+        maxCnxns = numCnxns;
+        super.setUp();
+    }
+
+    class CnxnThread extends Thread {
+        int i;
+        SocketChannel socket;
+        public CnxnThread(int i) {
+            super("CnxnThread-"+i);
+            this.i = i;
+        }
+
+        public void run() {
+            SocketChannel sChannel = null;
+            try {
+                /*
+                 * For future unwary socket programmers: although connect 'blocks' it
+                 * does not require an accept on the server side to return. Therefore
+                 * you can not assume that all the sockets are connected at the end of
+                 * this for loop.
+                 */
+                sChannel = SocketChannel.open();
+                sChannel.connect(new InetSocketAddress(host,port));
+                // Construct a connection request
+                ConnectRequest conReq = new ConnectRequest(0, 0,
+                        10000, 0, "password".getBytes());
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+                boa.writeInt(-1, "len");
+                conReq.serialize(boa, "connect");
+                baos.close();
+                ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
+                bb.putInt(bb.capacity() - 4);
+                bb.rewind();
+
+                /* Send a connect request. Any socket that has been closed (or at least
+                 * not added to the cnxn list on the server) will not have any bytes to
+                 * read and get an eof.
+                 *
+                 *  The trick here was finding a call that caused the server to put
+                 *  bytes in the input stream without closing the cnxn. None of
+                 *  the four letter commands do that, so we actually try to create
+                 *  a session which should send us something back, while maintaining
+                 *  the connection.
+                 */
+
+                int eof = sChannel.write(bb);
+                // If the socket times out, we count that as Assert.failed -
+                // the server should respond within 10s
+                sChannel.socket().setSoTimeout(10000);
+                if (!sChannel.socket().isClosed()){
+                    eof = sChannel.socket().getInputStream().read();
+                    if (eof != -1) {
+                        numConnected.incrementAndGet();
+                    }
+                }
+            }
+            catch (IOException io) {
+                // "Connection reset by peer"
+            }
+            finally {
+                if (sChannel != null) {
+                    try {
+                        sChannel.close();
+                    }
+                    catch (Exception e) {
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Verify the ability to limit the number of concurrent connections.
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    @Test
+    public void testMaxCnxns() throws IOException, InterruptedException{
+        String split[] = hostPort.split(":");
+        host = split[0];
+        port = Integer.parseInt(split[1]);
+        int numThreads = numCnxns + 5;
+        CnxnThread[] threads = new CnxnThread[numThreads];
+
+        for (int i=0;i<numCnxns;++i) {
+          threads[i] = new CnxnThread(i);
+        }
+
+        for (int i=0;i<numCnxns;++i) {
+            threads[i].start();
+        }
+
+        for (int i=0;i<numCnxns;++i) {
+            threads[i].join();
+        }
+        Assert.assertSame(numCnxns,numConnected.get());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java
new file mode 100644
index 0000000..0277c23
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java
@@ -0,0 +1,805 @@
+/*
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.AsyncCallback.MultiCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.Transaction;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.OpResult.CheckResult;
+import org.apache.zookeeper.OpResult.CreateResult;
+import org.apache.zookeeper.OpResult.DeleteResult;
+import org.apache.zookeeper.OpResult.ErrorResult;
+import org.apache.zookeeper.OpResult.SetDataResult;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class MultiTransactionTest extends ClientBase {
+    private static final Logger LOG = Logger.getLogger(MultiTransactionTest.class);
+
+    private ZooKeeper zk;
+    private ZooKeeper zk_chroot;
+
+    private final boolean useAsync;
+
+    public MultiTransactionTest(boolean useAsync) {
+        this.useAsync = useAsync;
+    }
+
+    @Parameters
+    public static Collection<Object[]> configs() {
+        return Arrays.asList(new Object[][] {
+            { false }, { true },
+        });
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        SyncRequestProcessor.setSnapCount(150);
+        super.setUp();
+        zk = createClient();
+    }
+
+    static class MultiResult {
+        int rc;
+        List<OpResult> results;
+        boolean finished = false;
+    }
+
+    private List<OpResult> multi(ZooKeeper zk, Iterable<Op> ops)
+    throws KeeperException, InterruptedException {
+        if (useAsync) {
+            final MultiResult res = new MultiResult();
+            zk.multi(ops, new MultiCallback() {
+                @Override
+                public void processResult(int rc, String path, Object ctx,
+                                          List<OpResult> opResults) {
+                    synchronized (res) {
+                        res.rc = rc;
+                        res.results = opResults;
+                        res.finished = true;
+                        res.notifyAll();
+                    }
+                }
+            }, null);
+            synchronized (res) {
+                while (!res.finished) {
+                    res.wait();
+                }
+            }
+            if (KeeperException.Code.OK.intValue() != res.rc) {
+                KeeperException ke = KeeperException.create(KeeperException.Code.get(res.rc));
+                throw ke;
+            }
+            return res.results;
+        } else {
+            return zk.multi(ops);
+        }
+    }
+
+    private void multiHavingErrors(ZooKeeper zk, Iterable<Op> ops,
+            List<Integer> expectedResultCodes, String expectedErr)
+            throws KeeperException, InterruptedException {
+        if (useAsync) {
+            final MultiResult res = new MultiResult();
+            zk.multi(ops, new MultiCallback() {
+                    @Override
+                    public void processResult(int rc, String path, Object ctx,
+                                              List<OpResult> opResults) {
+                        synchronized (res) {
+                            res.rc = rc;
+                            res.results = opResults;
+                            res.finished = true;
+                            res.notifyAll();
+                        }
+                    }
+                }, null);
+            synchronized (res) {
+                while (!res.finished) {
+                    res.wait();
+                }
+            }
+            for (int i = 0; i < res.results.size(); i++) {
+                OpResult opResult = res.results.get(i);
+                Assert.assertTrue("Did't recieve proper error response",
+                                  opResult instanceof ErrorResult);
+                ErrorResult errRes = (ErrorResult) opResult;
+                Assert.assertEquals("Did't recieve proper error code",
+                                    expectedResultCodes.get(i).intValue(), errRes.getErr());
+            }
+        } else {
+            try {
+                zk.multi(ops);
+                Assert.fail("Shouldn't have validated in ZooKeeper client!");
+            } catch (KeeperException e) {
+                Assert.assertEquals("Wrong exception", expectedErr, e.code()
+                                    .name());
+            } catch (IllegalArgumentException e) {
+                Assert.assertEquals("Wrong exception", expectedErr,
+                                    e.getMessage());
+            }
+        }
+    }
+
+    private List<OpResult> commit(Transaction txn)
+    throws KeeperException, InterruptedException {
+        if (useAsync) {
+            final MultiResult res = new MultiResult();
+            txn.commit(new MultiCallback() {
+                @Override
+                public void processResult(int rc, String path, Object ctx,
+                                          List<OpResult> opResults) {
+                    synchronized (res) {
+                        res.rc = rc;
+                        res.results = opResults;
+                        res.finished = true;
+                        res.notifyAll();
+                    }
+                }
+            }, null);
+            synchronized (res) {
+                while (!res.finished) {
+                    res.wait();
+                }
+            }
+            if (KeeperException.Code.OK.intValue() != res.rc) {
+                KeeperException ke = KeeperException.create(KeeperException.Code.get(res.rc));
+                throw ke;
+            }
+            return res.results;
+        } else {
+            return txn.commit();
+        }
+    }
+
+    /**
+     * Test verifies the multi calls with invalid znode path
+     */
+    @Test(timeout = 90000)
+    public void testInvalidPath() throws Exception {
+        List<Integer> expectedResultCodes = new ArrayList<Integer>();
+        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
+                                .intValue());
+        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
+        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
+                                .intValue());
+        // create with CreateMode
+        List<Op> opList = Arrays.asList(Op.create("/multi0", new byte[0],
+                                                  Ids.OPEN_ACL_UNSAFE,
+                                                  CreateMode.PERSISTENT),
+                                        Op.create(
+                                                  "/multi1/", new byte[0],
+                                                  Ids.OPEN_ACL_UNSAFE,
+                                                  CreateMode.PERSISTENT),
+                                        Op.create("/multi2", new byte[0],
+                                                  Ids.OPEN_ACL_UNSAFE,
+                                                  CreateMode.PERSISTENT));
+        String expectedErr = "Path must not end with / character";
+        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
+
+        // create with valid sequential flag
+        opList = Arrays.asList(Op.create("/multi0", new byte[0],
+                                         Ids.OPEN_ACL_UNSAFE,
+                                         CreateMode.PERSISTENT),
+                               Op.create("multi1/", new byte[0],
+                                         Ids.OPEN_ACL_UNSAFE,
+                                         CreateMode.EPHEMERAL_SEQUENTIAL.toFlag()),
+                               Op.create("/multi2",
+                                         new byte[0], Ids.OPEN_ACL_UNSAFE,
+                                         CreateMode.PERSISTENT));
+        expectedErr = "Path must start with / character";
+        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
+
+        // check
+        opList = Arrays.asList(Op.check("/multi0", -1),
+                               Op.check("/multi1/", 100),
+                               Op.check("/multi2", 5));
+        expectedErr = "Path must not end with / character";
+        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
+
+        // delete
+        opList = Arrays.asList(Op.delete("/multi0", -1),
+                               Op.delete("/multi1/", 100),
+                               Op.delete("/multi2", 5));
+        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
+
+        // Multiple bad arguments
+        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
+
+        // setdata
+        opList = Arrays.asList(Op.setData("/multi0", new byte[0], -1),
+                               Op.setData("/multi1/", new byte[0], -1),
+                               Op.setData("/multi2", new byte[0], -1),
+                               Op.setData("multi3", new byte[0], -1));
+        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
+    }
+
+    /**
+     * Test verifies the multi calls with blank znode path
+     */
+    @Test(timeout = 90000)
+    public void testBlankPath() throws Exception {
+        List<Integer> expectedResultCodes = new ArrayList<Integer>();
+        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
+                                .intValue());
+        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
+        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
+                                .intValue());
+        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
+
+        // delete
+        String expectedErr = "Path cannot be null";
+        List<Op> opList = Arrays.asList(Op.delete("/multi0", -1),
+                                        Op.delete(null, 100),
+                                        Op.delete("/multi2", 5),
+                                        Op.delete("", -1));
+        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
+    }
+
+    /**
+     * Test verifies the multi.create with invalid createModeFlag
+     */
+    @Test(timeout = 90000)
+    public void testInvalidCreateModeFlag() throws Exception {
+        List<Integer> expectedResultCodes = new ArrayList<Integer>();
+        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
+                                .intValue());
+        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
+        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
+                                .intValue());
+
+        int createModeFlag = 6789;
+        List<Op> opList = Arrays.asList(Op.create("/multi0", new byte[0],
+                                                  Ids.OPEN_ACL_UNSAFE,
+                                                  CreateMode.PERSISTENT),
+                                        Op.create("/multi1", new byte[0],
+                                                  Ids.OPEN_ACL_UNSAFE,
+                                                  createModeFlag),
+                                        Op.create("/multi2", new byte[0],
+                                                  Ids.OPEN_ACL_UNSAFE,
+                                                  CreateMode.PERSISTENT));
+        String expectedErr = KeeperException.Code.BADARGUMENTS.name();
+        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
+    }
+
+    /**
+     * ZOOKEEPER-2052:
+     * Multi abort shouldn't have any side effect.
+     * We fix a bug in rollback and the following scenario should work:
+     * 1. multi delete abort because of not empty directory
+     * 2. ephemeral nodes under that directory are deleted
+     * 3. multi delete should succeed.
+     */
+    @Test
+    public void testMultiRollback() throws Exception {
+        zk.create("/foo", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+        ZooKeeper epheZk = createClient();
+        epheZk.create("/foo/bar", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+
+        List<Op> opList = Arrays.asList(Op.delete("/foo", -1));
+        try {
+            multi(zk, opList);
+            Assert.fail("multi delete should failed for not empty directory");
+        } catch (KeeperException.NotEmptyException e) {
+        }
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        zk.exists("/foo/bar", new Watcher() {
+                @Override
+                public void process(WatchedEvent event) {
+                    if (event.getType() == Event.EventType.NodeDeleted){
+                        latch.countDown();
+                    }
+                }
+            });
+
+        epheZk.close();
+
+        latch.await();
+
+        try {
+            zk.getData("/foo/bar", false, null);
+            Assert.fail("ephemeral node should have been deleted");
+        } catch (KeeperException.NoNodeException e) {
+        }
+
+        multi(zk, opList);
+
+        try {
+            zk.getData("/foo", false, null);
+            Assert.fail("persistent node should have been deleted after multi");
+        } catch (KeeperException.NoNodeException e) {
+        }
+    }
+
+    @Test
+    public void testChRootCreateDelete() throws Exception {
+        // creating the subtree for chRoot clients.
+        String chRoot = createNameSpace();
+        // Creating child using chRoot client.
+        zk_chroot = createClient(this.hostPort + chRoot);
+        Op createChild = Op.create("/myid", new byte[0],
+                Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        multi(zk_chroot, Arrays.asList(createChild));
+        
+        Assert.assertNotNull("zNode is not created under chroot:" + chRoot, zk
+                .exists(chRoot + "/myid", false));
+        Assert.assertNotNull("zNode is not created under chroot:" + chRoot,
+                zk_chroot.exists("/myid", false));
+        Assert.assertNull("zNode is created directly under '/', ignored configured chroot",
+                zk.exists("/myid", false));
+        
+        // Deleting child using chRoot client.
+        Op deleteChild = Op.delete("/myid", 0);
+        multi(zk_chroot, Arrays.asList(deleteChild));
+        Assert.assertNull("zNode exists under chroot:" + chRoot, zk.exists(
+                chRoot + "/myid", false));
+        Assert.assertNull("zNode exists under chroot:" + chRoot, zk_chroot
+                .exists("/myid", false));
+    }
+
+    @Test
+    public void testChRootSetData() throws Exception {
+        // creating the subtree for chRoot clients.
+        String chRoot = createNameSpace();
+        // setData using chRoot client.
+        zk_chroot = createClient(this.hostPort + chRoot);
+        String[] names = {"/multi0", "/multi1", "/multi2"};
+        List<Op> ops = new ArrayList<Op>();
+
+        for (int i = 0; i < names.length; i++) {
+            ops.add(Op.create(names[i], new byte[0], Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT));
+            ops.add(Op.setData(names[i], names[i].getBytes(), 0));
+        }
+
+        multi(zk_chroot, ops) ;
+
+        for (int i = 0; i < names.length; i++) {
+            Assert.assertArrayEquals("zNode data not matching", names[i]
+                    .getBytes(), zk_chroot.getData(names[i], false, null));
+        }
+    }
+
+    @Test
+    public void testChRootCheck() throws Exception {
+        // creating the subtree for chRoot clients.
+        String chRoot = createNameSpace();
+        // checking the child version using chRoot client.
+        zk_chroot = createClient(this.hostPort + chRoot);
+        String[] names = {"/multi0", "/multi1", "/multi2"};
+        List<Op> ops = new ArrayList<Op>();
+        for (int i = 0; i < names.length; i++) {
+            zk.create(chRoot + names[i], new byte[0], Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        }
+        for (int i = 0; i < names.length; i++) {
+            ops.add(Op.check(names[i], 0));
+        }
+        multi(zk_chroot, ops) ;
+    }
+
+    @Test
+    public void testChRootTransaction() throws Exception {
+        // creating the subtree for chRoot clients.
+        String chRoot = createNameSpace();
+        // checking the child version using chRoot client.
+        zk_chroot = createClient(this.hostPort + chRoot);
+        String childPath = "/myid";
+        Transaction transaction = zk_chroot.transaction();
+        transaction.create(childPath, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        transaction.check(childPath, 0);
+        transaction.setData(childPath, childPath.getBytes(), 0);
+        commit(transaction);
+
+        Assert.assertNotNull("zNode is not created under chroot:" + chRoot, zk
+                .exists(chRoot + childPath, false));
+        Assert.assertNotNull("zNode is not created under chroot:" + chRoot,
+                zk_chroot.exists(childPath, false));
+        Assert.assertNull("zNode is created directly under '/', ignored configured chroot",
+                        zk.exists(childPath, false));
+        Assert.assertArrayEquals("zNode data not matching", childPath
+                .getBytes(), zk_chroot.getData(childPath, false, null));
+
+        transaction = zk_chroot.transaction();
+        // Deleting child using chRoot client.
+        transaction.delete(childPath, 1);
+        commit(transaction);
+
+        Assert.assertNull("chroot:" + chRoot + " exists after delete", zk
+                .exists(chRoot + "/myid", false));
+        Assert.assertNull("chroot:" + chRoot + " exists after delete",
+                zk_chroot.exists("/myid", false));
+    }
+
+    private String createNameSpace() throws InterruptedException,
+            KeeperException {
+        // creating the subtree for chRoot clients.
+        String chRoot = "/appsX";
+        Op createChRoot = Op.create(chRoot, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        multi(zk, Arrays.asList(createChRoot));
+        return chRoot;
+    }
+
+    @Test
+    public void testCreate() throws Exception {
+        multi(zk, Arrays.asList(
+                Op.create("/multi0", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.create("/multi1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.create("/multi2", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
+                ));
+        zk.getData("/multi0", false, null);
+        zk.getData("/multi1", false, null);
+        zk.getData("/multi2", false, null);
+    }
+    
+    @Test
+    public void testCreateDelete() throws Exception {
+
+        multi(zk, Arrays.asList(
+                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.delete("/multi", 0)
+                ));
+
+        // '/multi' should have been deleted
+        Assert.assertNull(zk.exists("/multi", null));
+    }
+
+    @Test
+    public void testInvalidVersion() throws Exception {
+
+        try {
+            multi(zk, Arrays.asList(
+                    Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                    Op.delete("/multi", 1)
+            ));
+            Assert.fail("delete /multi should have failed");
+        } catch (KeeperException e) {
+            /* PASS */
+        }
+    }
+
+    @Test
+    public void testNestedCreate() throws Exception {
+
+        multi(zk, Arrays.asList(
+                /* Create */
+                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.create("/multi/a", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.create("/multi/a/1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+
+                /* Delete */
+                Op.delete("/multi/a/1", 0),
+                Op.delete("/multi/a", 0),
+                Op.delete("/multi", 0)
+                ));
+
+        //Verify tree deleted
+        Assert.assertNull(zk.exists("/multi/a/1", null));
+        Assert.assertNull(zk.exists("/multi/a", null));
+        Assert.assertNull(zk.exists("/multi", null));
+    }
+
+    @Test
+    public void testSetData() throws Exception {
+
+        String[] names = {"/multi0", "/multi1", "/multi2"};
+        List<Op> ops = new ArrayList<Op>();
+
+        for (int i = 0; i < names.length; i++) {
+            ops.add(Op.create(names[i], new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT));
+            ops.add(Op.setData(names[i], names[i].getBytes(), 0));
+        }
+
+        multi(zk, ops) ;
+
+        for (int i = 0; i < names.length; i++) {
+            Assert.assertArrayEquals(names[i].getBytes(), zk.getData(names[i], false, null));
+        }
+    }
+
+    @Test
+    public void testUpdateConflict() throws Exception {
+    
+        Assert.assertNull(zk.exists("/multi", null));
+        
+        try {
+            multi(zk, Arrays.asList(
+                    Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                    Op.setData("/multi", "X".getBytes(), 0),
+                    Op.setData("/multi", "Y".getBytes(), 0)
+                    ));
+            Assert.fail("Should have thrown a KeeperException for invalid version");
+        } catch (KeeperException e) {
+            //PASS
+            LOG.error("STACKTRACE: " + e);
+        }
+
+        Assert.assertNull(zk.exists("/multi", null));
+
+        //Updating version solves conflict -- order matters
+        multi(zk, Arrays.asList(
+                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.setData("/multi", "X".getBytes(), 0),
+                Op.setData("/multi", "Y".getBytes(), 1)
+                ));
+
+        Assert.assertArrayEquals(zk.getData("/multi", false, null), "Y".getBytes());
+    }
+
+    @Test
+    public void TestDeleteUpdateConflict() throws Exception {
+
+        /* Delete of a node folowed by an update of the (now) deleted node */
+        try {
+            multi(zk, Arrays.asList(
+                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.delete("/multi", 0),
+                Op.setData("/multi", "Y".getBytes(), 0)
+                ));
+            Assert.fail("/multi should have been deleted so setData should have failed");
+        } catch (KeeperException e) {
+            /* PASS */
+        }
+
+        // '/multi' should never have been created as entire op should fail
+        Assert.assertNull(zk.exists("/multi", null)) ;
+    }
+
+    @Test
+    public void TestGetResults() throws Exception {
+        /* Delete of a node folowed by an update of the (now) deleted node */
+        Iterable<Op> ops = Arrays.asList(
+                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.delete("/multi", 0),
+                Op.setData("/multi", "Y".getBytes(), 0),
+                Op.create("/foo", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
+        );
+        List<OpResult> results = null;
+        if (useAsync) {
+            final MultiResult res = new MultiResult();
+            zk.multi(ops, new MultiCallback() {
+                @Override
+                public void processResult(int rc, String path, Object ctx,
+                                          List<OpResult> opResults) {
+                    synchronized (res) {
+                        res.rc = rc;
+                        res.results = opResults;
+                        res.finished = true;
+                        res.notifyAll();
+                    }
+                }
+            }, null);
+            synchronized (res) {
+                while (!res.finished) {
+                    res.wait();
+                }
+            }
+            Assert.assertFalse("/multi should have been deleted so setData should have failed",
+                               KeeperException.Code.OK.intValue() == res.rc);
+            Assert.assertNull(zk.exists("/multi", null));
+            results = res.results;
+        } else {
+            try {
+                zk.multi(ops);
+                Assert.fail("/multi should have been deleted so setData should have failed");
+            } catch (KeeperException e) {
+                // '/multi' should never have been created as entire op should fail
+                Assert.assertNull(zk.exists("/multi", null));
+                results = e.getResults();
+            }
+        }
+
+        Assert.assertNotNull(results);
+        for (OpResult r : results) {
+            LOG.info("RESULT==> " + r);
+            if (r instanceof ErrorResult) {
+                ErrorResult er = (ErrorResult) r;
+                LOG.info("ERROR RESULT: " + er + " ERR=>" + KeeperException.Code.get(er.getErr()));
+            }
+        }
+    }
+
+    /**
+     * Exercise the equals methods of OpResult classes.
+     */
+    @Test
+    public void testOpResultEquals() {
+        opEquals(new CreateResult("/foo"),
+                new CreateResult("/foo"),
+                new CreateResult("nope"));
+
+        opEquals(new CheckResult(),
+                new CheckResult(),
+                null);
+        
+        opEquals(new SetDataResult(new Stat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)),
+                new SetDataResult(new Stat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)),
+                new SetDataResult(new Stat(11, 12, 13, 14, 15, 16, 17, 18, 19, 110, 111)));
+        
+        opEquals(new ErrorResult(1),
+                new ErrorResult(1),
+                new ErrorResult(2));
+        
+        opEquals(new DeleteResult(),
+                new DeleteResult(),
+                null);
+
+        opEquals(new ErrorResult(1),
+                new ErrorResult(1),
+                new ErrorResult(2));
+    }
+
+    private void opEquals(OpResult expected, OpResult value, OpResult near) {
+        assertEquals(value, value);
+        assertFalse(value.equals(new Object()));
+        assertFalse(value.equals(near));
+        assertFalse(value.equals(value instanceof CreateResult ?
+                new ErrorResult(1) : new CreateResult("nope2")));
+        assertTrue(value.equals(expected));
+    }
+
+    @Test
+    public void testWatchesTriggered() throws KeeperException, InterruptedException {
+        HasTriggeredWatcher watcher = new HasTriggeredWatcher();
+        zk.getChildren("/", watcher);
+        multi(zk, Arrays.asList(
+                Op.create("/t", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.delete("/t", -1)
+        ));
+        assertTrue(watcher.triggered.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS));
+    }
+
+    @Test
+    public void testNoWatchesTriggeredForFailedMultiRequest() throws InterruptedException, KeeperException {
+        HasTriggeredWatcher watcher = new HasTriggeredWatcher();
+        zk.getChildren("/", watcher);
+        try {
+            multi(zk, Arrays.asList(
+                    Op.create("/t", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                    Op.delete("/nonexisting", -1)
+            ));
+            fail("expected previous multi op to fail!");
+        } catch (KeeperException.NoNodeException e) {
+            // expected
+        }
+        SyncCallback cb = new SyncCallback();
+        zk.sync("/", cb, null);
+
+        // by waiting for the callback we're assured that the event queue is flushed
+        cb.done.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
+        assertEquals(1, watcher.triggered.getCount());
+    }
+    
+    @Test
+    public void testTransactionBuilder() throws Exception {
+        List<OpResult> results = commit(zk.transaction()
+                .create("/t1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
+                .create("/t1/child", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
+                .create("/t2", null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL));
+        assertEquals(3, results.size());
+        for (OpResult r : results) {
+            CreateResult c = (CreateResult)r;
+            assertTrue(c.getPath().startsWith("/t"));
+            assertNotNull(c.toString());
+        }
+        assertNotNull(zk.exists("/t1", false));
+        assertNotNull(zk.exists("/t1/child", false));
+        assertNotNull(zk.exists("/t2", false));
+        
+        results = commit(zk.transaction()
+                .check("/t1", 0)
+                .check("/t1/child", 0)
+                .check("/t2", 0));
+        assertEquals(3, results.size());
+        for (OpResult r : results) {
+            CheckResult c = (CheckResult)r;
+            assertNotNull(c.toString());
+        }
+        
+        try {
+            results = commit(zk.transaction()
+                    .check("/t1", 0)
+                    .check("/t1/child", 0)
+                    .check("/t2", 1));
+            fail();
+        } catch (KeeperException.BadVersionException e) {
+            // expected
+        }
+        
+        results = commit(zk.transaction()
+                .check("/t1", 0)
+                .setData("/t1", new byte[0], 0));
+        assertEquals(2, results.size());
+        for (OpResult r : results) {
+            assertNotNull(r.toString());
+        }
+
+        try {
+            results = commit(zk.transaction()
+                    .check("/t1", 1)
+                    .setData("/t1", new byte[0], 2));
+            fail();
+        } catch (KeeperException.BadVersionException e) {
+            // expected
+        }
+        
+        results = commit(zk.transaction()
+                .check("/t1", 1)
+                .check("/t1/child", 0)
+                .check("/t2", 0));
+        assertEquals(3, results.size());
+
+        results = commit(zk.transaction()
+                .delete("/t2", -1)
+                .delete("/t1/child", -1));
+        assertEquals(2, results.size());
+        for (OpResult r : results) {
+            DeleteResult d = (DeleteResult)r;
+            assertNotNull(d.toString());
+        }
+        assertNotNull(zk.exists("/t1", false));
+        assertNull(zk.exists("/t1/child", false));
+        assertNull(zk.exists("/t2", false));
+    }
+
+    private static class HasTriggeredWatcher implements Watcher {
+        private final CountDownLatch triggered = new CountDownLatch(1);
+
+        @Override
+        public void process(WatchedEvent event) {
+            triggered.countDown();
+        }
+    }
+    private static class SyncCallback implements AsyncCallback.VoidCallback {
+        private final CountDownLatch done = new CountDownLatch(1);
+
+        @Override
+        public void processResult(int rc, String path, Object ctx) {
+            done.countDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java
new file mode 100644
index 0000000..d61a3e2
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.zookeeper.server.NettyServerCnxnFactory;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Run tests with: Nio Client against Netty server
+ */
+@RunWith(Suite.class)
+public class NioNettySuiteBase {
+    @BeforeClass
+    public static void setUp() {
+        System.setProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY,
+                NettyServerCnxnFactory.class.getName());
+    }
+
+    @AfterClass
+    public static void tearDown() {
+        System.clearProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java
new file mode 100644
index 0000000..96e7b0c
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.junit.runners.Suite;
+
+/**
+ * Run tests with: Nio Client against Netty server
+ */
+@Suite.SuiteClasses({
+        AsyncHammerTest.class
+        })
+public class NioNettySuiteHammerTest extends NioNettySuiteBase {
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java
new file mode 100644
index 0000000..eaf17b9
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.junit.runners.Suite;
+
+/**
+ * Run tests with: Nio Client against Netty server
+ */
+@Suite.SuiteClasses({
+        ACLTest.class,
+        AsyncOpsTest.class,
+        ChrootClientTest.class,
+        ClientTest.class,
+        FourLetterWordsTest.class,
+        NullDataTest.class,
+        SessionTest.class,
+        WatcherTest.class
+        })
+public class NioNettySuiteTest extends NioNettySuiteBase {
+}


[04/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java
new file mode 100644
index 0000000..6f281d9
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java
@@ -0,0 +1,291 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.LineNumberReader;
+import java.io.StringReader;
+import java.util.regex.Pattern;
+
+import junit.framework.Assert;
+
+import org.apache.log4j.Layout;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.WriterAppender;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NotReadOnlyException;
+import org.apache.zookeeper.Transaction;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooKeeper.States;
+import org.apache.zookeeper.common.Time;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.slf4j.LoggerFactory;
+
+
+public class ReadOnlyModeTest extends ZKTestCase {
+    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ReadOnlyModeTest.class);
+    private static int CONNECTION_TIMEOUT = QuorumBase.CONNECTION_TIMEOUT;
+    private QuorumUtil qu = new QuorumUtil(1);
+
+    @Before
+    public void setUp() throws Exception {
+        System.setProperty("readonlymode.enabled", "true");
+        qu.startQuorum();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        System.setProperty("readonlymode.enabled", "false");
+        qu.tearDown();
+    }
+
+    /**
+     * Test write operations using multi request.
+     */
+    @Test(timeout = 90000)
+    public void testMultiTransaction() throws Exception {
+        CountdownWatcher watcher = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
+                watcher, true);
+        watcher.waitForConnected(CONNECTION_TIMEOUT); // ensure zk got connected
+
+        final String data = "Data to be read in RO mode";
+        final String node1 = "/tnode1";
+        final String node2 = "/tnode2";
+        zk.create(node1, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        watcher.reset();
+        qu.shutdown(2);
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+        Assert.assertEquals("Should be in r-o mode", States.CONNECTEDREADONLY,
+                zk.getState());
+
+        // read operation during r/o mode
+        String remoteData = new String(zk.getData(node1, false, null));
+        Assert.assertEquals("Failed to read data in r-o mode", data, remoteData);
+
+        try {
+            Transaction transaction = zk.transaction();
+            transaction.setData(node1, "no way".getBytes(), -1);
+            transaction.create(node2, data.getBytes(),
+                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            transaction.commit();
+            Assert.fail("Write operation using multi-transaction"
+                    + " api has succeeded during RO mode");
+        } catch (NotReadOnlyException e) {
+            // ok
+        }
+
+        Assert.assertNull("Should have created the znode:" + node2,
+                zk.exists(node2, false));
+    }
+
+    /**
+     * Basic test of read-only client functionality. Tries to read and write
+     * during read-only mode, then regains a quorum and tries to write again.
+     */
+    @Test(timeout = 90000)
+    public void testReadOnlyClient() throws Exception {
+        CountdownWatcher watcher = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
+                watcher, true);
+        watcher.waitForConnected(CONNECTION_TIMEOUT); // ensure zk got connected
+
+        final String data = "Data to be read in RO mode";
+        final String node = "/tnode";
+        zk.create(node, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        watcher.reset();
+        qu.shutdown(2);
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+
+        // read operation during r/o mode
+        String remoteData = new String(zk.getData(node, false, null));
+        Assert.assertEquals(data, remoteData);
+
+        try {
+            zk.setData(node, "no way".getBytes(), -1);
+            Assert.fail("Write operation has succeeded during RO mode");
+        } catch (NotReadOnlyException e) {
+            // ok
+        }
+
+        watcher.reset();
+        qu.start(2);
+        Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(
+                "127.0.0.1:" + qu.getPeer(2).clientPort, CONNECTION_TIMEOUT));
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+        zk.setData(node, "We're in the quorum now".getBytes(), -1);
+
+        zk.close();
+    }
+
+    /**
+     * Ensures that upon connection to a read-only server client receives
+     * ConnectedReadOnly state notification.
+     */
+    @Test(timeout = 90000)
+    public void testConnectionEvents() throws Exception {
+        CountdownWatcher watcher = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
+                watcher, true);
+        boolean success = false;
+        for (int i = 0; i < 30; i++) {
+            try {
+                zk.create("/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+                success=true;
+                break;
+            } catch(KeeperException.ConnectionLossException e) {
+                Thread.sleep(1000);               
+            }            
+        }
+        Assert.assertTrue("Did not succeed in connecting in 30s", success);
+        Assert.assertFalse("The connection should not be read-only yet", watcher.readOnlyConnected);
+
+        // kill peer and wait no more than 5 seconds for read-only server
+        // to be started (which should take one tickTime (2 seconds))
+        qu.shutdown(2);
+        long start = Time.currentElapsedTime();
+        while (!(zk.getState() == States.CONNECTEDREADONLY)) {
+            Thread.sleep(200);
+            // FIXME this was originally 5 seconds, but realistically, on random/slow/virt hosts, there is no way to guarantee this
+            Assert.assertTrue("Can't connect to the server",
+                              Time.currentElapsedTime() - start < 30000);
+        }
+
+        watcher.waitForReadOnlyConnected(5000);
+        zk.close();
+    }
+
+    /**
+     * Tests a situation when client firstly connects to a read-only server and
+     * then connects to a majority server. Transition should be transparent for
+     * the user.
+     */
+    @Test(timeout = 90000)
+    public void testSessionEstablishment() throws Exception {
+        qu.shutdown(2);
+
+        CountdownWatcher watcher = new CountdownWatcher();
+        LOG.debug("Connection string: {}", qu.getConnString());
+        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
+                watcher, true);
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+        Assert.assertSame("should be in r/o mode", States.CONNECTEDREADONLY, zk
+                .getState());
+        long fakeId = zk.getSessionId();
+        LOG.info("Connected as r/o mode with state {} and session id {}",
+                zk.getState(), fakeId);
+
+        watcher.reset();
+        qu.start(2);
+        Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(
+                "127.0.0.1:" + qu.getPeer(2).clientPort, CONNECTION_TIMEOUT));
+        LOG.info("Server 127.0.0.1:{} is up", qu.getPeer(2).clientPort);
+        // ZOOKEEPER-2722: wait until we can connect to a read-write server after the quorum
+        // is formed. Otherwise, it is possible that client first connects to a read-only server,
+        // then drops the connection because of shutting down of the read-only server caused
+        // by leader election / quorum forming between the read-only server and the newly started
+        // server. If we happen to execute the zk.create after the read-only server is shutdown and
+        // before the quorum is formed, we will get a ConnectLossException.
+        watcher.waitForSyncConnected(CONNECTION_TIMEOUT);
+        Assert.assertEquals("Should be in read-write mode", States.CONNECTED,
+                zk.getState());
+        LOG.info("Connected as rw mode with state {} and session id {}",
+                zk.getState(), zk.getSessionId());
+        zk.create("/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        Assert.assertFalse("fake session and real session have same id", zk
+                .getSessionId() == fakeId);
+        zk.close();
+    }
+
+    /**
+     * Ensures that client seeks for r/w servers while it's connected to r/o
+     * server.
+     */
+    @SuppressWarnings("deprecation")
+    @Test(timeout = 90000)
+    public void testSeekForRwServer() throws Exception {
+
+        // setup the logger to capture all logs
+        Layout layout = Logger.getRootLogger().getAppender("CONSOLE")
+                .getLayout();
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        WriterAppender appender = new WriterAppender(layout, os);
+        appender.setImmediateFlush(true);
+        appender.setThreshold(Level.INFO);
+        Logger zlogger = Logger.getLogger("org.apache.zookeeper");
+        zlogger.addAppender(appender);
+
+        try {
+            qu.shutdown(2);
+            CountdownWatcher watcher = new CountdownWatcher();
+            ZooKeeper zk = new ZooKeeper(qu.getConnString(),
+                    CONNECTION_TIMEOUT, watcher, true);
+            watcher.waitForConnected(CONNECTION_TIMEOUT);
+
+            // if we don't suspend a peer it will rejoin a quorum
+            qu.getPeer(1).peer.suspend();
+
+            // start two servers to form a quorum; client should detect this and
+            // connect to one of them
+            watcher.reset();
+            qu.start(2);
+            qu.start(3);
+            ClientBase.waitForServerUp(qu.getConnString(), 2000);
+            watcher.waitForConnected(CONNECTION_TIMEOUT);
+            zk.create("/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+
+            // resume poor fellow
+            qu.getPeer(1).peer.resume();
+        } finally {
+            zlogger.removeAppender(appender);
+        }
+
+        os.close();
+        LineNumberReader r = new LineNumberReader(new StringReader(os
+                .toString()));
+        String line;
+        Pattern p = Pattern.compile(".*Majority server found.*");
+        boolean found = false;
+        while ((line = r.readLine()) != null) {
+            if (p.matcher(line).matches()) {
+                found = true;
+                break;
+            }
+        }
+        Assert.assertTrue(
+                "Majority server wasn't found while connected to r/o server",
+                found);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/RecoveryTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/RecoveryTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/RecoveryTest.java
new file mode 100644
index 0000000..c084a68
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/RecoveryTest.java
@@ -0,0 +1,209 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RecoveryTest extends ZKTestCase implements Watcher {
+    protected static final Logger LOG = LoggerFactory.getLogger(RecoveryTest.class);
+
+    private static final String HOSTPORT =
+        "127.0.0.1:" + PortAssignment.unique();
+
+    private volatile CountDownLatch startSignal;
+
+    /**
+     * Verify that if a server goes down that clients will reconnect
+     * automatically after the server is restarted. Note that this requires the
+     * server to restart within the connection timeout period.
+     *
+     * Also note that the client latches are used to eliminate any chance
+     * of spurrious connectionloss exceptions on the read ops. Specifically
+     * a sync operation will throw this exception if the server goes down
+     * (as recognized by the client) during the operation. If the operation
+     * occurs after the server is down, but before the client recognizes
+     * that the server is down (ping) then the op will throw connectionloss.
+     */
+    @Test
+    public void testRecovery() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+
+        int oldSnapCount = SyncRequestProcessor.getSnapCount();
+        SyncRequestProcessor.setSnapCount(1000);
+        try {
+            final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+            ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+            f.startup(zks);
+            LOG.info("starting up the the server, waiting");
+
+            Assert.assertTrue("waiting for server up",
+                       ClientBase.waitForServerUp(HOSTPORT,
+                                       CONNECTION_TIMEOUT));
+
+            startSignal = new CountDownLatch(1);
+            ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+            startSignal.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS);
+            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
+            String path;
+            LOG.info("starting creating nodes");
+            for (int i = 0; i < 10; i++) {
+                path = "/" + i;
+                zk.create(path,
+                          (path + "!").getBytes(),
+                          Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+                for (int j = 0; j < 10; j++) {
+                    String subpath = path + "/" + j;
+                    zk.create(subpath, (subpath + "!").getBytes(),
+                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+                    for (int k = 0; k < 20; k++) {
+                        String subsubpath = subpath + "/" + k;
+                        zk.create(subsubpath, (subsubpath + "!").getBytes(),
+                                Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+                    }
+                }
+            }
+
+            f.shutdown();
+            zks.shutdown();
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(HOSTPORT,
+                                          CONNECTION_TIMEOUT));
+
+            zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+            f = ServerCnxnFactory.createFactory(PORT, -1);
+
+            startSignal = new CountDownLatch(1);
+
+            f.startup(zks);
+
+            Assert.assertTrue("waiting for server up",
+                       ClientBase.waitForServerUp(HOSTPORT,
+                                           CONNECTION_TIMEOUT));
+
+            startSignal.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS);
+            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
+
+            Stat stat = new Stat();
+            for (int i = 0; i < 10; i++) {
+                path = "/" + i;
+                LOG.info("Checking " + path);
+                Assert.assertEquals(new String(zk.getData(path, false, stat)), path
+                        + "!");
+                for (int j = 0; j < 10; j++) {
+                    String subpath = path + "/" + j;
+                    Assert.assertEquals(new String(zk.getData(subpath, false, stat)),
+                            subpath + "!");
+                    for (int k = 0; k < 20; k++) {
+                        String subsubpath = subpath + "/" + k;
+                        Assert.assertEquals(new String(zk.getData(subsubpath, false,
+                                stat)), subsubpath + "!");
+                    }
+                }
+            }
+            f.shutdown();
+            zks.shutdown();
+
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(HOSTPORT,
+                                          ClientBase.CONNECTION_TIMEOUT));
+
+            zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+            f = ServerCnxnFactory.createFactory(PORT, -1);
+
+            startSignal = new CountDownLatch(1);
+
+            f.startup(zks);
+
+            Assert.assertTrue("waiting for server up",
+                       ClientBase.waitForServerUp(HOSTPORT,
+                               CONNECTION_TIMEOUT));
+
+            startSignal.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
+            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
+
+            stat = new Stat();
+            LOG.info("Check 2");
+            for (int i = 0; i < 10; i++) {
+                path = "/" + i;
+                Assert.assertEquals(new String(zk.getData(path, false, stat)),
+                             path + "!");
+                for (int j = 0; j < 10; j++) {
+                    String subpath = path + "/" + j;
+                    Assert.assertEquals(new String(zk.getData(subpath, false, stat)),
+                            subpath + "!");
+                    for (int k = 0; k < 20; k++) {
+                        String subsubpath = subpath + "/" + k;
+                        Assert.assertEquals(new String(zk.getData(subsubpath, false,
+                                stat)), subsubpath + "!");
+                    }
+                }
+            }
+            zk.close();
+
+            f.shutdown();
+            zks.shutdown();
+
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(HOSTPORT,
+                                                    CONNECTION_TIMEOUT));
+        } finally {
+            SyncRequestProcessor.setSnapCount(oldSnapCount);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatcherEvent)
+     */
+    public void process(WatchedEvent event) {
+        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
+        if (event.getState() == KeeperState.SyncConnected
+                && startSignal != null && startSignal.getCount() > 0)
+        {
+            startSignal.countDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java
new file mode 100644
index 0000000..f714a2c
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RepeatStartupTest extends ZKTestCase {
+
+    /** bring up 5 quorum peers and then shut them down
+     * and then bring one of the nodes as server
+     *
+     * @throws Exception might be thrown here
+     */
+    @Test
+    public void testFail() throws Exception {
+        QuorumBase qb = new QuorumBase();
+        qb.setUp();
+
+        System.out.println("Comment: the servers are at " + qb.hostPort);
+        ZooKeeper zk = qb.createClient();
+        zk.create("/test", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.close();
+        qb.shutdown(qb.s1);
+        qb.shutdown(qb.s2);
+        qb.shutdown(qb.s3);
+        qb.shutdown(qb.s4);
+        qb.shutdown(qb.s5);
+        String hp = qb.hostPort.split(",")[0];
+        ZooKeeperServer zks = new ZooKeeperServer(qb.s1.getTxnFactory().getSnapDir(),
+                qb.s1.getTxnFactory().getDataDir(), 3000);
+        final int PORT = Integer.parseInt(hp.split(":")[1]);
+        ServerCnxnFactory factory = ServerCnxnFactory.createFactory(PORT, -1);
+
+        factory.startup(zks);
+        System.out.println("Comment: starting factory");
+        Assert.assertTrue("waiting for server up",
+                   ClientBase.waitForServerUp("127.0.0.1:" + PORT,
+                           QuorumTest.CONNECTION_TIMEOUT));
+        factory.shutdown();
+        zks.shutdown();
+        Assert.assertTrue("waiting for server down",
+                   ClientBase.waitForServerDown("127.0.0.1:" + PORT,
+                                                QuorumTest.CONNECTION_TIMEOUT));
+        System.out.println("Comment: shutting down standalone");
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java
new file mode 100644
index 0000000..65cc0e2
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java
@@ -0,0 +1,91 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.util.List;
+import java.util.LinkedList;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.server.quorum.Leader.Proposal;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
+import org.junit.Assert;
+import org.junit.Test;
+
+/** After a replica starts, it should load commits in its committedLog list. 
+ *  This test checks if committedLog != 0 after replica restarted.
+ */
+public class RestoreCommittedLogTest extends ZKTestCase implements  Watcher {
+    private static final Logger LOG = Logger.getLogger(RestoreCommittedLogTest.class);
+    private static String HOSTPORT = "127.0.0.1:" + PortAssignment.unique();
+    private static final int CONNECTION_TIMEOUT = 3000;
+    /**
+     * test the purge
+     * @throws Exception an exception might be thrown here
+     */
+    @Test
+    public void testRestoreCommittedLog() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        SyncRequestProcessor.setSnapCount(100);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        Assert.assertTrue("waiting for server being up ",
+                ClientBase.waitForServerUp(HOSTPORT,CONNECTION_TIMEOUT));
+        ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+        try {
+            for (int i = 0; i< 2000; i++) {
+                zk.create("/invalidsnap-" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+            }
+        } finally {
+            zk.close();
+        }
+        f.shutdown();
+        zks.shutdown();
+        Assert.assertTrue("waiting for server to shutdown",
+                ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
+
+        // start server again
+        zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        zks.startdata();
+        LinkedList<Proposal> committedLog = zks.getZKDatabase().getCommittedLog();
+        int logsize = committedLog.size();
+        LOG.info("committedLog size = " + logsize);
+        Assert.assertTrue("log size != 0", (logsize != 0));
+        zks.shutdown();
+    }
+
+    public void process(WatchedEvent event) {
+        // do nothing
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java
new file mode 100644
index 0000000..9e28278
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java
@@ -0,0 +1,104 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.client.ZooKeeperSaslClient;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SaslAuthDesignatedClientTest extends ClientBase {
+    static {
+        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+        System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperClient");
+
+        try {
+            File tmpDir = createTmpDir();
+            File saslConfFile = new File(tmpDir, "jaas.conf");
+            FileWriter fwriter = new FileWriter(saslConfFile);
+
+            fwriter.write("" +
+                "Server {\n" +
+                "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "          user_myuser=\"mypassword\";\n" +
+                "};\n" +
+                "Client {\n" + /* this 'Client' section has an incorrect password, but we're not configured
+                                  to  use it (we're configured by the above System.setProperty(...LOGIN_CONTEXT_NAME_KEY...) to 
+                                  use the 'MyZookeeperClient' section below, which has the correct password).*/
+                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "       username=\"myuser\"\n" +
+                "       password=\"wrongpassword\";\n" +
+                "};" +
+                "MyZookeeperClient {\n" +
+                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "       username=\"myuser\"\n" +
+                "       password=\"mypassword\";\n" +
+                "};" + "\n");
+            fwriter.close();
+            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
+        }
+        catch (IOException e) {
+            // could not create tmp directory to hold JAAS conf file : test will fail now.
+        }
+    }
+
+    @Test
+    public void testAuth() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+            Thread.sleep(1000);
+        } catch (KeeperException e) {
+          Assert.fail("test failed :" + e);
+        }
+        finally {
+            zk.close();
+        }
+    }
+
+    @Test
+    public void testSaslConfig() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.getChildren("/", false);
+            Assert.assertFalse(zk.getSaslClient().
+                clientTunneledAuthenticationInProgress());
+            Assert.assertEquals(zk.getSaslClient().getSaslState(),
+                ZooKeeperSaslClient.SaslState.COMPLETE);
+            Assert.assertNotNull(
+                javax.security.auth.login.Configuration.getConfiguration().
+                    getAppConfigurationEntry("MyZookeeperClient"));
+            Assert.assertSame(zk.getSaslClient().getLoginContext(),
+                "MyZookeeperClient");
+        } catch (KeeperException e) {
+            Assert.fail("test failed :" + e);
+        } finally {
+            zk.close();
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java
new file mode 100644
index 0000000..aa30870
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java
@@ -0,0 +1,104 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.server.ZooKeeperSaslServer;
+import org.apache.zookeeper.JaasConfiguration;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SaslAuthDesignatedServerTest extends ClientBase {
+    public static int AUTHENTICATION_TIMEOUT = 30000;
+
+    static {
+        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+        System.setProperty(ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperServer");
+
+        JaasConfiguration conf = new JaasConfiguration();
+
+        /* this 'Server' section has an incorrect password, but we're not configured
+         * to  use it (we're configured by the above System.setProperty(...LOGIN_CONTEXT_NAME_KEY...)
+         * to use the 'MyZookeeperServer' section below, which has the correct password).
+         */
+        conf.addSection("Server", "org.apache.zookeeper.server.auth.DigestLoginModule",
+                        "user_myuser", "wrongpassword");
+
+        conf.addSection("MyZookeeperServer", "org.apache.zookeeper.server.auth.DigestLoginModule",
+                        "user_myuser", "mypassword");
+
+        conf.addSection("Client", "org.apache.zookeeper.server.auth.DigestLoginModule",
+                        "username", "myuser", "password", "mypassword");
+
+        javax.security.auth.login.Configuration.setConfiguration(conf);
+    }
+
+    private AtomicInteger authFailed = new AtomicInteger(0);
+
+    private class MyWatcher extends CountdownWatcher {
+        volatile CountDownLatch authCompleted;
+
+        @Override
+        synchronized public void reset() {
+            authCompleted = new CountDownLatch(1);
+            super.reset();
+        }
+
+        @Override
+        public synchronized void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.AuthFailed) {
+                authFailed.incrementAndGet();
+                authCompleted.countDown();
+            } else if (event.getState() == KeeperState.SaslAuthenticated) {
+                authCompleted.countDown();
+            } else {
+                super.process(event);
+            }
+        }
+    }
+
+    @Test
+    public void testAuth() throws Exception {
+        MyWatcher watcher = new MyWatcher();
+        ZooKeeper zk = createClient(watcher);
+        watcher.authCompleted.await(AUTHENTICATION_TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertEquals(authFailed.get(), 0);
+
+        try {
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+        } catch (KeeperException e) {
+          Assert.fail("test failed :" + e);
+        }
+        finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java
new file mode 100644
index 0000000..5291141
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java
@@ -0,0 +1,108 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.client.ZooKeeperSaslClient;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SaslAuthFailDesignatedClientTest extends ClientBase {
+    static {
+        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+        System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperClient");
+
+        try {
+            File tmpDir = createTmpDir();
+            File saslConfFile = new File(tmpDir, "jaas.conf");
+            FileWriter fwriter = new FileWriter(saslConfFile);
+
+            fwriter.write("" +
+                "Server {\n" +
+                "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "          user_myuser=\"mypassword\";\n" +
+                "};\n" +
+                "Client {\n" + /* this 'Client' section has the correct password, but we're not configured
+                                  to  use it (we're configured by the above System.setProperty(...LOGIN_CONTEXT_NAME_KEY...) to 
+                                  use the 'MyZookeeperClient' section, which has an incorrect password).*/
+                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "       username=\"myuser\"\n" +
+                "       password=\"mypassword\";\n" +
+                "};" +
+                "MyZookeeperClient {\n" +
+                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "       username=\"myuser\"\n" +
+                "       password=\"wrongpassword\";\n" +
+                "};" + "\n");
+            fwriter.close();
+            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
+        }
+        catch (IOException e) {
+            // could not create tmp directory to hold JAAS conf file : test will fail now.
+        }
+    }
+
+    private AtomicInteger authFailed = new AtomicInteger(0);
+
+    private class MyWatcher extends CountdownWatcher {
+        @Override
+        public synchronized void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.AuthFailed) {
+                authFailed.incrementAndGet();
+            }
+            else {
+                super.process(event);
+            }
+        }
+    }
+
+    @Test
+    public void testAuth() throws Exception {
+        // Cannot use createClient here because server may close session before 
+        // JMXEnv.ensureAll is called which will fail the test case
+        CountdownWatcher watcher = new CountdownWatcher();
+        TestableZooKeeper zk = new TestableZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
+        if (!watcher.clientConnected.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS))
+        {
+            Assert.fail("Unable to connect to server");
+        }
+        try {
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+            Assert.fail("Should have gotten exception.");
+        } catch (KeeperException e) {
+            // ok, exception as expected.
+            LOG.info("Got exception as expected: " + e);
+        }
+        finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java
new file mode 100644
index 0000000..2b00d86
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java
@@ -0,0 +1,98 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Test;
+import org.junit.Assert;
+
+public class SaslAuthFailNotifyTest extends ClientBase {
+    static {
+        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+        System.setProperty("zookeeper.allowSaslFailedClients","true");
+
+        try {
+            File tmpDir = createTmpDir();
+            File saslConfFile = new File(tmpDir, "jaas.conf");
+            FileWriter fwriter = new FileWriter(saslConfFile);
+
+            fwriter.write("" +
+                    "Server {\n" +
+                    "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                    "          user_super=\"test\";\n" +
+                    "};\n" +
+                    "Client {\n" +
+                    "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                    "       username=\"super\"\n" +
+                    "       password=\"test1\";\n" + // NOTE: wrong password ('test' != 'test1') : this is to test SASL authentication failure.
+                    "};" + "\n");
+            fwriter.close();
+            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
+        }
+        catch (IOException e) {
+            // could not create tmp directory to hold JAAS conf file.
+        }
+    }
+
+    private AtomicInteger authFailed = new AtomicInteger(0);
+    
+    @Override
+    protected TestableZooKeeper createClient(String hp)
+    throws IOException, InterruptedException
+    {
+        MyWatcher watcher = new MyWatcher();
+        return createClient(watcher, hp);
+    }
+
+    private class MyWatcher extends CountdownWatcher {
+        @Override
+        public synchronized void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.AuthFailed) {
+                synchronized(authFailed) {
+                    authFailed.incrementAndGet();
+                    authFailed.notify();
+                }
+            }
+            else {
+                super.process(event);
+            }
+        }
+    }
+
+    @Test
+    public void testBadSaslAuthNotifiesWatch() throws Exception {
+        ZooKeeper zk = createClient();
+        // wait for authFailed event from client's EventThread.
+        synchronized(authFailed) {
+            authFailed.wait();
+        }
+        Assert.assertEquals(authFailed.get(),1);
+        zk.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java
new file mode 100644
index 0000000..33a505e
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Test;
+import org.junit.Assert;
+
+public class SaslAuthFailTest extends ClientBase {
+    static {
+        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+        System.setProperty("zookeeper.allowSaslFailedClients","true");
+
+        try {
+            File tmpDir = createTmpDir();
+            File saslConfFile = new File(tmpDir, "jaas.conf");
+            FileWriter fwriter = new FileWriter(saslConfFile);
+
+            fwriter.write("" +
+                    "Server {\n" +
+                    "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                    "          user_super=\"test\";\n" +
+                    "};\n" +
+                    "Client {\n" +
+                    "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                    "       username=\"super\"\n" +
+                    "       password=\"test1\";\n" + // NOTE: wrong password ('test' != 'test1') : this is to test SASL authentication failure.
+                    "};" + "\n");
+            fwriter.close();
+            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
+        }
+        catch (IOException e) {
+            // could not create tmp directory to hold JAAS conf file.
+        }
+    }
+    
+    @Test
+    public void testAuthFail() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+            Assert.fail("Should have gotten exception.");
+        } catch(Exception e ) {
+            // ok, exception as expected.
+            LOG.info("Got exception as expected: " + e);
+        } finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java
new file mode 100644
index 0000000..98be0be
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java
@@ -0,0 +1,97 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.client.ZooKeeperSaslClient;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SaslAuthMissingClientConfigTest extends ClientBase {
+    static {
+        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+        // This configuration section 'MyZookeeperClient', is missing from the JAAS configuration.
+        // As a result, SASL authentication should fail, which is tested by this test (testAuth()).
+        System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperClient");
+
+        try {
+            File tmpDir = createTmpDir();
+            File saslConfFile = new File(tmpDir, "jaas.conf");
+            FileWriter fwriter = new FileWriter(saslConfFile);
+
+            fwriter.write("" +
+                "Server {\n" +
+                "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "          user_myuser=\"mypassword\";\n" +
+                "};\n" +
+                "Client {\n" + /* this 'Client' section has the correct password, but we're not configured
+                                  to  use it - we're configured instead by the above
+                                  System.setProperty(...LOGIN_CONTEXT_NAME_KEY...) to
+                                  use the (nonexistent) 'MyZookeeperClient' section. */
+                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+                "       username=\"myuser\"\n" +
+                "       password=\"mypassword\";\n" +
+                "};\n");
+            fwriter.close();
+            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
+        }
+        catch (IOException e) {
+            // could not create tmp directory to hold JAAS conf file : test will fail now.
+        }
+    }
+
+    private AtomicInteger authFailed = new AtomicInteger(0);
+
+    private class MyWatcher extends CountdownWatcher {
+        @Override
+        public synchronized void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.AuthFailed) {
+                authFailed.incrementAndGet();
+            }
+            else {
+                super.process(event);
+            }
+        }
+    }
+
+    @Test
+    public void testAuth() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+            Assert.fail("Should have gotten exception.");
+        } catch (KeeperException e) {
+            // ok, exception as expected.
+            LOG.info("Got exception as expected: " + e);
+        }
+        finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslClientTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslClientTest.java
new file mode 100644
index 0000000..8213abc
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SaslClientTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.client.ZooKeeperSaslClient;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+public class SaslClientTest extends ZKTestCase {
+
+    private String existingPropertyValue = null;
+
+    @Before
+    public void setUp() {
+        existingPropertyValue = System.getProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY);
+    }
+
+    @After
+    public void tearDown() {
+        // Restore the System property if it was set previously
+        if (existingPropertyValue != null) {
+            System.setProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY, existingPropertyValue);
+        }
+    }
+
+    @Test
+    public void testSaslClientDisabled() {
+        System.clearProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY);
+        Assert.assertTrue("SASL client disabled", ZooKeeperSaslClient.isEnabled());
+
+        for (String value : Arrays.asList("true", "TRUE")) {
+            System.setProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY, value);
+            Assert.assertTrue("SASL client disabled", ZooKeeperSaslClient.isEnabled());
+        }
+
+        for (String value : Arrays.asList("false", "FALSE")) {
+            System.setProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY, value);
+            Assert.assertFalse("SASL client disabled", ZooKeeperSaslClient.isEnabled());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java
new file mode 100644
index 0000000..3a0b2ee
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java
@@ -0,0 +1,105 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import junit.framework.Assert;
+
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooDefs.OpCode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.proto.ConnectRequest;
+import org.apache.zookeeper.proto.CreateRequest;
+import org.apache.zookeeper.proto.RequestHeader;
+import org.junit.Test;
+
+public class SessionInvalidationTest extends ClientBase {
+    /**
+     * Test solution for ZOOKEEPER-1208. Verify that operations are not
+     * accepted after a close session.
+     * 
+     * We're using our own marshalling here in order to force an operation
+     * after the session is closed (ZooKeeper.class will not allow this). Also
+     * by filling the pipe with operations it increases the likelyhood that
+     * the server will process the create before FinalRequestProcessor
+     * removes the session from the tracker.
+     */
+    @Test
+    public void testCreateAfterCloseShouldFail() throws Exception {
+        for (int i = 0; i < 10; i++) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+
+            // open a connection
+            boa.writeInt(44, "len");
+            ConnectRequest conReq = new ConnectRequest(0, 0, 30000, 0, new byte[16]);
+            conReq.serialize(boa, "connect");
+
+            // close connection
+            boa.writeInt(8, "len");
+            RequestHeader h = new RequestHeader(1, ZooDefs.OpCode.closeSession);
+            h.serialize(boa, "header");
+
+            // create ephemeral znode
+            boa.writeInt(52, "len"); // We'll fill this in later
+            RequestHeader header = new RequestHeader(2, OpCode.create);
+            header.serialize(boa, "header");
+            CreateRequest createReq = new CreateRequest("/foo" + i, new byte[0],
+                    Ids.OPEN_ACL_UNSAFE, 1);
+            createReq.serialize(boa, "request");
+            baos.close();
+            
+            System.out.println("Length:" + baos.toByteArray().length);
+            
+            String hp[] = hostPort.split(":");
+            Socket sock = new Socket(hp[0], Integer.parseInt(hp[1]));
+            InputStream resultStream = null;
+            try {
+                OutputStream outstream = sock.getOutputStream();
+                byte[] data = baos.toByteArray();
+                outstream.write(data);
+                outstream.flush();
+                
+                resultStream = sock.getInputStream();
+                byte[] b = new byte[10000];
+                int len;
+                while ((len = resultStream.read(b)) >= 0) {
+                    // got results
+                    System.out.println("gotlen:" + len);
+                }
+            } finally {
+                if (resultStream != null) {
+                    resultStream.close();
+                }
+                sock.close();
+            }
+        }
+        
+        ZooKeeper zk = createClient();
+        Assert.assertEquals(1, zk.getChildren("/", false).size());
+
+        zk.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTest.java
new file mode 100644
index 0000000..891b0f0
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTest.java
@@ -0,0 +1,394 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class SessionTest extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(SessionTest.class);
+
+    private static final String HOSTPORT = "127.0.0.1:" +
+            PortAssignment.unique();
+    
+    private ServerCnxnFactory serverFactory;
+    private ZooKeeperServer zs;
+
+    private CountDownLatch startSignal;
+
+    File tmpDir;
+
+    private final int TICK_TIME = 3000;
+
+    @Before
+    public void setUp() throws Exception {
+        if (tmpDir == null) {
+            tmpDir = ClientBase.createTmpDir();
+        }
+
+        ClientBase.setupTestEnv();
+        zs = new ZooKeeperServer(tmpDir, tmpDir, TICK_TIME);
+
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        serverFactory = ServerCnxnFactory.createFactory(PORT, -1);
+        serverFactory.startup(zs);
+
+        Assert.assertTrue("waiting for server up",
+                   ClientBase.waitForServerUp(HOSTPORT,
+                                              CONNECTION_TIMEOUT));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        serverFactory.shutdown();
+        zs.shutdown();
+        Assert.assertTrue("waiting for server down",
+                   ClientBase.waitForServerDown(HOSTPORT,
+                                                CONNECTION_TIMEOUT));
+    }
+
+    private static class CountdownWatcher implements Watcher {
+        volatile CountDownLatch clientConnected = new CountDownLatch(1);
+
+        public void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.SyncConnected) {
+                clientConnected.countDown();
+            }
+        }
+    }
+
+    private DisconnectableZooKeeper createClient()
+        throws IOException, InterruptedException
+    {
+        CountdownWatcher watcher = new CountdownWatcher();
+        return createClient(CONNECTION_TIMEOUT, watcher);
+    }
+
+    private DisconnectableZooKeeper createClient(int timeout)
+        throws IOException, InterruptedException
+    {
+        CountdownWatcher watcher = new CountdownWatcher();
+        return createClient(timeout, watcher);
+    }
+
+    private DisconnectableZooKeeper createClient(int timeout,
+            CountdownWatcher watcher)
+        throws IOException, InterruptedException
+    {
+        DisconnectableZooKeeper zk =
+                new DisconnectableZooKeeper(HOSTPORT, timeout, watcher);
+        if(!watcher.clientConnected.await(timeout, TimeUnit.MILLISECONDS)) {
+            Assert.fail("Unable to connect to server");
+        }
+
+        return zk;
+    }
+
+// FIXME this test is Assert.failing due to client close race condition fixing in separate patch for ZOOKEEPER-63
+//    /**
+//     * this test checks to see if the sessionid that was created for the
+//     * first zookeeper client can be reused for the second one immidiately
+//     * after the first client closes and the new client resues them.
+//     * @throws IOException
+//     * @throws InterruptedException
+//     * @throws KeeperException
+//     */
+//    public void testSessionReuse() throws IOException, InterruptedException {
+//        ZooKeeper zk = createClient();
+//
+//        long sessionId = zk.getSessionId();
+//        byte[] passwd = zk.getSessionPasswd();
+//        zk.close();
+//
+//        zk.close();
+//
+//        LOG.info("Closed first session");
+//
+//        startSignal = new CountDownLatch(1);
+//        zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this,
+//                sessionId, passwd);
+//        startSignal.await();
+//
+//        LOG.info("Opened reuse");
+//
+//        Assert.assertEquals(sessionId, zk.getSessionId());
+//
+//        zk.close();
+//    }
+
+    private class MyWatcher implements Watcher {
+        private String name;
+        public MyWatcher(String name) {
+            this.name = name;
+        }
+        public void process(WatchedEvent event) {
+            LOG.info(name + " event:" + event.getState() + " "
+                    + event.getType() + " " + event.getPath());
+            if (event.getState() == KeeperState.SyncConnected
+                    && startSignal != null && startSignal.getCount() > 0)
+            {
+                startSignal.countDown();
+            }
+        }
+    }
+
+    /**
+     * This test verifies that when the session id is reused, and the original
+     * client is disconnected, but not session closed, that the server
+     * will remove ephemeral nodes created by the original session.
+     */
+    @Test
+    public void testSession()
+        throws IOException, InterruptedException, KeeperException
+    {
+        DisconnectableZooKeeper zk = createClient();
+        zk.create("/e", new byte[0], Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.EPHEMERAL);
+        LOG.info("zk with session id 0x" + Long.toHexString(zk.getSessionId())
+                + " was destroyed!");
+
+        // disconnect the client by killing the socket, not sending the
+        // session disconnect to the server as usual. This allows the test
+        // to verify disconnect handling
+        zk.disconnect();
+
+        Stat stat = new Stat();
+        startSignal = new CountDownLatch(1);
+        zk = new DisconnectableZooKeeper(HOSTPORT, CONNECTION_TIMEOUT,
+                new MyWatcher("testSession"), zk.getSessionId(),
+                zk.getSessionPasswd());
+        startSignal.await();
+
+        LOG.info("zk with session id 0x" + Long.toHexString(zk.getSessionId())
+                 + " was created!");
+        zk.getData("/e", false, stat);
+        LOG.info("After get data /e");
+        zk.close();
+
+        zk = createClient();
+        Assert.assertEquals(null, zk.exists("/e", false));
+        LOG.info("before close zk with session id 0x"
+                + Long.toHexString(zk.getSessionId()) + "!");
+        zk.close();
+        try {
+            zk.getData("/e", false, stat);
+            Assert.fail("Should have received a SessionExpiredException");
+        } catch(KeeperException.SessionExpiredException e) {}
+        
+        AsyncCallback.DataCallback cb = new AsyncCallback.DataCallback() {
+            String status = "not done";
+            public void processResult(int rc, String p, Object c, byte[] b, Stat s) {
+                synchronized(this) { status = KeeperException.Code.get(rc).toString(); this.notify(); }
+            }
+           public String toString() { return status; }
+        };
+        zk.getData("/e", false, cb, null);
+        synchronized(cb) {
+            if (cb.toString().equals("not done")) {
+                cb.wait(1000);
+            }
+        }
+        Assert.assertEquals(KeeperException.Code.SESSIONEXPIRED.toString(), cb.toString());        
+    }
+
+    /**
+     * Make sure that we cannot have two connections with the same
+     * session id.
+     *
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws KeeperException
+     */
+    @Test
+    public void testSessionMove() throws Exception {
+        String hostPorts[] = HOSTPORT.split(",");
+        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(hostPorts[0],
+                CONNECTION_TIMEOUT, new MyWatcher("0"));
+        zk.create("/sessionMoveTest", new byte[0], Ids.OPEN_ACL_UNSAFE,
+                CreateMode.EPHEMERAL);
+        // we want to loop through the list twice
+        for(int i = 0; i < hostPorts.length*2; i++) {
+            zk.dontReconnect();
+            // This should stomp the zk handle
+            DisconnectableZooKeeper zknew = new DisconnectableZooKeeper(
+                    hostPorts[(i+1)%hostPorts.length],
+                    CONNECTION_TIMEOUT,
+                    new MyWatcher(Integer.toString(i+1)),
+                    zk.getSessionId(),
+                    zk.getSessionPasswd());
+            final int result[] = new int[1];
+            result[0] = Integer.MAX_VALUE;
+            zknew.sync("/", new AsyncCallback.VoidCallback() {
+                    public void processResult(int rc, String path, Object ctx) {
+                        synchronized(result) { result[0] = rc; result.notify(); }
+                    }
+                }, null);
+            synchronized(result) {
+                if(result[0] == Integer.MAX_VALUE) {
+                    result.wait(5000);
+                }
+            }
+            LOG.info(hostPorts[(i+1)%hostPorts.length] + " Sync returned " + result[0]);
+            Assert.assertTrue(result[0] == KeeperException.Code.OK.intValue());
+            zknew.setData("/", new byte[1], -1);
+            try {
+                zk.setData("/", new byte[1], -1);
+                Assert.fail("Should have lost the connection");
+            } catch(KeeperException.ConnectionLossException e) {
+                LOG.info("Got connection loss exception as expected");
+            }
+            //zk.close();
+            zk = zknew;
+        }
+        zk.close();
+    }
+    /**
+     * This test makes sure that duplicate state changes are not communicated
+     * to the client watcher. For example we should not notify state as
+     * "disconnected" if the watch has already been disconnected. In general
+     * we don't consider a dup state notification if the event type is
+     * not "None" (ie non-None communicates an event).
+     */
+    @Test
+    public void testSessionStateNoDupStateReporting()
+        throws IOException, InterruptedException, KeeperException
+    {
+        final int TIMEOUT = 3000;
+        DupWatcher watcher = new DupWatcher();
+        ZooKeeper zk = createClient(TIMEOUT, watcher);
+
+        // shutdown the server
+        serverFactory.shutdown();
+
+        try {
+            Thread.sleep(10000);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+
+        // verify that the size is just 2 - ie connect then disconnect
+        // if the client attempts reconnect and we are not handling current
+        // state correctly (ie eventing on duplicate disconnects) then we'll
+        // see a disconnect for each Assert.failed connection attempt
+        Assert.assertEquals(2, watcher.states.size());
+
+        zk.close();
+    }
+
+    /**
+     * Verify access to the negotiated session timeout.
+     */
+    @Test
+    public void testSessionTimeoutAccess() throws Exception {
+        // validate typical case - requested == negotiated
+        DisconnectableZooKeeper zk = createClient(TICK_TIME * 4);
+        Assert.assertEquals(TICK_TIME * 4, zk.getSessionTimeout());
+        // make sure tostring works in both cases
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+
+        // validate lower limit
+        zk = createClient(TICK_TIME);
+        Assert.assertEquals(TICK_TIME * 2, zk.getSessionTimeout());
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+
+        // validate upper limit
+        zk = createClient(TICK_TIME * 30);
+        Assert.assertEquals(TICK_TIME * 20, zk.getSessionTimeout());
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+    }
+
+    private class DupWatcher extends CountdownWatcher {
+        public LinkedList<WatchedEvent> states = new LinkedList<WatchedEvent>();
+        public void process(WatchedEvent event) {
+            super.process(event);
+            if (event.getType() == EventType.None) {
+                states.add(event);
+            }
+        }
+    }
+
+    @Test
+    public void testMinMaxSessionTimeout() throws Exception {
+        // override the defaults
+        final int MINSESS = 20000;
+        final int MAXSESS = 240000;
+        {
+            ZooKeeperServer zs = ClientBase.getServer(serverFactory);
+            zs.setMinSessionTimeout(MINSESS);
+            zs.setMaxSessionTimeout(MAXSESS);
+        }
+
+        // validate typical case - requested == negotiated
+        int timeout = 120000;
+        DisconnectableZooKeeper zk = createClient(timeout);
+        Assert.assertEquals(timeout, zk.getSessionTimeout());
+        // make sure tostring works in both cases
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+
+        // validate lower limit
+        zk = createClient(MINSESS/2);
+        Assert.assertEquals(MINSESS, zk.getSessionTimeout());
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+
+        // validate upper limit
+        zk = createClient(MAXSESS * 2);
+        Assert.assertEquals(MAXSESS, zk.getSessionTimeout());
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java
new file mode 100644
index 0000000..09badae
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java
@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class SessionTimeoutTest extends ClientBase {
+    protected static final Logger LOG = LoggerFactory.getLogger(SessionTimeoutTest.class);
+
+    private TestableZooKeeper zk;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        zk = createClient();
+    }
+
+    @Test
+    public void testSessionExpiration() throws InterruptedException,
+            KeeperException {
+        final CountDownLatch expirationLatch = new CountDownLatch(1);
+        Watcher watcher = new Watcher() {
+            @Override
+            public void process(WatchedEvent event) {
+                if ( event.getState() == Event.KeeperState.Expired ) {
+                    expirationLatch.countDown();
+                }
+            }
+        };
+        zk.exists("/foo", watcher);
+
+        zk.getTestable().injectSessionExpiration();
+        Assert.assertTrue(expirationLatch.await(5, TimeUnit.SECONDS));
+
+        boolean gotException = false;
+        try {
+            zk.exists("/foo", false);
+            Assert.fail("Should have thrown a SessionExpiredException");
+        } catch (KeeperException.SessionExpiredException e) {
+            // correct
+            gotException = true;
+        }
+        Assert.assertTrue(gotException);
+    }
+
+    /**
+     * Make sure ephemerals get cleaned up when session disconnects.
+     */
+    @Test
+    public void testSessionDisconnect() throws KeeperException, InterruptedException, IOException {
+        zk.create("/sdisconnect", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.EPHEMERAL);
+        assertNotNull("Ephemeral node has not been created", zk.exists("/sdisconnect", null));
+
+        zk.close();
+
+        zk = createClient();
+        assertNull("Ephemeral node shouldn't exist after client disconnect", zk.exists("/sdisconnect", null));
+    }
+
+    /**
+     * Make sure ephemerals are kept when session restores.
+     */
+    @Test
+    public void testSessionRestore() throws KeeperException, InterruptedException, IOException {
+        zk.create("/srestore", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.EPHEMERAL);
+        assertNotNull("Ephemeral node has not been created", zk.exists("/srestore", null));
+
+        zk.disconnect();
+        zk.close();
+
+        zk = createClient();
+        assertNotNull("Ephemeral node should be present when session is restored", zk.exists("/srestore", null));
+    }
+
+    /**
+     * Make sure ephemerals are kept when server restarts.
+     */
+    @Test
+    public void testSessionSurviveServerRestart() throws Exception {
+        zk.create("/sdeath", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.EPHEMERAL);
+        assertNotNull("Ephemeral node has not been created", zk.exists("/sdeath", null));
+
+        zk.disconnect();
+        stopServer();
+        startServer();
+        zk = createClient();
+
+        assertNotNull("Ephemeral node should be present when server restarted", zk.exists("/sdeath", null));
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SledgeHammer.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SledgeHammer.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SledgeHammer.java
new file mode 100644
index 0000000..614a93d
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SledgeHammer.java
@@ -0,0 +1,115 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+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 SledgeHammer extends Thread implements Watcher {
+    ZooKeeper zk;
+
+    int count;
+
+    int readsPerWrite;
+
+    public SledgeHammer(String hosts, int count, int readsPerWrite)
+            throws IOException {
+        zk = new ZooKeeper(hosts, 10000, this);
+        this.count = count;
+        this.readsPerWrite = readsPerWrite;
+    }
+
+    public void run() {
+        try {
+            Stat stat = new Stat();
+            String path = zk.create("/hammers/hammer-", new byte[0],
+                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            byte tag[] = (path + " was here!").getBytes();
+            synchronized (this) {
+                String startPath = "/hammers/start";
+                System.out.println("Waiting for " + startPath);
+                while (zk.exists(startPath, true) == null) {
+                    wait();
+                }
+                System.out.println("Running");
+            }
+            for (int i = 0; i < count; i++) {
+                try {
+                    System.out.print(i + "\r");
+                    List<String> childs =
+                        zk.getChildren("/hammers", false);
+                    Collections.shuffle(childs);
+                    for (String s : childs) {
+                        if (s.startsWith("hammer-")) {
+                            s = "/hammers/" + s;
+                            zk.setData(s, tag, -1);
+                            for (int j = 0; j < readsPerWrite; j++) {
+                                zk.getData(s, false, stat);
+                            }
+                            break;
+                        }
+                    }
+                } catch (KeeperException.ConnectionLossException e) {
+                    // ignore connection loss
+                } catch (KeeperException e) {
+                    e.printStackTrace();
+                }
+            }
+            System.out.println();
+            zk.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @param args
+     * @throws IOException
+     * @throws KeeperException
+     * @throws NumberFormatException
+     */
+    public static void main(String[] args) throws NumberFormatException,
+            IOException {
+        if (args.length != 3) {
+            System.err
+                    .println("USAGE: SledgeHammer zookeeper_server reps reads_per_rep");
+            System.exit(3);
+        }
+        SledgeHammer h = new SledgeHammer(args[0], Integer.parseInt(args[1]),
+                Integer.parseInt(args[2]));
+        h.start();
+        System.exit(0);
+    }
+
+    public void process(WatchedEvent event) {
+        synchronized (this) {
+            notifyAll();
+        }
+    }
+
+}


[07/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerTest.java
new file mode 100644
index 0000000..fa6b4a3
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerTest.java
@@ -0,0 +1,140 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.quorum.Leader;
+import org.apache.zookeeper.server.quorum.LearnerHandler;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FollowerTest extends ZKTestCase {
+    private static final Logger LOG = LoggerFactory.getLogger(FollowerTest.class);
+    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
+
+    volatile int counter = 0;
+    volatile int errors = 0;
+
+    /** 
+     * See ZOOKEEPER-790 for details 
+     * */
+    @Test
+    public void testFollowersStartAfterLeader() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        CountdownWatcher watcher = new CountdownWatcher();
+        qu.startQuorum();
+        
+        int index = 1;
+        while(qu.getPeer(index).peer.leader == null) {
+            index++;
+        }
+        
+        ZooKeeper zk = new ZooKeeper(
+                "127.0.0.1:" + qu.getPeer((index == 1)?2:1).peer.getClientPort(),
+                ClientBase.CONNECTION_TIMEOUT, watcher);
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+        
+        // break the quorum
+        qu.shutdown(index);
+
+        // Wait until we disconnect to proceed
+        watcher.waitForDisconnected(CONNECTION_TIMEOUT);
+        
+        // try to reestablish the quorum
+        qu.start(index);
+
+        try{
+            watcher.waitForConnected(30000);      
+        } catch(TimeoutException e) {
+            Assert.fail("client could not connect to reestablished quorum: giving up after 30+ seconds.");
+        }
+
+        zk.close();
+
+        qu.tearDown();
+    }
+
+    // skip superhammer and clientcleanup as they are too expensive for quorum
+    
+    /**
+     * Tests if a multiop submitted to a non-leader propagates to the leader properly
+     * (see ZOOKEEPER-1124).
+     * 
+     * The test works as follows. It has a client connect to a follower and submit a multiop
+     * to the follower. It then verifies that the multiop successfully gets committed by the leader.
+     *
+     * Without the fix in ZOOKEEPER-1124, this fails with a ConnectionLoss KeeperException.
+     */
+    @Test
+    public void testMultiToFollower() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        CountdownWatcher watcher = new CountdownWatcher();
+        qu.startQuorum();
+        
+        int index = 1;
+        while(qu.getPeer(index).peer.leader == null) {
+            index++;
+        }
+        
+        ZooKeeper zk = new ZooKeeper(
+                "127.0.0.1:" + qu.getPeer((index == 1)?2:1).peer.getClientPort(),
+                ClientBase.CONNECTION_TIMEOUT, watcher);
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+        
+        List<OpResult> results = new ArrayList<OpResult>();
+
+        results = zk.multi(Arrays.asList(
+                Op.create("/multi0", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.create("/multi1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                Op.create("/multi2", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
+                ));
+        zk.getData("/multi0", false, null);
+        zk.getData("/multi1", false, null);
+        zk.getData("/multi2", false, null);
+
+        zk.close();
+
+        qu.tearDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
new file mode 100644
index 0000000..49d90f7
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
@@ -0,0 +1,113 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.TestableZooKeeper;
+import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class FourLetterWordsQuorumTest extends QuorumBase {
+    protected static final Logger LOG =
+        LoggerFactory.getLogger(FourLetterWordsQuorumTest.class);
+
+    /** Test the various four letter words */
+    @Test
+    public void testFourLetterWords() throws Exception {
+        String servers[] = hostPort.split(",");
+        for (String hp : servers) {
+            verify(hp, "ruok", "imok");
+            verify(hp, "envi", "java.version");
+            verify(hp, "conf", "clientPort");
+            verify(hp, "stat", "Outstanding");
+            verify(hp, "srvr", "Outstanding");
+            verify(hp, "cons", "queued");
+            verify(hp, "dump", "Session");
+            verify(hp, "wchs", "watches");
+            verify(hp, "wchp", "");
+            verify(hp, "wchc", "");
+
+            verify(hp, "srst", "reset");
+            verify(hp, "crst", "reset");
+
+            verify(hp, "stat", "Outstanding");
+            verify(hp, "srvr", "Outstanding");
+            verify(hp, "cons", "queued");
+
+            TestableZooKeeper zk = createClient(hp);
+            String sid = getHexSessionId(zk.getSessionId());
+
+            verify(hp, "stat", "queued");
+            verify(hp, "srvr", "Outstanding");
+            verify(hp, "cons", sid);
+            verify(hp, "dump", sid);
+
+            zk.getData("/", true, null);
+
+            verify(hp, "stat", "queued");
+            verify(hp, "srvr", "Outstanding");
+            verify(hp, "cons", sid);
+            verify(hp, "dump", sid);
+            verify(hp, "wchs", "watching 1");
+            verify(hp, "wchp", sid);
+            verify(hp, "wchc", sid);
+
+            zk.close();
+
+            verify(hp, "ruok", "imok");
+            verify(hp, "envi", "java.version");
+            verify(hp, "conf", "clientPort");
+            verify(hp, "stat", "Outstanding");
+            verify(hp, "srvr", "Outstanding");
+            verify(hp, "cons", "queued");
+            verify(hp, "dump", "Session");
+            verify(hp, "wchs", "watch");
+            verify(hp, "wchp", "");
+            verify(hp, "wchc", "");
+
+            verify(hp, "srst", "reset");
+            verify(hp, "crst", "reset");
+
+            verify(hp, "stat", "Outstanding");
+            verify(hp, "srvr", "Outstanding");
+            verify(hp, "cons", "queued");
+
+            verify(hp, "mntr", "zk_version\t");
+        }
+    }
+
+    private void verify(String hp, String cmd, String expected)
+        throws IOException
+    {
+        for(HostPort hpobj: parseHostPortList(hp)) {
+            String resp = send4LetterWord(hpobj.host, hpobj.port, cmd);
+            LOG.info("cmd " + cmd + " expected " + expected + " got " + resp);
+            if (cmd.equals("dump")) {
+                Assert.assertTrue(resp.contains(expected)
+                        || resp.contains("Sessions with Ephemerals"));
+            } else {
+                Assert.assertTrue(resp.contains(expected));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java
new file mode 100644
index 0000000..bc8d071
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java
@@ -0,0 +1,238 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.regex.Pattern;
+
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.common.IOUtils;
+import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FourLetterWordsTest extends ClientBase {
+    protected static final Logger LOG =
+        LoggerFactory.getLogger(FourLetterWordsTest.class);
+
+    @Rule
+    public Timeout timeout = new Timeout(30000);
+
+    /** Test the various four letter words */
+    @Test
+    public void testFourLetterWords() throws Exception {
+        verify("ruok", "imok");
+        verify("envi", "java.version");
+        verify("conf", "clientPort");
+        verify("stat", "Outstanding");
+        verify("srvr", "Outstanding");
+        verify("cons", "queued");
+        verify("dump", "Session");
+        verify("wchs", "watches");
+        verify("wchp", "");
+        verify("wchc", "");
+
+        verify("srst", "reset");
+        verify("crst", "reset");
+
+        verify("stat", "Outstanding");
+        verify("srvr", "Outstanding");
+        verify("cons", "queued");
+
+        TestableZooKeeper zk = createClient();
+        String sid = getHexSessionId(zk.getSessionId());
+
+        verify("stat", "queued");
+        verify("srvr", "Outstanding");
+        verify("cons", sid);
+        verify("dump", sid);
+
+        zk.getData("/", true, null);
+
+        verify("stat", "queued");
+        verify("srvr", "Outstanding");
+        verify("cons", sid);
+        verify("dump", sid);
+
+        verify("wchs", "watching 1");
+        verify("wchp", sid);
+        verify("wchc", sid);
+        zk.close();
+
+        verify("ruok", "imok");
+        verify("envi", "java.version");
+        verify("conf", "clientPort");
+        verify("stat", "Outstanding");
+        verify("srvr", "Outstanding");
+        verify("cons", "queued");
+        verify("dump", "Session");
+        verify("wchs", "watch");
+        verify("wchp", "");
+        verify("wchc", "");
+
+        verify("srst", "reset");
+        verify("crst", "reset");
+
+        verify("stat", "Outstanding");
+        verify("srvr", "Outstanding");
+        verify("cons", "queued");
+        verify("mntr", "zk_server_state\tstandalone");
+        verify("mntr", "num_alive_connections");
+        verify("mntr", "fsync_threshold_exceed_count");
+        verify("stat", "Connections");
+        verify("srvr", "Connections");
+    }
+
+    private String sendRequest(String cmd) throws IOException {
+      HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
+      return send4LetterWord(hpobj.host, hpobj.port, cmd);
+    }
+    private String sendRequest(String cmd, int timeout) throws IOException {
+        HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
+        return send4LetterWord(hpobj.host, hpobj.port, cmd, timeout);
+      }
+
+    private void verify(String cmd, String expected) throws IOException {
+        String resp = sendRequest(cmd);
+        LOG.info("cmd " + cmd + " expected " + expected + " got " + resp);
+        Assert.assertTrue(resp.contains(expected));
+    }
+    
+    @Test
+    public void testValidateStatOutput() throws Exception {
+        ZooKeeper zk1 = createClient();
+        ZooKeeper zk2 = createClient();
+        
+        String resp = sendRequest("stat");
+        BufferedReader in = new BufferedReader(new StringReader(resp));
+
+        String line;
+        // first line should be version info
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^.*\\s\\d+\\.\\d+\\.\\d+-.*$", line));
+        Assert.assertTrue(Pattern.matches("^Clients:$", in.readLine()));
+
+        int count = 0;
+        while ((line = in.readLine()).length() > 0) {
+            count++;
+            Assert.assertTrue(Pattern.matches("^ /.*:\\d+\\[\\d+\\]\\(queued=\\d+,recved=\\d+,sent=\\d+\\)$", line));
+        }
+        // ensure at least the two clients we created are accounted for
+        Assert.assertTrue(count >= 2);
+
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Latency min/avg/max: \\d+/\\d+/\\d+$", line));
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Received: \\d+$", line));
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Sent: \\d+$", line));
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Connections: \\d+$", line));
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Outstanding: \\d+$", line));
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Zxid: 0x[\\da-fA-F]+$", line));
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Mode: .*$", line));
+        line = in.readLine();
+        Assert.assertTrue(Pattern.matches("^Node count: \\d+$", line));
+
+        zk1.close();
+        zk2.close();
+    }
+
+    @Test
+    public void testValidateConsOutput() throws Exception {
+        ZooKeeper zk1 = createClient();
+        ZooKeeper zk2 = createClient();
+        
+        String resp = sendRequest("cons");
+        BufferedReader in = new BufferedReader(new StringReader(resp));
+
+        String line;
+        int count = 0;
+        while ((line = in.readLine()) != null && line.length() > 0) {
+            count++;
+            Assert.assertTrue(line, Pattern.matches("^ /.*:\\d+\\[\\d+\\]\\(queued=\\d+,recved=\\d+,sent=\\d+.*\\)$", line));
+        }
+        // ensure at least the two clients we created are accounted for
+        Assert.assertTrue(count >= 2);
+
+        zk1.close();
+        zk2.close();
+    }
+
+    @Test(timeout=60000)
+    public void testValidateSocketTimeout() throws Exception {
+        /**
+         * testing positive scenario that even with timeout parameter the
+         * functionality works fine
+         */
+        String resp = sendRequest("isro", 2000);
+        Assert.assertTrue(resp.contains("rw"));
+    }
+
+    @Test
+    public void testSetTraceMask() throws Exception {
+        String gtmkResp = sendRequest("gtmk");
+        Assert.assertNotNull(gtmkResp);
+        gtmkResp = gtmkResp.trim();
+        Assert.assertFalse(gtmkResp.isEmpty());
+        long formerMask = Long.valueOf(gtmkResp);
+        try {
+            verify(buildSetTraceMaskRequest(0), "0");
+            verify("gtmk", "0");
+        } finally {
+            // Restore former value.
+            sendRequest(buildSetTraceMaskRequest(formerMask));
+        }
+    }
+
+    /**
+     * Builds a SetTraceMask request to be sent to the server, consisting of
+     * "stmk" followed by the 8-byte long representation of the trace mask.
+     *
+     * @param mask trace mask to set
+     * @return built request
+     * @throws IOException if there is an I/O error
+     */
+    private String buildSetTraceMaskRequest(long mask) throws IOException {
+        ByteArrayOutputStream baos = null;
+        DataOutputStream dos = null;
+        try {
+            baos = new ByteArrayOutputStream();
+            dos = new DataOutputStream(baos);
+            dos.writeBytes("stmk");
+            dos.writeLong(mask);
+        } finally {
+            IOUtils.closeStream(dos);
+            IOUtils.closeStream(baos);
+        }
+        return new String(baos.toByteArray());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java
new file mode 100644
index 0000000..515cbdc
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java
@@ -0,0 +1,253 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.server.ServerCnxn;
+import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FourLetterWordsWhiteListTest extends ClientBase {
+    protected static final Logger LOG =
+        LoggerFactory.getLogger(FourLetterWordsTest.class);
+
+    @Rule
+    public Timeout timeout = new Timeout(30000);
+
+    /*
+     * ZOOKEEPER-2693: test white list of four letter words.
+     * For 3.5.x default white list is empty. Verify that is
+     * the case (except 'stat' command which is enabled in ClientBase
+     * which other tests depend on.).
+     */
+    @Test(timeout=30000)
+    public void testFourLetterWordsAllDisabledByDefault() throws Exception {
+        stopServer();
+        ServerCnxn.resetWhiteList();
+        System.setProperty("zookeeper.4lw.commands.whitelist", "stat");
+        startServer();
+
+        // Default white list for 3.5.x is empty, so all command should fail.
+        verifyAllCommandsFail();
+
+        TestableZooKeeper zk = createClient();
+
+        verifyAllCommandsFail();
+
+        zk.getData("/", true, null);
+
+        verifyAllCommandsFail();
+
+        zk.close();
+
+        verifyFuzzyMatch("stat", "Outstanding");
+        verifyAllCommandsFail();
+    }
+
+    @Test(timeout=30000)
+    public void testFourLetterWordsEnableSomeCommands() throws Exception {
+        stopServer();
+        ServerCnxn.resetWhiteList();
+        System.setProperty("zookeeper.4lw.commands.whitelist", "stat, ruok, isro");
+        startServer();
+        // stat, ruok and isro are white listed.
+        verifyFuzzyMatch("stat", "Outstanding");
+        verifyExactMatch("ruok", "imok");
+        verifyExactMatch("isro", "rw");
+
+        // Rest of commands fail.
+        verifyExactMatch("conf", generateExpectedMessage("conf"));
+        verifyExactMatch("cons", generateExpectedMessage("cons"));
+        verifyExactMatch("crst", generateExpectedMessage("crst"));
+        verifyExactMatch("dump", generateExpectedMessage("dump"));
+        verifyExactMatch("envi", generateExpectedMessage("envi"));
+        verifyExactMatch("gtmk", generateExpectedMessage("gtmk"));
+        verifyExactMatch("stmk", generateExpectedMessage("stmk"));
+        verifyExactMatch("srst", generateExpectedMessage("srst"));
+        verifyExactMatch("wchc", generateExpectedMessage("wchc"));
+        verifyExactMatch("wchp", generateExpectedMessage("wchp"));
+        verifyExactMatch("wchs", generateExpectedMessage("wchs"));
+        verifyExactMatch("mntr", generateExpectedMessage("mntr"));
+    }
+
+    @Test(timeout=30000)
+    public void testISROEnabledWhenReadOnlyModeEnabled() throws Exception {
+        stopServer();
+        ServerCnxn.resetWhiteList();
+        System.setProperty("zookeeper.4lw.commands.whitelist", "stat");
+        System.setProperty("readonlymode.enabled", "true");
+        startServer();
+        verifyExactMatch("isro", "rw");
+        System.clearProperty("readonlymode.enabled");
+    }
+
+    @Test(timeout=30000)
+    public void testFourLetterWordsInvalidConfiguration() throws Exception {
+        stopServer();
+        ServerCnxn.resetWhiteList();
+        System.setProperty("zookeeper.4lw.commands.whitelist", "foo bar" +
+                " foo,,, " +
+                "bar :.,@#$%^&*() , , , , bar, bar, stat,        ");
+        startServer();
+
+        // Just make sure we are good when admin made some mistakes in config file.
+        verifyAllCommandsFail();
+        // But still, what's valid in white list will get through.
+        verifyFuzzyMatch("stat", "Outstanding");
+    }
+
+    @Test(timeout=30000)
+    public void testFourLetterWordsEnableAllCommandsThroughAsterisk() throws Exception {
+        stopServer();
+        ServerCnxn.resetWhiteList();
+        System.setProperty("zookeeper.4lw.commands.whitelist", "*");
+        startServer();
+        verifyAllCommandsSuccess();
+    }
+
+    @Test(timeout=30000)
+    public void testFourLetterWordsEnableAllCommandsThroughExplicitList() throws Exception {
+        stopServer();
+        ServerCnxn.resetWhiteList();
+        System.setProperty("zookeeper.4lw.commands.whitelist",
+                "ruok, envi, conf, stat, srvr, cons, dump," +
+                        "wchs, wchp, wchc, srst, crst, " +
+                        "mntr, gtmk, isro, stmk");
+        startServer();
+        verifyAllCommandsSuccess();
+    }
+
+    private void verifyAllCommandsSuccess() throws Exception {
+        verifyExactMatch("ruok", "imok");
+        verifyFuzzyMatch("envi", "java.version");
+        verifyFuzzyMatch("conf", "clientPort");
+        verifyFuzzyMatch("stat", "Outstanding");
+        verifyFuzzyMatch("srvr", "Outstanding");
+        verifyFuzzyMatch("cons", "queued");
+        verifyFuzzyMatch("dump", "Session");
+        verifyFuzzyMatch("wchs", "watches");
+        verifyFuzzyMatch("wchp", "");
+        verifyFuzzyMatch("wchc", "");
+
+        verifyFuzzyMatch("srst", "reset");
+        verifyFuzzyMatch("crst", "reset");
+
+        verifyFuzzyMatch("stat", "Outstanding");
+        verifyFuzzyMatch("srvr", "Outstanding");
+        verifyFuzzyMatch("cons", "queued");
+        verifyFuzzyMatch("gtmk", "306");
+        verifyFuzzyMatch("isro", "rw");
+
+        TestableZooKeeper zk = createClient();
+        String sid = getHexSessionId(zk.getSessionId());
+
+        verifyFuzzyMatch("stat", "queued");
+        verifyFuzzyMatch("srvr", "Outstanding");
+        verifyFuzzyMatch("cons", sid);
+        verifyFuzzyMatch("dump", sid);
+
+        zk.getData("/", true, null);
+
+        verifyFuzzyMatch("stat", "queued");
+        verifyFuzzyMatch("srvr", "Outstanding");
+        verifyFuzzyMatch("cons", sid);
+        verifyFuzzyMatch("dump", sid);
+
+        verifyFuzzyMatch("wchs", "watching 1");
+        verifyFuzzyMatch("wchp", sid);
+        verifyFuzzyMatch("wchc", sid);
+        zk.close();
+
+        verifyExactMatch("ruok", "imok");
+        verifyFuzzyMatch("envi", "java.version");
+        verifyFuzzyMatch("conf", "clientPort");
+        verifyFuzzyMatch("stat", "Outstanding");
+        verifyFuzzyMatch("srvr", "Outstanding");
+        verifyFuzzyMatch("cons", "queued");
+        verifyFuzzyMatch("dump", "Session");
+        verifyFuzzyMatch("wchs", "watch");
+        verifyFuzzyMatch("wchp", "");
+        verifyFuzzyMatch("wchc", "");
+
+        verifyFuzzyMatch("srst", "reset");
+        verifyFuzzyMatch("crst", "reset");
+
+        verifyFuzzyMatch("stat", "Outstanding");
+        verifyFuzzyMatch("srvr", "Outstanding");
+        verifyFuzzyMatch("cons", "queued");
+        verifyFuzzyMatch("mntr", "zk_server_state\tstandalone");
+        verifyFuzzyMatch("mntr", "num_alive_connections");
+        verifyFuzzyMatch("mntr", "fsync_threshold_exceed_count");
+        verifyFuzzyMatch("stat", "Connections");
+        verifyFuzzyMatch("srvr", "Connections");
+    }
+
+    private void verifyAllCommandsFail() throws Exception {
+        verifyExactMatch("ruok", generateExpectedMessage("ruok"));
+        verifyExactMatch("conf", generateExpectedMessage("conf"));
+        verifyExactMatch("cons", generateExpectedMessage("cons"));
+        verifyExactMatch("crst", generateExpectedMessage("crst"));
+        verifyExactMatch("dump", generateExpectedMessage("dump"));
+        verifyExactMatch("envi", generateExpectedMessage("envi"));
+        verifyExactMatch("gtmk", generateExpectedMessage("gtmk"));
+        verifyExactMatch("stmk", generateExpectedMessage("stmk"));
+        verifyExactMatch("srst", generateExpectedMessage("srst"));
+        verifyExactMatch("wchc", generateExpectedMessage("wchc"));
+        verifyExactMatch("wchp", generateExpectedMessage("wchp"));
+        verifyExactMatch("wchs", generateExpectedMessage("wchs"));
+        verifyExactMatch("mntr", generateExpectedMessage("mntr"));
+        verifyExactMatch("isro", generateExpectedMessage("isro"));
+
+        // srvr is enabled by default due to the sad fact zkServer.sh uses it.
+        verifyFuzzyMatch("srvr", "Outstanding");
+    }
+
+    private void verifyFuzzyMatch(String cmd, String expected) throws IOException {
+        String resp = sendRequest(cmd);
+        LOG.info("cmd " + cmd + " expected " + expected + " got " + resp);
+        Assert.assertTrue(resp.contains(expected));
+    }
+
+    private String generateExpectedMessage(String command) {
+        return command + " is not executed because it is not in the whitelist.";
+    }
+
+    private void verifyExactMatch(String cmd, String expected) throws IOException {
+        String resp = sendRequest(cmd);
+        LOG.info("cmd " + cmd + " expected an exact match of " + expected + "; got " + resp);
+        Assert.assertTrue(resp.trim().equals(expected));
+    }
+
+    private String sendRequest(String cmd) throws IOException {
+      HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
+      return send4LetterWord(hpobj.host, hpobj.port, cmd);
+    }
+
+    private String sendRequest(String cmd, int timeout) throws IOException {
+        HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
+        return send4LetterWord(hpobj.host, hpobj.port, cmd, timeout);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java
new file mode 100644
index 0000000..e41fffe
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java
@@ -0,0 +1,136 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class GetChildren2Test extends ClientBase {
+    private ZooKeeper zk;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        zk = createClient();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        zk.close();
+    }
+
+    @Test
+    public void testChild()
+        throws IOException, KeeperException, InterruptedException
+    {
+        String name = "/foo";
+        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        String childname = name + "/bar";
+        zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.EPHEMERAL);
+
+        Stat stat = new Stat();
+        List<String> s = zk.getChildren(name, false, stat);
+
+        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+        Assert.assertEquals(stat.getCzxid() + 1, stat.getPzxid());
+        Assert.assertEquals(stat.getCtime(), stat.getMtime());
+        Assert.assertEquals(1, stat.getCversion());
+        Assert.assertEquals(0, stat.getVersion());
+        Assert.assertEquals(0, stat.getAversion());
+        Assert.assertEquals(0, stat.getEphemeralOwner());
+        Assert.assertEquals(name.length(), stat.getDataLength());
+        Assert.assertEquals(1, stat.getNumChildren());
+        Assert.assertEquals(s.size(), stat.getNumChildren());
+
+        s = zk.getChildren(childname, false, stat);
+
+        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
+        Assert.assertEquals(stat.getCtime(), stat.getMtime());
+        Assert.assertEquals(0, stat.getCversion());
+        Assert.assertEquals(0, stat.getVersion());
+        Assert.assertEquals(0, stat.getAversion());
+        Assert.assertEquals(zk.getSessionId(), stat.getEphemeralOwner());
+        Assert.assertEquals(childname.length(), stat.getDataLength());
+        Assert.assertEquals(0, stat.getNumChildren());
+        Assert.assertEquals(s.size(), stat.getNumChildren());
+    }
+
+    @Test
+    public void testChildren()
+        throws IOException, KeeperException, InterruptedException
+    {
+        String name = "/foo";
+        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        List<String> children = new ArrayList<String>();
+        List<String> children_s = new ArrayList<String>();
+
+        for (int i = 0; i < 10; i++) {
+            String childname = name + "/bar" + i;
+            String childname_s = "bar" + i;
+            children.add(childname);
+            children_s.add(childname_s);
+        }
+
+        for(int i = 0; i < children.size(); i++) {
+            String childname = children.get(i);
+            zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.EPHEMERAL);
+
+            Stat stat = new Stat();
+            List<String> s = zk.getChildren(name, false, stat);
+
+            Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+            Assert.assertEquals(stat.getCzxid() + i + 1, stat.getPzxid());
+            Assert.assertEquals(stat.getCtime(), stat.getMtime());
+            Assert.assertEquals(i + 1, stat.getCversion());
+            Assert.assertEquals(0, stat.getVersion());
+            Assert.assertEquals(0, stat.getAversion());
+            Assert.assertEquals(0, stat.getEphemeralOwner());
+            Assert.assertEquals(name.length(), stat.getDataLength());
+            Assert.assertEquals(i + 1, stat.getNumChildren());
+            Assert.assertEquals(s.size(), stat.getNumChildren());
+        }
+        List<String> p = zk.getChildren(name, false, null);
+        List<String> c_a = children_s;
+        List<String> c_b = p;
+        Collections.sort(c_a);
+        Collections.sort(c_b);
+        Assert.assertEquals(c_a.size(), 10);
+        Assert.assertEquals(c_a, c_b);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java
new file mode 100644
index 0000000..051da13
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java
@@ -0,0 +1,309 @@
+/* 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.jmx.CommonNames;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class HierarchicalQuorumTest extends ClientBase {
+    private static final Logger LOG = LoggerFactory.getLogger(QuorumBase.class);
+
+    File s1dir, s2dir, s3dir, s4dir, s5dir;
+    QuorumPeer s1, s2, s3, s4, s5;
+    protected int port1;
+    protected int port2;
+    protected int port3;
+    protected int port4;
+    protected int port5;
+
+    protected int leport1;
+    protected int leport2;
+    protected int leport3;
+    protected int leport4;
+    protected int leport5;
+
+    Properties qp;
+    protected final ClientHammerTest cht = new ClientHammerTest();
+    
+    @Override
+    public void setUp() throws Exception {
+        setupTestEnv();
+
+        JMXEnv.setUp();
+
+        setUpAll();
+
+        port1 = PortAssignment.unique();
+        port2 = PortAssignment.unique();
+        port3 = PortAssignment.unique();
+        port4 = PortAssignment.unique();
+        port5 = PortAssignment.unique();
+        leport1 = PortAssignment.unique();
+        leport2 = PortAssignment.unique();
+        leport3 = PortAssignment.unique();
+        leport4 = PortAssignment.unique();
+        leport5 = PortAssignment.unique();
+
+        hostPort = "127.0.0.1:" + port1 
+            + ",127.0.0.1:" + port2 
+            + ",127.0.0.1:" + port3 
+            + ",127.0.0.1:" + port4 
+            + ",127.0.0.1:" + port5;
+        LOG.info("Ports are: " + hostPort);
+
+        s1dir = ClientBase.createTmpDir();
+        s2dir = ClientBase.createTmpDir();
+        s3dir = ClientBase.createTmpDir();
+        s4dir = ClientBase.createTmpDir();
+        s5dir = ClientBase.createTmpDir();
+
+        String config = "group.1=1:2:3\n" +
+        "group.2=4:5\n" +
+        "weight.1=1\n" +
+        "weight.2=1\n" +
+        "weight.3=1\n" +
+        "weight.4=0\n" +
+        "weight.5=0\n";
+
+        ByteArrayInputStream is = new ByteArrayInputStream(config.getBytes());
+        this.qp = new Properties();
+        
+        qp.load(is);
+        startServers();
+
+        cht.hostPort = hostPort;
+        cht.setUpAll();
+        
+        LOG.info("Setup finished");
+    }
+    
+    /**
+     * This method is here to keep backwards compatibility with the test code 
+     * written before observers. 
+     * @throws Exception
+     */
+    void startServers() throws Exception {
+        startServers(false);
+    }
+    
+    /**
+     * Starts 5 Learners. When withObservers == false, all 5 are Followers.
+     * When withObservers == true, 3 are Followers and 2 Observers.
+     * @param withObservers
+     * @throws Exception
+     */
+    void startServers(boolean withObservers) throws Exception {
+        int tickTime = 2000;
+        int initLimit = 3;
+        int syncLimit = 3;
+        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>();
+        peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000, leport1 + 1000, null));
+        peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000, leport2 + 1000, null));
+        peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000, leport3 + 1000, null));
+        peers.put(Long.valueOf(4), new QuorumServer(4, "127.0.0.1", port4 + 1000, leport4 + 1000,
+                withObservers ? QuorumPeer.LearnerType.OBSERVER
+                        : QuorumPeer.LearnerType.PARTICIPANT));
+        peers.put(Long.valueOf(5), new QuorumServer(5, "127.0.0.1", port5 + 1000, leport5 + 1000,
+                withObservers ? QuorumPeer.LearnerType.OBSERVER
+                        : QuorumPeer.LearnerType.PARTICIPANT));
+
+        LOG.info("creating QuorumPeer 1 port " + port1);
+        List <QuorumPeer> qps = new ArrayList<QuorumPeer>();
+        QuorumHierarchical hq1 = new QuorumHierarchical(qp); 
+        s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit, hq1);
+        qps.add(s1);
+        Assert.assertEquals(port1, s1.getClientPort());
+        
+        LOG.info("creating QuorumPeer 2 port " + port2);
+        QuorumHierarchical hq2 = new QuorumHierarchical(qp); 
+        s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit, hq2);
+        qps.add(s2);
+        Assert.assertEquals(port2, s2.getClientPort());
+        
+        LOG.info("creating QuorumPeer 3 port " + port3);
+        QuorumHierarchical hq3 = new QuorumHierarchical(qp); 
+        s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit, hq3);
+        qps.add(s3);
+        Assert.assertEquals(port3, s3.getClientPort());
+        
+        LOG.info("creating QuorumPeer 4 port " + port4);
+        QuorumHierarchical hq4 = new QuorumHierarchical(qp); 
+        s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit, hq4);
+        qps.add(s4);
+        if (withObservers) {
+            s4.setLearnerType(QuorumPeer.LearnerType.OBSERVER);
+        }
+        Assert.assertEquals(port4, s4.getClientPort());
+                       
+        LOG.info("creating QuorumPeer 5 port " + port5);
+        QuorumHierarchical hq5 = new QuorumHierarchical(qp); 
+        s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit, hq5);
+        qps.add(s5);
+        if (withObservers) {
+            s5.setLearnerType(QuorumPeer.LearnerType.OBSERVER);
+        }
+        Assert.assertEquals(port5, s5.getClientPort());
+        
+        // Observers are currently only compatible with LeaderElection
+        if (withObservers) {
+            s1.setElectionType(0);
+            s2.setElectionType(0);
+            s3.setElectionType(0);
+            s4.setElectionType(0);
+            s5.setElectionType(0);
+        }
+        
+        LOG.info("start QuorumPeer 1");
+        s1.start();
+        LOG.info("start QuorumPeer 2");
+        s2.start();
+        LOG.info("start QuorumPeer 3");
+        s3.start();
+        LOG.info("start QuorumPeer 4" + (withObservers ? "(observer)" : ""));
+        s4.start();
+        LOG.info("start QuorumPeer 5" + (withObservers ? "(observer)" : ""));
+        s5.start();
+        LOG.info("started QuorumPeer 5");
+
+        LOG.info ("Closing ports " + hostPort);
+        for (String hp : hostPort.split(",")) {
+            Assert.assertTrue("waiting for server up",
+                       ClientBase.waitForServerUp(hp,
+                                    CONNECTION_TIMEOUT));
+            LOG.info(hp + " is accepting client connections");
+        }
+
+        // interesting to see what's there...
+        JMXEnv.dump();
+        // make sure we have these 5 servers listed
+        Set<String> ensureNames = new LinkedHashSet<String>();
+        for (int i = 1; i <= 5; i++) {
+            ensureNames.add("InMemoryDataTree");
+        }
+        for (int i = 1; i <= 5; i++) {
+            ensureNames.add("name0=ReplicatedServer_id" + i
+                 + ",name1=replica." + i + ",name2=");
+        }
+        for (int i = 1; i <= 5; i++) {
+            for (int j = 1; j <= 5; j++) {
+                ensureNames.add("name0=ReplicatedServer_id" + i
+                     + ",name1=replica." + j);
+            }
+        }
+        for (int i = 1; i <= 5; i++) {
+            ensureNames.add("name0=ReplicatedServer_id" + i);
+        }
+        JMXEnv.ensureAll(ensureNames.toArray(new String[ensureNames.size()]));
+        verifyElectionTimeTakenJMXAttribute(qps);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        LOG.info("TearDown started");
+        cht.tearDownAll();
+
+        LOG.info("Shutting down server 1");
+        shutdown(s1);
+        LOG.info("Shutting down server 2");
+        shutdown(s2);
+        LOG.info("Shutting down server 3");
+        shutdown(s3);
+        LOG.info("Shutting down server 4");
+        shutdown(s4);
+        LOG.info("Shutting down server 5");
+        shutdown(s5);
+        
+        for (String hp : hostPort.split(",")) {
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(hp,
+                                           ClientBase.CONNECTION_TIMEOUT));
+            LOG.info(hp + " is no longer accepting client connections");
+        }
+
+        JMXEnv.tearDown();
+    }
+
+    protected void shutdown(QuorumPeer qp) {
+        QuorumBase.shutdown(qp);
+    }
+
+    protected TestableZooKeeper createClient()
+        throws IOException, InterruptedException
+    {
+        return createClient(hostPort);
+    }
+
+    protected TestableZooKeeper createClient(String hp)
+        throws IOException, InterruptedException
+    {
+        CountdownWatcher watcher = new CountdownWatcher();
+        return createClient(watcher, hp);
+    }
+
+    private void verifyElectionTimeTakenJMXAttribute(List<QuorumPeer> peers)
+            throws Exception {
+        LOG.info("Verify QuorumPeer#electionTimeTaken jmx bean attribute");
+
+        for (int i = 1; i <= peers.size(); i++) {
+            QuorumPeer qp = peers.get(i - 1);
+            if (qp.getLearnerType() == LearnerType.OBSERVER) {
+                continue; // Observer don't have electionTimeTaken attribute.
+            }
+            Long electionTimeTaken = -1L;
+            String bean = "";
+            if (qp.getPeerState() == ServerState.FOLLOWING) {
+                bean = String.format(
+                        "%s:name0=ReplicatedServer_id%d,name1=replica.%d,name2=Follower",
+                        CommonNames.DOMAIN, i, i);
+            } else if (qp.getPeerState() == ServerState.LEADING) {
+                bean = String.format(
+                        "%s:name0=ReplicatedServer_id%d,name1=replica.%d,name2=Leader",
+                        CommonNames.DOMAIN, i, i);
+            }
+            electionTimeTaken = (Long) JMXEnv.ensureBeanAttribute(bean,
+                    "ElectionTimeTaken");
+            Assert.assertTrue("Wrong electionTimeTaken value!",
+                    electionTimeTaken >= 0);
+        }
+    }
+
+    @Test
+    public void testHierarchicalQuorum() throws Throwable {
+        cht.runHammer(5, 10);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java
new file mode 100644
index 0000000..9a01a65
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java
@@ -0,0 +1,232 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+/**
+ * This is a simple test to check the integrity of ZooKeeper servers. The client
+ * simply cycles through blasting changes to ZooKeeper and the checking what it
+ * gets back.
+ *
+ * The check is very simple. The value of the last successful read or write is
+ * stored in lastValue. When we issue a request, that value becomes a possible
+ * value. The difficulty is that when a communication error happens, the client
+ * doesn't know if the set actually went through. So, our invariant that we
+ * check for is that we always read a value that is greater than or equal to
+ * a value that we have previously read or set. (Each time we set a value, the
+ * value will be one more than the previous set.)
+ */
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.data.Stat;
+
+public class IntegrityCheck implements Watcher, StatCallback, DataCallback {
+    private static final Logger LOG = LoggerFactory.getLogger(IntegrityCheck.class);
+
+    ZooKeeper zk;
+
+    HashMap<String, byte[]> lastValue = new HashMap<String, byte[]>();
+
+    int count;
+
+    String path;
+
+    int iteration;
+
+    int outstanding;
+
+    int errorCount;
+
+    synchronized void incOutstanding() {
+        outstanding++;
+    }
+
+    synchronized void decOutstanding() {
+        outstanding--;
+        notifyAll();
+    }
+
+    synchronized void waitOutstanding() throws InterruptedException {
+        while (outstanding > 0) {
+            wait();
+        }
+    }
+
+    IntegrityCheck(String hostPort, String path, int count) throws
+            IOException {
+        zk = new ZooKeeper(hostPort, 30000, this);
+        this.path = path;
+        this.count = count;
+    }
+
+    public void run() throws InterruptedException, KeeperException {
+        try{
+            LOG.warn("Creating znodes for "+path);
+            doCreate();
+            LOG.warn("Staring the test loop for "+path);
+            while (true) {
+                LOG.warn("Staring write cycle for "+path);
+                doPopulate();
+                waitOutstanding();
+                LOG.warn("Staring read cycle for "+path);
+                readAll();
+                waitOutstanding();
+            }
+        }finally{
+            LOG.warn("Test loop terminated for "+path);
+        }
+    }
+
+    void readAll() {
+        for (int i = 0; i < count; i++) {
+            String cpath = path + "/" + i;
+            zk.getData(cpath, false, this, null);
+            incOutstanding();
+        }
+
+    }
+
+    void doCreate() throws InterruptedException, KeeperException {
+        // create top level znode
+        try{
+            zk.create(path, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        }catch(KeeperException.NodeExistsException e){
+            // ignore duplicate create
+        }
+        iteration++;
+        byte v[] = ("" + iteration).getBytes();
+        // create child znodes
+        for (int i = 0; i < count; i++) {
+            String cpath = path + "/" + i;
+            try{
+                if(i%10==0)
+                    LOG.warn("Creating znode "+cpath);
+                zk.create(cpath, v, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            }catch(KeeperException.NodeExistsException e){
+                // ignore duplicate create
+            }
+            lastValue.put(cpath, v);
+        }
+    }
+
+    void doPopulate() {
+        iteration++;
+        byte v[] = ("" + iteration).getBytes();
+        for (int i = 0; i < count; i++) {
+            String cpath = path + "/" + i;
+            zk.setData(cpath, v, -1, this, v);
+            incOutstanding();
+        }
+    }
+
+    // watcher callback
+    public void process(WatchedEvent event) {
+        if(event.getState()==KeeperState.SyncConnected){
+            synchronized(this){
+                notifyAll();
+            }
+        }
+    }
+
+    synchronized void ensureConnected(){
+        while(zk.getState()!=ZooKeeper.States.CONNECTED){
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                return;
+            }
+        }
+    }
+
+    /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        if (args.length < 3) {
+            System.err.println("USAGE: IntegrityCheck zookeeperHostPort znode #children");
+            return;
+        }
+        int childrenCount=0;
+        try {
+            childrenCount=Integer.parseInt(args[2]);
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        try{
+            final IntegrityCheck ctest = new IntegrityCheck(args[0], args[1],childrenCount);
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                public void run() {
+                    System.out.println(new Date().toString()+": Error count = " + ctest.errorCount);
+                }
+            });
+            while(true){
+                try{
+                    ctest.ensureConnected();
+                    ctest.run();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(2);
+        }
+    }
+
+    public void processResult(int rc, String path, Object ctx, Stat stat) {
+        if (rc == 0) {
+            lastValue.put(path, (byte[]) ctx);
+        }
+        decOutstanding();
+    }
+
+    public void processResult(int rc, String path, Object ctx, byte[] data,
+            Stat stat) {
+        if (rc == 0) {
+            String string = new String(data);
+            String lastString = null;
+            byte[] v = lastValue.get(path);
+            if (v != null) {
+                lastString = new String(v);
+            }
+            if (lastString != null
+                    && Integer.parseInt(string) < Integer.parseInt(lastString)) {
+                LOG.error("ERROR: Got " + string + " expected >= "
+                        + lastString);
+                errorCount++;
+            }
+            lastValue.put(path, (byte[]) ctx);
+        }
+        decOutstanding();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java
new file mode 100644
index 0000000..c5a7b4f
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java
@@ -0,0 +1,125 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.util.concurrent.CountDownLatch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.server.LogFormatter;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SnapshotFormatter;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class InvalidSnapshotTest extends ZKTestCase implements Watcher {
+    private final static Logger LOG = LoggerFactory.getLogger(UpgradeTest.class);
+    private static final String HOSTPORT =
+            "127.0.0.1:" + PortAssignment.unique();
+
+    private static final File testData = new File(
+            System.getProperty("test.data.dir", "build/test/data"));
+    private CountDownLatch startSignal;
+
+    /**
+     * Verify the LogFormatter by running it on a known file.
+     */
+    @Test
+    public void testLogFormatter() throws Exception {
+        File snapDir = new File(testData, "invalidsnap");
+        File logfile = new File(new File(snapDir, "version-2"), "log.274");
+        String[] args = {logfile.getCanonicalFile().toString()};
+        LogFormatter.main(args);
+    }
+    
+
+    /**
+     * Verify the SnapshotFormatter by running it on a known file.
+     */
+    @Test
+    public void testSnapshotFormatter() throws Exception {
+        File snapDir = new File(testData, "invalidsnap");
+        File snapfile = new File(new File(snapDir, "version-2"), "snapshot.272");
+        String[] args = {snapfile.getCanonicalFile().toString()};
+        SnapshotFormatter.main(args);
+    }
+    
+    /**
+     * Verify the SnapshotFormatter by running it on a known file with one null data.
+     */
+    @Test
+    public void testSnapshotFormatterWithNull() throws Exception {
+        File snapDir = new File(testData, "invalidsnap");
+        File snapfile = new File(new File(snapDir, "version-2"), "snapshot.273");
+        String[] args = {snapfile.getCanonicalFile().toString()};
+        SnapshotFormatter.main(args);
+    }
+    
+    /**
+     * test the snapshot
+     * @throws Exception an exception could be expected
+     */
+    @Test
+    public void testSnapshot() throws Exception {
+        File snapDir = new File(testData, "invalidsnap");
+        ZooKeeperServer zks = new ZooKeeperServer(snapDir, snapDir, 3000);
+        SyncRequestProcessor.setSnapCount(1000);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        LOG.info("starting up the zookeeper server .. waiting");
+        Assert.assertTrue("waiting for server being up",
+                ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+        ZooKeeper zk = new ZooKeeper(HOSTPORT, 20000, this);
+        try {
+            // we know this from the data files
+            // this node is the last node in the snapshot
+
+            Assert.assertTrue(zk.exists("/9/9/8", false) != null);
+        } finally {
+            zk.close();
+        }
+        f.shutdown();
+        zks.shutdown();
+        Assert.assertTrue("waiting for server down",
+                   ClientBase.waitForServerDown(HOSTPORT,
+                           ClientBase.CONNECTION_TIMEOUT));
+
+    }
+
+    public void process(WatchedEvent event) {
+        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
+        if (event.getState() == KeeperState.SyncConnected
+                && startSignal != null && startSignal.getCount() > 0)
+        {
+            startSignal.countDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/JMXEnv.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/JMXEnv.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/JMXEnv.java
new file mode 100644
index 0000000..f67c67c
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/JMXEnv.java
@@ -0,0 +1,325 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import junit.framework.TestCase;
+
+import org.apache.zookeeper.jmx.CommonNames;
+import org.apache.zookeeper.jmx.MBeanRegistry;
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JMXEnv {
+    protected static final Logger LOG = LoggerFactory.getLogger(JMXEnv.class);
+
+    private static JMXConnectorServer cs;
+    private static JMXConnector cc;
+
+    public static void setUp() throws IOException {
+        MBeanServer mbs = MBeanRegistry.getInstance().getPlatformMBeanServer();
+        
+        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
+        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+        cs.start();
+
+       JMXServiceURL addr = cs.getAddress();
+        
+       cc = JMXConnectorFactory.connect(addr);
+    }
+    
+    public static void tearDown() {
+        try {
+            if (cc != null) {
+                cc.close();
+            }
+        } catch (IOException e) {
+            LOG.warn("Unexpected, ignoring", e);
+            
+        }
+        cc = null;
+        try {
+            if (cs != null) {
+                cs.stop();
+            }
+        } catch (IOException e) {
+            LOG.warn("Unexpected, ignoring", e);
+            
+        }
+        cs = null;
+    }
+    
+    public static MBeanServerConnection conn() throws IOException {
+        return cc.getMBeanServerConnection();
+    }
+
+    /**
+     * Ensure that all of the specified names are registered.
+     * Note that these are components of the name, and in particular
+     * order matters - you want the more specific name (leafs) specified
+     * before their parent(s) (since names are hierarchical)
+     * It waits in a loop up to 60 seconds before failing if there is a
+     * mismatch.
+     * @param expectedNames
+     * @return
+     * @throws IOException
+     * @throws MalformedObjectNameException
+     */
+    public static Set<ObjectName> ensureAll(String... expectedNames)
+        throws IOException, InterruptedException
+    {
+        Set<ObjectName> beans;
+        Set<ObjectName> found;
+        int nTry = 0;
+        do {
+            if (nTry++ > 0) {
+                Thread.sleep(100);
+            }
+            try {
+                beans = conn().queryNames(
+                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
+            } catch (MalformedObjectNameException e) {
+                throw new RuntimeException(e);
+            }
+        
+            found = new HashSet<ObjectName>();
+            for (String name : expectedNames) {
+                LOG.info("expect:" + name);
+                for (ObjectName bean : beans) {
+                    if (bean.toString().contains(name)) {
+                        LOG.info("found:" + name + " " + bean);
+                        found.add(bean);
+                        break;
+                    }
+                }
+                beans.removeAll(found);
+            }
+        } while ((expectedNames.length != found.size()) && (nTry < 600));
+        TestCase.assertEquals("expected " + Arrays.toString(expectedNames),
+                expectedNames.length, found.size());
+        return beans;
+    }
+
+    /**
+     * Ensure that only the specified names are registered.
+     * Note that these are components of the name, and in particular
+     * order matters - you want the more specific name (leafs) specified
+     * before their parent(s) (since names are hierarchical)
+     * @param expectedNames
+     * @return
+     * @throws IOException
+     * @throws MalformedObjectNameException
+     */
+    public static Set<ObjectName> ensureOnly(String... expectedNames)
+        throws IOException, InterruptedException
+    {
+        LOG.info("ensureOnly:" + Arrays.toString(expectedNames));
+        Set<ObjectName> beans = ensureAll(expectedNames);
+        for (ObjectName bean : beans) {
+            LOG.info("unexpected:" + bean.toString());
+        }
+        TestCase.assertEquals(0, beans.size());
+        return beans;
+    }
+    
+    public static void ensureNone(String... expectedNames)
+        throws IOException, InterruptedException
+    {
+        Set<ObjectName> beans;
+        int nTry = 0;
+        boolean foundUnexpected = false;
+        String unexpectedName = "";
+        do {
+            if (nTry++ > 0) {
+                Thread.sleep(100);
+            }
+            try {
+                beans = conn().queryNames(
+                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
+            } catch (MalformedObjectNameException e) {
+                throw new RuntimeException(e);
+            }
+  
+            foundUnexpected = false; 
+            for (String name : expectedNames) {
+                for (ObjectName bean : beans) {
+                    if (bean.toString().contains(name)) {
+                        LOG.info("didntexpect:" + name);
+                        foundUnexpected = true;
+                        unexpectedName = name + " " + bean.toString();
+                        break;
+                    }
+                }
+                if (foundUnexpected) {
+                    break;
+                }
+            }
+        } while ((foundUnexpected) && (nTry < 600));
+        if (foundUnexpected) {
+            LOG.info("List of all beans follows:");
+            for (ObjectName bean : beans) {
+                LOG.info("bean:" + bean.toString());
+            }
+            TestCase.fail(unexpectedName);
+        }
+    }
+
+    public static void dump() throws IOException {
+        LOG.info("JMXEnv.dump() follows");
+        Set<ObjectName> beans;
+        try {
+            beans = conn().queryNames(
+                    new ObjectName(CommonNames.DOMAIN + ":*"), null);
+        } catch (MalformedObjectNameException e) {
+            throw new RuntimeException(e);
+        }
+        for (ObjectName bean : beans) {
+            LOG.info("bean:" + bean.toString());
+        }
+    }
+
+    /**
+     * Ensure that the specified parent names are registered. Note that these
+     * are components of the name. It waits in a loop up to 60 seconds before
+     * failing if there is a mismatch. This will return the beans which are not
+     * matched.
+     * 
+     * {@link https://issues.apache.org/jira/browse/ZOOKEEPER-1858}
+     * 
+     * @param expectedNames
+     *            - expected beans
+     * @return the beans which are not matched with the given expected names
+     * 
+     * @throws IOException
+     * @throws InterruptedException
+     * 
+     */
+    public static Set<ObjectName> ensureParent(String... expectedNames)
+            throws IOException, InterruptedException {
+        LOG.info("ensureParent:" + Arrays.toString(expectedNames));
+
+        Set<ObjectName> beans;
+        int nTry = 0;
+        Set<ObjectName> found = new HashSet<ObjectName>();
+        do {
+            if (nTry++ > 0) {
+                Thread.sleep(500);
+            }
+            try {
+                beans = conn().queryNames(
+                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
+            } catch (MalformedObjectNameException e) {
+                throw new RuntimeException(e);
+            }
+            found.clear();
+            for (String name : expectedNames) {
+                LOG.info("expect:" + name);
+                for (ObjectName bean : beans) {
+                    // check the existence of name in bean
+                    if (compare(bean.toString(), name)) {
+                        LOG.info("found:" + name + " " + bean);
+                        found.add(bean);
+                        break;
+                    }
+                }
+                beans.removeAll(found);
+            }
+        } while (expectedNames.length != found.size() && nTry < 120);
+        TestCase.assertEquals("expected " + Arrays.toString(expectedNames),
+                expectedNames.length, found.size());
+        return beans;
+    }
+
+    /**
+     * Comparing that the given name exists in the bean. For component beans,
+     * the component name will be present at the end of the bean name
+     * 
+     * For example 'StandaloneServer' will present in the bean name like
+     * 'org.apache.ZooKeeperService:name0=StandaloneServer_port-1'
+     */
+    private static boolean compare(String bean, String name) {
+        String[] names = bean.split("=");
+        if (names.length > 0 && names[names.length - 1].contains(name)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Ensure that the specified bean name and its attribute is registered. Note
+     * that these are components of the name. It waits in a loop up to 60
+     * seconds before failing if there is a mismatch. This will return the beans
+     * which are not matched.
+     *
+     * @param expectedName
+     *            - expected bean
+     * @param expectedAttribute
+     *            - expected attribute
+     * @return the value of the attribute
+     *
+     * @throws Exception
+     */
+    public static Object ensureBeanAttribute(String expectedName,
+            String expectedAttribute) throws Exception {
+        String value = "";
+        LOG.info("ensure bean:{}, attribute:{}", new Object[] { expectedName,
+                expectedAttribute });
+
+        Set<ObjectName> beans;
+        int nTry = 0;
+        do {
+            if (nTry++ > 0) {
+                Thread.sleep(500);
+            }
+            try {
+                beans = conn().queryNames(
+                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
+            } catch (MalformedObjectNameException e) {
+                throw new RuntimeException(e);
+            }
+            LOG.info("expect:" + expectedName);
+            for (ObjectName bean : beans) {
+                // check the existence of name in bean
+                if (bean.toString().equals(expectedName)) {
+                    LOG.info("found:{} {}", new Object[] { expectedName, bean });
+                    return conn().getAttribute(bean, expectedAttribute);
+                }
+            }
+        } while (nTry < 120);
+        Assert.fail("Failed to find bean:" + expectedName + ", attribute:"
+                + expectedAttribute);
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java
new file mode 100644
index 0000000..55dc852
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.util.EnumSet;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class KeeperStateTest extends ZKTestCase {
+    
+    @Test
+    public void testIntConversion() {
+        // Ensure that we can convert all valid integers to KeeperStates
+        EnumSet<KeeperState> allStates = EnumSet.allOf(KeeperState.class);
+
+        for(KeeperState as : allStates) {
+            Assert.assertEquals(as, KeeperState.fromInt( as.getIntValue() ) );
+        }
+    }
+
+    @Test
+    public void testInvalidIntConversion() {
+        try {
+            KeeperState ks = KeeperState.fromInt(324142);
+            Assert.fail("Was able to create an invalid KeeperState via an integer");
+        } catch(RuntimeException re) {
+            // we're good.
+        }
+
+    }
+
+    /** Validate that the deprecated constant still works. There were issues
+     * found with switch statements - which need compile time constants.
+     */
+    @Test
+    @SuppressWarnings("deprecation")
+    public void testDeprecatedCodeOkInSwitch() {
+        int test = 1;
+        switch (test) {
+        case Code.Ok:
+            Assert.assertTrue(true);
+            break;
+        }
+    }
+
+    /** Verify the enum works (paranoid) */
+    @Test
+    public void testCodeOKInSwitch() {
+        Code test = Code.OK;
+        switch (test) {
+        case OK:
+            Assert.assertTrue(true);
+            break;
+        }
+    }
+}


[08/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java
new file mode 100644
index 0000000..619bdc6
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java
@@ -0,0 +1,58 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+
+public class DisconnectableZooKeeper extends ZooKeeper {
+    public DisconnectableZooKeeper(String host, int sessionTimeout, Watcher watcher)
+        throws IOException
+    {
+        super(host, sessionTimeout, watcher);
+    }
+    
+    public DisconnectableZooKeeper(String host, int sessionTimeout, Watcher watcher,
+        long sessionId, byte[] sessionPasswd)
+        throws IOException
+    {
+        super(host, sessionTimeout, watcher, sessionId, sessionPasswd);
+    }
+
+    /** Testing only!!! Really!!!! This is only here to test when the client
+     * disconnects from the server w/o sending a session disconnect (ie
+     * ending the session cleanly). The server will eventually notice the
+     * client is no longer pinging and will timeout the session.
+     */
+    public void disconnect() throws IOException {
+        cnxn.disconnect();
+    }
+
+    /**
+     * Prevent the client from automatically reconnecting if the connection to the
+     * server is lost
+     */
+    public void dontReconnect() throws Exception {
+        java.lang.reflect.Field f = cnxn.getClass().getDeclaredField("closing");
+        f.setAccessible(true);
+        f.setBoolean(cnxn, true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java
new file mode 100644
index 0000000..e81b7f4
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java
@@ -0,0 +1,258 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DisconnectedWatcherTest extends ClientBase {
+    protected static final Logger LOG = LoggerFactory.getLogger(DisconnectedWatcherTest.class);
+    final int TIMEOUT = 5000;
+
+    private class MyWatcher extends CountdownWatcher {
+        LinkedBlockingQueue<WatchedEvent> events =
+            new LinkedBlockingQueue<WatchedEvent>();
+
+        public void process(WatchedEvent event) {
+            super.process(event);
+            if (event.getType() != Event.EventType.None) {
+                try {
+                    events.put(event);
+                } catch (InterruptedException e) {
+                    LOG.warn("ignoring interrupt during event.put");
+                }
+            }
+        }
+    }
+
+    // @see jira issue ZOOKEEPER-961
+    
+    @Test
+    public void testChildWatcherAutoResetWithChroot() throws Exception {
+        ZooKeeper zk1 = createClient();
+
+        zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+
+        MyWatcher watcher = new MyWatcher();
+        ZooKeeper zk2 = createClient(watcher, hostPort + "/ch1");
+        zk2.getChildren("/", true );
+
+        // this call shouldn't trigger any error or watch
+        zk1.create("/youdontmatter1", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        // this should trigger the watch
+        zk1.create("/ch1/youshouldmatter1", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        WatchedEvent e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertNotNull(e);
+        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+        Assert.assertEquals("/", e.getPath());
+
+        MyWatcher childWatcher = new MyWatcher();
+        zk2.getChildren("/", childWatcher);
+        
+        stopServer();
+        watcher.waitForDisconnected(3000);
+        startServer();
+        watcher.waitForConnected(3000);
+
+        // this should trigger the watch
+        zk1.create("/ch1/youshouldmatter2", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertNotNull(e);
+        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+        Assert.assertEquals("/", e.getPath());
+    }
+    
+    @Test
+    public void testDefaultWatcherAutoResetWithChroot() throws Exception {
+        ZooKeeper zk1 = createClient();
+
+        zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+
+        MyWatcher watcher = new MyWatcher();
+        ZooKeeper zk2 = createClient(watcher, hostPort + "/ch1");
+        zk2.getChildren("/", true );
+
+        // this call shouldn't trigger any error or watch
+        zk1.create("/youdontmatter1", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        // this should trigger the watch
+        zk1.create("/ch1/youshouldmatter1", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        WatchedEvent e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertNotNull(e);
+        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+        Assert.assertEquals("/", e.getPath());
+
+        zk2.getChildren("/", true );
+
+        stopServer();
+        watcher.waitForDisconnected(3000);
+        startServer();
+        watcher.waitForConnected(3000);
+
+        // this should trigger the watch
+        zk1.create("/ch1/youshouldmatter2", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertNotNull(e);
+        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+        Assert.assertEquals("/", e.getPath());
+    }
+    
+    @Test
+    public void testDeepChildWatcherAutoResetWithChroot() throws Exception {
+        ZooKeeper zk1 = createClient();
+
+        zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.create("/ch1/here", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.create("/ch1/here/we", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.create("/ch1/here/we/are", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        MyWatcher watcher = new MyWatcher();
+        ZooKeeper zk2 = createClient(watcher, hostPort + "/ch1/here/we");
+        zk2.getChildren("/are", true );
+
+        // this should trigger the watch
+        zk1.create("/ch1/here/we/are/now", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        WatchedEvent e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertNotNull(e);
+        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+        Assert.assertEquals("/are", e.getPath());
+
+        MyWatcher childWatcher = new MyWatcher();
+        zk2.getChildren("/are", childWatcher);
+        
+        stopServer();
+        watcher.waitForDisconnected(3000);
+        startServer();
+        watcher.waitForConnected(3000);
+
+        // this should trigger the watch
+        zk1.create("/ch1/here/we/are/again", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertNotNull(e);
+        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+        Assert.assertEquals("/are", e.getPath());
+    }
+
+    // @see jira issue ZOOKEEPER-706. Test auto reset of a large number of
+    // watches which require multiple SetWatches calls.
+    @Test(timeout = 840000)
+    public void testManyChildWatchersAutoReset() throws Exception {
+        ZooKeeper zk1 = createClient();
+
+        MyWatcher watcher = new MyWatcher();
+        ZooKeeper zk2 = createClient(watcher);
+
+        // 110 character base path
+        String pathBase = "/long-path-000000000-111111111-222222222-333333333-444444444-"
+                          + "555555555-666666666-777777777-888888888-999999999";
+
+        zk1.create(pathBase, null, Ids.OPEN_ACL_UNSAFE,
+                   CreateMode.PERSISTENT);
+
+        // Create 10,000 nodes. This should ensure the length of our
+        // watches set below exceeds 1MB.
+        List<String> paths = new ArrayList<String>();
+        for (int i = 0; i < 10000; i++) {
+            String path = zk1.create(pathBase + "/ch-", null, Ids.OPEN_ACL_UNSAFE,
+                                     CreateMode.PERSISTENT_SEQUENTIAL);
+            paths.add(path);
+        }
+        LOG.info("Created 10,000 nodes.");
+
+        MyWatcher childWatcher = new MyWatcher();
+
+        // Set a combination of child/exists/data watches
+        int i = 0;
+        for (String path : paths) {
+            if (i % 3 == 0) {
+                zk2.getChildren(path, childWatcher);
+            } else if (i % 3 == 1) {
+                zk2.exists(path + "/foo", childWatcher);
+            } else if (i % 3 == 2) {
+                zk2.getData(path, childWatcher, null);
+            }
+
+            i++;
+        }
+
+        stopServer();
+        watcher.waitForDisconnected(30000);
+        startServer();
+        watcher.waitForConnected(30000);
+
+        // Trigger the watches and ensure they properly propagate to the client
+        i = 0;
+        for (String path : paths) {
+            if (i % 3 == 0) {
+                zk1.create(path + "/ch", null, Ids.OPEN_ACL_UNSAFE,
+                           CreateMode.PERSISTENT);
+
+                WatchedEvent e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+                Assert.assertNotNull(e);
+                Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+                Assert.assertEquals(path, e.getPath());
+            } else if (i % 3 == 1) {
+                zk1.create(path + "/foo", null, Ids.OPEN_ACL_UNSAFE,
+                           CreateMode.PERSISTENT);
+
+                WatchedEvent e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+                Assert.assertNotNull(e);
+                Assert.assertEquals(EventType.NodeCreated, e.getType());
+                Assert.assertEquals(path + "/foo", e.getPath());
+            } else if (i % 3 == 2) {
+                zk1.setData(path, new byte[]{1, 2, 3}, -1);
+
+                WatchedEvent e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+                Assert.assertNotNull(e);
+                Assert.assertEquals(EventType.NodeDataChanged, e.getType());
+                Assert.assertEquals(path, e.getPath());
+            }
+
+            i++;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/EventTypeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/EventTypeTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/EventTypeTest.java
new file mode 100644
index 0000000..e6a9826
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/EventTypeTest.java
@@ -0,0 +1,50 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.util.EnumSet;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EventTypeTest extends ZKTestCase {
+    
+    @Test
+    public void testIntConversion() {
+        // Ensure that we can convert all valid integers to EventTypes
+        EnumSet<EventType> allTypes = EnumSet.allOf(EventType.class);
+
+        for(EventType et : allTypes) {
+            Assert.assertEquals(et, EventType.fromInt( et.getIntValue() ) );
+        }
+    }
+
+    @Test
+    public void testInvalidIntConversion() {
+        try {
+            EventType et = EventType.fromInt(324242);
+            Assert.fail("Was able to create an invalid EventType via an integer");
+        } catch(RuntimeException re) {
+            // we're good.
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java
new file mode 100644
index 0000000..1731e6e
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java
@@ -0,0 +1,192 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.concurrent.Semaphore;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.server.quorum.FastLeaderElection;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.Vote;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FLENewEpochTest extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(FLENewEpochTest.class);
+
+    int count;
+    HashMap<Long,QuorumServer> peers;
+    ArrayList<LEThread> threads;
+    File tmpdir[];
+    int port[];
+    volatile int [] round;
+
+    Semaphore start0;
+    Semaphore finish3, finish0;
+
+    @Before
+    public void setUp() throws Exception {
+        count = 3;
+
+        peers = new HashMap<Long,QuorumServer>(count);
+        threads = new ArrayList<LEThread>(count);
+        tmpdir = new File[count];
+        port = new int[count];
+
+        round = new int[3];
+        round[0] = 0;
+        round[1] = 0;
+        round[2] = 0;
+
+        start0 = new Semaphore(0);
+        finish0 = new Semaphore(0);
+        finish3 = new Semaphore(0);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        for(int i = 0; i < threads.size(); i++) {
+            ((FastLeaderElection) threads.get(i).peer.getElectionAlg()).shutdown();
+        }
+    }
+
+
+    class LEThread extends Thread {
+        int i;
+        QuorumPeer peer;
+
+        LEThread(QuorumPeer peer, int i) {
+            this.i = i;
+            this.peer = peer;
+            LOG.info("Constructor: " + getName());
+
+        }
+
+        public void run(){
+            boolean flag = true;
+            try{
+                while(flag){
+                    Vote v = null;
+                    peer.setPeerState(ServerState.LOOKING);
+                    LOG.info("Going to call leader election again: " + i);
+                    v = peer.getElectionAlg().lookForLeader();
+
+                    if (v == null){
+                        Assert.fail("Thread " + i + " got a null vote");
+                    }
+
+                    /*
+                     * A real zookeeper would take care of setting the current vote. Here
+                     * we do it manually.
+                     */
+                    peer.setCurrentVote(v);
+
+                    LOG.info("Finished election: " + i + ", " + v.getId());
+                    //votes[i] = v;
+
+                    switch (i) {
+                    case 0:
+                        LOG.info("First peer, do nothing, just join");
+                        if(finish0.tryAcquire(1000, java.util.concurrent.TimeUnit.MILLISECONDS)){
+                        //if(threads.get(0).peer.getPeerState() == ServerState.LEADING ){
+                            LOG.info("Setting flag to false");
+                            flag = false;
+                        }
+                        break;
+                    case 1:
+                        LOG.info("Second entering case");
+                        if(round[1] != 0){
+                            finish0.release();
+                            flag = false;
+                        } else {
+                            finish3.acquire();
+                            start0.release();
+                        }
+                        LOG.info("Second is going to start second round");
+                        round[1]++;
+                        break;
+                    case 2:
+                        LOG.info("Third peer, shutting it down");
+                        QuorumBase.shutdown(peer);
+                        flag = false;
+                        round[2] = 1;
+                        finish3.release();
+                        LOG.info("Third leaving");
+                        break;
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+      @Test
+      public void testLENewEpoch() throws Exception {
+
+          FastLeaderElection le[] = new FastLeaderElection[count];
+
+          LOG.info("TestLE: " + getTestName()+ ", " + count);
+          for(int i = 0; i < count; i++) {
+              peers.put(Long.valueOf(i),
+                        new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
+                                         PortAssignment.unique(), null));
+              tmpdir[i] = ClientBase.createTmpDir();
+              port[i] = PortAssignment.unique();
+          }
+
+          for(int i = 1; i < le.length; i++) {
+              QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2);
+              peer.startLeaderElection();
+              LEThread thread = new LEThread(peer, i);
+              thread.start();
+              threads.add(thread);
+          }
+          if(!start0.tryAcquire(4000, java.util.concurrent.TimeUnit.MILLISECONDS))
+              Assert.fail("First leader election failed");
+
+          QuorumPeer peer = new QuorumPeer(peers, tmpdir[0], tmpdir[0], port[0], 3, 0, 1000, 2, 2);
+          peer.startLeaderElection();
+          LEThread thread = new LEThread(peer, 0);
+          thread.start();
+          threads.add(thread);
+
+          LOG.info("Started threads " + getTestName());
+
+          for(int i = 0; i < threads.size(); i++) {
+              threads.get(i).join(10000);
+              if (threads.get(i).isAlive()) {
+                  Assert.fail("Threads didn't join");
+              }
+
+          }
+      }
+  }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java
new file mode 100644
index 0000000..0ecac6e
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java
@@ -0,0 +1,104 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+
+import org.apache.zookeeper.server.quorum.FastLeaderElection;
+import org.apache.zookeeper.server.quorum.QuorumCnxManager;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZKTestCase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class FLEPredicateTest extends ZKTestCase {
+    
+    protected static final Logger LOG = LoggerFactory.getLogger(FLEPredicateTest.class);
+    
+    class MockFLE extends FastLeaderElection {
+        MockFLE(QuorumPeer peer){
+            super(peer, peer.createCnxnManager());
+        }
+        
+        boolean predicate(long newId, long newZxid, long newEpoch, long curId, long curZxid, long curEpoch){
+            return this.totalOrderPredicate(newId, newZxid, newEpoch, curId, curZxid, curEpoch);
+        }
+    }
+    
+    
+    HashMap<Long,QuorumServer> peers;
+    
+    @Test
+    public void testPredicate() throws IOException {
+        
+        peers = new HashMap<Long,QuorumServer>(3);
+        
+        /*
+         * Creates list of peers.
+         */
+        for(int i = 0; i < 3; i++) {
+            peers.put(Long.valueOf(i),
+                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
+                                       PortAssignment.unique(), null));
+        }
+
+        /*
+         * Creating peer.
+         */
+        try{
+            File tmpDir = ClientBase.createTmpDir();
+            QuorumPeer peer = new QuorumPeer(peers, tmpDir, tmpDir,
+                                        PortAssignment.unique(), 3, 0, 1000, 2, 2);
+        
+            MockFLE mock = new MockFLE(peer);
+            
+            /*
+             * Lower epoch must return false
+             */
+            
+            Assert.assertFalse (mock.predicate(4L, 0L, 0L, 3L, 0L, 2L));
+            
+            /*
+             * Later epoch
+             */
+            Assert.assertTrue (mock.predicate(0L, 0L, 1L, 1L, 0L, 0L));
+        
+            /*
+             * Higher zxid
+             */
+            Assert.assertTrue(mock.predicate(0L, 1L, 0L, 1L, 0L, 0L));
+        
+            /*
+             * Higher id
+             */
+            Assert.assertTrue(mock.predicate(1L, 1L, 0L, 0L, 1L, 0L));
+        } catch (IOException e) {
+            LOG.error("Exception while creating quorum peer", e);
+            Assert.fail("Exception while creating quorum peer");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLERestartTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLERestartTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLERestartTest.java
new file mode 100644
index 0000000..a7cecf6
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLERestartTest.java
@@ -0,0 +1,203 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.concurrent.Semaphore;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.server.quorum.FastLeaderElection;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.Vote;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FLERestartTest extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(FLETest.class);
+
+    static class TestVote {
+        TestVote(int id, long leader) {
+            this.leader = leader;
+        }
+
+        long leader;
+    }
+
+    int countVotes(HashSet<TestVote> hs, long id) {
+        int counter = 0;
+        for(TestVote v : hs){
+            if(v.leader == id) counter++;
+        }
+
+        return counter;
+    }
+
+    int count;
+    //    int baseport;
+    //    int baseLEport;
+    HashMap<Long,QuorumServer> peers;
+    ArrayList<FLERestartThread> restartThreads;
+    HashMap<Integer, HashSet<TestVote> > voteMap;
+    File tmpdir[];
+    int port[];
+    int successCount;
+    Semaphore finish;
+
+    volatile Vote votes[];
+    volatile boolean leaderDies;
+    volatile long leader = -1;
+    //volatile int round = 1;
+    Random rand = new Random();
+
+    @Before
+    public void setUp() throws Exception {
+        count = 3;
+
+        peers = new HashMap<Long,QuorumServer>(count);
+        restartThreads = new ArrayList<FLERestartThread>(count);
+        voteMap = new HashMap<Integer, HashSet<TestVote> >();
+        votes = new Vote[count];
+        tmpdir = new File[count];
+        port = new int[count];
+        successCount = 0;
+        finish = new Semaphore(0);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        for(int i = 0; i < restartThreads.size(); i++) {
+            ((FastLeaderElection) restartThreads.get(i).peer.getElectionAlg()).shutdown();
+        }
+    }
+
+    class FLERestartThread extends Thread {
+        int i;
+        QuorumPeer peer;
+        int peerRound = 0;
+
+        FLERestartThread(QuorumPeer peer, int i) {
+            this.i = i;
+            this.peer = peer;
+            LOG.info("Constructor: " + getName());
+        }
+        public void run() {
+            try {
+                Vote v = null;
+                while(true) {
+                    peer.setPeerState(ServerState.LOOKING);
+                    LOG.info("Going to call leader election again.");
+                    v = peer.getElectionAlg().lookForLeader();
+                    if(v == null){
+                        LOG.info("Thread " + i + " got a null vote");
+                        break;
+                    }
+
+                    /*
+                     * A real zookeeper would take care of setting the current vote. Here
+                     * we do it manually.
+                     */
+                    peer.setCurrentVote(v);
+
+                    LOG.info("Finished election: " + i + ", " + v.getId());
+                    //votes[i] = v;
+
+                    switch(i){
+                    case 0:
+                        if(peerRound == 0){
+                            LOG.info("First peer, shutting it down");
+                            QuorumBase.shutdown(peer);
+                            ((FastLeaderElection) restartThreads.get(i).peer.getElectionAlg()).shutdown();
+
+                            peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2);
+                            peer.startLeaderElection();
+                            peerRound++;
+                        } else {
+                            finish.release(2);
+                            return;
+                        }
+
+                        break;
+                    case 1:
+                        LOG.info("Second entering case");
+                        finish.acquire();
+                        //if(threads.get(0).peer.getPeerState() == ServerState.LEADING ){
+                        LOG.info("Release");
+
+                        return;
+                    case 2:
+                        LOG.info("First peer, do nothing, just join");
+                        finish.acquire();
+                        //if(threads.get(0).peer.getPeerState() == ServerState.LEADING ){
+                        LOG.info("Release");
+
+                        return;
+                    }
+                }
+            } catch (Exception e){
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    @Test
+    public void testLERestart() throws Exception {
+
+        FastLeaderElection le[] = new FastLeaderElection[count];
+        leaderDies = true;
+        boolean allowOneBadLeader = leaderDies;
+
+        LOG.info("TestLE: " + getTestName()+ ", " + count);
+        for(int i = 0; i < count; i++) {
+            peers.put(Long.valueOf(i),
+                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
+                                       PortAssignment.unique(), null));
+            tmpdir[i] = ClientBase.createTmpDir();
+            port[i] = PortAssignment.unique();
+        }
+
+        for(int i = 0; i < count; i++) {
+            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2);
+            peer.startLeaderElection();
+            FLERestartThread thread = new FLERestartThread(peer, i);
+            thread.start();
+            restartThreads.add(thread);
+        }
+        LOG.info("Started threads " + getTestName());
+        for(int i = 0; i < restartThreads.size(); i++) {
+            restartThreads.get(i).join(10000);
+            if (restartThreads.get(i).isAlive()) {
+                Assert.fail("Threads didn't join");
+            }
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLETest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLETest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLETest.java
new file mode 100644
index 0000000..6281a57
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLETest.java
@@ -0,0 +1,473 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.server.quorum.FastLeaderElection;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.Vote;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FLETest extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(FLETest.class);
+    private FLETest.LEThread leThread;
+
+    static class TestVote {
+        TestVote(int id, long leader) {
+            this.leader = leader;
+        }
+
+        long leader;
+    }
+
+    int countVotes(HashSet<TestVote> hs, long id) {
+        int counter = 0;
+        for(TestVote v : hs){
+            if(v.leader == id) counter++;
+        }
+
+        return counter;
+    }
+
+    int count;
+    HashMap<Long,QuorumServer> peers;
+    ArrayList<LEThread> threads;
+    HashMap<Integer, HashSet<TestVote> > voteMap;
+    File tmpdir[];
+    int port[];
+    int successCount;
+    Object finalObj;
+
+    volatile Vote votes[];
+    volatile boolean leaderDies;
+    volatile long leader = -1;
+    //volatile int round = 1;
+    Random rand = new Random();
+    Set<Long> joinedThreads;
+
+    @Before
+    public void setUp() throws Exception {
+        count = 7;
+
+        peers = new HashMap<Long,QuorumServer>(count);
+        threads = new ArrayList<LEThread>(count);
+        voteMap = new HashMap<Integer, HashSet<TestVote> >();
+        votes = new Vote[count];
+        tmpdir = new File[count];
+        port = new int[count];
+        successCount = 0;
+        finalObj = new Object();
+        joinedThreads = new HashSet<Long>();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        for (int i = 0; i < threads.size(); i++) {
+            leThread = threads.get(i);
+            QuorumBase.shutdown(leThread.peer);
+        }
+    }
+
+    class LEThread extends Thread {
+        int i;
+        QuorumPeer peer;
+        //int peerRound = 1;
+
+        LEThread(QuorumPeer peer, int i) {
+            this.i = i;
+            this.peer = peer;
+            LOG.info("Constructor: " + getName());
+        }
+        public void run() {
+            try {
+                Vote v = null;
+                while(true) {
+                    peer.setPeerState(ServerState.LOOKING);
+                    LOG.info("Going to call leader election again.");
+                    v = peer.getElectionAlg().lookForLeader();
+                    if(v == null){
+                        LOG.info("Thread " + i + " got a null vote");
+                        break;
+                    }
+
+                    /*
+                     * A real zookeeper would take care of setting the current vote. Here
+                     * we do it manually.
+                     */
+                    peer.setCurrentVote(v);
+
+                    LOG.info("Finished election: " + i + ", " + v.getId());
+                    votes[i] = v;
+
+                    /*
+                     * Get the current value of the logical clock for this peer.
+                     */
+                    int lc = (int) ((FastLeaderElection) peer.getElectionAlg()).getLogicalClock();
+
+                    if (v.getId() == i) {
+                        /*
+                         * A leader executes this part of the code. If it is the first leader to be
+                         * elected, then it Assert.fails right after. Otherwise, it waits until it has enough
+                         * followers supporting it.
+                         */
+                        LOG.info("I'm the leader: " + i);
+                        synchronized(FLETest.this) {
+                            if (leaderDies) {
+                                LOG.info("Leader " + i + " dying");
+                                leaderDies = false;
+                                ((FastLeaderElection) peer.getElectionAlg()).shutdown();
+                                leader = -1;
+                                LOG.info("Leader " + i + " dead");
+
+                                //round++;
+                                FLETest.this.notifyAll();
+
+                                break;
+
+                            } else {
+                                synchronized(voteMap){
+                                    if(voteMap.get(lc) == null)
+                                        voteMap.put(lc, new HashSet<TestVote>());
+                                    HashSet<TestVote> hs = voteMap.get(lc);
+                                    hs.add(new TestVote(i, v.getId()));
+
+                                    if(countVotes(hs, v.getId()) > (count/2)){
+                                        leader = i;
+                                        LOG.info("Got majority: " + i);
+                                    } else {
+                                        voteMap.wait(3000);
+                                        LOG.info("Notified or expired: " + i);
+                                        hs = voteMap.get(lc);
+                                        if(countVotes(hs, v.getId()) > (count/2)){
+                                            leader = i;
+                                            LOG.info("Got majority: " + i);
+                                        } else {
+                                            //round++;
+                                        }
+                                    }
+                                }
+                                FLETest.this.notifyAll();
+
+                                if(leader == i){
+                                    synchronized(finalObj){
+                                        successCount++;
+                                        joinedThreads.add((long)i);
+                                        if(successCount > (count/2)) finalObj.notify();
+                                    }
+
+                                    break;
+                                }
+                            }
+                        }
+                    } else {
+                        /*
+                         * Followers execute this part. They first add their vote to voteMap, and then
+                         * they wait for bounded amount of time. A leader notifies followers through the
+                         * FLETest.this object.
+                         *
+                         * Note that I can get FLETest.this, and then voteMap before adding the vote of
+                         * a follower, otherwise a follower would be blocked out until the leader notifies
+                         * or leaves the synchronized block on FLEtest.this.
+                         */
+
+
+                        LOG.info("Logical clock " + ((FastLeaderElection) peer.getElectionAlg()).getLogicalClock());
+                        synchronized(voteMap){
+                            LOG.info("Voting on " + votes[i].getId() + ", round " + ((FastLeaderElection) peer.getElectionAlg()).getLogicalClock());
+                            if(voteMap.get(lc) == null)
+                                voteMap.put(lc, new HashSet<TestVote>());
+                            HashSet<TestVote> hs = voteMap.get(lc);
+                            hs.add(new TestVote(i, votes[i].getId()));
+                            if(countVotes(hs, votes[i].getId()) > (count/2)){
+                                LOG.info("Logical clock: " + lc + ", " + votes[i].getId());
+                                voteMap.notify();
+                            }
+                        }
+
+                        /*
+                         * In this part a follower waits until the leader notifies it, and remove its
+                         * vote if the leader takes too long to respond.
+                         */
+                        synchronized(FLETest.this){
+                            if (leader != votes[i].getId()) FLETest.this.wait(3000);
+
+                            LOG.info("The leader: " + leader + " and my vote " + votes[i].getId());
+                            synchronized(voteMap){
+                                if (leader == votes[i].getId()) {
+                                    synchronized(finalObj){
+                                        successCount++;
+                                        joinedThreads.add((long)i);
+                                        if(successCount > (count/2)) finalObj.notify();
+                                    }
+                                    break;
+                                } else {
+                                    HashSet<TestVote> hs = voteMap.get(lc);
+                                    TestVote toRemove = null;
+                                    for(TestVote tv : hs){
+                                        if(v.getId() == i){
+                                            toRemove = tv;
+                                            break;
+                                        }
+                                    }
+                                    hs.remove(toRemove);
+                                }
+                            }
+                        }
+                    }
+                    /*
+                     * Add some randomness to the execution.
+                     */
+                    Thread.sleep(rand.nextInt(500));
+                    peer.setCurrentVote(new Vote(peer.getId(), 0));
+                }
+                LOG.debug("Thread " + i + " votes " + v);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Test
+    public void testLE() throws Exception {
+
+        FastLeaderElection le[] = new FastLeaderElection[count];
+        leaderDies = true;
+        boolean allowOneBadLeader = leaderDies;
+
+        LOG.info("TestLE: " + getTestName()+ ", " + count);
+        for(int i = 0; i < count; i++) {
+            peers.put(Long.valueOf(i),
+                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
+                                       PortAssignment.unique(), null));
+            tmpdir[i] = ClientBase.createTmpDir();
+            port[i] = PortAssignment.unique();
+        }
+
+        for(int i = 0; i < le.length; i++) {
+            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i],
+                    port[i], 3, i, 1000, 2, 2);
+            peer.startLeaderElection();
+            LEThread thread = new LEThread(peer, i);
+            thread.start();
+            threads.add(thread);
+        }
+        LOG.info("Started threads " + getTestName());
+
+
+        int waitCounter = 0;
+        synchronized(finalObj){
+            while((successCount <= count/2) && (waitCounter < 50)){
+                finalObj.wait(2000);
+                waitCounter++;
+            }
+        }
+
+        /*
+        * Lists what threads haven-t joined. A thread doesn't join if
+        * it hasn't decided upon a leader yet. It can happen that a
+        * peer is slow or disconnected, and it can take longer to
+        * nominate and connect to the current leader.
+        */
+       for (int i = 0; i < threads.size(); i++) {
+            if (threads.get(i).isAlive()) {
+                LOG.info("Threads didn't join: " + i);
+            }
+        }
+
+       /*
+        * If we have a majority, then we are good to go.
+        */
+       if(successCount <= count/2){
+           Assert.fail("Fewer than a a majority has joined");
+       }
+
+       synchronized(finalObj){
+           if(!joinedThreads.contains(leader)){
+               Assert.fail("Leader hasn't joined: " + leader);
+           }
+       }
+    }
+
+    /*
+     * Class to verify of the thread has become a follower
+     */
+    class VerifyState extends Thread {
+        volatile private boolean success = false;
+        QuorumPeer peer;
+        public VerifyState(QuorumPeer peer) {
+            this.peer = peer;
+        }
+        public void run() {
+            setName("VerifyState-" + peer.getId());
+            while (true) {
+                if(peer.getPeerState() == ServerState.FOLLOWING) {
+                    LOG.info("I am following");
+                    success = true;
+                    break;
+                } else if (peer.getPeerState() == ServerState.LEADING) {
+                    LOG.info("I am leading");
+                    success = false;
+                    break;
+                }
+                try {
+                    Thread.sleep(250);
+                } catch (Exception e) {
+                    LOG.warn("Sleep failed ", e);
+                }
+            }
+        }
+        public boolean isSuccess() {
+            return success;
+        }
+    }
+
+    /*
+     * For ZOOKEEPER-975 verify that a peer joining an established cluster
+     * does not go in LEADING state.
+     */
+    @Test
+    public void testJoin() throws Exception {
+        int sid;
+        QuorumPeer peer;
+        int waitTime = 10 * 1000;
+        ArrayList<QuorumPeer> peerList = new ArrayList<QuorumPeer>();
+        for(sid = 0; sid < 3; sid++) {
+            peers.put(Long.valueOf(sid),
+                      new QuorumServer(sid, "0.0.0.0", PortAssignment.unique(),
+                                       PortAssignment.unique(), null));
+            tmpdir[sid] = ClientBase.createTmpDir();
+            port[sid] = PortAssignment.unique();
+        }
+        // start 2 peers and verify if they form the cluster
+        for (sid = 0; sid < 2; sid++) {
+            peer = new QuorumPeer(peers, tmpdir[sid], tmpdir[sid],
+                                             port[sid], 3, sid, 2000, 2, 2);
+            LOG.info("Starting peer " + peer.getId());
+            peer.start();
+            peerList.add(sid, peer);
+        }
+        peer = peerList.get(0);
+        VerifyState v1 = new VerifyState(peerList.get(0));
+        v1.start();
+        v1.join(waitTime);
+        Assert.assertFalse("Unable to form cluster in " +
+            waitTime + " ms",
+            !v1.isSuccess());
+        // Start 3rd peer and check if it goes in LEADING state
+        peer = new QuorumPeer(peers, tmpdir[sid], tmpdir[sid],
+                 port[sid], 3, sid, 2000, 2, 2);
+        LOG.info("Starting peer " + peer.getId());
+        peer.start();
+        peerList.add(sid, peer);
+        v1 = new VerifyState(peer);
+        v1.start();
+        v1.join(waitTime);
+        if (v1.isAlive()) {
+               Assert.fail("Peer " + peer.getId() + " failed to join the cluster " +
+                "within " + waitTime + " ms");
+        } else if (!v1.isSuccess()) {
+               Assert.fail("Incorrect LEADING state for peer " + peer.getId());
+        }
+        // cleanup
+        for (int id = 0; id < 3; id++) {
+            peer = peerList.get(id);
+            if (peer != null) {
+                peer.shutdown();
+            }
+        }
+    }
+
+    /*
+     * For ZOOKEEPER-1732 verify that it is possible to join an ensemble with
+     * inconsistent election round information.
+     */
+    @Test
+    public void testJoinInconsistentEnsemble() throws Exception {
+        int sid;
+        QuorumPeer peer;
+        int waitTime = 10 * 1000;
+        ArrayList<QuorumPeer> peerList = new ArrayList<QuorumPeer>();
+        for(sid = 0; sid < 3; sid++) {
+            peers.put(Long.valueOf(sid),
+                      new QuorumServer(sid, "0.0.0.0", PortAssignment.unique(),
+                                       PortAssignment.unique(), null));
+            tmpdir[sid] = ClientBase.createTmpDir();
+            port[sid] = PortAssignment.unique();
+        }
+        // start 2 peers and verify if they form the cluster
+        for (sid = 0; sid < 2; sid++) {
+            peer = new QuorumPeer(peers, tmpdir[sid], tmpdir[sid],
+                                             port[sid], 3, sid, 2000, 2, 2);
+            LOG.info("Starting peer " + peer.getId());
+            peer.start();
+            peerList.add(sid, peer);
+        }
+        peer = peerList.get(0);
+        VerifyState v1 = new VerifyState(peerList.get(0));
+        v1.start();
+        v1.join(waitTime);
+        Assert.assertFalse("Unable to form cluster in " +
+            waitTime + " ms",
+            !v1.isSuccess());
+        // Change the election round for one of the members of the ensemble
+        long leaderSid = peer.getCurrentVote().getId();
+        long zxid = peer.getCurrentVote().getZxid();
+        long electionEpoch = peer.getCurrentVote().getElectionEpoch();
+        ServerState state = peer.getCurrentVote().getState();
+        long peerEpoch = peer.getCurrentVote().getPeerEpoch();
+        Vote newVote = new Vote(leaderSid, zxid+100, electionEpoch+100, peerEpoch, state);
+        peer.setCurrentVote(newVote);
+        // Start 3rd peer and check if it joins the quorum
+        peer = new QuorumPeer(peers, tmpdir[2], tmpdir[2],
+                 port[2], 3, 2, 2000, 2, 2);
+        LOG.info("Starting peer " + peer.getId());
+        peer.start();
+        peerList.add(sid, peer);
+        v1 = new VerifyState(peer);
+        v1.start();
+        v1.join(waitTime);
+        if (v1.isAlive()) {
+               Assert.fail("Peer " + peer.getId() + " failed to join the cluster " +
+                "within " + waitTime + " ms");
+        }
+        // cleanup
+        for (int id = 0; id < 3; id++) {
+            peer = peerList.get(id);
+            if (peer != null) {
+                peer.shutdown();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java
new file mode 100644
index 0000000..e8a8cf7
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java
@@ -0,0 +1,181 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.Random;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.server.quorum.FastLeaderElection;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.Vote;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FLEZeroWeightTest extends ZKTestCase {
+    private static final Logger LOG = LoggerFactory.getLogger(HierarchicalQuorumTest.class);
+
+    Properties qp;
+
+    int count;
+    HashMap<Long,QuorumServer> peers;
+    ArrayList<LEThread> threads;
+    File tmpdir[];
+    int port[];
+    Object finalObj;
+
+    volatile Vote votes[];
+    volatile boolean leaderDies;
+    volatile long leader = -1;
+    Random rand = new Random();
+
+
+    @Before
+    public void setUp() throws Exception {
+        count = 9;
+
+        peers = new HashMap<Long,QuorumServer>(count);
+        threads = new ArrayList<LEThread>(count);
+        votes = new Vote[count];
+        tmpdir = new File[count];
+        port = new int[count];
+        finalObj = new Object();
+
+        String config = "group.1=0:1:2\n" +
+        "group.2=3:4:5\n" +
+        "group.3=6:7:8\n" +
+        "weight.0=1\n" +
+        "weight.1=1\n" +
+        "weight.2=1\n" +
+        "weight.3=0\n" +
+        "weight.4=0\n" +
+        "weight.5=0\n" +
+        "weight.6=0\n" +
+        "weight.7=0\n" +
+        "weight.8=0";
+
+        ByteArrayInputStream is = new ByteArrayInputStream(config.getBytes());
+        this.qp = new Properties();
+        qp.load(is);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        for(int i = 0; i < threads.size(); i++) {
+            LEThread leThread = threads.get(i);
+            // shutdown() has to be explicitly called for every thread to
+            // make sure that resources are freed properly and all fixed network ports
+            // are available for other test cases
+            QuorumBase.shutdown(leThread.peer);
+        }
+    }
+
+    class LEThread extends Thread {
+        int i;
+        QuorumPeer peer;
+        boolean fail;
+
+        LEThread(QuorumPeer peer, int i) {
+            this.i = i;
+            this.peer = peer;
+            LOG.info("Constructor: " + getName());
+        }
+
+        public void run() {
+            try {
+                Vote v = null;
+                fail = false;
+                while(true){
+
+                    //while(true) {
+                    peer.setPeerState(ServerState.LOOKING);
+                    LOG.info("Going to call leader election.");
+                    v = peer.getElectionAlg().lookForLeader();
+                    if(v == null){
+                        LOG.info("Thread " + i + " got a null vote");
+                        return;
+                    }
+
+                    /*
+                     * A real zookeeper would take care of setting the current vote. Here
+                     * we do it manually.
+                     */
+                    peer.setCurrentVote(v);
+
+                    LOG.info("Finished election: " + i + ", " + v.getId());
+                    votes[i] = v;
+
+                    if((peer.getPeerState() == ServerState.LEADING) &&
+                            (peer.getId() > 2)) fail = true;
+
+                    if((peer.getPeerState() == ServerState.FOLLOWING) ||
+                            (peer.getPeerState() == ServerState.LEADING)) break;
+                }
+                LOG.debug("Thread " + i + " votes " + v);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Test
+    public void testZeroWeightQuorum() throws Exception {
+        FastLeaderElection le[] = new FastLeaderElection[count];
+
+        LOG.info("TestZeroWeightQuorum: " + getTestName()+ ", " + count);
+        for(int i = 0; i < count; i++) {
+            peers.put(Long.valueOf(i),
+                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(), PortAssignment.unique(), null));
+            tmpdir[i] = ClientBase.createTmpDir();
+            port[i] = PortAssignment.unique();
+        }
+
+        for(int i = 0; i < le.length; i++) {
+            QuorumHierarchical hq = new QuorumHierarchical(qp);
+            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2, hq);
+            peer.startLeaderElection();
+            LEThread thread = new LEThread(peer, i);
+            thread.start();
+            threads.add(thread);
+        }
+        LOG.info("Started threads " + getTestName());
+
+        for(int i = 0; i < threads.size(); i++) {
+            threads.get(i).join(15000);
+            if (threads.get(i).isAlive()) {
+                Assert.fail("Threads didn't join");
+            } else {
+                if(threads.get(i).fail)
+                    Assert.fail("Elected zero-weight server");
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java
new file mode 100644
index 0000000..acd05d6
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java
@@ -0,0 +1,607 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.server.ZKDatabase;
+import org.apache.zookeeper.server.quorum.Leader;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class FollowerResyncConcurrencyTest extends ZKTestCase {
+    private static final Logger LOG = Logger.getLogger(FollowerResyncConcurrencyTest.class);
+    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
+
+    private volatile int counter = 0;
+    private volatile int errors = 0;
+
+    /**
+     * See ZOOKEEPER-1319 - verify that a lagging follwer resyncs correctly
+     * 
+     * 1) start with down quorum
+     * 2) start leader/follower1, add some data
+     * 3) restart leader/follower1
+     * 4) start follower2
+     * 5) verify data consistency across the ensemble
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testLaggingFollowerResyncsUnderNewEpoch() throws Exception {
+        CountdownWatcher watcher1 = new CountdownWatcher();
+        CountdownWatcher watcher2 = new CountdownWatcher();
+        CountdownWatcher watcher3 = new CountdownWatcher();
+
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.shutdownAll();
+
+        qu.start(1);
+        qu.start(2);
+        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                + qu.getPeer(1).clientPort, ClientBase.CONNECTION_TIMEOUT));
+        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                + qu.getPeer(2).clientPort, ClientBase.CONNECTION_TIMEOUT));
+
+        ZooKeeper zk1 =
+                createClient(qu.getPeer(1).peer.getClientPort(), watcher1);
+        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
+
+        final String resyncPath = "/resyncundernewepoch";
+        zk1.create(resyncPath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk1.close();
+
+        qu.shutdown(1);
+        qu.shutdown(2);
+        Assert.assertTrue("Waiting for server down", ClientBase.waitForServerDown("127.0.0.1:"
+                + qu.getPeer(1).clientPort, ClientBase.CONNECTION_TIMEOUT));
+        Assert.assertTrue("Waiting for server down", ClientBase.waitForServerDown("127.0.0.1:"
+                + qu.getPeer(2).clientPort, ClientBase.CONNECTION_TIMEOUT));
+        
+        qu.start(1);
+        qu.start(2);
+        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                + qu.getPeer(1).clientPort, ClientBase.CONNECTION_TIMEOUT));
+        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                + qu.getPeer(2).clientPort, ClientBase.CONNECTION_TIMEOUT));
+
+        qu.start(3);
+        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                + qu.getPeer(3).clientPort, ClientBase.CONNECTION_TIMEOUT));
+
+        zk1 = createClient(qu.getPeer(1).peer.getClientPort(), watcher1);
+        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
+        
+        assertNotNull("zk1 has data", zk1.exists(resyncPath, false));
+
+        final ZooKeeper zk2 =
+                createClient(qu.getPeer(2).peer.getClientPort(), watcher2);
+        LOG.info("zk2 has session id 0x" + Long.toHexString(zk2.getSessionId()));
+
+        assertNotNull("zk2 has data", zk2.exists(resyncPath, false));
+
+        final ZooKeeper zk3 =
+            createClient(qu.getPeer(3).peer.getClientPort(), watcher3);
+        LOG.info("zk3 has session id 0x" + Long.toHexString(zk3.getSessionId()));
+
+        assertNotNull("zk3 has data", zk3.exists(resyncPath, false));
+
+        zk1.close();
+        zk2.close();
+        zk3.close();
+        
+        qu.shutdownAll();
+    }      
+
+    /**
+     * See ZOOKEEPER-962. This tests for one of the bugs hit while fixing this,
+     * setting the ZXID of the SNAP packet
+     * Starts up 3 ZKs. Shut down F1, write a node, restart the one that was shut down
+     * The non-leader ZKs are writing to cluster
+     * Shut down F1 again
+     * Restart after sessions are expired, expect to get a snap file
+     * Shut down, run some transactions through.
+     * Restart to a diff while transactions are running in leader
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws KeeperException
+     */
+    @Test
+    public void testResyncBySnapThenDiffAfterFollowerCrashes() 
+        throws IOException, InterruptedException, KeeperException,  Throwable
+    {
+        final Semaphore sem = new Semaphore(0);
+
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+        CountdownWatcher watcher1 = new CountdownWatcher();
+        CountdownWatcher watcher2 = new CountdownWatcher();
+        CountdownWatcher watcher3 = new CountdownWatcher();
+
+        int index = 1;
+        while(qu.getPeer(index).peer.leader == null) {
+            index++;
+        }
+
+        Leader leader = qu.getPeer(index).peer.leader;
+        assertNotNull(leader);    
+
+        /* Reusing the index variable to select a follower to connect to */
+        index = (index == 1) ? 2 : 1;
+        LOG.info("Connecting to follower:" + index);
+
+        qu.shutdown(index);
+
+        final ZooKeeper zk3 =
+            createClient(qu.getPeer(3).peer.getClientPort(), watcher3);
+        LOG.info("zk3 has session id 0x" + Long.toHexString(zk3.getSessionId()));
+
+        zk3.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
+
+        qu.restart(index);
+        final ZooKeeper zk1 =
+            createClient(qu.getPeer(index).peer.getClientPort(), watcher1);
+        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
+
+        final ZooKeeper zk2 =
+            createClient(qu.getPeer(index).peer.getClientPort(), watcher2);
+        LOG.info("zk2 has session id 0x" + Long.toHexString(zk2.getSessionId()));
+        
+        zk1.create("/first", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Thread mytestfooThread = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                for(int i = 0; i < 3000; i++) {
+                    zk3.create("/mytestfoo", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
+
+                        @Override
+                        public void processResult(int rc, String path, Object ctx, String name) {
+                            counter++;
+                            if (rc != 0) {
+                                errors++;
+                            }
+                            if(counter == 16200){
+                                sem.release();
+                            }
+                        }
+                    }, null);
+                    if(i%10==0){
+                        try {
+                            Thread.sleep(100);
+                        } catch (Exception e) {
+
+                        }
+                    }
+                }
+
+            }
+        });
+
+        for(int i = 0; i < 13000; i++) {
+            zk3.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
+
+                @Override
+                public void processResult(int rc, String path, Object ctx, String name) {
+                    counter++;
+                    if (rc != 0) {
+                        errors++;
+                    }
+                    if(counter == 16200){
+                        sem.release();
+                    }
+                }
+            }, null);            
+
+            if(i == 5000){
+                qu.shutdown(index);               
+                LOG.info("Shutting down s1");
+            }
+            if(i == 12000){
+                //Restart off of snap, then get some txns for a log, then shut down
+                mytestfooThread.start();
+                qu.restart(index);       
+                Thread.sleep(300);
+                qu.shutdown(index);               
+                Thread.sleep(300);                
+                qu.restart(index);
+                LOG.info("Setting up server: " + index);
+            }
+            if((i % 1000) == 0){
+                Thread.sleep(1000);
+            }
+
+            if(i%50 == 0) {
+                zk2.create("/newbaz", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
+                    @Override
+                    public void processResult(int rc, String path, Object ctx, String name) {
+                        counter++;
+                        if (rc != 0) {
+                            errors++;
+                        }
+                        if(counter == 16200){
+                            sem.release();
+                        }
+                    }
+                }, null);
+            }
+        }
+
+        // Wait until all updates return
+        if(!sem.tryAcquire(ClientBase.CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)) {
+            LOG.warn("Did not aquire semaphore fast enough");
+        }
+        mytestfooThread.join(ClientBase.CONNECTION_TIMEOUT);
+        if (mytestfooThread.isAlive()) {
+            LOG.error("mytestfooThread is still alive");
+        }
+        Thread.sleep(1000);
+        
+        verifyState(qu, index, leader);
+        
+        zk1.close();
+        zk2.close();
+        zk3.close();
+        
+        qu.shutdownAll();
+    }      
+    
+    /**
+     * This test:
+     * Starts up 3 ZKs. The non-leader ZKs are writing to cluster
+     * Shut down one of the non-leader ZKs. 
+     * Restart after sessions have expired but <500 txns have taken place (get a diff)
+     * Shut down immediately after restarting, start running separate thread with other transactions
+     * Restart to a diff while transactions are running in leader
+     * 
+     * 
+     * Before fixes for ZOOKEEPER-962, restarting off of diff could get an inconsistent view of data missing transactions that
+     * completed during diff syncing. Follower would also be considered "restarted" before all forwarded transactions
+     * were completely processed, so restarting would cause a snap file with a too-high zxid to be written, and transactions
+     * would be missed
+     * 
+     * This test should pretty reliably catch the failure of restarting the server before all diff messages have been processed,
+     * however, due to the transient nature of the system it may not catch failures due to concurrent processing of transactions
+     * during the leader's diff forwarding.
+     * 
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws KeeperException
+     * @throws Throwable
+     */
+
+    @Test
+    public void testResyncByDiffAfterFollowerCrashes() 
+        throws IOException, InterruptedException, KeeperException, Throwable
+    {
+        final Semaphore sem = new Semaphore(0);
+
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+        CountdownWatcher watcher1 = new CountdownWatcher();
+        CountdownWatcher watcher2 = new CountdownWatcher();
+        CountdownWatcher watcher3 = new CountdownWatcher();
+
+        int index = 1;
+        while(qu.getPeer(index).peer.leader == null) {
+            index++;
+        }
+
+        Leader leader = qu.getPeer(index).peer.leader;
+        assertNotNull(leader);
+
+        /* Reusing the index variable to select a follower to connect to */
+        index = (index == 1) ? 2 : 1;
+        LOG.info("Connecting to follower:" + index);
+
+        final ZooKeeper zk1 =
+            createClient(qu.getPeer(index).peer.getClientPort(), watcher1);
+        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
+
+        final ZooKeeper zk2 =
+            createClient(qu.getPeer(index).peer.getClientPort(), watcher2);
+        LOG.info("zk2 has session id 0x" + Long.toHexString(zk2.getSessionId()));
+
+        final ZooKeeper zk3 =
+            createClient(qu.getPeer(3).peer.getClientPort(), watcher3);
+        LOG.info("zk3 has session id 0x" + Long.toHexString(zk3.getSessionId()));
+
+        zk1.create("/first", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk2.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
+
+        final AtomicBoolean runNow = new AtomicBoolean(false);
+        Thread mytestfooThread = new Thread(new Runnable() {
+            @Override
+            public void run() {                                
+                int inSyncCounter = 0;
+                while(inSyncCounter < 400) {    
+                    if(runNow.get()) {
+                        zk3.create("/mytestfoo", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
+
+                            @Override
+                            public void processResult(int rc, String path, Object ctx, String name) {
+                                counter++;
+                                if (rc != 0) {
+                                    errors++;
+                                }
+                                if(counter > 7300){
+                                    sem.release();
+                                }
+                            }
+                        }, null);
+                        
+                        try {
+                            Thread.sleep(10);
+                        } catch (Exception e) {
+                        }
+                        inSyncCounter++;
+                    } else {
+                        Thread.yield();
+                    }
+                }
+
+            }
+        });
+
+        mytestfooThread.start();
+        for(int i = 0; i < 5000; i++) {
+            zk2.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
+
+                @Override
+                public void processResult(int rc, String path, Object ctx, String name) {
+                    counter++;
+                    if (rc != 0) {
+                        errors++;
+                    }
+                    if(counter > 7300){
+                        sem.release();
+                    }
+                }
+            }, null);            
+
+            if(i == 1000){
+                qu.shutdown(index);      
+                Thread.sleep(1100);
+                LOG.info("Shutting down s1");
+            }
+            if(i == 1100 || i == 1150 || i == 1200) {
+                Thread.sleep(1000);
+            }
+            
+            if(i == 1200){
+                qu.startThenShutdown(index);                                
+                runNow.set(true);
+                qu.restart(index);
+                LOG.info("Setting up server: " + index);
+            }
+        
+            if(i>=1000 &&  i%2== 0) {
+                zk3.create("/newbaz", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
+
+                    @Override
+                    public void processResult(int rc, String path, Object ctx, String name) {
+                        counter++;
+                        if (rc != 0) {
+                            errors++;
+                        }
+                        if(counter > 7300){
+                            sem.release();
+                        }
+                    }
+                }, null);
+            }
+            if(i == 1050 || i == 1100 || i == 1150) {
+                Thread.sleep(1000);
+            }
+        }
+
+        // Wait until all updates return
+        if(!sem.tryAcquire(ClientBase.CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)) {
+            LOG.warn("Did not aquire semaphore fast enough");
+        }
+        mytestfooThread.join(ClientBase.CONNECTION_TIMEOUT);
+        if (mytestfooThread.isAlive()) {
+            LOG.error("mytestfooThread is still alive");
+        }
+
+        Thread.sleep(1000);
+        // Verify that server is following and has the same epoch as the leader
+        
+        verifyState(qu, index, leader);
+        
+        zk1.close();
+        zk2.close();
+        zk3.close();
+        
+        qu.shutdownAll();
+    }
+
+    private static DisconnectableZooKeeper createClient(int port,
+            CountdownWatcher watcher)
+        throws IOException, TimeoutException, InterruptedException
+    {
+        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(
+                "127.0.0.1:" + port, ClientBase.CONNECTION_TIMEOUT, watcher);
+
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+        return zk;
+    }
+
+    private static TestableZooKeeper createTestableClient(String hp)
+        throws IOException, TimeoutException, InterruptedException
+    {
+        CountdownWatcher watcher = new CountdownWatcher();
+        return createTestableClient(watcher, hp);
+    }
+
+    private static TestableZooKeeper createTestableClient(
+            CountdownWatcher watcher, String hp)
+            throws IOException, TimeoutException, InterruptedException
+        {
+            TestableZooKeeper zk = new TestableZooKeeper(
+                    hp, ClientBase.CONNECTION_TIMEOUT, watcher);
+
+            watcher.waitForConnected(CONNECTION_TIMEOUT);
+            return zk;
+        }
+
+    private void verifyState(QuorumUtil qu, int index, Leader leader) {
+        assertTrue("Not following", qu.getPeer(index).peer.follower != null);
+        long epochF = (qu.getPeer(index).peer.getActiveServer().getZxid() >> 32L);
+        long epochL = (leader.getEpoch() >> 32L);
+        assertTrue("Zxid: " + qu.getPeer(index).peer.getActiveServer().getZKDatabase().getDataTreeLastProcessedZxid() + 
+                "Current epoch: " + epochF, epochF == epochL);
+        int leaderIndex = (index == 1) ? 2 : 1;    
+        Collection<Long> sessionsRestarted = qu.getPeer(index).peer.getActiveServer().getZKDatabase().getSessions();
+        Collection<Long> sessionsNotRestarted = qu.getPeer(leaderIndex).peer.getActiveServer().getZKDatabase().getSessions();
+        
+        for(Long l : sessionsRestarted) {
+            assertTrue("Should have same set of sessions in both servers, did not expect: " + l, sessionsNotRestarted.contains(l));        
+        }      
+        assertEquals("Should have same number of sessions", sessionsNotRestarted.size(), sessionsRestarted.size());
+        ZKDatabase restarted = qu.getPeer(index).peer.getActiveServer().getZKDatabase();
+        ZKDatabase clean =  qu.getPeer(3).peer.getActiveServer().getZKDatabase();
+        ZKDatabase lead = qu.getPeer(leaderIndex).peer.getActiveServer().getZKDatabase();
+        for(Long l : sessionsRestarted) {
+            assertTrue("Should have same set of sessions in both servers, did not expect: " + l, sessionsNotRestarted.contains(l));
+            HashSet ephemerals = restarted.getEphemerals(l);
+            HashSet cleanEphemerals = clean.getEphemerals(l);
+            for(Object o : cleanEphemerals) {
+                if(!ephemerals.contains(o)) {
+                    LOG.info("Restarted follower doesn't contain ephemeral " + o);
+                }
+            }
+            HashSet leadEphemerals = lead.getEphemerals(l);
+            for(Object o : leadEphemerals) {
+                if(!cleanEphemerals.contains(o)) {
+                    LOG.info("Follower doesn't contain ephemeral from leader " + o);
+                }
+            }
+            assertEquals("Should have same number of ephemerals in both followers", ephemerals.size(), cleanEphemerals.size());            
+            assertEquals("Leader should equal follower", lead.getEphemerals(l).size(), cleanEphemerals.size());
+        }
+    }      
+
+    /**
+     * Verify that the server is sending the proper zxid. See ZOOKEEPER-1412.
+     */
+    @Test
+    public void testFollowerSendsLastZxid() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+
+        int index = 1;
+        while(qu.getPeer(index).peer.follower == null) {
+            index++;
+        }
+        LOG.info("Connecting to follower:" + index);
+
+        TestableZooKeeper zk =
+                createTestableClient("localhost:" + qu.getPeer(index).peer.getClientPort());
+
+        assertEquals(0L, zk.testableLastZxid());
+        zk.exists("/", false);
+        long lzxid = zk.testableLastZxid();
+        assertTrue("lzxid:" + lzxid + " > 0", lzxid > 0);
+        zk.close();
+    }
+
+    private class MyWatcher extends CountdownWatcher {
+        LinkedBlockingQueue<WatchedEvent> events =
+            new LinkedBlockingQueue<WatchedEvent>();
+
+        public void process(WatchedEvent event) {
+            super.process(event);
+            if (event.getType() != Event.EventType.None) {
+                try {
+                    events.put(event);
+                } catch (InterruptedException e) {
+                    LOG.warn("ignoring interrupt during event.put");
+                }
+            }
+        }
+    }
+
+    /**
+     * Verify that the server is sending the proper zxid, and as a result
+     * the watch doesn't fire. See ZOOKEEPER-1412.
+     */
+    @Test
+    public void testFollowerWatcherResync() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+
+        int index = 1;
+        while(qu.getPeer(index).peer.follower == null) {
+            index++;
+        }
+        LOG.info("Connecting to follower:" + index);
+
+        TestableZooKeeper zk1 = createTestableClient(
+                "localhost:" + qu.getPeer(index).peer.getClientPort());
+        zk1.create("/foo", "foo".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+
+        MyWatcher watcher = new MyWatcher();
+        TestableZooKeeper zk2 = createTestableClient(watcher,
+                "localhost:" + qu.getPeer(index).peer.getClientPort());
+
+        zk2.exists("/foo", true);
+
+        watcher.reset();
+        zk2.testableConnloss();
+        if (!watcher.clientConnected.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS))
+        {
+            fail("Unable to connect to server");
+        }
+        assertArrayEquals("foo".getBytes(), zk2.getData("/foo", false, null));
+
+        assertNull(watcher.events.poll(5, TimeUnit.SECONDS));
+
+        zk1.close();
+        zk2.close();
+    }
+
+}


[22/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java
deleted file mode 100644
index 6f281d9..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ReadOnlyModeTest.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.LineNumberReader;
-import java.io.StringReader;
-import java.util.regex.Pattern;
-
-import junit.framework.Assert;
-
-import org.apache.log4j.Layout;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.apache.log4j.WriterAppender;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.KeeperException.NotReadOnlyException;
-import org.apache.zookeeper.Transaction;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooKeeper.States;
-import org.apache.zookeeper.common.Time;
-import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import org.slf4j.LoggerFactory;
-
-
-public class ReadOnlyModeTest extends ZKTestCase {
-    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ReadOnlyModeTest.class);
-    private static int CONNECTION_TIMEOUT = QuorumBase.CONNECTION_TIMEOUT;
-    private QuorumUtil qu = new QuorumUtil(1);
-
-    @Before
-    public void setUp() throws Exception {
-        System.setProperty("readonlymode.enabled", "true");
-        qu.startQuorum();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        System.setProperty("readonlymode.enabled", "false");
-        qu.tearDown();
-    }
-
-    /**
-     * Test write operations using multi request.
-     */
-    @Test(timeout = 90000)
-    public void testMultiTransaction() throws Exception {
-        CountdownWatcher watcher = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
-                watcher, true);
-        watcher.waitForConnected(CONNECTION_TIMEOUT); // ensure zk got connected
-
-        final String data = "Data to be read in RO mode";
-        final String node1 = "/tnode1";
-        final String node2 = "/tnode2";
-        zk.create(node1, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        watcher.reset();
-        qu.shutdown(2);
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-        Assert.assertEquals("Should be in r-o mode", States.CONNECTEDREADONLY,
-                zk.getState());
-
-        // read operation during r/o mode
-        String remoteData = new String(zk.getData(node1, false, null));
-        Assert.assertEquals("Failed to read data in r-o mode", data, remoteData);
-
-        try {
-            Transaction transaction = zk.transaction();
-            transaction.setData(node1, "no way".getBytes(), -1);
-            transaction.create(node2, data.getBytes(),
-                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            transaction.commit();
-            Assert.fail("Write operation using multi-transaction"
-                    + " api has succeeded during RO mode");
-        } catch (NotReadOnlyException e) {
-            // ok
-        }
-
-        Assert.assertNull("Should have created the znode:" + node2,
-                zk.exists(node2, false));
-    }
-
-    /**
-     * Basic test of read-only client functionality. Tries to read and write
-     * during read-only mode, then regains a quorum and tries to write again.
-     */
-    @Test(timeout = 90000)
-    public void testReadOnlyClient() throws Exception {
-        CountdownWatcher watcher = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
-                watcher, true);
-        watcher.waitForConnected(CONNECTION_TIMEOUT); // ensure zk got connected
-
-        final String data = "Data to be read in RO mode";
-        final String node = "/tnode";
-        zk.create(node, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        watcher.reset();
-        qu.shutdown(2);
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-
-        // read operation during r/o mode
-        String remoteData = new String(zk.getData(node, false, null));
-        Assert.assertEquals(data, remoteData);
-
-        try {
-            zk.setData(node, "no way".getBytes(), -1);
-            Assert.fail("Write operation has succeeded during RO mode");
-        } catch (NotReadOnlyException e) {
-            // ok
-        }
-
-        watcher.reset();
-        qu.start(2);
-        Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(
-                "127.0.0.1:" + qu.getPeer(2).clientPort, CONNECTION_TIMEOUT));
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-        zk.setData(node, "We're in the quorum now".getBytes(), -1);
-
-        zk.close();
-    }
-
-    /**
-     * Ensures that upon connection to a read-only server client receives
-     * ConnectedReadOnly state notification.
-     */
-    @Test(timeout = 90000)
-    public void testConnectionEvents() throws Exception {
-        CountdownWatcher watcher = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
-                watcher, true);
-        boolean success = false;
-        for (int i = 0; i < 30; i++) {
-            try {
-                zk.create("/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-                success=true;
-                break;
-            } catch(KeeperException.ConnectionLossException e) {
-                Thread.sleep(1000);               
-            }            
-        }
-        Assert.assertTrue("Did not succeed in connecting in 30s", success);
-        Assert.assertFalse("The connection should not be read-only yet", watcher.readOnlyConnected);
-
-        // kill peer and wait no more than 5 seconds for read-only server
-        // to be started (which should take one tickTime (2 seconds))
-        qu.shutdown(2);
-        long start = Time.currentElapsedTime();
-        while (!(zk.getState() == States.CONNECTEDREADONLY)) {
-            Thread.sleep(200);
-            // FIXME this was originally 5 seconds, but realistically, on random/slow/virt hosts, there is no way to guarantee this
-            Assert.assertTrue("Can't connect to the server",
-                              Time.currentElapsedTime() - start < 30000);
-        }
-
-        watcher.waitForReadOnlyConnected(5000);
-        zk.close();
-    }
-
-    /**
-     * Tests a situation when client firstly connects to a read-only server and
-     * then connects to a majority server. Transition should be transparent for
-     * the user.
-     */
-    @Test(timeout = 90000)
-    public void testSessionEstablishment() throws Exception {
-        qu.shutdown(2);
-
-        CountdownWatcher watcher = new CountdownWatcher();
-        LOG.debug("Connection string: {}", qu.getConnString());
-        ZooKeeper zk = new ZooKeeper(qu.getConnString(), CONNECTION_TIMEOUT,
-                watcher, true);
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-        Assert.assertSame("should be in r/o mode", States.CONNECTEDREADONLY, zk
-                .getState());
-        long fakeId = zk.getSessionId();
-        LOG.info("Connected as r/o mode with state {} and session id {}",
-                zk.getState(), fakeId);
-
-        watcher.reset();
-        qu.start(2);
-        Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(
-                "127.0.0.1:" + qu.getPeer(2).clientPort, CONNECTION_TIMEOUT));
-        LOG.info("Server 127.0.0.1:{} is up", qu.getPeer(2).clientPort);
-        // ZOOKEEPER-2722: wait until we can connect to a read-write server after the quorum
-        // is formed. Otherwise, it is possible that client first connects to a read-only server,
-        // then drops the connection because of shutting down of the read-only server caused
-        // by leader election / quorum forming between the read-only server and the newly started
-        // server. If we happen to execute the zk.create after the read-only server is shutdown and
-        // before the quorum is formed, we will get a ConnectLossException.
-        watcher.waitForSyncConnected(CONNECTION_TIMEOUT);
-        Assert.assertEquals("Should be in read-write mode", States.CONNECTED,
-                zk.getState());
-        LOG.info("Connected as rw mode with state {} and session id {}",
-                zk.getState(), zk.getSessionId());
-        zk.create("/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        Assert.assertFalse("fake session and real session have same id", zk
-                .getSessionId() == fakeId);
-        zk.close();
-    }
-
-    /**
-     * Ensures that client seeks for r/w servers while it's connected to r/o
-     * server.
-     */
-    @SuppressWarnings("deprecation")
-    @Test(timeout = 90000)
-    public void testSeekForRwServer() throws Exception {
-
-        // setup the logger to capture all logs
-        Layout layout = Logger.getRootLogger().getAppender("CONSOLE")
-                .getLayout();
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        WriterAppender appender = new WriterAppender(layout, os);
-        appender.setImmediateFlush(true);
-        appender.setThreshold(Level.INFO);
-        Logger zlogger = Logger.getLogger("org.apache.zookeeper");
-        zlogger.addAppender(appender);
-
-        try {
-            qu.shutdown(2);
-            CountdownWatcher watcher = new CountdownWatcher();
-            ZooKeeper zk = new ZooKeeper(qu.getConnString(),
-                    CONNECTION_TIMEOUT, watcher, true);
-            watcher.waitForConnected(CONNECTION_TIMEOUT);
-
-            // if we don't suspend a peer it will rejoin a quorum
-            qu.getPeer(1).peer.suspend();
-
-            // start two servers to form a quorum; client should detect this and
-            // connect to one of them
-            watcher.reset();
-            qu.start(2);
-            qu.start(3);
-            ClientBase.waitForServerUp(qu.getConnString(), 2000);
-            watcher.waitForConnected(CONNECTION_TIMEOUT);
-            zk.create("/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-
-            // resume poor fellow
-            qu.getPeer(1).peer.resume();
-        } finally {
-            zlogger.removeAppender(appender);
-        }
-
-        os.close();
-        LineNumberReader r = new LineNumberReader(new StringReader(os
-                .toString()));
-        String line;
-        Pattern p = Pattern.compile(".*Majority server found.*");
-        boolean found = false;
-        while ((line = r.readLine()) != null) {
-            if (p.matcher(line).matches()) {
-                found = true;
-                break;
-            }
-        }
-        Assert.assertTrue(
-                "Majority server wasn't found while connected to r/o server",
-                found);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/RecoveryTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/RecoveryTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/RecoveryTest.java
deleted file mode 100644
index c084a68..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/RecoveryTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class RecoveryTest extends ZKTestCase implements Watcher {
-    protected static final Logger LOG = LoggerFactory.getLogger(RecoveryTest.class);
-
-    private static final String HOSTPORT =
-        "127.0.0.1:" + PortAssignment.unique();
-
-    private volatile CountDownLatch startSignal;
-
-    /**
-     * Verify that if a server goes down that clients will reconnect
-     * automatically after the server is restarted. Note that this requires the
-     * server to restart within the connection timeout period.
-     *
-     * Also note that the client latches are used to eliminate any chance
-     * of spurrious connectionloss exceptions on the read ops. Specifically
-     * a sync operation will throw this exception if the server goes down
-     * (as recognized by the client) during the operation. If the operation
-     * occurs after the server is down, but before the client recognizes
-     * that the server is down (ping) then the op will throw connectionloss.
-     */
-    @Test
-    public void testRecovery() throws Exception {
-        File tmpDir = ClientBase.createTmpDir();
-
-        ClientBase.setupTestEnv();
-        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-
-        int oldSnapCount = SyncRequestProcessor.getSnapCount();
-        SyncRequestProcessor.setSnapCount(1000);
-        try {
-            final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-            ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-            f.startup(zks);
-            LOG.info("starting up the the server, waiting");
-
-            Assert.assertTrue("waiting for server up",
-                       ClientBase.waitForServerUp(HOSTPORT,
-                                       CONNECTION_TIMEOUT));
-
-            startSignal = new CountDownLatch(1);
-            ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
-            startSignal.await(CONNECTION_TIMEOUT,
-                    TimeUnit.MILLISECONDS);
-            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
-            String path;
-            LOG.info("starting creating nodes");
-            for (int i = 0; i < 10; i++) {
-                path = "/" + i;
-                zk.create(path,
-                          (path + "!").getBytes(),
-                          Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-                for (int j = 0; j < 10; j++) {
-                    String subpath = path + "/" + j;
-                    zk.create(subpath, (subpath + "!").getBytes(),
-                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-                    for (int k = 0; k < 20; k++) {
-                        String subsubpath = subpath + "/" + k;
-                        zk.create(subsubpath, (subsubpath + "!").getBytes(),
-                                Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-                    }
-                }
-            }
-
-            f.shutdown();
-            zks.shutdown();
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown(HOSTPORT,
-                                          CONNECTION_TIMEOUT));
-
-            zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-            f = ServerCnxnFactory.createFactory(PORT, -1);
-
-            startSignal = new CountDownLatch(1);
-
-            f.startup(zks);
-
-            Assert.assertTrue("waiting for server up",
-                       ClientBase.waitForServerUp(HOSTPORT,
-                                           CONNECTION_TIMEOUT));
-
-            startSignal.await(CONNECTION_TIMEOUT,
-                    TimeUnit.MILLISECONDS);
-            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
-
-            Stat stat = new Stat();
-            for (int i = 0; i < 10; i++) {
-                path = "/" + i;
-                LOG.info("Checking " + path);
-                Assert.assertEquals(new String(zk.getData(path, false, stat)), path
-                        + "!");
-                for (int j = 0; j < 10; j++) {
-                    String subpath = path + "/" + j;
-                    Assert.assertEquals(new String(zk.getData(subpath, false, stat)),
-                            subpath + "!");
-                    for (int k = 0; k < 20; k++) {
-                        String subsubpath = subpath + "/" + k;
-                        Assert.assertEquals(new String(zk.getData(subsubpath, false,
-                                stat)), subsubpath + "!");
-                    }
-                }
-            }
-            f.shutdown();
-            zks.shutdown();
-
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown(HOSTPORT,
-                                          ClientBase.CONNECTION_TIMEOUT));
-
-            zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-            f = ServerCnxnFactory.createFactory(PORT, -1);
-
-            startSignal = new CountDownLatch(1);
-
-            f.startup(zks);
-
-            Assert.assertTrue("waiting for server up",
-                       ClientBase.waitForServerUp(HOSTPORT,
-                               CONNECTION_TIMEOUT));
-
-            startSignal.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
-            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
-
-            stat = new Stat();
-            LOG.info("Check 2");
-            for (int i = 0; i < 10; i++) {
-                path = "/" + i;
-                Assert.assertEquals(new String(zk.getData(path, false, stat)),
-                             path + "!");
-                for (int j = 0; j < 10; j++) {
-                    String subpath = path + "/" + j;
-                    Assert.assertEquals(new String(zk.getData(subpath, false, stat)),
-                            subpath + "!");
-                    for (int k = 0; k < 20; k++) {
-                        String subsubpath = subpath + "/" + k;
-                        Assert.assertEquals(new String(zk.getData(subsubpath, false,
-                                stat)), subsubpath + "!");
-                    }
-                }
-            }
-            zk.close();
-
-            f.shutdown();
-            zks.shutdown();
-
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown(HOSTPORT,
-                                                    CONNECTION_TIMEOUT));
-        } finally {
-            SyncRequestProcessor.setSnapCount(oldSnapCount);
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatcherEvent)
-     */
-    public void process(WatchedEvent event) {
-        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
-        if (event.getState() == KeeperState.SyncConnected
-                && startSignal != null && startSignal.getCount() > 0)
-        {
-            startSignal.countDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java
deleted file mode 100644
index f714a2c..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/RepeatStartupTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class RepeatStartupTest extends ZKTestCase {
-
-    /** bring up 5 quorum peers and then shut them down
-     * and then bring one of the nodes as server
-     *
-     * @throws Exception might be thrown here
-     */
-    @Test
-    public void testFail() throws Exception {
-        QuorumBase qb = new QuorumBase();
-        qb.setUp();
-
-        System.out.println("Comment: the servers are at " + qb.hostPort);
-        ZooKeeper zk = qb.createClient();
-        zk.create("/test", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.close();
-        qb.shutdown(qb.s1);
-        qb.shutdown(qb.s2);
-        qb.shutdown(qb.s3);
-        qb.shutdown(qb.s4);
-        qb.shutdown(qb.s5);
-        String hp = qb.hostPort.split(",")[0];
-        ZooKeeperServer zks = new ZooKeeperServer(qb.s1.getTxnFactory().getSnapDir(),
-                qb.s1.getTxnFactory().getDataDir(), 3000);
-        final int PORT = Integer.parseInt(hp.split(":")[1]);
-        ServerCnxnFactory factory = ServerCnxnFactory.createFactory(PORT, -1);
-
-        factory.startup(zks);
-        System.out.println("Comment: starting factory");
-        Assert.assertTrue("waiting for server up",
-                   ClientBase.waitForServerUp("127.0.0.1:" + PORT,
-                           QuorumTest.CONNECTION_TIMEOUT));
-        factory.shutdown();
-        zks.shutdown();
-        Assert.assertTrue("waiting for server down",
-                   ClientBase.waitForServerDown("127.0.0.1:" + PORT,
-                                                QuorumTest.CONNECTION_TIMEOUT));
-        System.out.println("Comment: shutting down standalone");
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java
deleted file mode 100644
index 65cc0e2..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/RestoreCommittedLogTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.util.List;
-import java.util.LinkedList;
-
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.server.quorum.Leader.Proposal;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
-import org.junit.Assert;
-import org.junit.Test;
-
-/** After a replica starts, it should load commits in its committedLog list. 
- *  This test checks if committedLog != 0 after replica restarted.
- */
-public class RestoreCommittedLogTest extends ZKTestCase implements  Watcher {
-    private static final Logger LOG = Logger.getLogger(RestoreCommittedLogTest.class);
-    private static String HOSTPORT = "127.0.0.1:" + PortAssignment.unique();
-    private static final int CONNECTION_TIMEOUT = 3000;
-    /**
-     * test the purge
-     * @throws Exception an exception might be thrown here
-     */
-    @Test
-    public void testRestoreCommittedLog() throws Exception {
-        File tmpDir = ClientBase.createTmpDir();
-        ClientBase.setupTestEnv();
-        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-        SyncRequestProcessor.setSnapCount(100);
-        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-        f.startup(zks);
-        Assert.assertTrue("waiting for server being up ",
-                ClientBase.waitForServerUp(HOSTPORT,CONNECTION_TIMEOUT));
-        ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
-        try {
-            for (int i = 0; i< 2000; i++) {
-                zk.create("/invalidsnap-" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-            }
-        } finally {
-            zk.close();
-        }
-        f.shutdown();
-        zks.shutdown();
-        Assert.assertTrue("waiting for server to shutdown",
-                ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
-
-        // start server again
-        zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-        zks.startdata();
-        LinkedList<Proposal> committedLog = zks.getZKDatabase().getCommittedLog();
-        int logsize = committedLog.size();
-        LOG.info("committedLog size = " + logsize);
-        Assert.assertTrue("log size != 0", (logsize != 0));
-        zks.shutdown();
-    }
-
-    public void process(WatchedEvent event) {
-        // do nothing
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java
deleted file mode 100644
index 9e28278..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedClientTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.client.ZooKeeperSaslClient;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SaslAuthDesignatedClientTest extends ClientBase {
-    static {
-        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
-        System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperClient");
-
-        try {
-            File tmpDir = createTmpDir();
-            File saslConfFile = new File(tmpDir, "jaas.conf");
-            FileWriter fwriter = new FileWriter(saslConfFile);
-
-            fwriter.write("" +
-                "Server {\n" +
-                "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "          user_myuser=\"mypassword\";\n" +
-                "};\n" +
-                "Client {\n" + /* this 'Client' section has an incorrect password, but we're not configured
-                                  to  use it (we're configured by the above System.setProperty(...LOGIN_CONTEXT_NAME_KEY...) to 
-                                  use the 'MyZookeeperClient' section below, which has the correct password).*/
-                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "       username=\"myuser\"\n" +
-                "       password=\"wrongpassword\";\n" +
-                "};" +
-                "MyZookeeperClient {\n" +
-                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "       username=\"myuser\"\n" +
-                "       password=\"mypassword\";\n" +
-                "};" + "\n");
-            fwriter.close();
-            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
-        }
-        catch (IOException e) {
-            // could not create tmp directory to hold JAAS conf file : test will fail now.
-        }
-    }
-
-    @Test
-    public void testAuth() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-            Thread.sleep(1000);
-        } catch (KeeperException e) {
-          Assert.fail("test failed :" + e);
-        }
-        finally {
-            zk.close();
-        }
-    }
-
-    @Test
-    public void testSaslConfig() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            zk.getChildren("/", false);
-            Assert.assertFalse(zk.getSaslClient().
-                clientTunneledAuthenticationInProgress());
-            Assert.assertEquals(zk.getSaslClient().getSaslState(),
-                ZooKeeperSaslClient.SaslState.COMPLETE);
-            Assert.assertNotNull(
-                javax.security.auth.login.Configuration.getConfiguration().
-                    getAppConfigurationEntry("MyZookeeperClient"));
-            Assert.assertSame(zk.getSaslClient().getLoginContext(),
-                "MyZookeeperClient");
-        } catch (KeeperException e) {
-            Assert.fail("test failed :" + e);
-        } finally {
-            zk.close();
-        }
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java
deleted file mode 100644
index aa30870..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthDesignatedServerTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.server.ZooKeeperSaslServer;
-import org.apache.zookeeper.JaasConfiguration;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SaslAuthDesignatedServerTest extends ClientBase {
-    public static int AUTHENTICATION_TIMEOUT = 30000;
-
-    static {
-        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
-        System.setProperty(ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperServer");
-
-        JaasConfiguration conf = new JaasConfiguration();
-
-        /* this 'Server' section has an incorrect password, but we're not configured
-         * to  use it (we're configured by the above System.setProperty(...LOGIN_CONTEXT_NAME_KEY...)
-         * to use the 'MyZookeeperServer' section below, which has the correct password).
-         */
-        conf.addSection("Server", "org.apache.zookeeper.server.auth.DigestLoginModule",
-                        "user_myuser", "wrongpassword");
-
-        conf.addSection("MyZookeeperServer", "org.apache.zookeeper.server.auth.DigestLoginModule",
-                        "user_myuser", "mypassword");
-
-        conf.addSection("Client", "org.apache.zookeeper.server.auth.DigestLoginModule",
-                        "username", "myuser", "password", "mypassword");
-
-        javax.security.auth.login.Configuration.setConfiguration(conf);
-    }
-
-    private AtomicInteger authFailed = new AtomicInteger(0);
-
-    private class MyWatcher extends CountdownWatcher {
-        volatile CountDownLatch authCompleted;
-
-        @Override
-        synchronized public void reset() {
-            authCompleted = new CountDownLatch(1);
-            super.reset();
-        }
-
-        @Override
-        public synchronized void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.AuthFailed) {
-                authFailed.incrementAndGet();
-                authCompleted.countDown();
-            } else if (event.getState() == KeeperState.SaslAuthenticated) {
-                authCompleted.countDown();
-            } else {
-                super.process(event);
-            }
-        }
-    }
-
-    @Test
-    public void testAuth() throws Exception {
-        MyWatcher watcher = new MyWatcher();
-        ZooKeeper zk = createClient(watcher);
-        watcher.authCompleted.await(AUTHENTICATION_TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertEquals(authFailed.get(), 0);
-
-        try {
-            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-        } catch (KeeperException e) {
-          Assert.fail("test failed :" + e);
-        }
-        finally {
-            zk.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java
deleted file mode 100644
index 5291141..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailDesignatedClientTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.client.ZooKeeperSaslClient;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SaslAuthFailDesignatedClientTest extends ClientBase {
-    static {
-        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
-        System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperClient");
-
-        try {
-            File tmpDir = createTmpDir();
-            File saslConfFile = new File(tmpDir, "jaas.conf");
-            FileWriter fwriter = new FileWriter(saslConfFile);
-
-            fwriter.write("" +
-                "Server {\n" +
-                "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "          user_myuser=\"mypassword\";\n" +
-                "};\n" +
-                "Client {\n" + /* this 'Client' section has the correct password, but we're not configured
-                                  to  use it (we're configured by the above System.setProperty(...LOGIN_CONTEXT_NAME_KEY...) to 
-                                  use the 'MyZookeeperClient' section, which has an incorrect password).*/
-                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "       username=\"myuser\"\n" +
-                "       password=\"mypassword\";\n" +
-                "};" +
-                "MyZookeeperClient {\n" +
-                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "       username=\"myuser\"\n" +
-                "       password=\"wrongpassword\";\n" +
-                "};" + "\n");
-            fwriter.close();
-            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
-        }
-        catch (IOException e) {
-            // could not create tmp directory to hold JAAS conf file : test will fail now.
-        }
-    }
-
-    private AtomicInteger authFailed = new AtomicInteger(0);
-
-    private class MyWatcher extends CountdownWatcher {
-        @Override
-        public synchronized void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.AuthFailed) {
-                authFailed.incrementAndGet();
-            }
-            else {
-                super.process(event);
-            }
-        }
-    }
-
-    @Test
-    public void testAuth() throws Exception {
-        // Cannot use createClient here because server may close session before 
-        // JMXEnv.ensureAll is called which will fail the test case
-        CountdownWatcher watcher = new CountdownWatcher();
-        TestableZooKeeper zk = new TestableZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
-        if (!watcher.clientConnected.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS))
-        {
-            Assert.fail("Unable to connect to server");
-        }
-        try {
-            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-            Assert.fail("Should have gotten exception.");
-        } catch (KeeperException e) {
-            // ok, exception as expected.
-            LOG.info("Got exception as expected: " + e);
-        }
-        finally {
-            zk.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java
deleted file mode 100644
index 2b00d86..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailNotifyTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.junit.Test;
-import org.junit.Assert;
-
-public class SaslAuthFailNotifyTest extends ClientBase {
-    static {
-        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
-        System.setProperty("zookeeper.allowSaslFailedClients","true");
-
-        try {
-            File tmpDir = createTmpDir();
-            File saslConfFile = new File(tmpDir, "jaas.conf");
-            FileWriter fwriter = new FileWriter(saslConfFile);
-
-            fwriter.write("" +
-                    "Server {\n" +
-                    "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                    "          user_super=\"test\";\n" +
-                    "};\n" +
-                    "Client {\n" +
-                    "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                    "       username=\"super\"\n" +
-                    "       password=\"test1\";\n" + // NOTE: wrong password ('test' != 'test1') : this is to test SASL authentication failure.
-                    "};" + "\n");
-            fwriter.close();
-            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
-        }
-        catch (IOException e) {
-            // could not create tmp directory to hold JAAS conf file.
-        }
-    }
-
-    private AtomicInteger authFailed = new AtomicInteger(0);
-    
-    @Override
-    protected TestableZooKeeper createClient(String hp)
-    throws IOException, InterruptedException
-    {
-        MyWatcher watcher = new MyWatcher();
-        return createClient(watcher, hp);
-    }
-
-    private class MyWatcher extends CountdownWatcher {
-        @Override
-        public synchronized void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.AuthFailed) {
-                synchronized(authFailed) {
-                    authFailed.incrementAndGet();
-                    authFailed.notify();
-                }
-            }
-            else {
-                super.process(event);
-            }
-        }
-    }
-
-    @Test
-    public void testBadSaslAuthNotifiesWatch() throws Exception {
-        ZooKeeper zk = createClient();
-        // wait for authFailed event from client's EventThread.
-        synchronized(authFailed) {
-            authFailed.wait();
-        }
-        Assert.assertEquals(authFailed.get(),1);
-        zk.close();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java
deleted file mode 100644
index 33a505e..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthFailTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.junit.Test;
-import org.junit.Assert;
-
-public class SaslAuthFailTest extends ClientBase {
-    static {
-        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
-        System.setProperty("zookeeper.allowSaslFailedClients","true");
-
-        try {
-            File tmpDir = createTmpDir();
-            File saslConfFile = new File(tmpDir, "jaas.conf");
-            FileWriter fwriter = new FileWriter(saslConfFile);
-
-            fwriter.write("" +
-                    "Server {\n" +
-                    "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                    "          user_super=\"test\";\n" +
-                    "};\n" +
-                    "Client {\n" +
-                    "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                    "       username=\"super\"\n" +
-                    "       password=\"test1\";\n" + // NOTE: wrong password ('test' != 'test1') : this is to test SASL authentication failure.
-                    "};" + "\n");
-            fwriter.close();
-            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
-        }
-        catch (IOException e) {
-            // could not create tmp directory to hold JAAS conf file.
-        }
-    }
-    
-    @Test
-    public void testAuthFail() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-            Assert.fail("Should have gotten exception.");
-        } catch(Exception e ) {
-            // ok, exception as expected.
-            LOG.info("Got exception as expected: " + e);
-        } finally {
-            zk.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java
deleted file mode 100644
index 98be0be..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslAuthMissingClientConfigTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.client.ZooKeeperSaslClient;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SaslAuthMissingClientConfigTest extends ClientBase {
-    static {
-        System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
-        // This configuration section 'MyZookeeperClient', is missing from the JAAS configuration.
-        // As a result, SASL authentication should fail, which is tested by this test (testAuth()).
-        System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "MyZookeeperClient");
-
-        try {
-            File tmpDir = createTmpDir();
-            File saslConfFile = new File(tmpDir, "jaas.conf");
-            FileWriter fwriter = new FileWriter(saslConfFile);
-
-            fwriter.write("" +
-                "Server {\n" +
-                "          org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "          user_myuser=\"mypassword\";\n" +
-                "};\n" +
-                "Client {\n" + /* this 'Client' section has the correct password, but we're not configured
-                                  to  use it - we're configured instead by the above
-                                  System.setProperty(...LOGIN_CONTEXT_NAME_KEY...) to
-                                  use the (nonexistent) 'MyZookeeperClient' section. */
-                "       org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
-                "       username=\"myuser\"\n" +
-                "       password=\"mypassword\";\n" +
-                "};\n");
-            fwriter.close();
-            System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
-        }
-        catch (IOException e) {
-            // could not create tmp directory to hold JAAS conf file : test will fail now.
-        }
-    }
-
-    private AtomicInteger authFailed = new AtomicInteger(0);
-
-    private class MyWatcher extends CountdownWatcher {
-        @Override
-        public synchronized void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.AuthFailed) {
-                authFailed.incrementAndGet();
-            }
-            else {
-                super.process(event);
-            }
-        }
-    }
-
-    @Test
-    public void testAuth() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-            Assert.fail("Should have gotten exception.");
-        } catch (KeeperException e) {
-            // ok, exception as expected.
-            LOG.info("Got exception as expected: " + e);
-        }
-        finally {
-            zk.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslClientTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslClientTest.java
deleted file mode 100644
index 8213abc..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SaslClientTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.client.ZooKeeperSaslClient;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-
-public class SaslClientTest extends ZKTestCase {
-
-    private String existingPropertyValue = null;
-
-    @Before
-    public void setUp() {
-        existingPropertyValue = System.getProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY);
-    }
-
-    @After
-    public void tearDown() {
-        // Restore the System property if it was set previously
-        if (existingPropertyValue != null) {
-            System.setProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY, existingPropertyValue);
-        }
-    }
-
-    @Test
-    public void testSaslClientDisabled() {
-        System.clearProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY);
-        Assert.assertTrue("SASL client disabled", ZooKeeperSaslClient.isEnabled());
-
-        for (String value : Arrays.asList("true", "TRUE")) {
-            System.setProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY, value);
-            Assert.assertTrue("SASL client disabled", ZooKeeperSaslClient.isEnabled());
-        }
-
-        for (String value : Arrays.asList("false", "FALSE")) {
-            System.setProperty(ZooKeeperSaslClient.ENABLE_CLIENT_SASL_KEY, value);
-            Assert.assertFalse("SASL client disabled", ZooKeeperSaslClient.isEnabled());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java
deleted file mode 100644
index 3a0b2ee..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionInvalidationTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-import junit.framework.Assert;
-
-import org.apache.jute.BinaryOutputArchive;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooDefs.OpCode;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.proto.ConnectRequest;
-import org.apache.zookeeper.proto.CreateRequest;
-import org.apache.zookeeper.proto.RequestHeader;
-import org.junit.Test;
-
-public class SessionInvalidationTest extends ClientBase {
-    /**
-     * Test solution for ZOOKEEPER-1208. Verify that operations are not
-     * accepted after a close session.
-     * 
-     * We're using our own marshalling here in order to force an operation
-     * after the session is closed (ZooKeeper.class will not allow this). Also
-     * by filling the pipe with operations it increases the likelyhood that
-     * the server will process the create before FinalRequestProcessor
-     * removes the session from the tracker.
-     */
-    @Test
-    public void testCreateAfterCloseShouldFail() throws Exception {
-        for (int i = 0; i < 10; i++) {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-
-            // open a connection
-            boa.writeInt(44, "len");
-            ConnectRequest conReq = new ConnectRequest(0, 0, 30000, 0, new byte[16]);
-            conReq.serialize(boa, "connect");
-
-            // close connection
-            boa.writeInt(8, "len");
-            RequestHeader h = new RequestHeader(1, ZooDefs.OpCode.closeSession);
-            h.serialize(boa, "header");
-
-            // create ephemeral znode
-            boa.writeInt(52, "len"); // We'll fill this in later
-            RequestHeader header = new RequestHeader(2, OpCode.create);
-            header.serialize(boa, "header");
-            CreateRequest createReq = new CreateRequest("/foo" + i, new byte[0],
-                    Ids.OPEN_ACL_UNSAFE, 1);
-            createReq.serialize(boa, "request");
-            baos.close();
-            
-            System.out.println("Length:" + baos.toByteArray().length);
-            
-            String hp[] = hostPort.split(":");
-            Socket sock = new Socket(hp[0], Integer.parseInt(hp[1]));
-            InputStream resultStream = null;
-            try {
-                OutputStream outstream = sock.getOutputStream();
-                byte[] data = baos.toByteArray();
-                outstream.write(data);
-                outstream.flush();
-                
-                resultStream = sock.getInputStream();
-                byte[] b = new byte[10000];
-                int len;
-                while ((len = resultStream.read(b)) >= 0) {
-                    // got results
-                    System.out.println("gotlen:" + len);
-                }
-            } finally {
-                if (resultStream != null) {
-                    resultStream.close();
-                }
-                sock.close();
-            }
-        }
-        
-        ZooKeeper zk = createClient();
-        Assert.assertEquals(1, zk.getChildren("/", false).size());
-
-        zk.close();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTest.java
deleted file mode 100644
index 891b0f0..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTest.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class SessionTest extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(SessionTest.class);
-
-    private static final String HOSTPORT = "127.0.0.1:" +
-            PortAssignment.unique();
-    
-    private ServerCnxnFactory serverFactory;
-    private ZooKeeperServer zs;
-
-    private CountDownLatch startSignal;
-
-    File tmpDir;
-
-    private final int TICK_TIME = 3000;
-
-    @Before
-    public void setUp() throws Exception {
-        if (tmpDir == null) {
-            tmpDir = ClientBase.createTmpDir();
-        }
-
-        ClientBase.setupTestEnv();
-        zs = new ZooKeeperServer(tmpDir, tmpDir, TICK_TIME);
-
-        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-        serverFactory = ServerCnxnFactory.createFactory(PORT, -1);
-        serverFactory.startup(zs);
-
-        Assert.assertTrue("waiting for server up",
-                   ClientBase.waitForServerUp(HOSTPORT,
-                                              CONNECTION_TIMEOUT));
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        serverFactory.shutdown();
-        zs.shutdown();
-        Assert.assertTrue("waiting for server down",
-                   ClientBase.waitForServerDown(HOSTPORT,
-                                                CONNECTION_TIMEOUT));
-    }
-
-    private static class CountdownWatcher implements Watcher {
-        volatile CountDownLatch clientConnected = new CountDownLatch(1);
-
-        public void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.SyncConnected) {
-                clientConnected.countDown();
-            }
-        }
-    }
-
-    private DisconnectableZooKeeper createClient()
-        throws IOException, InterruptedException
-    {
-        CountdownWatcher watcher = new CountdownWatcher();
-        return createClient(CONNECTION_TIMEOUT, watcher);
-    }
-
-    private DisconnectableZooKeeper createClient(int timeout)
-        throws IOException, InterruptedException
-    {
-        CountdownWatcher watcher = new CountdownWatcher();
-        return createClient(timeout, watcher);
-    }
-
-    private DisconnectableZooKeeper createClient(int timeout,
-            CountdownWatcher watcher)
-        throws IOException, InterruptedException
-    {
-        DisconnectableZooKeeper zk =
-                new DisconnectableZooKeeper(HOSTPORT, timeout, watcher);
-        if(!watcher.clientConnected.await(timeout, TimeUnit.MILLISECONDS)) {
-            Assert.fail("Unable to connect to server");
-        }
-
-        return zk;
-    }
-
-// FIXME this test is Assert.failing due to client close race condition fixing in separate patch for ZOOKEEPER-63
-//    /**
-//     * this test checks to see if the sessionid that was created for the
-//     * first zookeeper client can be reused for the second one immidiately
-//     * after the first client closes and the new client resues them.
-//     * @throws IOException
-//     * @throws InterruptedException
-//     * @throws KeeperException
-//     */
-//    public void testSessionReuse() throws IOException, InterruptedException {
-//        ZooKeeper zk = createClient();
-//
-//        long sessionId = zk.getSessionId();
-//        byte[] passwd = zk.getSessionPasswd();
-//        zk.close();
-//
-//        zk.close();
-//
-//        LOG.info("Closed first session");
-//
-//        startSignal = new CountDownLatch(1);
-//        zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this,
-//                sessionId, passwd);
-//        startSignal.await();
-//
-//        LOG.info("Opened reuse");
-//
-//        Assert.assertEquals(sessionId, zk.getSessionId());
-//
-//        zk.close();
-//    }
-
-    private class MyWatcher implements Watcher {
-        private String name;
-        public MyWatcher(String name) {
-            this.name = name;
-        }
-        public void process(WatchedEvent event) {
-            LOG.info(name + " event:" + event.getState() + " "
-                    + event.getType() + " " + event.getPath());
-            if (event.getState() == KeeperState.SyncConnected
-                    && startSignal != null && startSignal.getCount() > 0)
-            {
-                startSignal.countDown();
-            }
-        }
-    }
-
-    /**
-     * This test verifies that when the session id is reused, and the original
-     * client is disconnected, but not session closed, that the server
-     * will remove ephemeral nodes created by the original session.
-     */
-    @Test
-    public void testSession()
-        throws IOException, InterruptedException, KeeperException
-    {
-        DisconnectableZooKeeper zk = createClient();
-        zk.create("/e", new byte[0], Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.EPHEMERAL);
-        LOG.info("zk with session id 0x" + Long.toHexString(zk.getSessionId())
-                + " was destroyed!");
-
-        // disconnect the client by killing the socket, not sending the
-        // session disconnect to the server as usual. This allows the test
-        // to verify disconnect handling
-        zk.disconnect();
-
-        Stat stat = new Stat();
-        startSignal = new CountDownLatch(1);
-        zk = new DisconnectableZooKeeper(HOSTPORT, CONNECTION_TIMEOUT,
-                new MyWatcher("testSession"), zk.getSessionId(),
-                zk.getSessionPasswd());
-        startSignal.await();
-
-        LOG.info("zk with session id 0x" + Long.toHexString(zk.getSessionId())
-                 + " was created!");
-        zk.getData("/e", false, stat);
-        LOG.info("After get data /e");
-        zk.close();
-
-        zk = createClient();
-        Assert.assertEquals(null, zk.exists("/e", false));
-        LOG.info("before close zk with session id 0x"
-                + Long.toHexString(zk.getSessionId()) + "!");
-        zk.close();
-        try {
-            zk.getData("/e", false, stat);
-            Assert.fail("Should have received a SessionExpiredException");
-        } catch(KeeperException.SessionExpiredException e) {}
-        
-        AsyncCallback.DataCallback cb = new AsyncCallback.DataCallback() {
-            String status = "not done";
-            public void processResult(int rc, String p, Object c, byte[] b, Stat s) {
-                synchronized(this) { status = KeeperException.Code.get(rc).toString(); this.notify(); }
-            }
-           public String toString() { return status; }
-        };
-        zk.getData("/e", false, cb, null);
-        synchronized(cb) {
-            if (cb.toString().equals("not done")) {
-                cb.wait(1000);
-            }
-        }
-        Assert.assertEquals(KeeperException.Code.SESSIONEXPIRED.toString(), cb.toString());        
-    }
-
-    /**
-     * Make sure that we cannot have two connections with the same
-     * session id.
-     *
-     * @throws IOException
-     * @throws InterruptedException
-     * @throws KeeperException
-     */
-    @Test
-    public void testSessionMove() throws Exception {
-        String hostPorts[] = HOSTPORT.split(",");
-        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(hostPorts[0],
-                CONNECTION_TIMEOUT, new MyWatcher("0"));
-        zk.create("/sessionMoveTest", new byte[0], Ids.OPEN_ACL_UNSAFE,
-                CreateMode.EPHEMERAL);
-        // we want to loop through the list twice
-        for(int i = 0; i < hostPorts.length*2; i++) {
-            zk.dontReconnect();
-            // This should stomp the zk handle
-            DisconnectableZooKeeper zknew = new DisconnectableZooKeeper(
-                    hostPorts[(i+1)%hostPorts.length],
-                    CONNECTION_TIMEOUT,
-                    new MyWatcher(Integer.toString(i+1)),
-                    zk.getSessionId(),
-                    zk.getSessionPasswd());
-            final int result[] = new int[1];
-            result[0] = Integer.MAX_VALUE;
-            zknew.sync("/", new AsyncCallback.VoidCallback() {
-                    public void processResult(int rc, String path, Object ctx) {
-                        synchronized(result) { result[0] = rc; result.notify(); }
-                    }
-                }, null);
-            synchronized(result) {
-                if(result[0] == Integer.MAX_VALUE) {
-                    result.wait(5000);
-                }
-            }
-            LOG.info(hostPorts[(i+1)%hostPorts.length] + " Sync returned " + result[0]);
-            Assert.assertTrue(result[0] == KeeperException.Code.OK.intValue());
-            zknew.setData("/", new byte[1], -1);
-            try {
-                zk.setData("/", new byte[1], -1);
-                Assert.fail("Should have lost the connection");
-            } catch(KeeperException.ConnectionLossException e) {
-                LOG.info("Got connection loss exception as expected");
-            }
-            //zk.close();
-            zk = zknew;
-        }
-        zk.close();
-    }
-    /**
-     * This test makes sure that duplicate state changes are not communicated
-     * to the client watcher. For example we should not notify state as
-     * "disconnected" if the watch has already been disconnected. In general
-     * we don't consider a dup state notification if the event type is
-     * not "None" (ie non-None communicates an event).
-     */
-    @Test
-    public void testSessionStateNoDupStateReporting()
-        throws IOException, InterruptedException, KeeperException
-    {
-        final int TIMEOUT = 3000;
-        DupWatcher watcher = new DupWatcher();
-        ZooKeeper zk = createClient(TIMEOUT, watcher);
-
-        // shutdown the server
-        serverFactory.shutdown();
-
-        try {
-            Thread.sleep(10000);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-
-        // verify that the size is just 2 - ie connect then disconnect
-        // if the client attempts reconnect and we are not handling current
-        // state correctly (ie eventing on duplicate disconnects) then we'll
-        // see a disconnect for each Assert.failed connection attempt
-        Assert.assertEquals(2, watcher.states.size());
-
-        zk.close();
-    }
-
-    /**
-     * Verify access to the negotiated session timeout.
-     */
-    @Test
-    public void testSessionTimeoutAccess() throws Exception {
-        // validate typical case - requested == negotiated
-        DisconnectableZooKeeper zk = createClient(TICK_TIME * 4);
-        Assert.assertEquals(TICK_TIME * 4, zk.getSessionTimeout());
-        // make sure tostring works in both cases
-        LOG.info(zk.toString());
-        zk.close();
-        LOG.info(zk.toString());
-
-        // validate lower limit
-        zk = createClient(TICK_TIME);
-        Assert.assertEquals(TICK_TIME * 2, zk.getSessionTimeout());
-        LOG.info(zk.toString());
-        zk.close();
-        LOG.info(zk.toString());
-
-        // validate upper limit
-        zk = createClient(TICK_TIME * 30);
-        Assert.assertEquals(TICK_TIME * 20, zk.getSessionTimeout());
-        LOG.info(zk.toString());
-        zk.close();
-        LOG.info(zk.toString());
-    }
-
-    private class DupWatcher extends CountdownWatcher {
-        public LinkedList<WatchedEvent> states = new LinkedList<WatchedEvent>();
-        public void process(WatchedEvent event) {
-            super.process(event);
-            if (event.getType() == EventType.None) {
-                states.add(event);
-            }
-        }
-    }
-
-    @Test
-    public void testMinMaxSessionTimeout() throws Exception {
-        // override the defaults
-        final int MINSESS = 20000;
-        final int MAXSESS = 240000;
-        {
-            ZooKeeperServer zs = ClientBase.getServer(serverFactory);
-            zs.setMinSessionTimeout(MINSESS);
-            zs.setMaxSessionTimeout(MAXSESS);
-        }
-
-        // validate typical case - requested == negotiated
-        int timeout = 120000;
-        DisconnectableZooKeeper zk = createClient(timeout);
-        Assert.assertEquals(timeout, zk.getSessionTimeout());
-        // make sure tostring works in both cases
-        LOG.info(zk.toString());
-        zk.close();
-        LOG.info(zk.toString());
-
-        // validate lower limit
-        zk = createClient(MINSESS/2);
-        Assert.assertEquals(MINSESS, zk.getSessionTimeout());
-        LOG.info(zk.toString());
-        zk.close();
-        LOG.info(zk.toString());
-
-        // validate upper limit
-        zk = createClient(MAXSESS * 2);
-        Assert.assertEquals(MAXSESS, zk.getSessionTimeout());
-        LOG.info(zk.toString());
-        zk.close();
-        LOG.info(zk.toString());
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java
deleted file mode 100644
index 09badae..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SessionTimeoutTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-public class SessionTimeoutTest extends ClientBase {
-    protected static final Logger LOG = LoggerFactory.getLogger(SessionTimeoutTest.class);
-
-    private TestableZooKeeper zk;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        zk = createClient();
-    }
-
-    @Test
-    public void testSessionExpiration() throws InterruptedException,
-            KeeperException {
-        final CountDownLatch expirationLatch = new CountDownLatch(1);
-        Watcher watcher = new Watcher() {
-            @Override
-            public void process(WatchedEvent event) {
-                if ( event.getState() == Event.KeeperState.Expired ) {
-                    expirationLatch.countDown();
-                }
-            }
-        };
-        zk.exists("/foo", watcher);
-
-        zk.getTestable().injectSessionExpiration();
-        Assert.assertTrue(expirationLatch.await(5, TimeUnit.SECONDS));
-
-        boolean gotException = false;
-        try {
-            zk.exists("/foo", false);
-            Assert.fail("Should have thrown a SessionExpiredException");
-        } catch (KeeperException.SessionExpiredException e) {
-            // correct
-            gotException = true;
-        }
-        Assert.assertTrue(gotException);
-    }
-
-    /**
-     * Make sure ephemerals get cleaned up when session disconnects.
-     */
-    @Test
-    public void testSessionDisconnect() throws KeeperException, InterruptedException, IOException {
-        zk.create("/sdisconnect", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.EPHEMERAL);
-        assertNotNull("Ephemeral node has not been created", zk.exists("/sdisconnect", null));
-
-        zk.close();
-
-        zk = createClient();
-        assertNull("Ephemeral node shouldn't exist after client disconnect", zk.exists("/sdisconnect", null));
-    }
-
-    /**
-     * Make sure ephemerals are kept when session restores.
-     */
-    @Test
-    public void testSessionRestore() throws KeeperException, InterruptedException, IOException {
-        zk.create("/srestore", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.EPHEMERAL);
-        assertNotNull("Ephemeral node has not been created", zk.exists("/srestore", null));
-
-        zk.disconnect();
-        zk.close();
-
-        zk = createClient();
-        assertNotNull("Ephemeral node should be present when session is restored", zk.exists("/srestore", null));
-    }
-
-    /**
-     * Make sure ephemerals are kept when server restarts.
-     */
-    @Test
-    public void testSessionSurviveServerRestart() throws Exception {
-        zk.create("/sdeath", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.EPHEMERAL);
-        assertNotNull("Ephemeral node has not been created", zk.exists("/sdeath", null));
-
-        zk.disconnect();
-        stopServer();
-        startServer();
-        zk = createClient();
-
-        assertNotNull("Ephemeral node should be present when server restarted", zk.exists("/sdeath", null));
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SledgeHammer.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SledgeHammer.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SledgeHammer.java
deleted file mode 100644
index 614a93d..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SledgeHammer.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-
-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 SledgeHammer extends Thread implements Watcher {
-    ZooKeeper zk;
-
-    int count;
-
-    int readsPerWrite;
-
-    public SledgeHammer(String hosts, int count, int readsPerWrite)
-            throws IOException {
-        zk = new ZooKeeper(hosts, 10000, this);
-        this.count = count;
-        this.readsPerWrite = readsPerWrite;
-    }
-
-    public void run() {
-        try {
-            Stat stat = new Stat();
-            String path = zk.create("/hammers/hammer-", new byte[0],
-                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            byte tag[] = (path + " was here!").getBytes();
-            synchronized (this) {
-                String startPath = "/hammers/start";
-                System.out.println("Waiting for " + startPath);
-                while (zk.exists(startPath, true) == null) {
-                    wait();
-                }
-                System.out.println("Running");
-            }
-            for (int i = 0; i < count; i++) {
-                try {
-                    System.out.print(i + "\r");
-                    List<String> childs =
-                        zk.getChildren("/hammers", false);
-                    Collections.shuffle(childs);
-                    for (String s : childs) {
-                        if (s.startsWith("hammer-")) {
-                            s = "/hammers/" + s;
-                            zk.setData(s, tag, -1);
-                            for (int j = 0; j < readsPerWrite; j++) {
-                                zk.getData(s, false, stat);
-                            }
-                            break;
-                        }
-                    }
-                } catch (KeeperException.ConnectionLossException e) {
-                    // ignore connection loss
-                } catch (KeeperException e) {
-                    e.printStackTrace();
-                }
-            }
-            System.out.println();
-            zk.close();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * @param args
-     * @throws IOException
-     * @throws KeeperException
-     * @throws NumberFormatException
-     */
-    public static void main(String[] args) throws NumberFormatException,
-            IOException {
-        if (args.length != 3) {
-            System.err
-                    .println("USAGE: SledgeHammer zookeeper_server reps reads_per_rep");
-            System.exit(3);
-        }
-        SledgeHammer h = new SledgeHammer(args[0], Integer.parseInt(args[1]),
-                Integer.parseInt(args[2]));
-        h.start();
-        System.exit(0);
-    }
-
-    public void process(WatchedEvent event) {
-        synchronized (this) {
-            notifyAll();
-        }
-    }
-
-}


[35/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/AsyncCallback.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/AsyncCallback.java b/zookeeper-common/src/main/java/org/apache/zookeeper/AsyncCallback.java
deleted file mode 100644
index f02a824..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/AsyncCallback.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper;
-
-import java.util.List;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-
-/**
- * Interface definitions of asynchronous callbacks.
- * An asynchronous callback is deferred to invoke after a function returns.
- * Asynchronous calls usually improve system efficiency on IO-related APIs.
- * <p/>
- * ZooKeeper provides asynchronous version as equivalent to synchronous APIs.
- */
-@InterfaceAudience.Public
-public interface AsyncCallback {
-
-    /**
-     * This callback is used to retrieve the stat of the node.
-     */
-    @InterfaceAudience.Public
-    interface StatCallback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * <p/>
-         * On success, rc is
-         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
-         * <p/>
-         * On failure, rc is set to the corresponding failure code in
-         * {@link org.apache.zookeeper.KeeperException}.
-         * <ul>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
-         * - The node on given path doesn't exist for some API calls.
-         * </li>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#BADVERSION}
-         * - The given version doesn't match the node's version
-         * for some API calls.
-         * </li>
-         * </ul>
-         *
-         * @param rc   The return code or the result of the call.
-         * @param path The path that we passed to asynchronous calls.
-         * @param ctx  Whatever context object that we passed to
-         *             asynchronous calls.
-         * @param stat {@link org.apache.zookeeper.data.Stat} object of
-         *             the node on given path.
-         */
-        public void processResult(int rc, String path, Object ctx, Stat stat);
-    }
-
-    /**
-     * This callback is used to retrieve the data and stat of the node.
-     */
-    @InterfaceAudience.Public
-    interface DataCallback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * <p/>
-         * On success, rc is
-         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
-         * <p/>
-         * On failure, rc is set to the corresponding failure code in
-         * {@link org.apache.zookeeper.KeeperException}.
-         * <ul>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
-         * - The node on given path doesn't exist for some API calls.
-         * </li>
-         * </ul>
-         *
-         * @param rc   The return code or the result of the call.
-         * @param path The path that we passed to asynchronous calls.
-         * @param ctx  Whatever context object that we passed to
-         *             asynchronous calls.
-         * @param data The {@link org.apache.zookeeper.server.DataNode#data}
-         *             of the node.
-         * @param stat {@link org.apache.zookeeper.data.Stat} object of
-         *             the node on given path.
-         */
-        public void processResult(int rc, String path, Object ctx, byte data[],
-                Stat stat);
-    }
-
-    /**
-     * This callback is used to retrieve the ACL and stat of the node.
-     */
-    @InterfaceAudience.Public
-    interface ACLCallback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * <p/>
-         * On success, rc is
-         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
-         * <p/>
-         * On failure, rc is set to the corresponding failure code in
-         * {@link org.apache.zookeeper.KeeperException}.
-         * <ul>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
-         * - The node on given path doesn't exist for some API calls.
-         * </li>
-         * </ul>
-         *
-         * @param rc   The return code or the result of the call.
-         * @param path The path that we passed to asynchronous calls.
-         * @param ctx  Whatever context object that we passed to
-         *             asynchronous calls.
-         * @param acl  ACL Id in
-         *             {@link org.apache.zookeeper.ZooDefs.Ids}.
-         * @param stat {@link org.apache.zookeeper.data.Stat} object of
-         *             the node on given path.
-         */
-        public void processResult(int rc, String path, Object ctx,
-                List<ACL> acl, Stat stat);
-    }
-
-    /**
-     * This callback is used to retrieve the children of the node.
-     */
-    @InterfaceAudience.Public
-    interface ChildrenCallback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * <p/>
-         * On success, rc is
-         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
-         * <p/>
-         * On failure, rc is set to the corresponding failure code in
-         * {@link org.apache.zookeeper.KeeperException}.
-         * <ul>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
-         * - The node on given path doesn't exist for some API calls.
-         * </li>
-         * </ul>
-         *
-         * @param rc       The return code or the result of the call.
-         * @param path     The path that we passed to asynchronous calls.
-         * @param ctx      Whatever context object that we passed to
-         *                 asynchronous calls.
-         * @param children An unordered array of children of the node on
-         *                 given path.
-         */
-        public void processResult(int rc, String path, Object ctx,
-                List<String> children);
-    }
-
-    /**
-     * This callback is used to retrieve the children and stat of the node.
-     */
-    @InterfaceAudience.Public
-    interface Children2Callback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * See {@link org.apache.zookeeper.AsyncCallback.ChildrenCallback}.
-         *
-         * @param rc       The return code or the result of the call.
-         * @param path     The path that we passed to asynchronous calls.
-         * @param ctx      Whatever context object that we passed to
-         *                 asynchronous calls.
-         * @param children An unordered array of children of the node on
-         *                 given path.
-         * @param stat     {@link org.apache.zookeeper.data.Stat} object of
-         *                 the node on given path.
-         */
-        public void processResult(int rc, String path, Object ctx,
-                List<String> children, Stat stat);
-    }
-
-    /**
-     * This callback is used to retrieve the name of the node.
-     */
-    @InterfaceAudience.Public
-    interface StringCallback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * <p/>
-         * On success, rc is
-         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
-         * <p/>
-         * On failure, rc is set to the corresponding failure code in
-         * {@link org.apache.zookeeper.KeeperException}.
-         * <ul>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NODEEXISTS}
-         * - The node on give path already exists for some API calls.
-         * </li>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
-         * - The node on given path doesn't exist for some API calls.
-         * </li>
-         * <li>
-         * {@link
-         * org.apache.zookeeper.KeeperException.Code#NOCHILDRENFOREPHEMERALS}
-         * - an ephemeral node cannot have children. There is discussion in
-         * community. It might be changed in the future.
-         * </li>
-         * </ul>
-         *
-         * @param rc   The return code or the result of the call.
-         * @param path The path that we passed to asynchronous calls.
-         * @param ctx  Whatever context object that we passed to
-         *             asynchronous calls.
-         * @param name The name of the Znode that was created.
-         *             On success, <i>name</i> and <i>path</i> are usually
-         *             equal, unless a sequential node has been created.
-         */
-        public void processResult(int rc, String path, Object ctx, String name);
-    }
-
-    /**
-     * This callback doesn't retrieve anything from the node. It is useful
-     * for some APIs that doesn't want anything sent back, e.g. {@link
-     * org.apache.zookeeper.ZooKeeper#sync(String,
-     * org.apache.zookeeper.AsyncCallback.VoidCallback, Object)}.
-     */
-    @InterfaceAudience.Public
-    interface VoidCallback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * <p/>
-         * On success, rc is
-         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
-         * <p/>
-         * On failure, rc is set to the corresponding failure code in
-         * {@link org.apache.zookeeper.KeeperException}.
-         * <ul>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
-         * - The node on given path doesn't exist for some API calls.
-         * </li>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#BADVERSION}
-         * - The given version doesn't match the node's version
-         * for some API calls.
-         * </li>
-         * <li>
-         * {@link org.apache.zookeeper.KeeperException.Code#NOTEMPTY}
-         * - the node has children and some API calls cannnot succeed,
-         * e.g. {@link
-         * org.apache.zookeeper.ZooKeeper#delete(String, int,
-         * org.apache.zookeeper.AsyncCallback.VoidCallback, Object)}.
-         * </li>
-         * </ul>
-         *
-         * @param rc   The return code or the result of the call.
-         * @param path The path that we passed to asynchronous calls.
-         * @param ctx  Whatever context object that we passed to
-         *             asynchronous calls.
-         */
-        public void processResult(int rc, String path, Object ctx);
-    }
-
-    /**
-     * This callback is used to process the multiple results from
-     * a single multi call.
-     * See {@link org.apache.zookeeper.ZooKeeper#multi} for more information.
-     * @since 3.4.7
-     */
-    @InterfaceAudience.Public
-    interface MultiCallback extends AsyncCallback {
-        /**
-         * Process the result of the asynchronous call.
-         * <p/>
-         * On success, rc is
-         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
-         * All opResults are
-         * non-{@link org.apache.zookeeper.OpResult.ErrorResult},
-         *
-         * <p/>
-         * On failure, rc is a failure code in
-         * {@link org.apache.zookeeper.KeeperException.Code}.
-         * All opResults are
-         * {@link org.apache.zookeeper.OpResult.ErrorResult}.
-         * All operations will be rollback-ed even if operations
-         * before the failing one were successful.
-         *
-         * @param rc   The return code or the result of the call.
-         * @param path The path that we passed to asynchronous calls.
-         * @param ctx  Whatever context object that we passed to
-         *             asynchronous calls.
-         * @param opResults The list of results.
-         *                  One result for each operation,
-         *                  and the order matches that of input.
-         */
-        public void processResult(int rc, String path, Object ctx,
-                List<OpResult> opResults);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxn.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxn.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxn.java
deleted file mode 100644
index 447a3ee..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxn.java
+++ /dev/null
@@ -1,1481 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.net.ConnectException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import javax.security.auth.login.LoginException;
-import javax.security.sasl.SaslException;
-
-import org.apache.jute.BinaryInputArchive;
-import org.apache.jute.BinaryOutputArchive;
-import org.apache.jute.Record;
-import org.apache.zookeeper.AsyncCallback.ACLCallback;
-import org.apache.zookeeper.AsyncCallback.Children2Callback;
-import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.AsyncCallback.MultiCallback;
-import org.apache.zookeeper.AsyncCallback.StatCallback;
-import org.apache.zookeeper.AsyncCallback.StringCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.OpResult.ErrorResult;
-import org.apache.zookeeper.Watcher.Event;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.OpCode;
-import org.apache.zookeeper.ZooKeeper.States;
-import org.apache.zookeeper.ZooKeeper.WatchRegistration;
-import org.apache.zookeeper.client.HostProvider;
-import org.apache.zookeeper.client.ZooKeeperSaslClient;
-import org.apache.zookeeper.common.Time;
-import org.apache.zookeeper.proto.AuthPacket;
-import org.apache.zookeeper.proto.ConnectRequest;
-import org.apache.zookeeper.proto.CreateResponse;
-import org.apache.zookeeper.proto.ExistsResponse;
-import org.apache.zookeeper.proto.GetACLResponse;
-import org.apache.zookeeper.proto.GetChildren2Response;
-import org.apache.zookeeper.proto.GetChildrenResponse;
-import org.apache.zookeeper.proto.GetDataResponse;
-import org.apache.zookeeper.proto.GetSASLRequest;
-import org.apache.zookeeper.proto.ReplyHeader;
-import org.apache.zookeeper.proto.RequestHeader;
-import org.apache.zookeeper.proto.SetACLResponse;
-import org.apache.zookeeper.proto.SetDataResponse;
-import org.apache.zookeeper.proto.SetWatches;
-import org.apache.zookeeper.proto.WatcherEvent;
-import org.apache.zookeeper.server.ByteBufferInputStream;
-import org.apache.zookeeper.server.ZooKeeperThread;
-import org.apache.zookeeper.server.ZooTrace;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class manages the socket i/o for the client. ClientCnxn maintains a list
- * of available servers to connect to and "transparently" switches servers it is
- * connected to as needed.
- *
- */
-public class ClientCnxn {
-    private static final Logger LOG = LoggerFactory.getLogger(ClientCnxn.class);
-
-    private static final String ZK_SASL_CLIENT_USERNAME =
-        "zookeeper.sasl.client.username";
-
-    /* ZOOKEEPER-706: If a session has a large number of watches set then
-     * attempting to re-establish those watches after a connection loss may
-     * fail due to the SetWatches request exceeding the server's configured
-     * jute.maxBuffer value. To avoid this we instead split the watch
-     * re-establishement across multiple SetWatches calls. This constant
-     * controls the size of each call. It is set to 128kB to be conservative
-     * with respect to the server's 1MB default for jute.maxBuffer.
-     */
-    private static final int SET_WATCHES_MAX_LENGTH = 128 * 1024;
-
-    /** This controls whether automatic watch resetting is enabled.
-     * Clients automatically reset watches during session reconnect, this
-     * option allows the client to turn off this behavior by setting
-     * the environment variable "zookeeper.disableAutoWatchReset" to "true" */
-    private static boolean disableAutoWatchReset;
-    static {
-        // this var should not be public, but otw there is no easy way
-        // to test
-        disableAutoWatchReset =
-            Boolean.getBoolean("zookeeper.disableAutoWatchReset");
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("zookeeper.disableAutoWatchReset is "
-                    + disableAutoWatchReset);
-        }
-    }
-
-    static class AuthData {
-        AuthData(String scheme, byte data[]) {
-            this.scheme = scheme;
-            this.data = data;
-        }
-
-        String scheme;
-
-        byte data[];
-    }
-
-    private final CopyOnWriteArraySet<AuthData> authInfo = new CopyOnWriteArraySet<AuthData>();
-
-    /**
-     * These are the packets that have been sent and are waiting for a response.
-     */
-    private final LinkedList<Packet> pendingQueue = new LinkedList<Packet>();
-
-    /**
-     * These are the packets that need to be sent.
-     */
-    private final LinkedList<Packet> outgoingQueue = new LinkedList<Packet>();
-
-    private int connectTimeout;
-
-    /**
-     * The timeout in ms the client negotiated with the server. This is the
-     * "real" timeout, not the timeout request by the client (which may have
-     * been increased/decreased by the server which applies bounds to this
-     * value.
-     */
-    private volatile int negotiatedSessionTimeout;
-
-    private int readTimeout;
-
-    private final int sessionTimeout;
-
-    private final ZooKeeper zooKeeper;
-
-    private final ClientWatchManager watcher;
-
-    private long sessionId;
-
-    private byte sessionPasswd[] = new byte[16];
-
-    /**
-     * If true, the connection is allowed to go to r-o mode. This field's value
-     * is sent, besides other data, during session creation handshake. If the
-     * server on the other side of the wire is partitioned it'll accept
-     * read-only clients only.
-     */
-    private boolean readOnly;
-
-    final String chrootPath;
-
-    final SendThread sendThread;
-
-    final EventThread eventThread;
-
-    /**
-     * Set to true when close is called. Latches the connection such that we
-     * don't attempt to re-connect to the server if in the middle of closing the
-     * connection (client sends session disconnect to server as part of close
-     * operation)
-     */
-    private volatile boolean closing = false;
-    
-    /**
-     * A set of ZooKeeper hosts this client could connect to.
-     */
-    private final HostProvider hostProvider;
-
-    /**
-     * Is set to true when a connection to a r/w server is established for the
-     * first time; never changed afterwards.
-     * <p>
-     * Is used to handle situations when client without sessionId connects to a
-     * read-only server. Such client receives "fake" sessionId from read-only
-     * server, but this sessionId is invalid for other servers. So when such
-     * client finds a r/w server, it sends 0 instead of fake sessionId during
-     * connection handshake and establishes new, valid session.
-     * <p>
-     * If this field is false (which implies we haven't seen r/w server before)
-     * then non-zero sessionId is fake, otherwise it is valid.
-     */
-    volatile boolean seenRwServerBefore = false;
-
-
-    public ZooKeeperSaslClient zooKeeperSaslClient;
-
-    public long getSessionId() {
-        return sessionId;
-    }
-
-    public byte[] getSessionPasswd() {
-        return sessionPasswd;
-    }
-
-    public int getSessionTimeout() {
-        return negotiatedSessionTimeout;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        SocketAddress local = sendThread.getClientCnxnSocket().getLocalSocketAddress();
-        SocketAddress remote = sendThread.getClientCnxnSocket().getRemoteSocketAddress();
-        sb
-            .append("sessionid:0x").append(Long.toHexString(getSessionId()))
-            .append(" local:").append(local)
-            .append(" remoteserver:").append(remote)
-            .append(" lastZxid:").append(lastZxid)
-            .append(" xid:").append(xid)
-            .append(" sent:").append(sendThread.getClientCnxnSocket().getSentCount())
-            .append(" recv:").append(sendThread.getClientCnxnSocket().getRecvCount())
-            .append(" queuedpkts:").append(outgoingQueue.size())
-            .append(" pendingresp:").append(pendingQueue.size())
-            .append(" queuedevents:").append(eventThread.waitingEvents.size());
-
-        return sb.toString();
-    }
-
-    /**
-     * This class allows us to pass the headers and the relevant records around.
-     */
-    static class Packet {
-        RequestHeader requestHeader;
-
-        ReplyHeader replyHeader;
-
-        Record request;
-
-        Record response;
-
-        ByteBuffer bb;
-
-        /** Client's view of the path (may differ due to chroot) **/
-        String clientPath;
-        /** Servers's view of the path (may differ due to chroot) **/
-        String serverPath;
-
-        boolean finished;
-
-        AsyncCallback cb;
-
-        Object ctx;
-
-        WatchRegistration watchRegistration;
-
-        public boolean readOnly;
-
-        /** Convenience ctor */
-        Packet(RequestHeader requestHeader, ReplyHeader replyHeader,
-               Record request, Record response,
-               WatchRegistration watchRegistration) {
-            this(requestHeader, replyHeader, request, response,
-                 watchRegistration, false);
-        }
-
-        Packet(RequestHeader requestHeader, ReplyHeader replyHeader,
-               Record request, Record response,
-               WatchRegistration watchRegistration, boolean readOnly) {
-
-            this.requestHeader = requestHeader;
-            this.replyHeader = replyHeader;
-            this.request = request;
-            this.response = response;
-            this.readOnly = readOnly;
-            this.watchRegistration = watchRegistration;
-        }
-
-        public void createBB() {
-            try {
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-                boa.writeInt(-1, "len"); // We'll fill this in later
-                if (requestHeader != null) {
-                    requestHeader.serialize(boa, "header");
-                }
-                if (request instanceof ConnectRequest) {
-                    request.serialize(boa, "connect");
-                    // append "am-I-allowed-to-be-readonly" flag
-                    boa.writeBool(readOnly, "readOnly");
-                } else if (request != null) {
-                    request.serialize(boa, "request");
-                }
-                baos.close();
-                this.bb = ByteBuffer.wrap(baos.toByteArray());
-                this.bb.putInt(this.bb.capacity() - 4);
-                this.bb.rewind();
-            } catch (IOException e) {
-                LOG.warn("Ignoring unexpected exception", e);
-            }
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-
-            sb.append("clientPath:" + clientPath);
-            sb.append(" serverPath:" + serverPath);
-            sb.append(" finished:" + finished);
-
-            sb.append(" header:: " + requestHeader);
-            sb.append(" replyHeader:: " + replyHeader);
-            sb.append(" request:: " + request);
-            sb.append(" response:: " + response);
-
-            // jute toString is horrible, remove unnecessary newlines
-            return sb.toString().replaceAll("\r*\n+", " ");
-        }
-    }
-
-    /**
-     * Creates a connection object. The actual network connect doesn't get
-     * established until needed. The start() instance method must be called
-     * subsequent to construction.
-     *
-     * @param chrootPath - the chroot of this client. Should be removed from this Class in ZOOKEEPER-838
-     * @param hostProvider
-     *                the list of ZooKeeper servers to connect to
-     * @param sessionTimeout
-     *                the timeout for connections.
-     * @param zooKeeper
-     *                the zookeeper object that this connection is related to.
-     * @param watcher watcher for this connection
-     * @param clientCnxnSocket
-     *                the socket implementation used (e.g. NIO/Netty)
-     * @param canBeReadOnly
-     *                whether the connection is allowed to go to read-only
-     *                mode in case of partitioning
-     * @throws IOException
-     */
-    public ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,
-            ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket, boolean canBeReadOnly)
-            throws IOException {
-        this(chrootPath, hostProvider, sessionTimeout, zooKeeper, watcher,
-             clientCnxnSocket, 0, new byte[16], canBeReadOnly);
-    }
-
-    /**
-     * Creates a connection object. The actual network connect doesn't get
-     * established until needed. The start() instance method must be called
-     * subsequent to construction.
-     *
-     * @param chrootPath - the chroot of this client. Should be removed from this Class in ZOOKEEPER-838
-     * @param hostProvider
-     *                the list of ZooKeeper servers to connect to
-     * @param sessionTimeout
-     *                the timeout for connections.
-     * @param zooKeeper
-     *                the zookeeper object that this connection is related to.
-     * @param watcher watcher for this connection
-     * @param clientCnxnSocket
-     *                the socket implementation used (e.g. NIO/Netty)
-     * @param sessionId session id if re-establishing session
-     * @param sessionPasswd session passwd if re-establishing session
-     * @param canBeReadOnly
-     *                whether the connection is allowed to go to read-only
-     *                mode in case of partitioning
-     * @throws IOException
-     */
-    public ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,
-            ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket,
-            long sessionId, byte[] sessionPasswd, boolean canBeReadOnly) {
-        this.zooKeeper = zooKeeper;
-        this.watcher = watcher;
-        this.sessionId = sessionId;
-        this.sessionPasswd = sessionPasswd;
-        this.sessionTimeout = sessionTimeout;
-        this.hostProvider = hostProvider;
-        this.chrootPath = chrootPath;
-
-        connectTimeout = sessionTimeout / hostProvider.size();
-        readTimeout = sessionTimeout * 2 / 3;
-        readOnly = canBeReadOnly;
-
-        sendThread = new SendThread(clientCnxnSocket);
-        eventThread = new EventThread();
-
-    }
-
-    /**
-     * tests use this to check on reset of watches
-     * @return if the auto reset of watches are disabled
-     */
-    public static boolean getDisableAutoResetWatch() {
-        return disableAutoWatchReset;
-    }
-    /**
-     * tests use this to set the auto reset
-     * @param b the value to set disable watches to
-     */
-    public static void setDisableAutoResetWatch(boolean b) {
-        disableAutoWatchReset = b;
-    }
-    public void start() {
-        sendThread.start();
-        eventThread.start();
-    }
-
-    private Object eventOfDeath = new Object();
-
-    private static class WatcherSetEventPair {
-        private final Set<Watcher> watchers;
-        private final WatchedEvent event;
-
-        public WatcherSetEventPair(Set<Watcher> watchers, WatchedEvent event) {
-            this.watchers = watchers;
-            this.event = event;
-        }
-    }
-
-    /**
-     * Guard against creating "-EventThread-EventThread-EventThread-..." thread
-     * names when ZooKeeper object is being created from within a watcher.
-     * See ZOOKEEPER-795 for details.
-     */
-    private static String makeThreadName(String suffix) {
-        String name = Thread.currentThread().getName().
-            replaceAll("-EventThread", "");
-        return name + suffix;
-    }
-
-    class EventThread extends ZooKeeperThread {
-        private final LinkedBlockingQueue<Object> waitingEvents =
-            new LinkedBlockingQueue<Object>();
-
-        /** This is really the queued session state until the event
-         * thread actually processes the event and hands it to the watcher.
-         * But for all intents and purposes this is the state.
-         */
-        private volatile KeeperState sessionState = KeeperState.Disconnected;
-
-       private volatile boolean wasKilled = false;
-       private volatile boolean isRunning = false;
-
-        EventThread() {
-            super(makeThreadName("-EventThread"));
-            setDaemon(true);
-        }
-
-        public void queueEvent(WatchedEvent event) {
-            if (event.getType() == EventType.None
-                    && sessionState == event.getState()) {
-                return;
-            }
-            sessionState = event.getState();
-
-            // materialize the watchers based on the event
-            WatcherSetEventPair pair = new WatcherSetEventPair(
-                    watcher.materialize(event.getState(), event.getType(),
-                            event.getPath()),
-                            event);
-            // queue the pair (watch set & event) for later processing
-            waitingEvents.add(pair);
-        }
-
-       public void queuePacket(Packet packet) {
-          if (wasKilled) {
-             synchronized (waitingEvents) {
-                if (isRunning) waitingEvents.add(packet);
-                else processEvent(packet);
-             }
-          } else {
-             waitingEvents.add(packet);
-          }
-       }
-
-        public void queueEventOfDeath() {
-            waitingEvents.add(eventOfDeath);
-        }
-
-        @Override
-        public void run() {
-           try {
-              isRunning = true;
-              while (true) {
-                 Object event = waitingEvents.take();
-                 if (event == eventOfDeath) {
-                    wasKilled = true;
-                 } else {
-                    processEvent(event);
-                 }
-                 if (wasKilled)
-                    synchronized (waitingEvents) {
-                       if (waitingEvents.isEmpty()) {
-                          isRunning = false;
-                          break;
-                       }
-                    }
-              }
-           } catch (InterruptedException e) {
-              LOG.error("Event thread exiting due to interruption", e);
-           }
-
-            LOG.info("EventThread shut down for session: 0x{}",
-                     Long.toHexString(getSessionId()));
-        }
-
-       private void processEvent(Object event) {
-          try {
-              if (event instanceof WatcherSetEventPair) {
-                  // each watcher will process the event
-                  WatcherSetEventPair pair = (WatcherSetEventPair) event;
-                  for (Watcher watcher : pair.watchers) {
-                      try {
-                          watcher.process(pair.event);
-                      } catch (Throwable t) {
-                          LOG.error("Error while calling watcher ", t);
-                      }
-                  }
-              } else {
-                  Packet p = (Packet) event;
-                  int rc = 0;
-                  String clientPath = p.clientPath;
-                  if (p.replyHeader.getErr() != 0) {
-                      rc = p.replyHeader.getErr();
-                  }
-                  if (p.cb == null) {
-                      LOG.warn("Somehow a null cb got to EventThread!");
-                  } else if (p.response instanceof ExistsResponse
-                          || p.response instanceof SetDataResponse
-                          || p.response instanceof SetACLResponse) {
-                      StatCallback cb = (StatCallback) p.cb;
-                      if (rc == 0) {
-                          if (p.response instanceof ExistsResponse) {
-                              cb.processResult(rc, clientPath, p.ctx,
-                                      ((ExistsResponse) p.response)
-                                              .getStat());
-                          } else if (p.response instanceof SetDataResponse) {
-                              cb.processResult(rc, clientPath, p.ctx,
-                                      ((SetDataResponse) p.response)
-                                              .getStat());
-                          } else if (p.response instanceof SetACLResponse) {
-                              cb.processResult(rc, clientPath, p.ctx,
-                                      ((SetACLResponse) p.response)
-                                              .getStat());
-                          }
-                      } else {
-                          cb.processResult(rc, clientPath, p.ctx, null);
-                      }
-                  } else if (p.response instanceof GetDataResponse) {
-                      DataCallback cb = (DataCallback) p.cb;
-                      GetDataResponse rsp = (GetDataResponse) p.response;
-                      if (rc == 0) {
-                          cb.processResult(rc, clientPath, p.ctx, rsp
-                                  .getData(), rsp.getStat());
-                      } else {
-                          cb.processResult(rc, clientPath, p.ctx, null,
-                                  null);
-                      }
-                  } else if (p.response instanceof GetACLResponse) {
-                      ACLCallback cb = (ACLCallback) p.cb;
-                      GetACLResponse rsp = (GetACLResponse) p.response;
-                      if (rc == 0) {
-                          cb.processResult(rc, clientPath, p.ctx, rsp
-                                  .getAcl(), rsp.getStat());
-                      } else {
-                          cb.processResult(rc, clientPath, p.ctx, null,
-                                  null);
-                      }
-                  } else if (p.response instanceof GetChildrenResponse) {
-                      ChildrenCallback cb = (ChildrenCallback) p.cb;
-                      GetChildrenResponse rsp = (GetChildrenResponse) p.response;
-                      if (rc == 0) {
-                          cb.processResult(rc, clientPath, p.ctx, rsp
-                                  .getChildren());
-                      } else {
-                          cb.processResult(rc, clientPath, p.ctx, null);
-                      }
-                  } else if (p.response instanceof GetChildren2Response) {
-                      Children2Callback cb = (Children2Callback) p.cb;
-                      GetChildren2Response rsp = (GetChildren2Response) p.response;
-                      if (rc == 0) {
-                          cb.processResult(rc, clientPath, p.ctx, rsp
-                                  .getChildren(), rsp.getStat());
-                      } else {
-                          cb.processResult(rc, clientPath, p.ctx, null, null);
-                      }
-                  } else if (p.response instanceof CreateResponse) {
-                      StringCallback cb = (StringCallback) p.cb;
-                      CreateResponse rsp = (CreateResponse) p.response;
-                      if (rc == 0) {
-                          cb.processResult(rc, clientPath, p.ctx,
-                                  (chrootPath == null
-                                          ? rsp.getPath()
-                                          : rsp.getPath()
-                                    .substring(chrootPath.length())));
-                      } else {
-                          cb.processResult(rc, clientPath, p.ctx, null);
-                      }
-                  } else if (p.response instanceof MultiResponse) {
-                          MultiCallback cb = (MultiCallback) p.cb;
-                          MultiResponse rsp = (MultiResponse) p.response;
-                          if (rc == 0) {
-                                  List<OpResult> results = rsp.getResultList();
-                                  int newRc = rc;
-                                  for (OpResult result : results) {
-                                          if (result instanceof ErrorResult
-                                              && KeeperException.Code.OK.intValue()
-                                                  != (newRc = ((ErrorResult) result).getErr())) {
-                                                  break;
-                                          }
-                                  }
-                                  cb.processResult(newRc, clientPath, p.ctx, results);
-                          } else {
-                                  cb.processResult(rc, clientPath, p.ctx, null);
-                          }
-                  }  else if (p.cb instanceof VoidCallback) {
-                      VoidCallback cb = (VoidCallback) p.cb;
-                      cb.processResult(rc, clientPath, p.ctx);
-                  }
-              }
-          } catch (Throwable t) {
-              LOG.error("Caught unexpected throwable", t);
-          }
-       }
-    }
-
-    private void finishPacket(Packet p) {
-        if (p.watchRegistration != null) {
-            p.watchRegistration.register(p.replyHeader.getErr());
-        }
-
-        if (p.cb == null) {
-            synchronized (p) {
-                p.finished = true;
-                p.notifyAll();
-            }
-        } else {
-            p.finished = true;
-            eventThread.queuePacket(p);
-        }
-    }
-
-    private void conLossPacket(Packet p) {
-        if (p.replyHeader == null) {
-            return;
-        }
-        switch (state) {
-        case AUTH_FAILED:
-            p.replyHeader.setErr(KeeperException.Code.AUTHFAILED.intValue());
-            break;
-        case CLOSED:
-            p.replyHeader.setErr(KeeperException.Code.SESSIONEXPIRED.intValue());
-            break;
-        default:
-            p.replyHeader.setErr(KeeperException.Code.CONNECTIONLOSS.intValue());
-        }
-        finishPacket(p);
-    }
-
-    private volatile long lastZxid;
-
-    public long getLastZxid() {
-        return lastZxid;
-    }
-
-    static class EndOfStreamException extends IOException {
-        private static final long serialVersionUID = -5438877188796231422L;
-
-        public EndOfStreamException(String msg) {
-            super(msg);
-        }
-        
-        @Override
-        public String toString() {
-            return "EndOfStreamException: " + getMessage();
-        }
-    }
-
-    private static class SessionTimeoutException extends IOException {
-        private static final long serialVersionUID = 824482094072071178L;
-
-        public SessionTimeoutException(String msg) {
-            super(msg);
-        }
-    }
-    
-    private static class SessionExpiredException extends IOException {
-        private static final long serialVersionUID = -1388816932076193249L;
-
-        public SessionExpiredException(String msg) {
-            super(msg);
-        }
-    }
-
-    private static class RWServerFoundException extends IOException {
-        private static final long serialVersionUID = 90431199887158758L;
-
-        public RWServerFoundException(String msg) {
-            super(msg);
-        }
-    }
-    
-    public static final int packetLen = Integer.getInteger("jute.maxbuffer",
-            4096 * 1024);
-
-    /**
-     * This class services the outgoing request queue and generates the heart
-     * beats. It also spawns the ReadThread.
-     */
-    class SendThread extends ZooKeeperThread {
-        private long lastPingSentNs;
-        private final ClientCnxnSocket clientCnxnSocket;
-        private Random r = new Random(System.nanoTime());        
-        private boolean isFirstConnect = true;
-
-        void readResponse(ByteBuffer incomingBuffer) throws IOException {
-            ByteBufferInputStream bbis = new ByteBufferInputStream(
-                    incomingBuffer);
-            BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis);
-            ReplyHeader replyHdr = new ReplyHeader();
-
-            replyHdr.deserialize(bbia, "header");
-            if (replyHdr.getXid() == -2) {
-                // -2 is the xid for pings
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Got ping response for sessionid: 0x"
-                            + Long.toHexString(sessionId)
-                            + " after "
-                            + ((System.nanoTime() - lastPingSentNs) / 1000000)
-                            + "ms");
-                }
-                return;
-            }
-            if (replyHdr.getXid() == -4) {
-                // -4 is the xid for AuthPacket               
-                if(replyHdr.getErr() == KeeperException.Code.AUTHFAILED.intValue()) {
-                    state = States.AUTH_FAILED;                    
-                    eventThread.queueEvent( new WatchedEvent(Watcher.Event.EventType.None, 
-                            Watcher.Event.KeeperState.AuthFailed, null) );            		            		
-                }
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Got auth sessionid:0x"
-                            + Long.toHexString(sessionId));
-                }
-                return;
-            }
-            if (replyHdr.getXid() == -1) {
-                // -1 means notification
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Got notification sessionid:0x"
-                        + Long.toHexString(sessionId));
-                }
-                WatcherEvent event = new WatcherEvent();
-                event.deserialize(bbia, "response");
-
-                // convert from a server path to a client path
-                if (chrootPath != null) {
-                    String serverPath = event.getPath();
-                    if(serverPath.compareTo(chrootPath)==0)
-                        event.setPath("/");
-                    else if (serverPath.length() > chrootPath.length())
-                        event.setPath(serverPath.substring(chrootPath.length()));
-                    else {
-                    	LOG.warn("Got server path " + event.getPath()
-                    			+ " which is too short for chroot path "
-                    			+ chrootPath);
-                    }
-                }
-
-                WatchedEvent we = new WatchedEvent(event);
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Got " + we + " for sessionid 0x"
-                            + Long.toHexString(sessionId));
-                }
-
-                eventThread.queueEvent( we );
-                return;
-            }
-
-            // If SASL authentication is currently in progress, construct and
-            // send a response packet immediately, rather than queuing a
-            // response as with other packets.
-            if (clientTunneledAuthenticationInProgress()) {
-                GetSASLRequest request = new GetSASLRequest();
-                request.deserialize(bbia,"token");
-                zooKeeperSaslClient.respondToServer(request.getToken(),
-                  ClientCnxn.this);
-                return;
-            }
-
-            Packet packet;
-            synchronized (pendingQueue) {
-                if (pendingQueue.size() == 0) {
-                    throw new IOException("Nothing in the queue, but got "
-                            + replyHdr.getXid());
-                }
-                packet = pendingQueue.remove();
-            }
-            /*
-             * Since requests are processed in order, we better get a response
-             * to the first request!
-             */
-            try {
-                if (packet.requestHeader.getXid() != replyHdr.getXid()) {
-                    packet.replyHeader.setErr(
-                            KeeperException.Code.CONNECTIONLOSS.intValue());
-                    throw new IOException("Xid out of order. Got Xid "
-                            + replyHdr.getXid() + " with err " +
-                            + replyHdr.getErr() +
-                            " expected Xid "
-                            + packet.requestHeader.getXid()
-                            + " for a packet with details: "
-                            + packet );
-                }
-
-                packet.replyHeader.setXid(replyHdr.getXid());
-                packet.replyHeader.setErr(replyHdr.getErr());
-                packet.replyHeader.setZxid(replyHdr.getZxid());
-                if (replyHdr.getZxid() > 0) {
-                    lastZxid = replyHdr.getZxid();
-                }
-                if (packet.response != null && replyHdr.getErr() == 0) {
-                    packet.response.deserialize(bbia, "response");
-                }
-
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Reading reply sessionid:0x"
-                            + Long.toHexString(sessionId) + ", packet:: " + packet);
-                }
-            } finally {
-                finishPacket(packet);
-            }
-        }
-
-        SendThread(ClientCnxnSocket clientCnxnSocket) {
-            super(makeThreadName("-SendThread()"));
-            state = States.CONNECTING;
-            this.clientCnxnSocket = clientCnxnSocket;
-            setDaemon(true);
-        }
-
-        // TODO: can not name this method getState since Thread.getState()
-        // already exists
-        // It would be cleaner to make class SendThread an implementation of
-        // Runnable
-        /**
-         * Used by ClientCnxnSocket
-         * 
-         * @return
-         */
-        ZooKeeper.States getZkState() {
-            return state;
-        }
-
-        ClientCnxnSocket getClientCnxnSocket() {
-            return clientCnxnSocket;
-        }
-
-        void primeConnection() throws IOException {
-            LOG.info("Socket connection established to "
-                     + clientCnxnSocket.getRemoteSocketAddress()
-                     + ", initiating session");
-            isFirstConnect = false;
-            long sessId = (seenRwServerBefore) ? sessionId : 0;
-            ConnectRequest conReq = new ConnectRequest(0, lastZxid,
-                    sessionTimeout, sessId, sessionPasswd);
-            synchronized (outgoingQueue) {
-                // We add backwards since we are pushing into the front
-                // Only send if there's a pending watch
-                // TODO: here we have the only remaining use of zooKeeper in
-                // this class. It's to be eliminated!
-                if (!disableAutoWatchReset) {
-                    List<String> dataWatches = zooKeeper.getDataWatches();
-                    List<String> existWatches = zooKeeper.getExistWatches();
-                    List<String> childWatches = zooKeeper.getChildWatches();
-                    if (!dataWatches.isEmpty()
-                                || !existWatches.isEmpty() || !childWatches.isEmpty()) {
-
-                        Iterator<String> dataWatchesIter = prependChroot(dataWatches).iterator();
-                        Iterator<String> existWatchesIter = prependChroot(existWatches).iterator();
-                        Iterator<String> childWatchesIter = prependChroot(childWatches).iterator();
-                        long setWatchesLastZxid = lastZxid;
-
-                        while (dataWatchesIter.hasNext()
-                                       || existWatchesIter.hasNext() || childWatchesIter.hasNext()) {
-                            List<String> dataWatchesBatch = new ArrayList<String>();
-                            List<String> existWatchesBatch = new ArrayList<String>();
-                            List<String> childWatchesBatch = new ArrayList<String>();
-                            int batchLength = 0;
-
-                            // Note, we may exceed our max length by a bit when we add the last
-                            // watch in the batch. This isn't ideal, but it makes the code simpler.
-                            while (batchLength < SET_WATCHES_MAX_LENGTH) {
-                                final String watch;
-                                if (dataWatchesIter.hasNext()) {
-                                    watch = dataWatchesIter.next();
-                                    dataWatchesBatch.add(watch);
-                                } else if (existWatchesIter.hasNext()) {
-                                    watch = existWatchesIter.next();
-                                    existWatchesBatch.add(watch);
-                                } else if (childWatchesIter.hasNext()) {
-                                    watch = childWatchesIter.next();
-                                    childWatchesBatch.add(watch);
-                                } else {
-                                    break;
-                                }
-                                batchLength += watch.length();
-                            }
-
-                            SetWatches sw = new SetWatches(setWatchesLastZxid,
-                                    dataWatchesBatch,
-                                    existWatchesBatch,
-                                    childWatchesBatch);
-                            RequestHeader h = new RequestHeader();
-                            h.setType(ZooDefs.OpCode.setWatches);
-                            h.setXid(-8);
-                            Packet packet = new Packet(h, new ReplyHeader(), sw, null, null);
-                            outgoingQueue.addFirst(packet);
-                        }
-                    }
-                }
-
-                for (AuthData id : authInfo) {
-                    outgoingQueue.addFirst(new Packet(new RequestHeader(-4,
-                            OpCode.auth), null, new AuthPacket(0, id.scheme,
-                            id.data), null, null));
-                }
-                outgoingQueue.addFirst(new Packet(null, null, conReq,
-                            null, null, readOnly));
-            }
-            clientCnxnSocket.enableReadWriteOnly();
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Session establishment request sent on "
-                        + clientCnxnSocket.getRemoteSocketAddress());
-            }
-        }
-
-        private List<String> prependChroot(List<String> paths) {
-            if (chrootPath != null && !paths.isEmpty()) {
-                for (int i = 0; i < paths.size(); ++i) {
-                    String clientPath = paths.get(i);
-                    String serverPath;
-                    // handle clientPath = "/"
-                    if (clientPath.length() == 1) {
-                        serverPath = chrootPath;
-                    } else {
-                        serverPath = chrootPath + clientPath;
-                    }
-                    paths.set(i, serverPath);
-                }
-            }
-            return paths;
-        }
-
-        private void sendPing() {
-            lastPingSentNs = System.nanoTime();
-            RequestHeader h = new RequestHeader(-2, OpCode.ping);
-            queuePacket(h, null, null, null, null, null, null, null, null);
-        }
-
-        private InetSocketAddress rwServerAddress = null;
-
-        private final static int minPingRwTimeout = 100;
-
-        private final static int maxPingRwTimeout = 60000;
-
-        private int pingRwTimeout = minPingRwTimeout;
-
-        // Set to true if and only if constructor of ZooKeeperSaslClient
-        // throws a LoginException: see startConnect() below.
-        private boolean saslLoginFailed = false;
-
-        private void startConnect(InetSocketAddress addr) throws IOException {
-            // initializing it for new connection
-            saslLoginFailed = false;
-            state = States.CONNECTING;
-
-            setName(getName().replaceAll("\\(.*\\)",
-                    "(" + addr.getHostName() + ":" + addr.getPort() + ")"));
-            if (ZooKeeperSaslClient.isEnabled()) {
-                try {
-                    String principalUserName = System.getProperty(
-                            ZK_SASL_CLIENT_USERNAME, "zookeeper");
-                    zooKeeperSaslClient =
-                        new ZooKeeperSaslClient(
-                                principalUserName+"/"+addr.getHostName());
-                } catch (LoginException e) {
-                    // An authentication error occurred when the SASL client tried to initialize:
-                    // for Kerberos this means that the client failed to authenticate with the KDC.
-                    // This is different from an authentication error that occurs during communication
-                    // with the Zookeeper server, which is handled below.
-                    LOG.warn("SASL configuration failed: " + e + " Will continue connection to Zookeeper server without "
-                      + "SASL authentication, if Zookeeper server allows it.");
-                    eventThread.queueEvent(new WatchedEvent(
-                      Watcher.Event.EventType.None,
-                      Watcher.Event.KeeperState.AuthFailed, null));
-                    saslLoginFailed = true;
-                }
-            }
-            logStartConnect(addr);
-
-            clientCnxnSocket.connect(addr);
-        }
-
-        private void logStartConnect(InetSocketAddress addr) {
-            String msg = "Opening socket connection to server " + addr;
-            if (zooKeeperSaslClient != null) {
-              msg += ". " + zooKeeperSaslClient.getConfigStatus();
-            }
-            LOG.info(msg);
-        }
-
-        private static final String RETRY_CONN_MSG =
-            ", closing socket connection and attempting reconnect";
-        
-        @Override
-        public void run() {
-            clientCnxnSocket.introduce(this,sessionId);
-            clientCnxnSocket.updateNow();
-            clientCnxnSocket.updateLastSendAndHeard();
-            int to;
-            long lastPingRwServer = Time.currentElapsedTime();
-            final int MAX_SEND_PING_INTERVAL = 10000; //10 seconds
-            InetSocketAddress serverAddress = null;
-            while (state.isAlive()) {
-                try {
-                    if (!clientCnxnSocket.isConnected()) {
-                        if(!isFirstConnect){
-                            try {
-                                Thread.sleep(r.nextInt(1000));
-                            } catch (InterruptedException e) {
-                                LOG.warn("Unexpected exception", e);
-                            }
-                        }
-                        // don't re-establish connection if we are closing
-                        if (closing || !state.isAlive()) {
-                            break;
-                        }
-                        if (rwServerAddress != null) {
-                            serverAddress = rwServerAddress;
-                            rwServerAddress = null;
-                        } else {
-                            serverAddress = hostProvider.next(1000);
-                        }
-                        startConnect(serverAddress);
-                        clientCnxnSocket.updateLastSendAndHeard();
-                    }
-
-                    if (state.isConnected()) {
-                        // determine whether we need to send an AuthFailed event.
-                        if (zooKeeperSaslClient != null) {
-                            boolean sendAuthEvent = false;
-                            if (zooKeeperSaslClient.getSaslState() == ZooKeeperSaslClient.SaslState.INITIAL) {
-                                try {
-                                    zooKeeperSaslClient.initialize(ClientCnxn.this);
-                                } catch (SaslException e) {
-                                   LOG.error("SASL authentication with Zookeeper Quorum member failed: " + e);
-                                    state = States.AUTH_FAILED;
-                                    sendAuthEvent = true;
-                                }
-                            }
-                            KeeperState authState = zooKeeperSaslClient.getKeeperState();
-                            if (authState != null) {
-                                if (authState == KeeperState.AuthFailed) {
-                                    // An authentication error occurred during authentication with the Zookeeper Server.
-                                    state = States.AUTH_FAILED;
-                                    sendAuthEvent = true;
-                                } else {
-                                    if (authState == KeeperState.SaslAuthenticated) {
-                                        sendAuthEvent = true;
-                                    }
-                                }
-                            }
-
-                            if (sendAuthEvent == true) {
-                                eventThread.queueEvent(new WatchedEvent(
-                                      Watcher.Event.EventType.None,
-                                      authState,null));
-                            }
-                        }
-                        to = readTimeout - clientCnxnSocket.getIdleRecv();
-                    } else {
-                        to = connectTimeout - clientCnxnSocket.getIdleRecv();
-                    }
-                    
-                    if (to <= 0) {
-                        String warnInfo;
-                        warnInfo = "Client session timed out, have not heard from server in "
-                            + clientCnxnSocket.getIdleRecv()
-                            + "ms"
-                            + " for sessionid 0x"
-                            + Long.toHexString(sessionId);
-                        LOG.warn(warnInfo);
-                        throw new SessionTimeoutException(warnInfo);
-                    }
-                    if (state.isConnected()) {
-                    	//1000(1 second) is to prevent race condition missing to send the second ping
-                    	//also make sure not to send too many pings when readTimeout is small 
-                        int timeToNextPing = readTimeout / 2 - clientCnxnSocket.getIdleSend() - 
-                        		((clientCnxnSocket.getIdleSend() > 1000) ? 1000 : 0);
-                        //send a ping request either time is due or no packet sent out within MAX_SEND_PING_INTERVAL
-                        if (timeToNextPing <= 0 || clientCnxnSocket.getIdleSend() > MAX_SEND_PING_INTERVAL) {
-                            sendPing();
-                            clientCnxnSocket.updateLastSend();
-                        } else {
-                            if (timeToNextPing < to) {
-                                to = timeToNextPing;
-                            }
-                        }
-                    }
-
-                    // If we are in read-only mode, seek for read/write server
-                    if (state == States.CONNECTEDREADONLY) {
-                        long now = Time.currentElapsedTime();
-                        int idlePingRwServer = (int) (now - lastPingRwServer);
-                        if (idlePingRwServer >= pingRwTimeout) {
-                            lastPingRwServer = now;
-                            idlePingRwServer = 0;
-                            pingRwTimeout =
-                                Math.min(2*pingRwTimeout, maxPingRwTimeout);
-                            pingRwServer();
-                        }
-                        to = Math.min(to, pingRwTimeout - idlePingRwServer);
-                    }
-
-                    clientCnxnSocket.doTransport(to, pendingQueue, outgoingQueue, ClientCnxn.this);
-                } catch (Throwable e) {
-                    if (closing) {
-                        if (LOG.isDebugEnabled()) {
-                            // closing so this is expected
-                            LOG.debug("An exception was thrown while closing send thread for session 0x"
-                                    + Long.toHexString(getSessionId())
-                                    + " : " + e.getMessage());
-                        }
-                        break;
-                    } else {
-                        // this is ugly, you have a better way speak up
-                        if (e instanceof SessionExpiredException) {
-                            LOG.info(e.getMessage() + ", closing socket connection");
-                        } else if (e instanceof SessionTimeoutException) {
-                            LOG.info(e.getMessage() + RETRY_CONN_MSG);
-                        } else if (e instanceof EndOfStreamException) {
-                            LOG.info(e.getMessage() + RETRY_CONN_MSG);
-                        } else if (e instanceof RWServerFoundException) {
-                            LOG.info(e.getMessage());
-                        } else if (e instanceof SocketException) {
-                            LOG.info("Socket error occurred: {}: {}", serverAddress, e.getMessage());
-                        } else {
-                            LOG.warn("Session 0x{} for server {}, unexpected error{}",
-                                            Long.toHexString(getSessionId()),
-                                            serverAddress,
-                                            RETRY_CONN_MSG,
-                                            e);
-                        }
-                        cleanup();
-                        if (state.isAlive()) {
-                            eventThread.queueEvent(new WatchedEvent(
-                                    Event.EventType.None,
-                                    Event.KeeperState.Disconnected,
-                                    null));
-                        }
-                        clientCnxnSocket.updateNow();
-                        clientCnxnSocket.updateLastSendAndHeard();
-                    }
-                }
-            }
-            cleanup();
-            clientCnxnSocket.close();
-            if (state.isAlive()) {
-                eventThread.queueEvent(new WatchedEvent(Event.EventType.None,
-                        Event.KeeperState.Disconnected, null));
-            }
-            ZooTrace.logTraceMessage(LOG, ZooTrace.getTextTraceLevel(),
-                    "SendThread exited loop for session: 0x"
-                           + Long.toHexString(getSessionId()));
-        }
-
-        private void pingRwServer() throws RWServerFoundException, UnknownHostException {
-            String result = null;
-            InetSocketAddress addr = hostProvider.next(0);
-            LOG.info("Checking server " + addr + " for being r/w." +
-                    " Timeout " + pingRwTimeout);
-
-            Socket sock = null;
-            BufferedReader br = null;
-            try {
-                sock = new Socket(addr.getHostName(), addr.getPort());
-                sock.setSoLinger(false, -1);
-                sock.setSoTimeout(1000);
-                sock.setTcpNoDelay(true);
-                sock.getOutputStream().write("isro".getBytes());
-                sock.getOutputStream().flush();
-                sock.shutdownOutput();
-                br = new BufferedReader(
-                        new InputStreamReader(sock.getInputStream()));
-                result = br.readLine();
-            } catch (ConnectException e) {
-                // ignore, this just means server is not up
-            } catch (IOException e) {
-                // some unexpected error, warn about it
-                LOG.warn("Exception while seeking for r/w server " +
-                        e.getMessage(), e);
-            } finally {
-                if (sock != null) {
-                    try {
-                        sock.close();
-                    } catch (IOException e) {
-                        LOG.warn("Unexpected exception", e);
-                    }
-                }
-                if (br != null) {
-                    try {
-                        br.close();
-                    } catch (IOException e) {
-                        LOG.warn("Unexpected exception", e);
-                    }
-                }
-            }
-
-            if ("rw".equals(result)) {
-                pingRwTimeout = minPingRwTimeout;
-                // save the found address so that it's used during the next
-                // connection attempt
-                rwServerAddress = addr;
-                throw new RWServerFoundException("Majority server found at "
-                        + addr.getHostName() + ":" + addr.getPort());
-            }
-        }
-
-        private void cleanup() {
-            clientCnxnSocket.cleanup();
-            synchronized (pendingQueue) {
-                for (Packet p : pendingQueue) {
-                    conLossPacket(p);
-                }
-                pendingQueue.clear();
-            }
-            synchronized (outgoingQueue) {
-                for (Packet p : outgoingQueue) {
-                    conLossPacket(p);
-                }
-                outgoingQueue.clear();
-            }
-        }
-
-        /**
-         * Callback invoked by the ClientCnxnSocket once a connection has been
-         * established.
-         * 
-         * @param _negotiatedSessionTimeout
-         * @param _sessionId
-         * @param _sessionPasswd
-         * @param isRO
-         * @throws IOException
-         */
-        void onConnected(int _negotiatedSessionTimeout, long _sessionId,
-                byte[] _sessionPasswd, boolean isRO) throws IOException {
-            negotiatedSessionTimeout = _negotiatedSessionTimeout;
-            if (negotiatedSessionTimeout <= 0) {
-                state = States.CLOSED;
-
-                eventThread.queueEvent(new WatchedEvent(
-                        Watcher.Event.EventType.None,
-                        Watcher.Event.KeeperState.Expired, null));
-                eventThread.queueEventOfDeath();
-
-                String warnInfo;
-                warnInfo = "Unable to reconnect to ZooKeeper service, session 0x"
-                    + Long.toHexString(sessionId) + " has expired";
-                LOG.warn(warnInfo);
-                throw new SessionExpiredException(warnInfo);
-            }
-            if (!readOnly && isRO) {
-                LOG.error("Read/write client got connected to read-only server");
-            }
-            readTimeout = negotiatedSessionTimeout * 2 / 3;
-            connectTimeout = negotiatedSessionTimeout / hostProvider.size();
-            hostProvider.onConnected();
-            sessionId = _sessionId;
-            sessionPasswd = _sessionPasswd;
-            state = (isRO) ?
-                    States.CONNECTEDREADONLY : States.CONNECTED;
-            seenRwServerBefore |= !isRO;
-            LOG.info("Session establishment complete on server "
-                    + clientCnxnSocket.getRemoteSocketAddress()
-                    + ", sessionid = 0x" + Long.toHexString(sessionId)
-                    + ", negotiated timeout = " + negotiatedSessionTimeout
-                    + (isRO ? " (READ-ONLY mode)" : ""));
-            KeeperState eventState = (isRO) ?
-                    KeeperState.ConnectedReadOnly : KeeperState.SyncConnected;
-            eventThread.queueEvent(new WatchedEvent(
-                    Watcher.Event.EventType.None,
-                    eventState, null));
-        }
-
-        void close() {
-            state = States.CLOSED;
-            clientCnxnSocket.wakeupCnxn();
-        }
-
-        void testableCloseSocket() throws IOException {
-            clientCnxnSocket.testableCloseSocket();
-        }
-
-        public boolean clientTunneledAuthenticationInProgress() {
-            // 1. SASL client is disabled.
-            if (!ZooKeeperSaslClient.isEnabled()) {
-                return false;
-            }
-
-            // 2. SASL login failed.
-            if (saslLoginFailed == true) {
-                return false;
-            }
-
-            // 3. SendThread has not created the authenticating object yet,
-            // therefore authentication is (at the earliest stage of being) in progress.
-            if (zooKeeperSaslClient == null) {
-                return true;
-            }
-
-            // 4. authenticating object exists, so ask it for its progress.
-            return zooKeeperSaslClient.clientTunneledAuthenticationInProgress();
-        }
-
-        public void sendPacket(Packet p) throws IOException {
-            clientCnxnSocket.sendPacket(p);
-        }
-    }
-
-    /**
-     * Shutdown the send/event threads. This method should not be called
-     * directly - rather it should be called as part of close operation. This
-     * method is primarily here to allow the tests to verify disconnection
-     * behavior.
-     */
-    public void disconnect() {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Disconnecting client for session: 0x"
-                      + Long.toHexString(getSessionId()));
-        }
-
-        sendThread.close();
-        eventThread.queueEventOfDeath();
-    }
-
-    /**
-     * Close the connection, which includes; send session disconnect to the
-     * server, shutdown the send/event threads.
-     *
-     * @throws IOException
-     */
-    public void close() throws IOException {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Closing client for session: 0x"
-                      + Long.toHexString(getSessionId()));
-        }
-
-        try {
-            RequestHeader h = new RequestHeader();
-            h.setType(ZooDefs.OpCode.closeSession);
-
-            submitRequest(h, null, null, null);
-        } catch (InterruptedException e) {
-            // ignore, close the send/event threads
-        } finally {
-            disconnect();
-        }
-    }
-
-    private int xid = 1;
-
-    // @VisibleForTesting
-    volatile States state = States.NOT_CONNECTED;
-
-    /*
-     * getXid() is called externally by ClientCnxnNIO::doIO() when packets are sent from the outgoingQueue to
-     * the server. Thus, getXid() must be public.
-     */
-    synchronized public int getXid() {
-        return xid++;
-    }
-
-    public ReplyHeader submitRequest(RequestHeader h, Record request,
-            Record response, WatchRegistration watchRegistration)
-            throws InterruptedException {
-        ReplyHeader r = new ReplyHeader();
-        Packet packet = queuePacket(h, r, request, response, null, null, null,
-                    null, watchRegistration);
-        synchronized (packet) {
-            while (!packet.finished) {
-                packet.wait();
-            }
-        }
-        return r;
-    }
-
-    public void enableWrite() {
-        sendThread.getClientCnxnSocket().enableWrite();
-    }
-
-    public void sendPacket(Record request, Record response, AsyncCallback cb, int opCode)
-    throws IOException {
-        // Generate Xid now because it will be sent immediately,
-        // by call to sendThread.sendPacket() below.
-        int xid = getXid();
-        RequestHeader h = new RequestHeader();
-        h.setXid(xid);
-        h.setType(opCode);
-
-        ReplyHeader r = new ReplyHeader();
-        r.setXid(xid);
-
-        Packet p = new Packet(h, r, request, response, null, false);
-        p.cb = cb;
-        sendThread.sendPacket(p);
-    }
-
-    Packet queuePacket(RequestHeader h, ReplyHeader r, Record request,
-            Record response, AsyncCallback cb, String clientPath,
-            String serverPath, Object ctx, WatchRegistration watchRegistration)
-    {
-        Packet packet = null;
-
-        // Note that we do not generate the Xid for the packet yet. It is
-        // generated later at send-time, by an implementation of ClientCnxnSocket::doIO(),
-        // where the packet is actually sent.
-        synchronized (outgoingQueue) {
-            packet = new Packet(h, r, request, response, watchRegistration);
-            packet.cb = cb;
-            packet.ctx = ctx;
-            packet.clientPath = clientPath;
-            packet.serverPath = serverPath;
-            if (!state.isAlive() || closing) {
-                conLossPacket(packet);
-            } else {
-                // If the client is asking to close the session then
-                // mark as closing
-                if (h.getType() == OpCode.closeSession) {
-                    closing = true;
-                }
-                outgoingQueue.add(packet);
-            }
-        }
-        sendThread.getClientCnxnSocket().wakeupCnxn();
-        return packet;
-    }
-
-    public void addAuthInfo(String scheme, byte auth[]) {
-        if (!state.isAlive()) {
-            return;
-        }
-        authInfo.add(new AuthData(scheme, auth));
-        queuePacket(new RequestHeader(-4, OpCode.auth), null,
-                new AuthPacket(0, scheme, auth), null, null, null, null,
-                null, null);
-    }
-
-    States getState() {
-        return state;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java
deleted file mode 100644
index b676531..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.jute.BinaryInputArchive;
-import org.apache.zookeeper.ClientCnxn.Packet;
-import org.apache.zookeeper.common.Time;
-import org.apache.zookeeper.proto.ConnectResponse;
-import org.apache.zookeeper.server.ByteBufferInputStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A ClientCnxnSocket does the lower level communication with a socket
- * implementation.
- * 
- * This code has been moved out of ClientCnxn so that a Netty implementation can
- * be provided as an alternative to the NIO socket code.
- * 
- */
-abstract class ClientCnxnSocket {
-    private static final Logger LOG = LoggerFactory.getLogger(ClientCnxnSocket.class);
-
-    protected boolean initialized;
-
-    /**
-     * This buffer is only used to read the length of the incoming message.
-     */
-    protected final ByteBuffer lenBuffer = ByteBuffer.allocateDirect(4);
-
-    /**
-     * After the length is read, a new incomingBuffer is allocated in
-     * readLength() to receive the full message.
-     */
-    protected ByteBuffer incomingBuffer = lenBuffer;
-    protected long sentCount = 0;
-    protected long recvCount = 0;
-    protected long lastHeard;
-    protected long lastSend;
-    protected long now;
-    protected ClientCnxn.SendThread sendThread;
-
-    /**
-     * The sessionId is only available here for Log and Exception messages.
-     * Otherwise the socket doesn't need to know it.
-     */
-    protected long sessionId;
-
-    void introduce(ClientCnxn.SendThread sendThread, long sessionId) {
-        this.sendThread = sendThread;
-        this.sessionId = sessionId;
-    }
-
-    void updateNow() {
-        now = Time.currentElapsedTime();
-    }
-
-    int getIdleRecv() {
-        return (int) (now - lastHeard);
-    }
-
-    int getIdleSend() {
-        return (int) (now - lastSend);
-    }
-
-    long getSentCount() {
-        return sentCount;
-    }
-
-    long getRecvCount() {
-        return recvCount;
-    }
-
-    void updateLastHeard() {
-        this.lastHeard = now;
-    }
-
-    void updateLastSend() {
-        this.lastSend = now;
-    }
-
-    void updateLastSendAndHeard() {
-        this.lastSend = now;
-        this.lastHeard = now;
-    }
-
-    protected void readLength() throws IOException {
-        int len = incomingBuffer.getInt();
-        if (len < 0 || len >= ClientCnxn.packetLen) {
-            throw new IOException("Packet len" + len + " is out of range!");
-        }
-        incomingBuffer = ByteBuffer.allocate(len);
-    }
-
-    void readConnectResult() throws IOException {
-        if (LOG.isTraceEnabled()) {
-            StringBuilder buf = new StringBuilder("0x[");
-            for (byte b : incomingBuffer.array()) {
-                buf.append(Integer.toHexString(b) + ",");
-            }
-            buf.append("]");
-            LOG.trace("readConnectResult " + incomingBuffer.remaining() + " "
-                    + buf.toString());
-        }
-        ByteBufferInputStream bbis = new ByteBufferInputStream(incomingBuffer);
-        BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis);
-        ConnectResponse conRsp = new ConnectResponse();
-        conRsp.deserialize(bbia, "connect");
-
-        // read "is read-only" flag
-        boolean isRO = false;
-        try {
-            isRO = bbia.readBool("readOnly");
-        } catch (IOException e) {
-            // this is ok -- just a packet from an old server which
-            // doesn't contain readOnly field
-            LOG.warn("Connected to an old server; r-o mode will be unavailable");
-        }
-
-        this.sessionId = conRsp.getSessionId();
-        sendThread.onConnected(conRsp.getTimeOut(), this.sessionId,
-                conRsp.getPasswd(), isRO);
-    }
-
-    abstract boolean isConnected();
-
-    abstract void connect(InetSocketAddress addr) throws IOException;
-
-    abstract SocketAddress getRemoteSocketAddress();
-
-    abstract SocketAddress getLocalSocketAddress();
-
-    abstract void cleanup();
-
-    abstract void close();
-
-    abstract void wakeupCnxn();
-
-    abstract void enableWrite();
-
-    abstract void disableWrite();
-
-    abstract void enableReadWriteOnly();
-
-    abstract void doTransport(int waitTimeOut, List<Packet> pendingQueue,
-            LinkedList<Packet> outgoingQueue, ClientCnxn cnxn)
-            throws IOException, InterruptedException;
-
-    abstract void testableCloseSocket() throws IOException;
-
-    abstract void sendPacket(Packet p) throws IOException;
-}


[29/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/resources/lib/log4j-1.2.17.LICENSE.txt
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/resources/lib/log4j-1.2.17.LICENSE.txt b/zookeeper-common/src/main/resources/lib/log4j-1.2.17.LICENSE.txt
deleted file mode 100644
index 6279e52..0000000
--- a/zookeeper-common/src/main/resources/lib/log4j-1.2.17.LICENSE.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright 1999-2005 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.

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt b/zookeeper-common/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt
deleted file mode 100644
index 315bd49..0000000
--- a/zookeeper-common/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright (c) 2004-2017 QOS.ch
-All rights reserved.
-
-Permission is hereby granted, free  of charge, to any person obtaining
-a  copy  of this  software  and  associated  documentation files  (the
-"Software"), to  deal in  the Software without  restriction, including
-without limitation  the rights to  use, copy, modify,  merge, publish,
-distribute,  sublicense, and/or sell  copies of  the Software,  and to
-permit persons to whom the Software  is furnished to do so, subject to
-the following conditions:
-
-The  above  copyright  notice  and  this permission  notice  shall  be
-included in all copies or substantial portions of the Software.
-
-THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
-EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
-MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/ClientReconnectTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/ClientReconnectTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/ClientReconnectTest.java
deleted file mode 100644
index 8d66a7e..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/ClientReconnectTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper;
-
-
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.zookeeper.client.HostProvider;
-import org.junit.Test;
-
-public class ClientReconnectTest extends TestCase {
-    private SocketChannel sc;
-    private CountDownLatch countDownLatch = new CountDownLatch(3);
-    
-    class MockCnxn extends ClientCnxnSocketNIO {
-        MockCnxn() throws IOException {
-            super();
-        }
-
-        @Override
-        void registerAndConnect(SocketChannel sock, InetSocketAddress addr) throws
-        IOException {
-            countDownLatch.countDown();
-            throw new IOException("failed to register");
-        }
-
-        @Override
-        SocketChannel createSock() {
-            return sc;
-        }
-    }
-
-    @Test
-    public void testClientReconnect() throws IOException, InterruptedException {
-        HostProvider hostProvider = mock(HostProvider.class);
-        when(hostProvider.size()).thenReturn(1);
-        InetSocketAddress inaddr = new InetSocketAddress(1111);
-        when(hostProvider.next(anyLong())).thenReturn(inaddr);
-        ZooKeeper zk = mock(ZooKeeper.class);
-        sc =  SocketChannel.open();
-
-        ClientCnxnSocketNIO nioCnxn = new MockCnxn();
-        ClientWatchManager watcher = mock(ClientWatchManager.class);
-        ClientCnxn clientCnxn = new ClientCnxn(
-                "tmp", hostProvider, 5000,
-                zk, watcher, nioCnxn, false);
-        clientCnxn.start();
-        countDownLatch.await(5000, TimeUnit.MILLISECONDS);
-        Assert.assertTrue(countDownLatch.getCount() == 0);
-        clientCnxn.close();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java b/zookeeper-common/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java
deleted file mode 100644
index 37149cc..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.junit.Test;
-import org.junit.internal.runners.statements.InvokeMethod;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-
-/**
- * The sole responsibility of this class is to print to the log when a test
- * starts and when it finishes.
- */
-public class JUnit4ZKTestRunner extends BlockJUnit4ClassRunner {
-    private static final Logger LOG = LoggerFactory.getLogger(JUnit4ZKTestRunner.class);
-
-    public JUnit4ZKTestRunner(Class<?> klass) throws InitializationError {
-        super(klass);
-    }
-
-    public class LoggedInvokeMethod extends InvokeMethod {
-        private final FrameworkMethod method;
-        private final String name;
-
-        public LoggedInvokeMethod(FrameworkMethod method, Object target) {
-            super(method, target);
-            this.method = method;
-            name = method.getName();
-        }
-
-        @Override
-        public void evaluate() throws Throwable {
-            LOG.info("RUNNING TEST METHOD {}", name);
-            try {
-                super.evaluate();
-                Runtime rt = Runtime.getRuntime();
-                long usedKB = (rt.totalMemory() - rt.freeMemory()) / 1024;
-                LOG.info("Memory used {}", usedKB);
-                ThreadGroup tg = Thread.currentThread().getThreadGroup();
-                while (tg.getParent() != null) {
-                    tg = tg.getParent();
-                }
-                LOG.info("Number of threads {}", tg.activeCount());
-            } catch (Throwable t) {
-                // The test method threw an exception, but it might be an
-                // expected exception as defined in the @Test annotation.
-                // Check the annotation and log an appropriate message.
-                Test annotation = this.method.getAnnotation(Test.class);
-                if (annotation != null && annotation.expected() != null &&
-                        annotation.expected().isAssignableFrom(t.getClass())) {
-                    LOG.info("TEST METHOD {} THREW EXPECTED EXCEPTION {}", name,
-                        annotation.expected());
-                } else {
-                    LOG.info("TEST METHOD FAILED {}", name, t);
-                }
-                throw t;
-            }
-            LOG.info("FINISHED TEST METHOD {}", name);
-        }
-    }
-
-    @Override
-    protected Statement methodInvoker(FrameworkMethod method, Object test) {
-        return new LoggedInvokeMethod(method, test);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/JaasConfiguration.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/JaasConfiguration.java b/zookeeper-common/src/test/java/org/apache/zookeeper/JaasConfiguration.java
deleted file mode 100644
index bf145d0..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/JaasConfiguration.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
-
-/**
- * This helper class allows to programmatically create a JAAS configuration.
- * Each section must have a name and a login module, and a set of key/values
- * to describe login options.
- *
- * Example:
- *   jaas = new JaasConfiguration();
- *   jaas.addSection("Server", "org.apache.zookeeper.server.auth.DigestLoginModule",
- *                   "username", "passowrd");
- */
-public class JaasConfiguration extends javax.security.auth.login.Configuration {
-    private final Map<String, AppConfigurationEntry[]> sections =
-      new HashMap<String, AppConfigurationEntry[]>();
-
-    public JaasConfiguration() {
-    }
-
-    /**
-     * Add a section to the jaas.conf
-     * @param name Section name
-     * @param loginModuleName Login module name
-     * @param args login key/value args
-     */
-    public void addSection(String name, String loginModuleName, String... args) {
-        Map<String, String> conf = new HashMap<String, String>();
-        // loop through the args (must be key/value sequence)
-        for (int i = 0; i < args.length - 1; i += 2) {
-            conf.put(args[i], args[i + 1]);
-        }
-        addSection(name, loginModuleName, conf);
-    }
-
-    /**
-     * Add a section to the jaas.conf
-     * @param name Section name
-     * @param loginModuleName Login module name
-     * @param conf login key/value args
-     */
-    public void addSection(String name, String loginModuleName, final Map<String,String> conf) {
-        AppConfigurationEntry[] entries = new AppConfigurationEntry[1];
-        entries[0] = new AppConfigurationEntry(loginModuleName, LoginModuleControlFlag.REQUIRED, conf);
-        this.sections.put(name, entries);
-    }
-
-    @Override
-    public AppConfigurationEntry[] getAppConfigurationEntry(String appName) {
-        return sections.get(appName);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/MockPacket.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/MockPacket.java b/zookeeper-common/src/test/java/org/apache/zookeeper/MockPacket.java
deleted file mode 100644
index f4bb19a..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/MockPacket.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.zookeeper.proto.RequestHeader;
-import org.apache.zookeeper.proto.ReplyHeader;
-import org.apache.jute.Record;
-import org.apache.zookeeper.ZooKeeper.WatchRegistration;
-import java.nio.ByteBuffer;
-
-public class MockPacket extends ClientCnxn.Packet {
-
-    public MockPacket(RequestHeader requestHeader, ReplyHeader replyHeader,
-               Record request, Record response,
-               WatchRegistration watchRegistration) {
-        super(requestHeader, replyHeader, request, response, watchRegistration);
-    }
-
-    public MockPacket(RequestHeader requestHeader, ReplyHeader replyHeader,
-               Record request, Record response,
-               WatchRegistration watchRegistration, boolean readOnly) {
-        super(requestHeader, replyHeader, request, response, watchRegistration, readOnly);
-    }
-
-    public ByteBuffer createAndReturnBB() {
-        createBB();
-        return this.bb;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/MultiResponseTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/MultiResponseTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/MultiResponseTest.java
deleted file mode 100644
index a03feb3..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/MultiResponseTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import junit.framework.TestCase;
-import org.apache.jute.BinaryInputArchive;
-import org.apache.jute.BinaryOutputArchive;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.ByteBufferInputStream;
-import org.junit.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-public class MultiResponseTest extends TestCase {
-    public void testRoundTrip() throws IOException {
-        MultiResponse response = new MultiResponse();
-
-        response.add(new OpResult.CheckResult());
-        response.add(new OpResult.CreateResult("foo-bar"));
-        response.add(new OpResult.DeleteResult());
-
-        Stat s = new Stat();
-        s.setCzxid(546);
-        response.add(new OpResult.SetDataResult(s));
-
-        MultiResponse decodedResponse = codeDecode(response);
-
-        assertEquals(response, decodedResponse);
-        assertEquals(response.hashCode(), decodedResponse.hashCode());
-    }
-
-    @Test
-    public void testEmptyRoundTrip() throws IOException {
-        MultiResponse result = new MultiResponse();
-        MultiResponse decodedResult = codeDecode(result);
-
-        assertEquals(result, decodedResult);
-        assertEquals(result.hashCode(), decodedResult.hashCode());
-    }
-
-    private MultiResponse codeDecode(MultiResponse request) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-        request.serialize(boa, "result");
-        baos.close();
-        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
-        bb.rewind();
-
-        BinaryInputArchive bia = BinaryInputArchive.getArchive(new ByteBufferInputStream(bb));
-        MultiResponse decodedRequest = new MultiResponse();
-        decodedRequest.deserialize(bia, "result");
-        return decodedRequest;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java
deleted file mode 100644
index 3749564..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import junit.framework.TestCase;
-import org.apache.jute.BinaryInputArchive;
-import org.apache.jute.BinaryOutputArchive;
-import org.apache.zookeeper.server.ByteBufferInputStream;
-import org.junit.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-public class MultiTransactionRecordTest extends TestCase {
-    @Test
-    public void testRoundTrip() throws IOException {
-        MultiTransactionRecord request = new MultiTransactionRecord();
-        request.add(Op.check("check", 1));
-        request.add(Op.create("create", "create data".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, ZooDefs.Perms.ALL));
-        request.add(Op.delete("delete", 17));
-        request.add(Op.setData("setData", "set data".getBytes(), 19));
-
-        MultiTransactionRecord decodedRequest = codeDecode(request);
-
-        assertEquals(request, decodedRequest);
-        assertEquals(request.hashCode(), decodedRequest.hashCode());
-    }
-
-    @Test
-    public void testEmptyRoundTrip() throws IOException {
-        MultiTransactionRecord request = new MultiTransactionRecord();
-        MultiTransactionRecord decodedRequest = codeDecode(request);
-
-        assertEquals(request, decodedRequest);
-        assertEquals(request.hashCode(), decodedRequest.hashCode());
-    }
-
-    private MultiTransactionRecord codeDecode(MultiTransactionRecord request) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-        request.serialize(boa, "request");
-        baos.close();
-        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
-        bb.rewind();
-
-        BinaryInputArchive bia = BinaryInputArchive.getArchive(new ByteBufferInputStream(bb));
-        MultiTransactionRecord decodedRequest = new MultiTransactionRecord();
-        decodedRequest.deserialize(bia, "request");
-        return decodedRequest;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/PortAssignment.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/PortAssignment.java b/zookeeper-common/src/test/java/org/apache/zookeeper/PortAssignment.java
deleted file mode 100644
index 06f9361..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/PortAssignment.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Assign ports to tests */
-public class PortAssignment {
-    private static final Logger LOG = LoggerFactory.getLogger(PortAssignment.class);
-
-    private static int nextPort = 11221;
-
-    /** Assign a new, unique port to the test */
-    public synchronized static int unique() {
-        LOG.info("assigning port " + nextPort);
-        return nextPort++;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/SaslAuthTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/SaslAuthTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/SaslAuthTest.java
deleted file mode 100644
index eac0703..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/SaslAuthTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.zookeeper.ClientCnxn.SendThread;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Id;
-import org.apache.zookeeper.test.ClientBase;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class SaslAuthTest extends ClientBase {
-    @BeforeClass
-    public static void init() {
-        System.setProperty("zookeeper.authProvider.1",
-                "org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
-        try {
-            File tmpDir = createTmpDir();
-            File saslConfFile = new File(tmpDir, "jaas.conf");
-            String jaasContent = getJaasFileContent();
-            FileWriter fwriter = new FileWriter(saslConfFile);
-            fwriter.write(jaasContent);
-            fwriter.close();
-            System.setProperty("java.security.auth.login.config", saslConfFile.getAbsolutePath());
-        } catch (IOException e) {
-            // could not create tmp directory to hold JAAS conf file : test will
-            // fail now.
-        }
-    }
-
-    private static String getJaasFileContent() {
-        StringBuilder jaasContent=new StringBuilder();
-        String newLine = System.getProperty("line.separator");
-        jaasContent.append("Server {");
-        jaasContent.append(newLine);
-        jaasContent.append("org.apache.zookeeper.server.auth.DigestLoginModule required");
-        jaasContent.append(newLine);
-        jaasContent.append("user_super=\"test\";");
-        jaasContent.append(newLine);
-        jaasContent.append("};");
-        jaasContent.append(newLine);
-        jaasContent.append("Client {");
-        jaasContent.append(newLine);
-        jaasContent.append("org.apache.zookeeper.server.auth.DigestLoginModule required");
-        jaasContent.append(newLine);
-        jaasContent.append("username=\"super\"");
-        jaasContent.append(newLine);
-        jaasContent.append("password=\"test\";");
-        jaasContent.append(newLine);
-        jaasContent.append("};");
-        jaasContent.append(newLine);
-        return jaasContent.toString();
-    }
-
-    @AfterClass
-    public static void clean() {
-        System.clearProperty("zookeeper.authProvider.1");
-        System.clearProperty("java.security.auth.login.config");
-    }
-
-    private AtomicInteger authFailed = new AtomicInteger(0);
-    
-    @Override
-    protected TestableZooKeeper createClient(String hp)
-    throws IOException, InterruptedException
-    {
-        MyWatcher watcher = new MyWatcher();
-        return createClient(watcher, hp);
-    }
-
-    private class MyWatcher extends CountdownWatcher {
-        @Override
-        public synchronized void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.AuthFailed) {
-                authFailed.incrementAndGet();
-            }
-            else {
-                super.process(event);
-            }
-        }
-    }
-
-    @Test
-    public void testAuth() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-            Thread.sleep(1000);
-        } finally {
-            zk.close();
-        }
-    }
-
-    @Test
-    public void testValidSaslIds() throws Exception {
-        ZooKeeper zk = createClient();
-
-        List<String> validIds = new ArrayList<String>();
-        validIds.add("user");
-        validIds.add("service/host.name.com");
-        validIds.add("user@KERB.REALM");
-        validIds.add("service/host.name.com@KERB.REALM");
-
-        int i = 0;
-        for(String validId: validIds) {
-            List<ACL> aclList = new ArrayList<ACL>();
-            ACL acl = new ACL(0,new Id("sasl",validId));
-            aclList.add(acl);
-            zk.create("/valid"+i,null,aclList,CreateMode.PERSISTENT);
-            i++;
-        }
-    }
-
-    @Test
-    public void testInvalidSaslIds() throws Exception {
-        ZooKeeper zk = createClient();
-
-        List<String> invalidIds = new ArrayList<String>();
-        invalidIds.add("user@KERB.REALM/server.com");
-        invalidIds.add("user@KERB.REALM1@KERB.REALM2");
-
-        int i = 0;
-        for(String invalidId: invalidIds) {
-            List<ACL> aclList = new ArrayList<ACL>();
-            try {
-                ACL acl = new ACL(0,new Id("sasl",invalidId));
-                aclList.add(acl);
-                zk.create("/invalid"+i,null,aclList,CreateMode.PERSISTENT);
-                Assert.fail("SASLAuthenticationProvider.isValid() failed to catch invalid Id.");
-            }
-            catch (KeeperException.InvalidACLException e) {
-                // ok.
-            }
-            finally {
-                i++;
-            }
-        }
-    }
-    
-    @Test
-    public void testZKOperationsAfterClientSaslAuthFailure() throws Exception {
-        CountdownWatcher watcher = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-        try {
-            setSaslFailureFlag(zk);
-
-            // try node creation for around 15 second,
-            int totalTry = 10;
-            int tryCount = 0;
-
-            boolean success = false;
-            while (!success && tryCount++ <= totalTry) {
-                try {
-                    zk.create("/saslAuthFail", "data".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                            CreateMode.PERSISTENT_SEQUENTIAL);
-                    success = true;
-                } catch (KeeperException.ConnectionLossException e) {
-                    Thread.sleep(1000);
-                    // do nothing
-                }
-            }
-            assertTrue("ZNode creation is failing continuously after Sasl auth failure.", success);
-
-        } finally {
-            zk.close();
-        }
-    }
-
-    // set saslLoginFailed to true to simulate the LoginException
-    private void setSaslFailureFlag(ZooKeeper zk) throws Exception {
-        Field cnxnField = zk.getClass().getDeclaredField("cnxn");
-        cnxnField.setAccessible(true);
-        ClientCnxn clientCnxn = (ClientCnxn) cnxnField.get(zk);
-        Field sendThreadField = clientCnxn.getClass().getDeclaredField("sendThread");
-        sendThreadField.setAccessible(true);
-        SendThread sendThread = (SendThread) sendThreadField.get(clientCnxn);
-        Field saslLoginFailedField = sendThread.getClass().getDeclaredField("saslLoginFailed");
-        saslLoginFailedField.setAccessible(true);
-        saslLoginFailedField.setBoolean(sendThread, true);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/ServerConfigTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/ServerConfigTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/ServerConfigTest.java
deleted file mode 100644
index 27faa74..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/ServerConfigTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.zookeeper.server.ServerConfig;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-
-public class ServerConfigTest {
-
-    private ServerConfig serverConfig;
-
-    @Before
-    public void setUp() {
-        serverConfig = new ServerConfig();
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testFewArguments() {
-        String[] args = {"2181"};
-        serverConfig.parse(args);
-    }
-
-    @Test
-    public void testValidArguments() {
-        String[] args = {"2181", "/data/dir", "60000", "10000"};
-        serverConfig.parse(args);
-
-        assertEquals(2181, serverConfig.getClientPortAddress().getPort());
-        assertTrue(checkEquality("/data/dir", serverConfig.getDataDir()));
-        assertEquals(60000, serverConfig.getTickTime());
-        assertEquals(10000, serverConfig.getMaxClientCnxns());
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testTooManyArguments() {
-        String[] args = {"2181", "/data/dir", "60000", "10000", "9999"};
-        serverConfig.parse(args);
-    }
-
-    boolean checkEquality(String a, String b) {
-        assertNotNull(a);
-        assertNotNull(b);
-        return a.equals(b);
-    }
-
-    boolean checkEquality(String a, File b) {
-        assertNotNull(a);
-        assertNotNull(b);
-        return new File(a).equals(b);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/TestableZooKeeper.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/TestableZooKeeper.java b/zookeeper-common/src/test/java/org/apache/zookeeper/TestableZooKeeper.java
deleted file mode 100644
index dd70056..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/TestableZooKeeper.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.jute.Record;
-import org.apache.zookeeper.proto.ReplyHeader;
-import org.apache.zookeeper.proto.RequestHeader;
-
-public class TestableZooKeeper extends ZooKeeper {
-
-    public TestableZooKeeper(String host, int sessionTimeout,
-            Watcher watcher) throws IOException {
-        super(host, sessionTimeout, watcher);
-    }
-    
-    @Override
-    public List<String> getChildWatches() {
-        return super.getChildWatches();
-    }
-
-
-    @Override
-    public List<String> getDataWatches() {
-        return super.getDataWatches();
-    }
-
-
-    @Override
-    public List<String> getExistWatches() {
-        return super.getExistWatches();
-    }
-
-    /**
-     * Cause this ZooKeeper object to disconnect from the server. It will then
-     * later attempt to reconnect.
-     */
-    public void testableConnloss() throws IOException {
-        synchronized(cnxn) {
-            cnxn.sendThread.testableCloseSocket();
-        }
-    }
-
-    /**
-     * Cause this ZooKeeper object to stop receiving from the ZooKeeperServer
-     * for the given number of milliseconds.
-     * @param ms the number of milliseconds to pause.
-     * @return true if the connection is paused, otherwise false
-     */
-    public boolean pauseCnxn(final long ms) {
-        final CountDownLatch initiatedPause = new CountDownLatch(1);
-        new Thread() {
-            public void run() {
-                synchronized(cnxn) {
-                    try {
-                        try {
-                            cnxn.sendThread.testableCloseSocket();
-                        } catch (IOException e) {
-                            e.printStackTrace();
-                        } finally {
-                            initiatedPause.countDown();
-                        }
-                        Thread.sleep(ms);
-                    } catch (InterruptedException e) {
-                    }
-                }
-            }
-        }.start();
-
-        try {
-            return initiatedPause.await(ms, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
-    
-    public boolean testableWaitForShutdown(int wait)
-        throws InterruptedException
-    {
-        return super.testableWaitForShutdown(wait);
-    }
-
-    public SocketAddress testableLocalSocketAddress() {
-        return super.testableLocalSocketAddress();
-    }
-
-    public SocketAddress testableRemoteSocketAddress() {
-        return super.testableRemoteSocketAddress();
-    }
-
-    /**
-     * @return the last zxid as seen by the client session
-     */
-    public long testableLastZxid() {
-        return cnxn.getLastZxid();
-    }
-
-    public ReplyHeader submitRequest(RequestHeader h, Record request,
-            Record response, WatchRegistration watchRegistration) throws InterruptedException {
-        return cnxn.submitRequest(h, request, response, watchRegistration);
-    }
-
-    /** Testing only!!! Really!!!! This is only here to test when the client
-     * disconnects from the server w/o sending a session disconnect (ie
-     * ending the session cleanly). The server will eventually notice the
-     * client is no longer pinging and will timeout the session.
-     */
-    public void disconnect() {
-        cnxn.disconnect();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/VerGenTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/VerGenTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/VerGenTest.java
deleted file mode 100644
index 607edbb..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/VerGenTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.apache.zookeeper.test.ClientBase;
-import org.apache.zookeeper.version.util.VerGen;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-
-/**
- * Test VerGen, used during the build.
- *
- */
-@RunWith(Parameterized.class)
-public class VerGenTest extends ZKTestCase {
-    @Parameters
-    public static Collection<Object[]> data() {
-            return Arrays.asList(new Object[][] {
-                            {"1.2.3", new Object[] {1, 2, 3, null}},
-                            {"1.2.3-dev", new Object[] {1, 2, 3, "dev"}},
-                            {"1.2.3-SNAPSHOT", new Object[] {1, 2, 3, "SNAPSHOT"}},
-                            {"1.2.3-SNAPSHOT", new Object[] {1, 2, 3, "SNAPSHOT"}},
-                            {"1.2.3-foo-bar+123", new Object[] {1, 2, 3, "foo-bar+123"}},
-                            {"1.2.3.4.5-SNAPSHOT", new Object[] {1, 2, 3, "SNAPSHOT"}},
-                            {"1.2.3.4.5-foo-bar+123", new Object[] {1, 2, 3, "foo-bar+123"}}
-            });
-    }
-
-    private String input;
-
-    private Object[] expected;
-
-    public VerGenTest(String input, Object[] expected) {
-        this.input = input;
-        this.expected = expected;
-    }
-
-    @Test
-    public void testParser() {
-        VerGen.Version v = VerGen.parseVersionString(input);
-        Assert.assertEquals(expected[0], v.maj);
-        Assert.assertEquals(expected[1], v.min);
-        Assert.assertEquals(expected[2], v.micro);
-        Assert.assertEquals(expected[3], v.qualifier);
-    }
-
-    @Test
-    public void testGenFile() throws Exception {
-        VerGen.Version v = VerGen.parseVersionString(input);
-        File outputDir = ClientBase.createTmpDir();
-        VerGen.generateFile(outputDir, v, "1", "Nov1");
-        ClientBase.recursiveDelete(outputDir);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/ZKTestCase.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/ZKTestCase.java b/zookeeper-common/src/test/java/org/apache/zookeeper/ZKTestCase.java
deleted file mode 100644
index 9098fc4..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/ZKTestCase.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.junit.Assume;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.junit.Rule;
-import org.junit.rules.MethodRule;
-import org.junit.rules.TestWatchman;
-import org.junit.runner.RunWith;
-import org.junit.runners.model.FrameworkMethod;
-
-import java.io.IOException;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-
-/**
- * Base class for a non-parameterized ZK test.
- *
- * Basic utilities shared by all tests. Also logging of various events during
- * the test execution (start/stop/success/failure/etc...)
- */
-@RunWith(JUnit4ZKTestRunner.class)
-public class ZKTestCase {
-    private static final Logger LOG = LoggerFactory.getLogger(ZKTestCase.class);
-
-    private String testName;
-
-    protected String getTestName() {
-        return testName;
-    }
-
-    @Rule
-    public MethodRule watchman = new TestWatchman() {
-        @Override
-        public void starting(FrameworkMethod method) {
-            testName = method.getName();
-            // ZOOKEEPER-2693 disables all 4lw by default.
-            // Here we enable the 4lw which ZooKeeper tests depends.
-            System.setProperty("zookeeper.4lw.commands.whitelist", "*");
-
-            LOG.info("STARTING " + testName);
-        }
-
-        @Override
-        public void finished(FrameworkMethod method) {
-            LOG.info("FINISHED " + testName);
-        }
-
-        @Override
-        public void succeeded(FrameworkMethod method) {
-            LOG.info("SUCCEEDED " + testName);
-        }
-
-        @Override
-        public void failed(Throwable e, FrameworkMethod method) {
-            LOG.info("FAILED " + testName, e);
-        }
-
-    };
-
-    protected void assumeIPv6Available() {
-        try {
-            InetAddress address = Inet6Address.getByName("0:0:0:0:0:0:0:1");
-            Assume.assumeTrue(address.isReachable(1000));
-        } catch (IOException exception) {
-            Assume.assumeTrue(false);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/ZooKeeperTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/ZooKeeperTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/ZooKeeperTest.java
deleted file mode 100644
index 2cdc4cb..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/ZooKeeperTest.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper;
-
-import static org.junit.Assert.*;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.test.ClientBase;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * 
- * Testing Zookeeper public methods
- *
- */
-public class ZooKeeperTest extends ClientBase {
-
-    @Test
-    public void testDeleteRecursive() throws IOException, InterruptedException,
-            KeeperException {
-        final ZooKeeper zk = createClient();
-        // making sure setdata works on /
-        zk.setData("/", "some".getBytes(), -1);
-        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b/v/1", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/c", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/c/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        List<String> children = zk.getChildren("/a", false);
-
-        Assert.assertEquals("2 children - b & c should be present ", children
-                .size(), 2);
-        Assert.assertTrue(children.contains("b"));
-        Assert.assertTrue(children.contains("c"));
-
-        ZKUtil.deleteRecursive(zk, "/a");
-        Assert.assertNull(zk.exists("/a", null));
-    }
-
-    @Test
-    public void testDeleteRecursiveAsync() throws IOException,
-            InterruptedException, KeeperException {
-        final ZooKeeper zk = createClient();
-        // making sure setdata works on /
-        zk.setData("/", "some".getBytes(), -1);
-        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b/v/1", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/c", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/c/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        for (int i = 0; i < 50; ++i) {
-            zk.create("/a/c/" + i, "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        }
-        List<String> children = zk.getChildren("/a", false);
-
-        Assert.assertEquals("2 children - b & c should be present ", children
-                .size(), 2);
-        Assert.assertTrue(children.contains("b"));
-        Assert.assertTrue(children.contains("c"));
-
-        VoidCallback cb = new VoidCallback() {
-
-            @Override
-            public void processResult(int rc, String path, Object ctx) {
-                synchronized (ctx) {
-                    ((AtomicInteger) ctx).set(4);
-                    ctx.notify();
-                }
-            }
-
-        };
-        final AtomicInteger ctx = new AtomicInteger(3);
-        ZKUtil.deleteRecursive(zk, "/a", cb, ctx);
-        synchronized (ctx) {
-            ctx.wait();
-        }
-        Assert.assertEquals(4, ((AtomicInteger) ctx).get());
-    }
-    
-    @Test
-    public void testStatWhenPathDoesNotExist() throws IOException,
-    		InterruptedException {
-    	final ZooKeeper zk = createClient();
-    	ZooKeeperMain main = new ZooKeeperMain(zk);
-    	String cmdstring = "stat /invalidPath";
-    	main.cl.parseCommand(cmdstring);
-    	try {
-    		main.processZKCmd(main.cl);
-    		Assert.fail("As Node does not exist, command should fail by throwing No Node Exception.");
-    	} catch (KeeperException e) {
-    		Assert.assertEquals("KeeperErrorCode = NoNode for /invalidPath", e.getMessage());
-    	}
-    }
-
-    @Test
-    public void testParseWithExtraSpaces() throws Exception {
-        final ZooKeeper zk = createClient();
-        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-        String cmdstring = "      ls       /  ";
-        zkMain.cl.parseCommand(cmdstring);
-        Assert.assertEquals("Spaces also considered as characters", zkMain.cl.getNumArguments(), 2);
-        Assert.assertEquals("ls is not taken as first argument", zkMain.cl.getCmdArgument(0), "ls");
-        Assert.assertEquals("/ is not taken as second argument", zkMain.cl.getCmdArgument(1), "/");
-    }
-
-    @Test
-    public void testCheckInvalidAcls() throws Exception {
-         final ZooKeeper zk = createClient();
-            ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-            String cmdstring = "create -s -e /node data ip:scheme:gggsd"; //invalid acl's
-            try{
-                 zkMain.executeLine(cmdstring);
-            }catch(KeeperException.InvalidACLException e){
-                fail("For Invalid ACls should not throw exception");
-            }
-    }
-
-    @Test
-    public void testDeleteWithInvalidVersionNo() throws Exception {
-         final ZooKeeper zk = createClient();
-            ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-            String cmdstring = "create -s -e /node1 data "; 
-            String cmdstring1 = "delete /node1 2";//invalid dataversion no
-                 zkMain.executeLine(cmdstring);
-           try{
-               zkMain.executeLine(cmdstring1);
-                     
-            }catch(KeeperException.BadVersionException e){
-                fail("For Invalid dataversion number should not throw exception");
-            }
-    }
-
-    @Test
-    public void testCliCommandsNotEchoingUsage() throws Exception {
-            // setup redirect out/err streams to get System.in/err, use this judiciously!
-           final PrintStream systemErr = System.err; // get current err
-           final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
-           System.setErr(new PrintStream(errContent));
-           final ZooKeeper zk = createClient();
-           ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-           String cmd1 = "printwatches";
-           zkMain.executeLine(cmd1);
-           String cmd2 = "history";
-           zkMain.executeLine(cmd2);
-           String cmd3 = "redo";
-           zkMain.executeLine(cmd3);
-           // revert redirect of out/err streams - important step!
-           System.setErr(systemErr);
-           if (errContent.toString().contains("ZooKeeper -server host:port cmd args")) {
-                fail("CLI commands (history, redo, connect, printwatches) display usage info!");
-            }
-    }
-
-     @Test
-    public void testParseWithQuotes() throws Exception {
-        final ZooKeeper zk = createClient();
-        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-        for (String quoteChar : new String[] {"'", "\""}) {
-            String cmdstring = String.format("create /node %1$squoted data%1$s", quoteChar);
-            zkMain.cl.parseCommand(cmdstring);
-            Assert.assertEquals("quotes combine arguments", zkMain.cl.getNumArguments(), 3);
-            Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
-            Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
-            Assert.assertEquals("quoted data is not taken as third argument", zkMain.cl.getCmdArgument(2), "quoted data");
-        }
-    }
-
-    @Test
-    public void testParseWithMixedQuotes() throws Exception {
-        final ZooKeeper zk = createClient();
-        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-        for (String[] quoteChars : new String[][] {{"'", "\""}, {"\"", "'"}}) {
-            String outerQuotes = quoteChars[0];
-            String innerQuotes = quoteChars[1];
-            String cmdstring = String.format("create /node %1$s%2$squoted data%2$s%1$s", outerQuotes, innerQuotes);
-            zkMain.cl.parseCommand(cmdstring);
-            Assert.assertEquals("quotes combine arguments", zkMain.cl.getNumArguments(), 3);
-            Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
-            Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
-            Assert.assertEquals("quoted data is not taken as third argument", zkMain.cl.getCmdArgument(2), innerQuotes + "quoted data" + innerQuotes);
-        }
-    }
-
-    @Test
-    public void testParseWithEmptyQuotes() throws Exception {
-        final ZooKeeper zk = createClient();
-        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-        String cmdstring = "create /node ''";
-        zkMain.cl.parseCommand(cmdstring);
-        Assert.assertEquals("empty quotes should produce arguments", zkMain.cl.getNumArguments(), 3);
-        Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
-        Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
-        Assert.assertEquals("empty string is not taken as third argument", zkMain.cl.getCmdArgument(2), "");
-    }
-
-    @Test
-    public void testParseWithMultipleQuotes() throws Exception {
-        final ZooKeeper zk = createClient();
-        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-        String cmdstring = "create /node '' ''";
-        zkMain.cl.parseCommand(cmdstring);
-        Assert.assertEquals("expected 5 arguments", zkMain.cl.getNumArguments(), 4);
-        Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
-        Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
-        Assert.assertEquals("empty string is not taken as third argument", zkMain.cl.getCmdArgument(2), "");
-        Assert.assertEquals("empty string is not taken as fourth argument", zkMain.cl.getCmdArgument(3), "");
-    }
-
-    // ZOOKEEPER-2467 : Testing negative number for redo command
-    @Test
-    public void testRedoWithNegativeCmdNumber() throws Exception {
-        final ZooKeeper zk = createClient();
-        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
-        String cmd1 = "redo -1";
-
-        // setup redirect out/err streams to get System.in/err, use this
-        // judiciously!
-        final PrintStream systemOut = System.out; // get current out
-        final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
-        System.setOut(new PrintStream(outContent));
-        try {
-            zkMain.executeLine(cmd1);
-            Assert.assertEquals("Command index out of range", outContent
-                    .toString().trim());
-        } finally {
-            // revert redirect of out/err streams - important step!
-            System.setOut(systemOut);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/common/TimeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/common/TimeTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/common/TimeTest.java
deleted file mode 100644
index d938556..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/common/TimeTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.common;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.test.ClientBase;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Command line program for demonstrating robustness to clock
- * changes.
- * <p/>
- * How to run:
- * ant clean compile-test
- * echo build/test/lib/*.jar build/lib/*.jar build/classes build/test/classes | sed -e 's/ /:/g' > cp
- * java -cp $(cat cp) org.apache.zookeeper.common.TimeTest | tee log-without-patch
- * <p/>
- * After test program starts, in another window, do commands:
- * date -s '+1hour'
- * date -s '-1hour'
- * <p/>
- * As long as there isn't any expired event, the experiment is successful.
- */
-public class TimeTest extends ClientBase {
-    private static final long mt0 = System.currentTimeMillis();
-    private static final long nt0 = Time.currentElapsedTime();
-
-    private static AtomicInteger watchCount = new AtomicInteger(0);
-
-
-    public static void main(String[] args) throws Exception {
-        System.out.printf("Starting\n");
-        final TimeTest test = new TimeTest();
-        System.out.printf("After construct\n");
-        test.setUp();
-        ZooKeeper zk = test.createClient();
-        zk.create("/ephemeral", new byte[]{1, 2, 3},
-                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-        while (Time.currentElapsedTime() - nt0 < 100000) {
-            System.out.printf("%d\t%s\n", discrepancy(),
-                    zk.exists("/ephemeral",
-                            watchCount.get() == 0 ? createWatcher() : null) != null);
-            waitByYielding(500);
-        }
-    }
-
-    private static Watcher createWatcher() {
-        watchCount.incrementAndGet();
-        return new Watcher() {
-            @Override
-            public void process(WatchedEvent event) {
-                watchCount.decrementAndGet();
-                System.out.printf("%d event = %s\n", discrepancy(), event);
-            }
-        };
-
-    }
-
-    private static void waitByYielding(long delay) {
-        long t0 = Time.currentElapsedTime();
-        while (Time.currentElapsedTime() < t0 + delay) {
-            Thread.yield();
-        }
-    }
-
-    private static long discrepancy() {
-        return (System.currentTimeMillis() - mt0) - (Time.currentElapsedTime() - nt0);
-    }
-
-    @Test
-    public void testElapsedTimeToDate() throws Exception {
-        long walltime = Time.currentWallTime();
-        long elapsedTime = Time.currentElapsedTime();
-        Thread.sleep(200);
-
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(Time.elapsedTimeToDate(elapsedTime));
-        int calculatedDate = cal.get(Calendar.HOUR_OF_DAY);
-        cal.setTime(new Date(walltime));
-        int realDate = cal.get(Calendar.HOUR_OF_DAY);
-
-        Assert.assertEquals(calculatedDate, realDate);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLCountTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLCountTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLCountTest.java
deleted file mode 100644
index 88b8869..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLCountTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.concurrent.CountDownLatch;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ACLCountTest extends ZKTestCase implements Watcher {
-    private static final Logger LOG = LoggerFactory.getLogger(ACLTest.class);
-    private static final String HOSTPORT =
-        "127.0.0.1:" + PortAssignment.unique();
-    private volatile CountDownLatch startSignal;
-
-    /**
-     *
-     * Create a node and add 4 ACL values to it, but there are only 2 unique ACL values,
-     * and each is repeated once:
-     *
-     *   ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE);
-     *   ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS);
-     *   ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE);
-     *   ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS);
-     *
-     * Even though we've added 4 ACL values, there should only be 2 ACLs for that node,
-     * since there are only 2 *unique* ACL values.
-     */
-    @Test
-    public void testAclCount() throws Exception {
-        File tmpDir = ClientBase.createTmpDir();
-        ClientBase.setupTestEnv();
-        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-        SyncRequestProcessor.setSnapCount(1000);
-        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-        f.startup(zks);
-        ZooKeeper zk;
-
-        final ArrayList<ACL> CREATOR_ALL_AND_WORLD_READABLE =
-          new ArrayList<ACL>() { {
-            add(new ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE));
-            add(new ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS));
-            add(new ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE));
-            add(new ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS));
-        }};
-
-        try {
-            LOG.info("starting up the zookeeper server .. waiting");
-            Assert.assertTrue("waiting for server being up",
-                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
-            zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
-
-            zk.addAuthInfo("digest", "pat:test".getBytes());
-            zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
-
-            String path = "/path";
-
-            try {
-              Assert.assertEquals(4,CREATOR_ALL_AND_WORLD_READABLE.size());
-            }
-            catch (Exception e) {
-              LOG.error("Something is fundamentally wrong with ArrayList's add() method. add()ing four times to an empty ArrayList should result in an ArrayList with 4 members.");
-              throw e;
-            }
-
-            zk.create(path,path.getBytes(),CREATOR_ALL_AND_WORLD_READABLE,CreateMode.PERSISTENT);
-            List<ACL> acls = zk.getACL("/path", new Stat());
-            Assert.assertEquals(2,acls.size());
-        }
-        catch (Exception e) {
-          // test failed somehow.
-          Assert.assertTrue(false);
-        }
-
-        f.shutdown();
-        zks.shutdown();
-    }
-
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatcherEvent)
-     */
-    public void process(WatchedEvent event) {
-        LOG.info("Event:" + event.getState() + " " + event.getType() + " "
-                 + event.getPath());
-        if (event.getState() == KeeperState.SyncConnected) {
-            if (startSignal != null && startSignal.getCount() > 0) {
-                LOG.info("startsignal.countDown()");
-                startSignal.countDown();
-            } else {
-                LOG.warn("startsignal " + startSignal);
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLRootTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
deleted file mode 100644
index 7307cbf..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ACLRootTest extends ClientBase {
-    private static final Logger LOG = LoggerFactory.getLogger(ACLRootTest.class);
-
-    @Test
-    public void testRootAcl() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            // set auth using digest
-            zk.addAuthInfo("digest", "pat:test".getBytes());
-            zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
-            zk.getData("/", false, null);
-            zk.close();
-            // verify no access
-            zk = createClient();
-            try {
-                zk.getData("/", false, null);
-                Assert.fail("validate auth");
-            } catch (KeeperException.NoAuthException e) {
-                // expected
-            }
-            try {
-                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
-                        CreateMode.PERSISTENT);
-                Assert.fail("validate auth");
-            } catch (KeeperException.InvalidACLException e) {
-                // expected
-            }
-            zk.addAuthInfo("digest", "world:anyone".getBytes());
-            try {
-                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
-                        CreateMode.PERSISTENT);
-                Assert.fail("validate auth");
-            } catch (KeeperException.NoAuthException e) {
-                // expected
-            }
-            zk.close();
-            // verify access using original auth
-            zk = createClient();
-            zk.addAuthInfo("digest", "pat:test".getBytes());
-            zk.getData("/", false, null);
-            zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
-                    CreateMode.PERSISTENT);
-            zk.delete("/apps", -1);
-            // reset acl (back to open) and verify accessible again
-            zk.setACL("/", Ids.OPEN_ACL_UNSAFE, -1);
-            zk.close();
-            zk = createClient();
-            zk.getData("/", false, null);
-            zk.create("/apps", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            try {
-                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
-                        CreateMode.PERSISTENT);
-                Assert.fail("validate auth");
-            } catch (KeeperException.InvalidACLException e) {
-                // expected
-            }
-            zk.delete("/apps", -1);
-            zk.addAuthInfo("digest", "world:anyone".getBytes());
-            zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
-                    CreateMode.PERSISTENT);
-            zk.close();
-            zk = createClient();
-            zk.delete("/apps", -1);
-        } finally {
-            zk.close();
-        }
-    }
-}


[36/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Author: Norbert Kalmar <nk...@yahoo.com>

Reviewers: andor@apache.org

Closes #675 from nkalmar/ZOOKEEPER-3032r-3.4


Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo
Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/7291e47c
Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/7291e47c
Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/7291e47c

Branch: refs/heads/branch-3.4
Commit: 7291e47cb8a41f369a41e30e16f7780d419fb832
Parents: f0c8683
Author: Norbert Kalmar <nk...@yahoo.com>
Authored: Wed Oct 24 11:32:09 2018 +0200
Committer: Andor Molnar <an...@apache.org>
Committed: Wed Oct 24 11:32:09 2018 +0200

----------------------------------------------------------------------
 .gitignore                                      |    4 +-
 bin/zkEnv.sh                                    |    2 +-
 build.xml                                       |  115 +-
 .../zookeeper-client-c/tests/zkServer.sh        |    2 +-
 .../zookeeper/client/ConnectStringParser.java   |   87 -
 .../zookeeper/client/FourLetterWordMain.java    |  107 -
 .../apache/zookeeper/client/HostProvider.java   |   66 -
 .../zookeeper/client/StaticHostProvider.java    |  179 --
 .../zookeeper/client/ZooKeeperSaslClient.java   |  439 ---
 .../org/apache/zookeeper/AsyncCallback.java     |  309 --
 .../java/org/apache/zookeeper/ClientCnxn.java   | 1481 ----------
 .../org/apache/zookeeper/ClientCnxnSocket.java  |  175 --
 .../apache/zookeeper/ClientCnxnSocketNIO.java   |  431 ---
 .../apache/zookeeper/ClientWatchManager.java    |   40 -
 .../java/org/apache/zookeeper/CreateMode.java   |   94 -
 .../java/org/apache/zookeeper/Environment.java  |  103 -
 .../org/apache/zookeeper/KeeperException.java   |  728 -----
 .../main/java/org/apache/zookeeper/Login.java   |  407 ---
 .../org/apache/zookeeper/MultiResponse.java     |  166 --
 .../zookeeper/MultiTransactionRecord.java       |  160 --
 .../src/main/java/org/apache/zookeeper/Op.java  |  351 ---
 .../java/org/apache/zookeeper/OpResult.java     |  185 --
 .../main/java/org/apache/zookeeper/Quotas.java  |   68 -
 .../zookeeper/SaslClientCallbackHandler.java    |  104 -
 .../org/apache/zookeeper/ServerAdminClient.java |  316 --
 .../main/java/org/apache/zookeeper/Shell.java   |  477 ---
 .../java/org/apache/zookeeper/StatsTrack.java   |  101 -
 .../java/org/apache/zookeeper/Testable.java     |   29 -
 .../java/org/apache/zookeeper/Transaction.java  |   70 -
 .../main/java/org/apache/zookeeper/Version.java |   90 -
 .../java/org/apache/zookeeper/WatchedEvent.java |   81 -
 .../main/java/org/apache/zookeeper/Watcher.java |  155 -
 .../main/java/org/apache/zookeeper/ZKUtil.java  |  124 -
 .../main/java/org/apache/zookeeper/ZooDefs.java |  125 -
 .../java/org/apache/zookeeper/ZooKeeper.java    | 1857 ------------
 .../org/apache/zookeeper/ZooKeeperMain.java     |  871 ------
 .../org/apache/zookeeper/ZooKeeperTestable.java |   47 -
 .../common/AtomicFileOutputStream.java          |  126 -
 .../org/apache/zookeeper/common/IOUtils.java    |  123 -
 .../org/apache/zookeeper/common/PathTrie.java   |  293 --
 .../org/apache/zookeeper/common/PathUtils.java  |  103 -
 .../java/org/apache/zookeeper/common/Time.java  |   52 -
 .../apache/zookeeper/util/SecurityUtils.java    |  298 --
 .../apache/zookeeper/version/util/VerGen.java   |  178 --
 .../src/main/resources/lib/cobertura/README.txt |    3 -
 .../resources/lib/jdiff/zookeeper_3.1.1.xml     | 2717 ------------------
 .../main/resources/lib/log4j-1.2.17.LICENSE.txt |  202 --
 .../main/resources/lib/slf4j-1.7.25.LICENSE.txt |   24 -
 .../apache/zookeeper/ClientReconnectTest.java   |   78 -
 .../apache/zookeeper/JUnit4ZKTestRunner.java    |   86 -
 .../org/apache/zookeeper/JaasConfiguration.java |   75 -
 .../java/org/apache/zookeeper/MockPacket.java   |   46 -
 .../org/apache/zookeeper/MultiResponseTest.java |   72 -
 .../zookeeper/MultiTransactionRecordTest.java   |   68 -
 .../org/apache/zookeeper/PortAssignment.java    |   35 -
 .../java/org/apache/zookeeper/SaslAuthTest.java |  213 --
 .../org/apache/zookeeper/ServerConfigTest.java  |   74 -
 .../org/apache/zookeeper/TestableZooKeeper.java |  133 -
 .../java/org/apache/zookeeper/VerGenTest.java   |   78 -
 .../java/org/apache/zookeeper/ZKTestCase.java   |   88 -
 .../org/apache/zookeeper/ZooKeeperTest.java     |  281 --
 .../org/apache/zookeeper/common/TimeTest.java   |  109 -
 .../org/apache/zookeeper/test/ACLCountTest.java |  136 -
 .../org/apache/zookeeper/test/ACLRootTest.java  |   98 -
 .../java/org/apache/zookeeper/test/ACLTest.java |  186 --
 .../apache/zookeeper/test/AsyncHammerTest.java  |  245 --
 .../org/apache/zookeeper/test/AsyncOps.java     |  655 -----
 .../org/apache/zookeeper/test/AsyncOpsTest.java |  227 --
 .../org/apache/zookeeper/test/AsyncTest.java    |  172 --
 .../test/AtomicFileOutputStreamTest.java        |  200 --
 .../org/apache/zookeeper/test/AuthTest.java     |  174 --
 .../apache/zookeeper/test/BufferSizeTest.java   |  132 -
 .../apache/zookeeper/test/ChrootAsyncTest.java  |   47 -
 .../apache/zookeeper/test/ChrootClientTest.java |   54 -
 .../org/apache/zookeeper/test/ChrootTest.java   |  136 -
 .../org/apache/zookeeper/test/ClientBase.java   |  757 -----
 .../apache/zookeeper/test/ClientHammerTest.java |  246 --
 .../zookeeper/test/ClientPortBindTest.java      |  127 -
 .../org/apache/zookeeper/test/ClientRetry.java  |   72 -
 .../org/apache/zookeeper/test/ClientTest.java   |  805 ------
 .../zookeeper/test/ConnectStringParserTest.java |   68 -
 .../apache/zookeeper/test/CreateModeTest.java   |   81 -
 .../zookeeper/test/DisconnectableZooKeeper.java |   58 -
 .../zookeeper/test/DisconnectedWatcherTest.java |  258 --
 .../apache/zookeeper/test/EventTypeTest.java    |   50 -
 .../apache/zookeeper/test/FLENewEpochTest.java  |  192 --
 .../apache/zookeeper/test/FLEPredicateTest.java |  104 -
 .../apache/zookeeper/test/FLERestartTest.java   |  203 --
 .../java/org/apache/zookeeper/test/FLETest.java |  473 ---
 .../zookeeper/test/FLEZeroWeightTest.java       |  181 --
 .../test/FollowerResyncConcurrencyTest.java     |  607 ----
 .../org/apache/zookeeper/test/FollowerTest.java |  140 -
 .../test/FourLetterWordsQuorumTest.java         |  113 -
 .../zookeeper/test/FourLetterWordsTest.java     |  238 --
 .../test/FourLetterWordsWhiteListTest.java      |  253 --
 .../apache/zookeeper/test/GetChildren2Test.java |  136 -
 .../zookeeper/test/HierarchicalQuorumTest.java  |  309 --
 .../apache/zookeeper/test/IntegrityCheck.java   |  232 --
 .../zookeeper/test/InvalidSnapshotTest.java     |  125 -
 .../java/org/apache/zookeeper/test/JMXEnv.java  |  325 ---
 .../apache/zookeeper/test/KeeperStateTest.java  |   76 -
 .../zookeeper/test/LENonTerminateTest.java      |  378 ---
 .../java/org/apache/zookeeper/test/LETest.java  |  137 -
 .../zookeeper/test/LoadFromLogNoServerTest.java |  175 --
 .../apache/zookeeper/test/LoadFromLogTest.java  |  223 --
 .../org/apache/zookeeper/test/MaxCnxnsTest.java |  139 -
 .../zookeeper/test/MultiTransactionTest.java    |  805 ------
 .../zookeeper/test/NioNettySuiteBase.java       |   43 -
 .../zookeeper/test/NioNettySuiteHammerTest.java |   30 -
 .../zookeeper/test/NioNettySuiteTest.java       |   37 -
 .../zookeeper/test/NonRecoverableErrorTest.java |  183 --
 .../org/apache/zookeeper/test/NullDataTest.java |   75 -
 .../java/org/apache/zookeeper/test/OOMTest.java |  161 --
 .../org/apache/zookeeper/test/OSMXBeanTest.java |   70 -
 .../test/ObserverHierarchicalQuorumTest.java    |   43 -
 .../apache/zookeeper/test/ObserverLETest.java   |   76 -
 .../test/ObserverQuorumHammerTest.java          |   39 -
 .../org/apache/zookeeper/test/ObserverTest.java |  233 --
 .../org/apache/zookeeper/test/QuorumBase.java   |  341 ---
 .../apache/zookeeper/test/QuorumHammerTest.java |   51 -
 .../apache/zookeeper/test/QuorumQuotaTest.java  |   63 -
 .../org/apache/zookeeper/test/QuorumTest.java   |  296 --
 .../org/apache/zookeeper/test/QuorumUtil.java   |  261 --
 .../zookeeper/test/QuorumZxidSyncTest.java      |  171 --
 .../apache/zookeeper/test/ReadOnlyModeTest.java |  291 --
 .../org/apache/zookeeper/test/RecoveryTest.java |  209 --
 .../zookeeper/test/RepeatStartupTest.java       |   69 -
 .../zookeeper/test/RestoreCommittedLogTest.java |   91 -
 .../test/SaslAuthDesignatedClientTest.java      |  104 -
 .../test/SaslAuthDesignatedServerTest.java      |  104 -
 .../test/SaslAuthFailDesignatedClientTest.java  |  108 -
 .../zookeeper/test/SaslAuthFailNotifyTest.java  |   98 -
 .../apache/zookeeper/test/SaslAuthFailTest.java |   76 -
 .../test/SaslAuthMissingClientConfigTest.java   |   97 -
 .../apache/zookeeper/test/SaslClientTest.java   |   62 -
 .../zookeeper/test/SessionInvalidationTest.java |  105 -
 .../org/apache/zookeeper/test/SessionTest.java  |  394 ---
 .../zookeeper/test/SessionTimeoutTest.java      |  129 -
 .../org/apache/zookeeper/test/SledgeHammer.java |  115 -
 .../apache/zookeeper/test/StandaloneTest.java   |   65 -
 .../org/apache/zookeeper/test/StatTest.java     |  205 --
 .../zookeeper/test/StaticHostProviderTest.java  |  362 ---
 .../org/apache/zookeeper/test/SyncCallTest.java |  108 -
 .../org/apache/zookeeper/test/TestHammer.java   |   63 -
 .../org/apache/zookeeper/test/TestUtils.java    |   60 -
 .../org/apache/zookeeper/test/TruncateTest.java |  256 --
 .../org/apache/zookeeper/test/UpgradeTest.java  |  105 -
 .../zookeeper/test/WatchEventWhenAutoReset.java |  212 --
 .../apache/zookeeper/test/WatchedEventTest.java |   95 -
 .../apache/zookeeper/test/WatcherFuncTest.java  |  478 ---
 .../org/apache/zookeeper/test/WatcherTest.java  |  408 ---
 .../test/ZkDatabaseCorruptionTest.java          |  161 --
 .../zookeeper/test/ZooKeeperQuotaTest.java      |   85 -
 .../zookeeper/test/ZooKeeperTestClient.java     |  422 ---
 .../src/test/resources/check_compatibility.py   |  204 --
 .../resources/checkstyle-noframes-sorted.xsl    |  178 --
 .../src/test/resources/checkstyle.xml           |  187 --
 .../data/buffersize/create/version-2/log.1      |  Bin 51216 -> 0 bytes
 .../data/buffersize/create/version-2/snapshot.0 |  Bin 296 -> 0 bytes
 .../data/buffersize/set/version-2/log.1         |  Bin 51216 -> 0 bytes
 .../data/buffersize/set/version-2/snapshot.0    |  Bin 296 -> 0 bytes
 .../data/buffersize/snapshot/version-2/log.1    |  Bin 51216 -> 0 bytes
 .../buffersize/snapshot/version-2/snapshot.0    |  Bin 296 -> 0 bytes
 .../buffersize/snapshot/version-2/snapshot.2    |  Bin 5429 -> 0 bytes
 .../resources/data/invalidsnap/version-2/log.1  |  Bin 59360 -> 0 bytes
 .../data/invalidsnap/version-2/log.274          |  Bin 91616 -> 0 bytes
 .../resources/data/invalidsnap/version-2/log.42 |  Bin 184 -> 0 bytes
 .../data/invalidsnap/version-2/log.63b          |  Bin 49008 -> 0 bytes
 .../data/invalidsnap/version-2/snapshot.0       |  Bin 296 -> 0 bytes
 .../data/invalidsnap/version-2/snapshot.272     |  Bin 56408 -> 0 bytes
 .../data/invalidsnap/version-2/snapshot.273     |  Bin 56521 -> 0 bytes
 .../data/invalidsnap/version-2/snapshot.639     |  Bin 143163 -> 0 bytes
 .../data/invalidsnap/version-2/snapshot.83f     |  Bin 4824 -> 0 bytes
 .../resources/data/kerberos/minikdc-krb5.conf   |   30 -
 .../test/resources/data/kerberos/minikdc.ldiff  |   52 -
 .../test/resources/data/upgrade/log.100000001   |  Bin 2458624 -> 0 bytes
 .../test/resources/data/upgrade/log.100001bf0   |  Bin 1025024 -> 0 bytes
 .../resources/data/upgrade/snapshot.100000000   |  Bin 73 -> 0 bytes
 .../resources/data/upgrade/snapshot.100001bec   |  Bin 2567595 -> 0 bytes
 .../src/test/resources/findbugsExcludeFile.xml  |  166 --
 .../src/test/resources/test-github-pr.sh        |  616 ----
 .../src/test/resources/test-patch.properties    |   18 -
 .../src/test/resources/test-patch.sh            |  637 ----
 zookeeper-contrib/build-contrib.xml             |    4 +-
 .../zookeeper-contrib-fatjar/build.xml          |    2 +-
 .../zookeeper-contrib-rest/build.xml            |    4 +-
 .../zookeeper-contrib-rest/src/test/zkServer.sh |    2 +-
 .../src/test/zkServer.sh                        |    2 +-
 zookeeper-recipes/build-recipes.xml             |    2 +-
 .../src/main/c/tests/zkServer.sh                |    2 +-
 .../src/main/c/tests/zkServer.sh                |    2 +-
 .../org/apache/zookeeper/AsyncCallback.java     |  309 ++
 .../java/org/apache/zookeeper/ClientCnxn.java   | 1481 ++++++++++
 .../org/apache/zookeeper/ClientCnxnSocket.java  |  175 ++
 .../apache/zookeeper/ClientCnxnSocketNIO.java   |  431 +++
 .../apache/zookeeper/ClientWatchManager.java    |   40 +
 .../java/org/apache/zookeeper/CreateMode.java   |   94 +
 .../java/org/apache/zookeeper/Environment.java  |  103 +
 .../org/apache/zookeeper/KeeperException.java   |  728 +++++
 .../main/java/org/apache/zookeeper/Login.java   |  407 +++
 .../org/apache/zookeeper/MultiResponse.java     |  166 ++
 .../zookeeper/MultiTransactionRecord.java       |  160 ++
 .../src/main/java/org/apache/zookeeper/Op.java  |  351 +++
 .../java/org/apache/zookeeper/OpResult.java     |  185 ++
 .../main/java/org/apache/zookeeper/Quotas.java  |   68 +
 .../zookeeper/SaslClientCallbackHandler.java    |  104 +
 .../org/apache/zookeeper/ServerAdminClient.java |  316 ++
 .../main/java/org/apache/zookeeper/Shell.java   |  477 +++
 .../java/org/apache/zookeeper/StatsTrack.java   |  101 +
 .../java/org/apache/zookeeper/Testable.java     |   29 +
 .../java/org/apache/zookeeper/Transaction.java  |   70 +
 .../main/java/org/apache/zookeeper/Version.java |   90 +
 .../java/org/apache/zookeeper/WatchedEvent.java |   81 +
 .../main/java/org/apache/zookeeper/Watcher.java |  155 +
 .../main/java/org/apache/zookeeper/ZKUtil.java  |  124 +
 .../main/java/org/apache/zookeeper/ZooDefs.java |  125 +
 .../java/org/apache/zookeeper/ZooKeeper.java    | 1857 ++++++++++++
 .../org/apache/zookeeper/ZooKeeperMain.java     |  871 ++++++
 .../org/apache/zookeeper/ZooKeeperTestable.java |   47 +
 .../zookeeper/client/ConnectStringParser.java   |   87 +
 .../zookeeper/client/FourLetterWordMain.java    |  107 +
 .../apache/zookeeper/client/HostProvider.java   |   66 +
 .../zookeeper/client/StaticHostProvider.java    |  179 ++
 .../zookeeper/client/ZooKeeperSaslClient.java   |  439 +++
 .../common/AtomicFileOutputStream.java          |  126 +
 .../org/apache/zookeeper/common/IOUtils.java    |  123 +
 .../org/apache/zookeeper/common/PathTrie.java   |  293 ++
 .../org/apache/zookeeper/common/PathUtils.java  |  103 +
 .../java/org/apache/zookeeper/common/Time.java  |   52 +
 .../apache/zookeeper/util/SecurityUtils.java    |  298 ++
 .../apache/zookeeper/version/util/VerGen.java   |  178 ++
 .../src/main/resources/lib/cobertura/README.txt |    3 +
 .../resources/lib/jdiff/zookeeper_3.1.1.xml     | 2717 ++++++++++++++++++
 .../main/resources/lib/log4j-1.2.17.LICENSE.txt |  202 ++
 .../main/resources/lib/slf4j-1.7.25.LICENSE.txt |   24 +
 .../apache/zookeeper/ClientReconnectTest.java   |   78 +
 .../apache/zookeeper/JUnit4ZKTestRunner.java    |   86 +
 .../org/apache/zookeeper/JaasConfiguration.java |   75 +
 .../java/org/apache/zookeeper/MockPacket.java   |   46 +
 .../org/apache/zookeeper/MultiResponseTest.java |   72 +
 .../zookeeper/MultiTransactionRecordTest.java   |   68 +
 .../org/apache/zookeeper/PortAssignment.java    |   35 +
 .../java/org/apache/zookeeper/SaslAuthTest.java |  213 ++
 .../org/apache/zookeeper/ServerConfigTest.java  |   74 +
 .../org/apache/zookeeper/TestableZooKeeper.java |  133 +
 .../java/org/apache/zookeeper/VerGenTest.java   |   78 +
 .../java/org/apache/zookeeper/ZKTestCase.java   |   88 +
 .../org/apache/zookeeper/ZooKeeperTest.java     |  281 ++
 .../org/apache/zookeeper/common/TimeTest.java   |  109 +
 .../org/apache/zookeeper/test/ACLCountTest.java |  136 +
 .../org/apache/zookeeper/test/ACLRootTest.java  |   98 +
 .../java/org/apache/zookeeper/test/ACLTest.java |  186 ++
 .../apache/zookeeper/test/AsyncHammerTest.java  |  245 ++
 .../org/apache/zookeeper/test/AsyncOps.java     |  655 +++++
 .../org/apache/zookeeper/test/AsyncOpsTest.java |  227 ++
 .../org/apache/zookeeper/test/AsyncTest.java    |  172 ++
 .../test/AtomicFileOutputStreamTest.java        |  200 ++
 .../org/apache/zookeeper/test/AuthTest.java     |  174 ++
 .../apache/zookeeper/test/BufferSizeTest.java   |  132 +
 .../apache/zookeeper/test/ChrootAsyncTest.java  |   47 +
 .../apache/zookeeper/test/ChrootClientTest.java |   54 +
 .../org/apache/zookeeper/test/ChrootTest.java   |  136 +
 .../org/apache/zookeeper/test/ClientBase.java   |  757 +++++
 .../apache/zookeeper/test/ClientHammerTest.java |  246 ++
 .../zookeeper/test/ClientPortBindTest.java      |  127 +
 .../org/apache/zookeeper/test/ClientRetry.java  |   72 +
 .../org/apache/zookeeper/test/ClientTest.java   |  805 ++++++
 .../zookeeper/test/ConnectStringParserTest.java |   68 +
 .../apache/zookeeper/test/CreateModeTest.java   |   81 +
 .../zookeeper/test/DisconnectableZooKeeper.java |   58 +
 .../zookeeper/test/DisconnectedWatcherTest.java |  258 ++
 .../apache/zookeeper/test/EventTypeTest.java    |   50 +
 .../apache/zookeeper/test/FLENewEpochTest.java  |  192 ++
 .../apache/zookeeper/test/FLEPredicateTest.java |  104 +
 .../apache/zookeeper/test/FLERestartTest.java   |  203 ++
 .../java/org/apache/zookeeper/test/FLETest.java |  473 +++
 .../zookeeper/test/FLEZeroWeightTest.java       |  181 ++
 .../test/FollowerResyncConcurrencyTest.java     |  607 ++++
 .../org/apache/zookeeper/test/FollowerTest.java |  140 +
 .../test/FourLetterWordsQuorumTest.java         |  113 +
 .../zookeeper/test/FourLetterWordsTest.java     |  238 ++
 .../test/FourLetterWordsWhiteListTest.java      |  253 ++
 .../apache/zookeeper/test/GetChildren2Test.java |  136 +
 .../zookeeper/test/HierarchicalQuorumTest.java  |  309 ++
 .../apache/zookeeper/test/IntegrityCheck.java   |  232 ++
 .../zookeeper/test/InvalidSnapshotTest.java     |  125 +
 .../java/org/apache/zookeeper/test/JMXEnv.java  |  325 +++
 .../apache/zookeeper/test/KeeperStateTest.java  |   76 +
 .../zookeeper/test/LENonTerminateTest.java      |  378 +++
 .../java/org/apache/zookeeper/test/LETest.java  |  137 +
 .../zookeeper/test/LoadFromLogNoServerTest.java |  175 ++
 .../apache/zookeeper/test/LoadFromLogTest.java  |  223 ++
 .../org/apache/zookeeper/test/MaxCnxnsTest.java |  139 +
 .../zookeeper/test/MultiTransactionTest.java    |  805 ++++++
 .../zookeeper/test/NioNettySuiteBase.java       |   43 +
 .../zookeeper/test/NioNettySuiteHammerTest.java |   30 +
 .../zookeeper/test/NioNettySuiteTest.java       |   37 +
 .../zookeeper/test/NonRecoverableErrorTest.java |  183 ++
 .../org/apache/zookeeper/test/NullDataTest.java |   75 +
 .../java/org/apache/zookeeper/test/OOMTest.java |  161 ++
 .../org/apache/zookeeper/test/OSMXBeanTest.java |   70 +
 .../test/ObserverHierarchicalQuorumTest.java    |   43 +
 .../apache/zookeeper/test/ObserverLETest.java   |   76 +
 .../test/ObserverQuorumHammerTest.java          |   39 +
 .../org/apache/zookeeper/test/ObserverTest.java |  233 ++
 .../org/apache/zookeeper/test/QuorumBase.java   |  341 +++
 .../apache/zookeeper/test/QuorumHammerTest.java |   51 +
 .../apache/zookeeper/test/QuorumQuotaTest.java  |   63 +
 .../org/apache/zookeeper/test/QuorumTest.java   |  296 ++
 .../org/apache/zookeeper/test/QuorumUtil.java   |  261 ++
 .../zookeeper/test/QuorumZxidSyncTest.java      |  171 ++
 .../apache/zookeeper/test/ReadOnlyModeTest.java |  291 ++
 .../org/apache/zookeeper/test/RecoveryTest.java |  209 ++
 .../zookeeper/test/RepeatStartupTest.java       |   69 +
 .../zookeeper/test/RestoreCommittedLogTest.java |   91 +
 .../test/SaslAuthDesignatedClientTest.java      |  104 +
 .../test/SaslAuthDesignatedServerTest.java      |  104 +
 .../test/SaslAuthFailDesignatedClientTest.java  |  108 +
 .../zookeeper/test/SaslAuthFailNotifyTest.java  |   98 +
 .../apache/zookeeper/test/SaslAuthFailTest.java |   76 +
 .../test/SaslAuthMissingClientConfigTest.java   |   97 +
 .../apache/zookeeper/test/SaslClientTest.java   |   62 +
 .../zookeeper/test/SessionInvalidationTest.java |  105 +
 .../org/apache/zookeeper/test/SessionTest.java  |  394 +++
 .../zookeeper/test/SessionTimeoutTest.java      |  129 +
 .../org/apache/zookeeper/test/SledgeHammer.java |  115 +
 .../apache/zookeeper/test/StandaloneTest.java   |   65 +
 .../org/apache/zookeeper/test/StatTest.java     |  205 ++
 .../zookeeper/test/StaticHostProviderTest.java  |  362 +++
 .../org/apache/zookeeper/test/SyncCallTest.java |  108 +
 .../org/apache/zookeeper/test/TestHammer.java   |   63 +
 .../org/apache/zookeeper/test/TestUtils.java    |   60 +
 .../org/apache/zookeeper/test/TruncateTest.java |  256 ++
 .../org/apache/zookeeper/test/UpgradeTest.java  |  105 +
 .../zookeeper/test/WatchEventWhenAutoReset.java |  212 ++
 .../apache/zookeeper/test/WatchedEventTest.java |   95 +
 .../apache/zookeeper/test/WatcherFuncTest.java  |  478 +++
 .../org/apache/zookeeper/test/WatcherTest.java  |  408 +++
 .../test/ZkDatabaseCorruptionTest.java          |  161 ++
 .../zookeeper/test/ZooKeeperQuotaTest.java      |   85 +
 .../zookeeper/test/ZooKeeperTestClient.java     |  422 +++
 .../src/test/resources/check_compatibility.py   |  204 ++
 .../resources/checkstyle-noframes-sorted.xsl    |  178 ++
 .../src/test/resources/checkstyle.xml           |  187 ++
 .../data/buffersize/create/version-2/log.1      |  Bin 0 -> 51216 bytes
 .../data/buffersize/create/version-2/snapshot.0 |  Bin 0 -> 296 bytes
 .../data/buffersize/set/version-2/log.1         |  Bin 0 -> 51216 bytes
 .../data/buffersize/set/version-2/snapshot.0    |  Bin 0 -> 296 bytes
 .../data/buffersize/snapshot/version-2/log.1    |  Bin 0 -> 51216 bytes
 .../buffersize/snapshot/version-2/snapshot.0    |  Bin 0 -> 296 bytes
 .../buffersize/snapshot/version-2/snapshot.2    |  Bin 0 -> 5429 bytes
 .../resources/data/invalidsnap/version-2/log.1  |  Bin 0 -> 59360 bytes
 .../data/invalidsnap/version-2/log.274          |  Bin 0 -> 91616 bytes
 .../resources/data/invalidsnap/version-2/log.42 |  Bin 0 -> 184 bytes
 .../data/invalidsnap/version-2/log.63b          |  Bin 0 -> 49008 bytes
 .../data/invalidsnap/version-2/snapshot.0       |  Bin 0 -> 296 bytes
 .../data/invalidsnap/version-2/snapshot.272     |  Bin 0 -> 56408 bytes
 .../data/invalidsnap/version-2/snapshot.273     |  Bin 0 -> 56521 bytes
 .../data/invalidsnap/version-2/snapshot.639     |  Bin 0 -> 143163 bytes
 .../data/invalidsnap/version-2/snapshot.83f     |  Bin 0 -> 4824 bytes
 .../resources/data/kerberos/minikdc-krb5.conf   |   30 +
 .../test/resources/data/kerberos/minikdc.ldiff  |   52 +
 .../test/resources/data/upgrade/log.100000001   |  Bin 0 -> 2458624 bytes
 .../test/resources/data/upgrade/log.100001bf0   |  Bin 0 -> 1025024 bytes
 .../resources/data/upgrade/snapshot.100000000   |  Bin 0 -> 73 bytes
 .../resources/data/upgrade/snapshot.100001bec   |  Bin 0 -> 2567595 bytes
 .../src/test/resources/findbugsExcludeFile.xml  |  166 ++
 .../src/test/resources/test-github-pr.sh        |  616 ++++
 .../src/test/resources/test-patch.properties    |   18 +
 .../src/test/resources/test-patch.sh            |  637 ++++
 370 files changed, 35558 insertions(+), 35633 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 3544456..ab54763 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,8 +66,8 @@ zookeeper-client/zookeeper-client-c/*.lo
 zookeeper-client/zookeeper-client-c/*.o
 zookeeper-client/zookeeper-client-c/generated/
 src/java/generated/
-zookeeper-common/src/main/resources/lib/ant-eclipse-*
-zookeeper-common/src/main/resources/lib/ivy-*
+zookeeper-server/src/main/resources/lib/ant-eclipse-*
+zookeeper-server/src/main/resources/lib/ivy-*
 zookeeper-client/zookeeper-client-c/Makefile.in
 zookeeper-client/zookeeper-client-c/aclocal.m4
 zookeeper-client/zookeeper-client-c/autom4te.cache/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/bin/zkEnv.sh
----------------------------------------------------------------------
diff --git a/bin/zkEnv.sh b/bin/zkEnv.sh
index 4e6fb97..5c860ce 100755
--- a/bin/zkEnv.sh
+++ b/bin/zkEnv.sh
@@ -70,7 +70,7 @@ fi
 #add the zoocfg dir to classpath
 CLASSPATH="$ZOOCFGDIR:$CLASSPATH"
 
-for i in "$ZOOBINDIR"/../zookeeper-common/src/main/resources/lib/*.jar
+for i in "$ZOOBINDIR"/../zookeeper-server/src/main/resources/lib/*.jar
 do
     CLASSPATH="$i:$CLASSPATH"
 done

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index 6a1ef2b..01a2a9f 100644
--- a/build.xml
+++ b/build.xml
@@ -86,12 +86,9 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
     <property name="src.dir" value="${basedir}/src" />
     <property name="java.server.src.dir" value="${basedir}/zookeeper-server/src/main/java" />
     <property name="java.server.resources.dir" value="${basedir}/zookeeper-server/src/main/resources" />
-    <property name="java.common.src.dir" value="${basedir}/zookeeper-common/src/main/java" />
-    <property name="java.common.resources.dir" value="${basedir}/zookeeper-common/src/main/resources" />
-    <property name="java.client.src.dir" value="${basedir}/zookeeper-client/zookeeper-client-java/src/main/java" />
     <property name="jute.src.dir" value="${basedir}/zookeeper-jute/src/main/java" />
 
-    <property name="lib.dir" value="${java.common.resources.dir}/lib" />
+    <property name="lib.dir" value="${java.server.resources.dir}/lib" />
     <property name="lib.dir.includes" value="**/*.jar" />
     <property name="lib.dir.excludes" value="**/excluded/" />
 
@@ -118,8 +115,7 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
     <property name="test.java.build.dir" value="${build.dir}/test"/>
     <property name="test.java.classes" value="${test.java.build.dir}/classes"/>
     <property name="java.server.test.dir" value="${basedir}/zookeeper-server/src/test/java"/>
-    <property name="java.common.test.dir" value="${basedir}/zookeeper-common/src/test/java"/>
-    <property name="common.test.resource.dir" value="${basedir}/zookeeper-common/src/test/resources"/>
+    <property name="server.test.resource.dir" value="${basedir}/zookeeper-server/src/test/resources"/>
     <property name="jute.test.src.dir" value="${basedir}/zookeeper-jute/src/test/java" />
     <property name="systest.src.dir" value="${basedir}/zookeeper-it/src/test/java"/>
     <property name="test.log.dir" value="${test.java.build.dir}/logs" />
@@ -146,12 +142,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
               value="http://docs.oracle.com/javase/6/docs/api/" />
     <property name="javadoc.packages" value="org.apache.*" />
 
-    <path id="java.src.dir">
-      <pathelement path="${java.server.src.dir}"/>
-      <pathelement path="${java.common.src.dir}"/>
-      <pathelement path="${java.client.src.dir}"/>
-    </path>
-
     <property name="dist.dir" value="${build.dir}/${final.name}"/>
     <property name="dist.maven.dir" value="${dist.dir}/dist-maven"/>
 
@@ -201,8 +191,8 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
     <property name="grep.cmd" value="grep"/>
     <property name="patch.cmd" value="patch"/>
     <property name="make.cmd" value="make"/>
-    <property name="test_patch_sh" value="${common.test.resource.dir}/test-patch.sh"/>
-    <property name="test_pullrequest_sh" value="${common.test.resource.dir}/test-github-pr.sh"/>
+    <property name="test_patch_sh" value="${server.test.resource.dir}/test-patch.sh"/>
+    <property name="test_pullrequest_sh" value="${server.test.resource.dir}/test-github-pr.sh"/>
 
 	<!-- jdiff.home property set -->
     <property name="jdiff.home" value="${ivy.jdiff.lib}"/>
@@ -365,7 +355,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
             target="${javac.target}" source="${javac.source}"
             includes="org/apache/zookeeper/version/util/**" debug="on">
             <src path="${java.server.src.dir}" />
-            <src path="${java.common.src.dir}" />
         </javac>
     </target>
     
@@ -474,8 +463,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
         <javac destdir="${build.classes}" includeantruntime="false"
                target="${javac.target}" source="${javac.source}" debug="on">
             <src path="${java.server.src.dir}"/>
-            <src path="${java.common.src.dir}"/>
-            <src path="${java.client.src.dir}"/>
             <src path="${jute.src.dir}"/>
             <classpath refid="java.classpath"/>
             <compilerarg value="-Xlint:all"/>
@@ -488,7 +475,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
       <javac destdir="${test.java.classes}" includeantruntime="false"
              target="${javac.target}" source="${javac.source}" debug="on">
           <src path="${java.server.test.dir}"/>
-          <src path="${java.common.test.dir}"/>
         <src path="${jute.test.src.dir}"/>
         <classpath refid="test.java.classpath"/>
       </javac>
@@ -565,12 +551,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
           <include name="org/apache/**"/>
           <exclude name="org/apache/jute/**"/>
     	</packageset>
-        <packageset dir="${java.common.src.dir}">
-          <include name="org/apache/**"/>
-        </packageset>
-        <packageset dir="${java.client.src.dir}">
-          <include name="org/apache/**"/>
-        </packageset>
     	<packageset dir="${src_generated.dir}"/>
         <link href="${javadoc.link.java}"/>
         <classpath refid="java.classpath"/>
@@ -606,14 +586,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
           <include name="org/apache/**"/>
           <exclude name="org/apache/zookeeper/server/**"/>
     	</packageset>
-        <packageset dir="${java.common.src.dir}">
-          <include name="org/apache/**"/>
-          <exclude name="org/apache/zookeeper/server/**"/>
-        </packageset>
-        <packageset dir="${java.client.src.dir}">
-          <include name="org/apache/**"/>
-          <exclude name="org/apache/zookeeper/server/**"/>
-        </packageset>
         <packageset dir="${jute.src.dir}">
           <include name="org/apache/**"/>
         </packageset>
@@ -651,8 +623,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
             <fileset file="LICENSE.txt" />
             <fileset dir="${build.classes}" excludes="**/.generated"/>
             <fileset dir="${java.server.src.dir}"/>
-            <fileset dir="${java.common.src.dir}"/>
-            <fileset dir="${java.client.src.dir}"/>
             <fileset dir="${jute.src.dir}"/>
             <fileset dir="${src_generated.dir}" excludes="**/.generated"/>
             <manifest>
@@ -728,8 +698,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
         <jar jarfile="${build.dir}/${final.name}-sources.jar">
             <fileset file="LICENSE.txt" />
             <fileset dir="${java.server.src.dir}"/>
-            <fileset dir="${java.common.src.dir}"/>
-            <fileset dir="${java.client.src.dir}"/>
             <fileset dir="${jute.src.dir}"/>
             <fileset dir="${src_generated.dir}" excludes="**/.generated"/>
             <manifest>
@@ -883,7 +851,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
           <include name="zookeeper-contrib/**"/>
           <include name="zookeeper-client/**"/>
           <include name="zookeeper-jute/**"/>
-          <include name="zookeeper-common/**"/>
           <include name="zookeeper-server/**"/>
         </fileset>
         <fileset file="${java.server.resources.dir}/pom.template"/>
@@ -1378,18 +1345,18 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
         <mkdir dir="${test.data.upgrade.dir}" />
         <mkdir dir="${test.data.invalid.dir}" />
         <copy todir="${test.data.upgrade.dir}">
-            <fileset dir="${common.test.resource.dir}/data/upgrade"/>
+            <fileset dir="${server.test.resource.dir}/data/upgrade"/>
         </copy>
         <copy todir="${test.data.invalid.dir}">
-            <fileset dir="${common.test.resource.dir}/data/invalidsnap"/>
+            <fileset dir="${server.test.resource.dir}/data/invalidsnap"/>
         </copy>
         <mkdir dir="${test.data.buffersize.dir}" />
         <copy todir="${test.data.buffersize.dir}">
-            <fileset dir="${common.test.resource.dir}/data/buffersize"/>
+            <fileset dir="${server.test.resource.dir}/data/buffersize"/>
         </copy>
         <mkdir dir="${test.data.kerberos.dir}" />
         <copy todir="${test.data.kerberos.dir}">
-            <fileset dir="${common.test.resource.dir}/data/kerberos"/>
+            <fileset dir="${server.test.resource.dir}/data/kerberos"/>
         </copy>
     </target>
 
@@ -1439,10 +1406,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
               <include name="**/*${test.category}Test.java"/>
               <exclude name="**/*HammerTest.java"/>
             </fileset>
-            <fileset dir="${java.common.test.dir}">
-              <include name="**/*${test.category}Test.java"/>
-              <exclude name="**/*HammerTest.java"/>
-            </fileset>
             <fileset dir="${jute.test.src.dir}">
               <include name="**/*${test.category}Test.java" />
             </fileset>
@@ -1451,16 +1414,12 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
             <fileset dir="${java.server.test.dir}">
               <include name="**/*${test.category}Test.java"/>
             </fileset>
-            <fileset dir="${java.common.test.dir}">
-              <include name="**/*${test.category}Test.java"/>
-            </fileset>
             <fileset dir="${jute.test.src.dir}">
               <include name="**/*${test.category}Test.java" />
             </fileset>
           </batchtest>
           <batchtest todir="${test.log.dir}" if="testcase">
             <fileset dir="${java.server.test.dir}" includes="**/${testcase}.java"/>
-            <fileset dir="${java.common.test.dir}" includes="**/${testcase}.java"/>
             <fileset dir="${jute.test.src.dir}" includes="**/${testcase}.java"/>
           </batchtest>
         </junit>
@@ -1631,24 +1590,11 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
                  includes="org/apache/zookeeper/**/*"
                  excludes="org/apache/zookeeper/version/**/*">
         </fileset>
-        <fileset dir="${java.common.src.dir}"
-               includes="org/apache/zookeeper/**/*"
-               excludes="org/apache/zookeeper/version/**/*">
-        </fileset>
-        <fileset dir="${java.client.src.dir}"
-               includes="org/apache/zookeeper/**/*"
-               excludes="org/apache/zookeeper/version/**/*">
-        </fileset>
         <testsources dir="${java.server.test.dir}">
           <testclass package="org.apache.zookeeper.*" name=".*Test">
               <testmethod annotation="Test"/>
           </testclass>
         </testsources>
-        <testsources dir="${java.common.test.dir}">
-          <testclass package="org.apache.zookeeper.*" name=".*Test">
-              <testmethod annotation="Test"/>
-          </testclass>
-        </testsources>
       </clover-setup>
     </target>
 
@@ -1695,7 +1641,7 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
     <property name="findbugs.home" value="" />
     <target name="findbugs" depends="check-for-findbugs, jar" if="findbugs.present">
         <property name="findbugs.out.dir" value="${test.java.build.dir}/findbugs" />
-        <property name="findbugs.exclude.file" value="${common.test.resource.dir}/findbugsExcludeFile.xml" />
+        <property name="findbugs.exclude.file" value="${server.test.resource.dir}/findbugsExcludeFile.xml" />
         <property name="findbugs.report.htmlfile" value="${findbugs.out.dir}/zookeeper-findbugs-report.html" />
         <property name="findbugs.report.xmlfile" value="${findbugs.out.dir}/zookeeper-findbugs-report.xml" />
         <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask" 
@@ -1709,8 +1655,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
                 </fileset>
             </auxClasspath>
             <sourcePath path="${java.server.src.dir}" />
-            <sourcePath path="${java.common.src.dir}" />
-            <sourcePath path="${java.client.src.dir}" />
             <class location="${build.dir}/${final.name}.jar" />
         </findbugs>
         <xslt style="${findbugs.home}/src/xsl/default.xsl" in="${findbugs.report.xmlfile}" 
@@ -1776,13 +1720,10 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
 
             <formatter type="${test.junit.output.format}" />
             <batchtest todir="${test.log.dir}" unless="testcase">
-                <fileset dir="${java.common.test.dir}"
-                         includes="**/*Test.java"/>
                 <fileset dir="${java.server.test.dir}"
                          includes="**/*Test.java"/>
             </batchtest>
             <batchtest todir="${test.log.dir}" if="testcase">
-                <fileset dir="${java.common.test.dir}" includes="**/${testcase}.java"/>
                 <fileset dir="${java.server.test.dir}" includes="**/${testcase}.java"/>
             </batchtest>
         </junit>
@@ -1811,13 +1752,11 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
         </classpath>
       </taskdef>
       <mkdir dir="${test.java.build.dir}"/>
-      <cs:checkstyle config="${common.test.resource.dir}/checkstyle.xml" failOnViolation="false">
-        <fileset dir="${basedir}/zookeeper-common" includes="**/*.java" excludes="**/generated/**"/>
-        <fileset dir="${basedir}/zookeeper-client" includes="**/*.java" excludes="**/generated/**"/>
+      <cs:checkstyle config="${server.test.resource.dir}/checkstyle.xml" failOnViolation="false">
         <fileset dir="${basedir}/zookeeper-server" includes="**/*.java" excludes="**/generated/**"/>
         <formatter type="xml" toFile="${test.java.build.dir}/checkstyle-errors.xml"/>
       </cs:checkstyle>
-      <xslt style="${common.test.resource.dir}/checkstyle-noframes-sorted.xsl" in="${test.java.build.dir}/checkstyle-errors.xml"
+      <xslt style="${server.test.resource.dir}/checkstyle-noframes-sorted.xsl" in="${test.java.build.dir}/checkstyle-errors.xml"
             out="${test.java.build.dir}/checkstyle-errors.html"/>
     </target>
 
@@ -1906,9 +1845,9 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
           <exclude name="src/zookeeper-client/zookeeper-client-c/config**"/>
           <exclude name="src/zookeeper-client/zookeeper-client-c/src/hashtable/"/>
           <exclude name="src/zookeeper-jute/target/main/java/.generated/"/>
-          <exclude name="src/zookeeper-common/src/test/resources/checkstyle*.xml"/>
-          <exclude name="src/zookeeper-common/src/test/resources/checkstyle*.xsl"/>
-          <exclude name="src/zookeeper-common/src/test/resources/findbugs*.xml"/>
+          <exclude name="src/zookeeper-server/src/test/resources/checkstyle*.xml"/>
+          <exclude name="src/zookeeper-server/src/test/resources/checkstyle*.xsl"/>
+          <exclude name="src/zookeeper-server/src/test/resources/findbugs*.xml"/>
           <exclude name="src/**/*.vcproj"/>
           <exclude name="src/**/*.sln"/>
         </fileset>
@@ -1997,12 +1936,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
            <include name="org/apache/zookeeper"/>
            <exclude name="org/apache/jute"/>
          </packageset>
-         <packageset dir="${java.common.src.dir}">
-           <include name="org/apache/zookeeper"/>
-         </packageset>
-         <packageset dir="${java.client.src.dir}">
-           <include name="org/apache/zookeeper"/>
-         </packageset>
          <classpath>
            <pathelement location="${build.classes}"/>
            <fileset dir="${lib.dir}">
@@ -2028,8 +1961,6 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
                 excludepackagenames="org.apache.jute"	
                 sourceFiles="${jdiff.home}/Null.java">
          <fileset dir="${java.server.src.dir}"/>
-         <fileset dir="${java.common.src.dir}"/>
-         <fileset dir="${java.client.src.dir}"/>
          <doclet name="jdiff.JDiff"
                  path="${ivy.jdiff.lib}/jdiff-1.0.9.jar:${ivy.jdiff.lib}/xerces-1.4.4.jar">
            <param name="-oldapi" value="${name} ${jdiff.stable}"/>
@@ -2059,19 +1990,19 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
 
      <target name="ant-eclipse-download" unless="ant-eclipse.jar.exists">
        <get src="https://downloads.sourceforge.net/project/ant-eclipse/ant-eclipse/1.0/ant-eclipse-1.0.bin.tar.bz2"
-            dest="${java.common.resources.dir}/ant-eclipse-1.0.bin.tar.bz2" usetimestamp="false" />
+            dest="${java.server.resources.dir}/ant-eclipse-1.0.bin.tar.bz2" usetimestamp="false" />
 
-       <bunzip2 src="${java.common.resources.dir}/ant-eclipse-1.0.bin.tar.bz2"/>
+       <bunzip2 src="${java.server.resources.dir}/ant-eclipse-1.0.bin.tar.bz2"/>
 
-       <untar src="${java.common.resources.dir}/ant-eclipse-1.0.bin.tar"
-              dest="${java.common.resources.dir}">
+       <untar src="${java.server.resources.dir}/ant-eclipse-1.0.bin.tar"
+              dest="${java.server.resources.dir}">
          <patternset>
            <include name="lib/ant-eclipse-1.0-jvm1.2.jar"/>
          </patternset>
        </untar>
 
-       <delete file="${java.common.resources.dir}/ant-eclipse-1.0.bin.tar" />
-       <delete file="${java.common.resources.dir}/ant-eclipse-1.0.bin.tar.bz2" />
+       <delete file="${java.server.resources.dir}/ant-eclipse-1.0.bin.tar" />
+       <delete file="${java.server.resources.dir}/ant-eclipse-1.0.bin.tar.bz2" />
      </target>
 
      <target name="eclipse"
@@ -2092,16 +2023,10 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
          <classpath>
            <source path="${java.server.src.dir}"
                    output="${build.dir.eclipse-main-classes}" />
-           <source path="${java.common.src.dir}"
-                   output="${build.dir.eclipse-main-classes}" />
-           <source path="${java.client.src.dir}"
-                   output="${build.dir.eclipse-main-classes}" />
            <source path="${jute.src.dir}"
                    output="${build.dir.eclipse-main-classes}" />
            <source path="${src_generated.dir}"
                    output="${build.dir.eclipse-main-classes}" />
-           <source path="${java.common.test.dir}"
-                   output="${build.dir.eclipse-test-classes}" />
            <source path="${java.server.test.dir}"
                    output="${build.dir.eclipse-test-classes}" />
            <source path="${systest.src.dir}"

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/zkServer.sh b/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
index 9c84738..f06e338 100755
--- a/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
+++ b/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
@@ -90,7 +90,7 @@ do
     CLASSPATH="$CLASSPATH:$i"
 done
 
-for i in "${zk_base}"/zookeeper-common/src/main/resource/lib/*.jar
+for i in "${zk_base}"/zookeeper-server/src/main/resource/lib/*.jar
 do
     CLASSPATH="$CLASSPATH:$i"
 done

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java b/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
deleted file mode 100644
index ff0425a..0000000
--- a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.client;
-
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-
-import org.apache.zookeeper.common.PathUtils;
-
-/**
- * A parser for ZooKeeper Client connect strings.
- * 
- * This class is not meant to be seen or used outside of ZooKeeper itself.
- * 
- * The chrootPath member should be replaced by a Path object in issue
- * ZOOKEEPER-849.
- * 
- * @see org.apache.zookeeper.ZooKeeper
- */
-public final class ConnectStringParser {
-    private static final int DEFAULT_PORT = 2181;
-
-    private final String chrootPath;
-
-    private final ArrayList<InetSocketAddress> serverAddresses = new ArrayList<InetSocketAddress>();
-
-    /**
-     * 
-     * @throws IllegalArgumentException
-     *             for an invalid chroot path.
-     */
-    public ConnectStringParser(String connectString) {
-        // parse out chroot, if any
-        int off = connectString.indexOf('/');
-        if (off >= 0) {
-            String chrootPath = connectString.substring(off);
-            // ignore "/" chroot spec, same as null
-            if (chrootPath.length() == 1) {
-                this.chrootPath = null;
-            } else {
-                PathUtils.validatePath(chrootPath);
-                this.chrootPath = chrootPath;
-            }
-            connectString = connectString.substring(0, off);
-        } else {
-            this.chrootPath = null;
-        }
-
-        String hostsList[] = connectString.split(",");
-        for (String host : hostsList) {
-            int port = DEFAULT_PORT;
-            int pidx = host.lastIndexOf(':');
-            if (pidx >= 0) {
-                // otherwise : is at the end of the string, ignore
-                if (pidx < host.length() - 1) {
-                    port = Integer.parseInt(host.substring(pidx + 1));
-                }
-                host = host.substring(0, pidx);
-            }
-            serverAddresses.add(InetSocketAddress.createUnresolved(host, port));
-        }
-    }
-
-    public String getChrootPath() {
-        return chrootPath;
-    }
-
-    public ArrayList<InetSocketAddress> getServerAddresses() {
-        return serverAddresses;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java b/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java
deleted file mode 100644
index a4175e4..0000000
--- a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.client;
-
-import org.apache.log4j.Logger;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketTimeoutException;
-
-import org.apache.yetus.audience.InterfaceAudience;
-
-@InterfaceAudience.Public
-public class FourLetterWordMain {
-    //in milliseconds, socket should connect/read within this period otherwise SocketTimeoutException
-    private static final int DEFAULT_SOCKET_TIMEOUT = 5000;
-    protected static final Logger LOG = Logger.getLogger(FourLetterWordMain.class);
-
-    /**
-     * Send the 4letterword
-     * @param host the destination host
-     * @param port the destination port
-     * @param cmd the 4letterword
-     * @return server response
-     * @throws java.io.IOException
-     */
-    public static String send4LetterWord(String host, int port, String cmd)
-            throws IOException
-    {
-        return send4LetterWord(host, port, cmd, DEFAULT_SOCKET_TIMEOUT);
-    }
-    /**
-     * Send the 4letterword
-     * @param host the destination host
-     * @param port the destination port
-     * @param cmd the 4letterword
-     * @param timeout in milliseconds, maximum time to wait while connecting/reading data
-     * @return server response
-     * @throws java.io.IOException
-     */
-    public static String send4LetterWord(String host, int port, String cmd, int timeout)
-            throws IOException
-    {
-        LOG.info("connecting to " + host + " " + port);
-        Socket sock = new Socket();
-        InetSocketAddress hostaddress= host != null ? new InetSocketAddress(host, port) :
-            new InetSocketAddress(InetAddress.getByName(null), port);
-        BufferedReader reader = null;
-        try {
-            sock.setSoTimeout(timeout);
-            sock.connect(hostaddress, timeout);
-            OutputStream outstream = sock.getOutputStream();
-            outstream.write(cmd.getBytes());
-            outstream.flush();
-            // this replicates NC - close the output stream before reading
-            sock.shutdownOutput();
-
-            reader =
-                    new BufferedReader(
-                            new InputStreamReader(sock.getInputStream()));
-            StringBuilder sb = new StringBuilder();
-            String line;
-            while((line = reader.readLine()) != null) {
-                sb.append(line + "\n");
-            }
-            return sb.toString();
-        } catch (SocketTimeoutException e) {
-            throw new IOException("Exception while executing four letter word: " + cmd, e);
-        } finally {
-            sock.close();
-            if (reader != null) {
-                reader.close();
-            }
-        }
-    }
-    
-    public static void main(String[] args)
-            throws IOException
-    {
-        if (args.length != 3) {
-            System.out.println("Usage: FourLetterWordMain <host> <port> <cmd>");
-        } else {
-            System.out.println(send4LetterWord(args[0], Integer.parseInt(args[1]), args[2]));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/HostProvider.java
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/HostProvider.java b/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/HostProvider.java
deleted file mode 100644
index 61d9108..0000000
--- a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/HostProvider.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.client;
-
-import org.apache.yetus.audience.InterfaceAudience;
-
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-
-/**
- * A set of hosts a ZooKeeper client should connect to.
- * 
- * Classes implementing this interface must guarantee the following:
- * 
- * * Every call to next() returns an InetSocketAddress. So the iterator never
- * ends.
- * 
- * * The size() of a HostProvider may never be zero.
- * 
- * A HostProvider must return resolved InetSocketAddress instances on next(),
- * but it's up to the HostProvider, when it wants to do the resolving.
- * 
- * Different HostProvider could be imagined:
- * 
- * * A HostProvider that loads the list of Hosts from an URL or from DNS 
- * * A HostProvider that re-resolves the InetSocketAddress after a timeout. 
- * * A HostProvider that prefers nearby hosts.
- */
-@InterfaceAudience.Public
-public interface HostProvider {
-    public int size();
-
-    /**
-     * The next host to try to connect to.
-     *
-     * For a spinDelay of 0 there should be no wait.
-     *
-     * @param spinDelay Milliseconds to wait if all hosts have been tried once.
-     * @return The next host to try to connect to with resolved address. If the host is not resolvable, the unresolved
-     * address will be returned.
-     */
-    public InetSocketAddress next(long spinDelay);
-
-    /**
-     * Notify the HostProvider of a successful connection.
-     * 
-     * The HostProvider may use this notification to reset it's inner state.
-     */
-    public void onConnected();
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java b/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java
deleted file mode 100644
index 0005942..0000000
--- a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.client;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Most simple HostProvider, resolves on every next() call.
- *
- * Please be aware that although this class doesn't do any DNS caching, there're multiple levels of caching already
- * present across the stack like in JVM, OS level, hardware, etc. The best we could do here is to get the most recent
- * address from the underlying system which is considered up-to-date.
- *
- */
-@InterfaceAudience.Public
-public final class StaticHostProvider implements HostProvider {
-    public interface Resolver {
-        InetAddress[] getAllByName(String name) throws UnknownHostException;
-    }
-
-    private static final Logger LOG = LoggerFactory
-            .getLogger(StaticHostProvider.class);
-
-    private final List<InetSocketAddress> serverAddresses = new ArrayList<InetSocketAddress>(5);
-
-    private int lastIndex = -1;
-
-    private int currentIndex = -1;
-
-    private Resolver resolver;
-
-    /**
-     * Constructs a SimpleHostSet.
-     *
-     * @param serverAddresses
-     *            possibly unresolved ZooKeeper server addresses
-     * @throws IllegalArgumentException
-     *             if serverAddresses is empty or resolves to an empty list
-     */
-    public StaticHostProvider(Collection<InetSocketAddress> serverAddresses) {
-        this.resolver = new Resolver() {
-            @Override
-            public InetAddress[] getAllByName(String name) throws UnknownHostException {
-                return InetAddress.getAllByName(name);
-            }
-        };
-        init(serverAddresses);
-    }
-
-    /**
-     * Introduced for testing purposes. getAllByName() is a static method of InetAddress, therefore cannot be easily mocked.
-     * By abstraction of Resolver interface we can easily inject a mocked implementation in tests.
-     *
-     * @param serverAddresses
-     *            possibly unresolved ZooKeeper server addresses
-     * @param resolver
-     *            custom resolver implementation
-     * @throws IllegalArgumentException
-     *             if serverAddresses is empty or resolves to an empty list
-     */
-    public StaticHostProvider(Collection<InetSocketAddress> serverAddresses, Resolver resolver) {
-        this.resolver = resolver;
-        init(serverAddresses);
-    }
-
-    /**
-     * Common init method for all constructors.
-     * Resolve all unresolved server addresses, put them in a list and shuffle.
-     */
-    private void init(Collection<InetSocketAddress> serverAddresses) {
-        if (serverAddresses.isEmpty()) {
-            throw new IllegalArgumentException(
-                    "A HostProvider may not be empty!");
-        }
-
-        this.serverAddresses.addAll(serverAddresses);
-        Collections.shuffle(this.serverAddresses);
-    }
-
-    /**
-     * Evaluate to a hostname if one is available and otherwise it returns the
-     * string representation of the IP address.
-     *
-     * In Java 7, we have a method getHostString, but earlier versions do not support it.
-     * This method is to provide a replacement for InetSocketAddress.getHostString().
-     *
-     * @param addr
-     * @return Hostname string of address parameter
-     */
-    private String getHostString(InetSocketAddress addr) {
-        String hostString = "";
-
-        if (addr == null) {
-            return hostString;
-        }
-        if (!addr.isUnresolved()) {
-            InetAddress ia = addr.getAddress();
-
-            // If the string starts with '/', then it has no hostname
-            // and we want to avoid the reverse lookup, so we return
-            // the string representation of the address.
-            if (ia.toString().startsWith("/")) {
-                hostString = ia.getHostAddress();
-            } else {
-                hostString = addr.getHostName();
-            }
-        } else {
-            // According to the Java 6 documentation, if the hostname is
-            // unresolved, then the string before the colon is the hostname.
-            String addrString = addr.toString();
-            hostString = addrString.substring(0, addrString.lastIndexOf(':'));
-        }
-
-        return hostString;
-    }
-
-    public int size() {
-        return serverAddresses.size();
-    }
-
-    public InetSocketAddress next(long spinDelay) {
-        currentIndex = ++currentIndex % serverAddresses.size();
-        if (currentIndex == lastIndex && spinDelay > 0) {
-            try {
-                Thread.sleep(spinDelay);
-            } catch (InterruptedException e) {
-                LOG.warn("Unexpected exception", e);
-            }
-        } else if (lastIndex == -1) {
-            // We don't want to sleep on the first ever connect attempt.
-            lastIndex = 0;
-        }
-
-        InetSocketAddress curAddr = serverAddresses.get(currentIndex);
-        try {
-            String curHostString = getHostString(curAddr);
-            List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>(Arrays.asList(this.resolver.getAllByName(curHostString)));
-            if (resolvedAddresses.isEmpty()) {
-                return curAddr;
-            }
-            Collections.shuffle(resolvedAddresses);
-            return new InetSocketAddress(resolvedAddresses.get(0), curAddr.getPort());
-        } catch (UnknownHostException e) {
-            return curAddr;
-        }
-    }
-
-    @Override
-    public void onConnected() {
-        lastIndex = currentIndex;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java b/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java
deleted file mode 100644
index af3303c..0000000
--- a/zookeeper-client/zookeeper-client-java/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java
+++ /dev/null
@@ -1,439 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.client;
-
-import java.io.IOException;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginException;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.ClientCnxn;
-import org.apache.zookeeper.Environment;
-import org.apache.zookeeper.Login;
-import org.apache.zookeeper.SaslClientCallbackHandler;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.proto.GetSASLRequest;
-import org.apache.zookeeper.proto.SetSASLResponse;
-import org.apache.zookeeper.util.SecurityUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class manages SASL authentication for the client. It
- * allows ClientCnxn to authenticate using SASL with a Zookeeper server.
- */
-public class ZooKeeperSaslClient {
-    public static final String LOGIN_CONTEXT_NAME_KEY = "zookeeper.sasl.clientconfig";
-    public static final String ENABLE_CLIENT_SASL_KEY = "zookeeper.sasl.client";
-    public static final String ENABLE_CLIENT_SASL_DEFAULT = "true";
-    private static volatile boolean initializedLogin = false; 
-
-    /**
-     * Returns true if the SASL client is enabled. By default, the client
-     * is enabled but can be disabled by setting the system property
-     * <code>zookeeper.sasl.client</code> to <code>false</code>. See
-     * ZOOKEEPER-1657 for more information.
-     *
-     * @return If the SASL client is enabled.
-     */
-    public static boolean isEnabled() {
-        return Boolean.valueOf(System.getProperty(ENABLE_CLIENT_SASL_KEY, ENABLE_CLIENT_SASL_DEFAULT));
-    }
-
-    private static final Logger LOG = LoggerFactory.getLogger(ZooKeeperSaslClient.class);
-    private static Login login = null;
-    private SaslClient saslClient;
-    private boolean isSASLConfigured = true;
-
-    private byte[] saslToken = new byte[0];
-
-    public enum SaslState {
-        INITIAL,INTERMEDIATE,COMPLETE,FAILED
-    }
-
-    private SaslState saslState = SaslState.INITIAL;
-
-    private boolean gotLastPacket = false;
-    /** informational message indicating the current configuration status */
-    private final String configStatus;
-
-    public SaslState getSaslState() {
-        return saslState;
-    }
-
-    public String getLoginContext() {
-        if (login != null)
-            return login.getLoginContextName();
-        return null;
-    }
-
-    public ZooKeeperSaslClient(final String serverPrincipal)
-            throws LoginException {
-        /**
-         * ZOOKEEPER-1373: allow system property to specify the JAAS
-         * configuration section that the zookeeper client should use.
-         * Default to "Client".
-         */
-        String clientSection = System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client");
-        // Note that 'Configuration' here refers to javax.security.auth.login.Configuration.
-        AppConfigurationEntry entries[] = null;
-        RuntimeException runtimeException = null;
-        try {
-            entries = Configuration.getConfiguration().getAppConfigurationEntry(clientSection);
-        } catch (SecurityException e) {
-            // handle below: might be harmless if the user doesn't intend to use JAAS authentication.
-            runtimeException = e;
-        } catch (IllegalArgumentException e) {
-            // third party customized getAppConfigurationEntry could throw IllegalArgumentException when JAAS
-            // configuration isn't set. We can reevaluate whether to catch RuntimeException instead when more 
-            // different types of RuntimeException found
-            runtimeException = e;
-        }
-        if (entries != null) {
-            this.configStatus = "Will attempt to SASL-authenticate using Login Context section '" + clientSection + "'";
-            this.saslClient = createSaslClient(serverPrincipal, clientSection);
-        } else {
-            // Handle situation of clientSection's being null: it might simply because the client does not intend to 
-            // use SASL, so not necessarily an error.
-            saslState = SaslState.FAILED;
-            String explicitClientSection = System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY);
-            if (explicitClientSection != null) {
-                // If the user explicitly overrides the default Login Context, they probably expected SASL to
-                // succeed. But if we got here, SASL failed.
-                if (runtimeException != null) {
-                    throw new LoginException("Zookeeper client cannot authenticate using the " + explicitClientSection +
-                            " section of the supplied JAAS configuration: '" +
-                            System.getProperty(Environment.JAAS_CONF_KEY) + "' because of a " +
-                            "RuntimeException: " + runtimeException);
-                } else {
-                    throw new LoginException("Client cannot SASL-authenticate because the specified JAAS configuration " +
-                            "section '" + explicitClientSection + "' could not be found.");
-                }
-            } else {
-                // The user did not override the default context. It might be that they just don't intend to use SASL,
-                // so log at INFO, not WARN, since they don't expect any SASL-related information.
-                String msg = "Will not attempt to authenticate using SASL ";
-                if (runtimeException != null) {
-                    msg += "(" + runtimeException + ")";
-                } else {
-                    msg += "(unknown error)";
-                }
-                this.configStatus = msg;
-                this.isSASLConfigured = false;
-            }
-            if (System.getProperty(Environment.JAAS_CONF_KEY)  != null) {
-                // Again, the user explicitly set something SASL-related, so they probably expected SASL to succeed.
-                if (runtimeException != null) {
-                    throw new LoginException("Zookeeper client cannot authenticate using the '" +
-                            System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client") +
-                            "' section of the supplied JAAS configuration: '" +
-                            System.getProperty(Environment.JAAS_CONF_KEY) + "' because of a " +
-                            "RuntimeException: " + runtimeException);
-                } else {
-                    throw new LoginException("No JAAS configuration section named '" +
-                            System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client") +
-                            "' was found in specified JAAS configuration file: '" +
-                            System.getProperty(Environment.JAAS_CONF_KEY) + "'.");
-                }
-            }
-        }
-    }
-    
-    /**
-     * @return informational message indicating the current configuration status.
-     */
-    public String getConfigStatus() {
-        return configStatus;
-    }
-
-    public boolean isComplete() {
-        return (saslState == SaslState.COMPLETE);
-    }
-
-    public boolean isFailed() {
-        return (saslState == SaslState.FAILED);
-    }
-
-    public static class ServerSaslResponseCallback implements AsyncCallback.DataCallback {
-        public void processResult(int rc, String path, Object ctx, byte data[], Stat stat) {
-            // processResult() is used by ClientCnxn's sendThread to respond to
-            // data[] contains the Zookeeper Server's SASL token.
-            // ctx is the ZooKeeperSaslClient object. We use this object's respondToServer() method
-            // to reply to the Zookeeper Server's SASL token
-            ZooKeeperSaslClient client = ((ClientCnxn)ctx).zooKeeperSaslClient;
-            if (client == null) {
-                LOG.warn("sasl client was unexpectedly null: cannot respond to Zookeeper server.");
-                return;
-            }
-            byte[] usedata = data;
-            if (data != null) {
-                LOG.debug("ServerSaslResponseCallback(): saslToken server response: (length="+usedata.length+")");
-            }
-            else {
-                usedata = new byte[0];
-                LOG.debug("ServerSaslResponseCallback(): using empty data[] as server response (length="+usedata.length+")");
-            }
-            client.respondToServer(usedata, (ClientCnxn)ctx);
-        }
-    }
-
-    private SaslClient createSaslClient(final String servicePrincipal,
-                                                     final String loginContext) throws LoginException {
-        try {
-            if (!initializedLogin) {
-                synchronized (ZooKeeperSaslClient.class) {
-                    if (login == null) {
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("JAAS loginContext is: " + loginContext);
-                        }
-                        // note that the login object is static: it's shared amongst all zookeeper-related connections.
-                        // in order to ensure the login is initialized only once, it must be synchronized the code snippet.
-                        login = new Login(loginContext, new SaslClientCallbackHandler(null, "Client"));
-                        login.startThreadIfNeeded();
-                        initializedLogin = true;
-                    }
-                }
-            }
-            return SecurityUtils.createSaslClient(login.getSubject(),
-                    servicePrincipal, "zookeeper", "zk-sasl-md5", LOG, "Client");
-        } catch (LoginException e) {
-            // We throw LoginExceptions...
-            throw e;
-        } catch (Exception e) {
-            // ..but consume (with a log message) all other types of exceptions.
-            LOG.error("Exception while trying to create SASL client: " + e);
-            return null;
-        }
-    }
-
-    public void respondToServer(byte[] serverToken, ClientCnxn cnxn) {
-        if (saslClient == null) {
-            LOG.error("saslClient is unexpectedly null. Cannot respond to server's SASL message; ignoring.");
-            return;
-        }
-
-        if (!(saslClient.isComplete())) {
-            try {
-                saslToken = createSaslToken(serverToken);
-                if (saslToken != null) {
-                    sendSaslPacket(saslToken, cnxn);
-                }
-            } catch (SaslException e) {
-                LOG.error("SASL authentication failed using login context '" +
-                        this.getLoginContext() + "' with exception: {}", e);
-                saslState = SaslState.FAILED;
-                gotLastPacket = true;
-            }
-        }
-
-        if (saslClient.isComplete()) {
-            // GSSAPI: server sends a final packet after authentication succeeds
-            // or fails.
-            if ((serverToken == null) && (saslClient.getMechanismName().equals("GSSAPI")))
-                gotLastPacket = true;
-            // non-GSSAPI: no final packet from server.
-            if (!saslClient.getMechanismName().equals("GSSAPI")) {
-                gotLastPacket = true;
-            }
-            // SASL authentication is completed, successfully or not:
-            // enable the socket's writable flag so that any packets waiting for authentication to complete in
-            // the outgoing queue will be sent to the Zookeeper server.
-            cnxn.enableWrite();
-        }
-    }
-
-    private byte[] createSaslToken() throws SaslException {
-        saslState = SaslState.INTERMEDIATE;
-        return createSaslToken(saslToken);
-    }
-
-    private byte[] createSaslToken(final byte[] saslToken) throws SaslException {
-        if (saslToken == null) {
-            // TODO: introspect about runtime environment (such as jaas.conf)
-            saslState = SaslState.FAILED;
-            throw new SaslException("Error in authenticating with a Zookeeper Quorum member: the quorum member's saslToken is null.");
-        }
-
-        Subject subject = login.getSubject();
-        if (subject != null) {
-            synchronized(login) {
-                try {
-                    final byte[] retval =
-                        Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
-                                public byte[] run() throws SaslException {
-                                    LOG.debug("saslClient.evaluateChallenge(len="+saslToken.length+")");
-                                    return saslClient.evaluateChallenge(saslToken);
-                                }
-                            });
-                    return retval;
-                }
-                catch (PrivilegedActionException e) {
-                    String error = "An error: (" + e + ") occurred when evaluating Zookeeper Quorum Member's " +
-                      " received SASL token.";
-                    // Try to provide hints to use about what went wrong so they can fix their configuration.
-                    // TODO: introspect about e: look for GSS information.
-                    final String UNKNOWN_SERVER_ERROR_TEXT =
-                      "(Mechanism level: Server not found in Kerberos database (7) - UNKNOWN_SERVER)";
-                    if (e.toString().indexOf(UNKNOWN_SERVER_ERROR_TEXT) > -1) {
-                        error += " This may be caused by Java's being unable to resolve the Zookeeper Quorum Member's" +
-                          " hostname correctly. You may want to try to adding" +
-                          " '-Dsun.net.spi.nameservice.provider.1=dns,sun' to your client's JVMFLAGS environment.";
-                    }
-                    error += " Zookeeper Client will go to AUTH_FAILED state.";
-                    LOG.error(error);
-                    saslState = SaslState.FAILED;
-                    throw new SaslException(error);
-                }
-            }
-        }
-        else {
-            throw new SaslException("Cannot make SASL token without subject defined. " +
-              "For diagnosis, please look for WARNs and ERRORs in your log related to the Login class.");
-        }
-    }
-
-    private void sendSaslPacket(byte[] saslToken, ClientCnxn cnxn)
-      throws SaslException{
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("ClientCnxn:sendSaslPacket:length="+saslToken.length);
-        }
-
-        GetSASLRequest request = new GetSASLRequest();
-        request.setToken(saslToken);
-        SetSASLResponse response = new SetSASLResponse();
-        ServerSaslResponseCallback cb = new ServerSaslResponseCallback();
-
-        try {
-            cnxn.sendPacket(request,response,cb, ZooDefs.OpCode.sasl);
-        } catch (IOException e) {
-            throw new SaslException("Failed to send SASL packet to server.",
-                e);
-        }
-    }
-
-    private void sendSaslPacket(ClientCnxn cnxn) throws SaslException {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("ClientCnxn:sendSaslPacket:length="+saslToken.length);
-        }
-        GetSASLRequest request = new GetSASLRequest();
-        request.setToken(createSaslToken());
-        SetSASLResponse response = new SetSASLResponse();
-        ServerSaslResponseCallback cb = new ServerSaslResponseCallback();
-        try {
-            cnxn.sendPacket(request,response,cb, ZooDefs.OpCode.sasl);
-        } catch (IOException e) {
-            throw new SaslException("Failed to send SASL packet to server due " +
-              "to IOException:", e);
-        }
-    }
-
-    // used by ClientCnxn to know whether to emit a SASL-related event: either AuthFailed or SaslAuthenticated,
-    // or none, if not ready yet. Sets saslState to COMPLETE as a side-effect.
-    public KeeperState getKeeperState() {
-        if (saslClient != null) {
-            if (saslState == SaslState.FAILED) {
-              return KeeperState.AuthFailed;
-            }
-            if (saslClient.isComplete()) {
-                if (saslState == SaslState.INTERMEDIATE) {
-                    saslState = SaslState.COMPLETE;
-                    return KeeperState.SaslAuthenticated;
-                }
-            }
-        }
-        // No event ready to emit yet.
-        return null;
-    }
-
-    // Initialize the client's communications with the Zookeeper server by sending the server the first
-    // authentication packet.
-    public void initialize(ClientCnxn cnxn) throws SaslException {
-        if (saslClient == null) {
-            saslState = SaslState.FAILED;
-            throw new SaslException("saslClient failed to initialize properly: it's null.");
-        }
-        if (saslState == SaslState.INITIAL) {
-            if (saslClient.hasInitialResponse()) {
-                sendSaslPacket(cnxn);
-            }
-            else {
-                byte[] emptyToken = new byte[0];
-                sendSaslPacket(emptyToken, cnxn);
-            }
-            saslState = SaslState.INTERMEDIATE;
-        }
-    }
-
-    public boolean clientTunneledAuthenticationInProgress() {
-    	if (!isSASLConfigured) {
-    	    return false;
-        } 
-        // TODO: Rather than checking a disjunction here, should be a single member
-        // variable or method in this class to determine whether the client is
-        // configured to use SASL. (see also ZOOKEEPER-1455).
-        try {
-  	    if ((System.getProperty(Environment.JAAS_CONF_KEY) != null) ||
-              ((javax.security.auth.login.Configuration.getConfiguration() != null) &&
-                  (javax.security.auth.login.Configuration.getConfiguration().
-                       getAppConfigurationEntry(System.
-                       getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY,"Client")) 
-                           != null))) {
-                // Client is configured to use a valid login Configuration, so
-                // authentication is either in progress, successful, or failed.
-
-                // 1. Authentication hasn't finished yet: we must wait for it to do so.
-                if ((isComplete() == false) &&
-                    (isFailed() == false)) {
-                    return true;
-                }
-
-                // 2. SASL authentication has succeeded or failed..
-                if (isComplete() || isFailed()) {
-                    if (gotLastPacket == false) {
-                        // ..but still in progress, because there is a final SASL
-                        // message from server which must be received.
-                    return true;
-                    }
-                }
-            }
-            // Either client is not configured to use a tunnelled authentication
-            // scheme, or tunnelled authentication has completed (successfully or
-            // not), and all server SASL messages have been received.
-            return false;
-        } catch (SecurityException e) {
-            // Thrown if the caller does not have permission to retrieve the Configuration.
-            // In this case, simply returning false is correct.
-            if (LOG.isDebugEnabled() == true) {
-                LOG.debug("Could not retrieve login configuration: " + e);
-            }
-            return false;
-        }
-    }
-
-
-}


[20/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherTest.java
deleted file mode 100644
index 1c06690..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherTest.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.ClientCnxn;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.AsyncCallback.StatCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.Watcher.Event;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class WatcherTest extends ClientBase {
-    protected static final Logger LOG = LoggerFactory.getLogger(WatcherTest.class);
-
-    private long timeOfLastWatcherInvocation;
-
-    private final class MyStatCallback implements StatCallback {
-        int rc;
-        public void processResult(int rc, String path, Object ctx, Stat stat) {
-            ((int[])ctx)[0]++;
-            this.rc = rc;
-        }
-    }
-
-    private class MyWatcher extends CountdownWatcher {
-        LinkedBlockingQueue<WatchedEvent> events =
-            new LinkedBlockingQueue<WatchedEvent>();
-
-        public void process(WatchedEvent event) {
-            super.process(event);
-            if (event.getType() != Event.EventType.None) {
-                timeOfLastWatcherInvocation = System.currentTimeMillis();
-                try {
-                    events.put(event);
-                } catch (InterruptedException e) {
-                    LOG.warn("ignoring interrupt during event.put");
-                }
-            }
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        // Reset to default value since some test cases set this to true.
-        // Needed for JDK7 since unit test can run is random order
-        ClientCnxn.setDisableAutoResetWatch(false);
-    }
-
-    /**
-     * Verify that we get all of the events we expect to get. This particular
-     * case verifies that we see all of the data events on a particular node.
-     * There was a bug (ZOOKEEPER-137) that resulted in events being dropped
-     * in some cases (timing).
-     *
-     * @throws IOException
-     * @throws InterruptedException
-     * @throws KeeperException
-     */
-    @Test
-    public void testWatcherCorrectness()
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk = null;
-        try {
-            MyWatcher watcher = new MyWatcher();
-            zk = createClient(watcher, hostPort);
-
-            StatCallback scb = new StatCallback() {
-                public void processResult(int rc, String path, Object ctx,
-                        Stat stat) {
-                    // don't do anything
-                }
-            };
-            VoidCallback vcb = new VoidCallback() {
-                public void processResult(int rc, String path, Object ctx) {
-                    // don't do anything
-                }
-            };
-
-            String names[] = new String[10];
-            for (int i = 0; i < names.length; i++) {
-                String name = zk.create("/tc-", "initialvalue".getBytes(),
-                        Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-                names[i] = name;
-
-                Stat stat = new Stat();
-                zk.getData(name, watcher, stat);
-                zk.setData(name, "new".getBytes(), stat.getVersion(), scb, null);
-                stat = zk.exists(name, watcher);
-                zk.delete(name, stat.getVersion(), vcb, null);
-            }
-
-            for (int i = 0; i < names.length; i++) {
-                String name = names[i];
-                WatchedEvent event = watcher.events.poll(10, TimeUnit.SECONDS);
-                Assert.assertEquals(name, event.getPath());
-                Assert.assertEquals(Event.EventType.NodeDataChanged, event.getType());
-                Assert.assertEquals(Event.KeeperState.SyncConnected, event.getState());
-                event = watcher.events.poll(10, TimeUnit.SECONDS);
-                Assert.assertEquals(name, event.getPath());
-                Assert.assertEquals(Event.EventType.NodeDeleted, event.getType());
-                Assert.assertEquals(Event.KeeperState.SyncConnected, event.getState());
-            }
-        } finally {
-            if (zk != null) {
-                zk.close();
-            }
-        }
-    }
-
-    @Test
-    public void testWatcherCount() 
-    throws IOException, InterruptedException, KeeperException {
-        ZooKeeper zk1 = null, zk2 = null;
-        try {
-            MyWatcher w1 = new MyWatcher();
-            zk1 = createClient(w1, hostPort);
-
-            MyWatcher w2 = new MyWatcher();
-            zk2 = createClient(w2, hostPort);
-
-            Stat stat = new Stat();
-            zk1.create("/watch-count-test", "value".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-            zk1.create("/watch-count-test-2", "value".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-
-            zk1.getData("/watch-count-test", w1, stat);
-            zk1.getData("/watch-count-test-2", w1, stat);
-            zk2.getData("/watch-count-test", w2, stat);
-
-            Assert.assertEquals(ClientBase.getServer(serverFactory)
-                    .getZKDatabase().getDataTree().getWatchCount(), 3);
-
-        } finally {
-            if(zk1 != null) {
-                zk1.close();
-            }
-            if(zk2 != null) {
-                zk2.close();
-            }
-        }
-
-    }
-
-    final static int COUNT = 100;
-    /**
-     * This test checks that watches for pending requests do not get triggered,
-     * but watches set by previous requests do.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testWatchAutoResetWithPending() throws Exception {
-       MyWatcher watches[] = new MyWatcher[COUNT];
-       MyStatCallback cbs[] = new MyStatCallback[COUNT];
-       MyWatcher watcher = new MyWatcher();
-       int count[] = new int[1];
-       TestableZooKeeper zk = createClient(watcher, hostPort, 6000);
-       ZooKeeper zk2 = createClient(watcher, hostPort, 5000);
-       zk2.create("/test", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-       for(int i = 0; i < COUNT/2; i++) {
-           watches[i] = new MyWatcher();
-           cbs[i] = new MyStatCallback();
-           zk.exists("/test", watches[i], cbs[i], count);
-       }
-       zk.exists("/test", false);
-       Assert.assertTrue("Failed to pause the connection!", zk.pauseCnxn(3000));
-       zk2.close();
-       stopServer();
-       watches[0].waitForDisconnected(60000);
-       for(int i = COUNT/2; i < COUNT; i++) {
-           watches[i] = new MyWatcher();
-           cbs[i] = new MyStatCallback();
-           zk.exists("/test", watches[i], cbs[i], count);
-       }
-       startServer();
-       watches[COUNT/2-1].waitForConnected(60000);
-       Assert.assertEquals(null, zk.exists("/test", false));
-       waitForAllWatchers();
-       for(int i = 0; i < COUNT/2; i++) {
-           Assert.assertEquals("For " + i, 1, watches[i].events.size());
-       }
-       for(int i = COUNT/2; i < COUNT; i++) {
-           if (cbs[i].rc == 0) {
-               Assert.assertEquals("For " +i, 1, watches[i].events.size());
-           } else {
-               Assert.assertEquals("For " +i, 0, watches[i].events.size());
-           }
-       }
-       Assert.assertEquals(COUNT, count[0]);
-       zk.close();
-    }
-
-    /**
-     * Wait until no watcher has been fired in the last second to ensure that all watches
-     * that are waiting to be fired have been fired
-     * @throws Exception
-     */
-    private void waitForAllWatchers() throws Exception {
-        timeOfLastWatcherInvocation = System.currentTimeMillis();
-        while (System.currentTimeMillis() - timeOfLastWatcherInvocation < 1000) {
-            Thread.sleep(1000);
-        }
-    }
-    
-    final int TIMEOUT = 5000;
-
-    @Test
-    public void testWatcherAutoResetWithGlobal() throws Exception {
-        ZooKeeper zk = null;
-        MyWatcher watcher = new MyWatcher();
-        zk = createClient(watcher, hostPort, TIMEOUT);
-        testWatcherAutoReset(zk, watcher, watcher);
-        zk.close();
-    }
-
-    @Test
-    public void testWatcherAutoResetWithLocal() throws Exception {
-        ZooKeeper zk = null;
-        MyWatcher watcher = new MyWatcher();
-        zk = createClient(watcher, hostPort, TIMEOUT);
-        testWatcherAutoReset(zk, watcher, new MyWatcher());
-        zk.close();
-    }
-
-    @Test
-    public void testWatcherAutoResetDisabledWithGlobal() throws Exception {
-        ClientCnxn.setDisableAutoResetWatch(true);
-        testWatcherAutoResetWithGlobal();
-    }
-
-    @Test
-    public void testWatcherAutoResetDisabledWithLocal() throws Exception {
-        ClientCnxn.setDisableAutoResetWatch(true);
-        testWatcherAutoResetWithLocal();
-    }
-
-    private void testWatcherAutoReset(ZooKeeper zk, MyWatcher globalWatcher,
-            MyWatcher localWatcher) throws Exception {
-        boolean isGlobal = (localWatcher == globalWatcher);
-        // First test to see if the watch survives across reconnects
-        zk.create("/watchtest", new byte[0], Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk.create("/watchtest/child", new byte[0], Ids.OPEN_ACL_UNSAFE,
-                CreateMode.EPHEMERAL);
-        if (isGlobal) {
-            zk.getChildren("/watchtest", true);
-            zk.getData("/watchtest/child", true, new Stat());
-            zk.exists("/watchtest/child2", true);
-        } else {
-            zk.getChildren("/watchtest", localWatcher);
-            zk.getData("/watchtest/child", localWatcher, new Stat());
-            zk.exists("/watchtest/child2", localWatcher);
-        }
-
-        Assert.assertTrue(localWatcher.events.isEmpty());
-
-        stopServer();
-        globalWatcher.waitForDisconnected(3000);
-        localWatcher.waitForDisconnected(500);
-        startServer();
-        globalWatcher.waitForConnected(3000);
-        if (!isGlobal && !ClientCnxn.getDisableAutoResetWatch()) {
-            localWatcher.waitForConnected(500);
-        }
-
-        Assert.assertTrue(localWatcher.events.isEmpty());
-        zk.setData("/watchtest/child", new byte[1], -1);
-        zk.create("/watchtest/child2", new byte[0], Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        WatchedEvent e;
-        if (!ClientCnxn.getDisableAutoResetWatch()) {
-            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-            Assert.assertEquals(e.getPath(), EventType.NodeDataChanged, e.getType());
-            Assert.assertEquals("/watchtest/child", e.getPath());
-        } else {
-            // we'll catch this later if it does happen after timeout, so
-            // why waste the time on poll
-        }
-
-        if (!ClientCnxn.getDisableAutoResetWatch()) {
-            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-            // The create will trigger the get children and the exist
-            // watches
-            Assert.assertEquals(EventType.NodeCreated, e.getType());
-            Assert.assertEquals("/watchtest/child2", e.getPath());
-        } else {
-            // we'll catch this later if it does happen after timeout, so
-            // why waste the time on poll
-        }
-
-        if (!ClientCnxn.getDisableAutoResetWatch()) {
-            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-            Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-            Assert.assertEquals("/watchtest", e.getPath());
-        } else {
-            // we'll catch this later if it does happen after timeout, so
-            // why waste the time on poll
-        }
-
-        Assert.assertTrue(localWatcher.events.isEmpty()); // ensure no late arrivals
-        stopServer();
-        globalWatcher.waitForDisconnected(TIMEOUT);
-        try {
-            try {
-                localWatcher.waitForDisconnected(500);
-                if (!isGlobal && !ClientCnxn.getDisableAutoResetWatch()) {
-                    Assert.fail("Got an event when I shouldn't have");
-                }
-            } catch(TimeoutException toe) {
-                if (ClientCnxn.getDisableAutoResetWatch()) {
-                    Assert.fail("Didn't get an event when I should have");
-                }
-                // Else what we are expecting since there are no outstanding watches
-            }
-        } catch (Exception e1) {
-            LOG.error("bad", e1);
-            throw new RuntimeException(e1);
-        }
-        startServer();
-        globalWatcher.waitForConnected(TIMEOUT);
-
-        if (isGlobal) {
-            zk.getChildren("/watchtest", true);
-            zk.getData("/watchtest/child", true, new Stat());
-            zk.exists("/watchtest/child2", true);
-        } else {
-            zk.getChildren("/watchtest", localWatcher);
-            zk.getData("/watchtest/child", localWatcher, new Stat());
-            zk.exists("/watchtest/child2", localWatcher);
-        }
-
-        // Do trigger an event to make sure that we do not get
-        // it later
-        zk.delete("/watchtest/child2", -1);
-
-        e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertEquals(EventType.NodeDeleted, e.getType());
-        Assert.assertEquals("/watchtest/child2", e.getPath());
-
-        e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-        Assert.assertEquals("/watchtest", e.getPath());
-
-        Assert.assertTrue(localWatcher.events.isEmpty());
-
-        stopServer();
-        globalWatcher.waitForDisconnected(TIMEOUT);
-        localWatcher.waitForDisconnected(500);
-        startServer();
-        globalWatcher.waitForConnected(TIMEOUT);
-        if (!isGlobal && !ClientCnxn.getDisableAutoResetWatch()) {
-            localWatcher.waitForConnected(500);
-        }
-
-        zk.delete("/watchtest/child", -1);
-        zk.delete("/watchtest", -1);
-
-        if (!ClientCnxn.getDisableAutoResetWatch()) {
-            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-            Assert.assertEquals(EventType.NodeDeleted, e.getType());
-            Assert.assertEquals("/watchtest/child", e.getPath());
-        } else {
-            // we'll catch this later if it does happen after timeout, so
-            // why waste the time on poll
-        }
-
-        // Make sure nothing is straggling!
-        Thread.sleep(1000);
-        Assert.assertTrue(localWatcher.events.isEmpty());
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java
deleted file mode 100644
index c213b2a..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.Arrays;
-
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZkDatabaseCorruptionTest extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(ZkDatabaseCorruptionTest.class);
-    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
-
-    private final QuorumBase qb = new QuorumBase();
-
-    @Before
-    public void setUp() throws Exception {
-        LOG.info("STARTING quorum " + getClass().getName());
-        qb.setUp();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        LOG.info("STOPPING quorum " + getClass().getName());
-    }
-
-    private void corruptFile(File f) throws IOException {
-        RandomAccessFile outFile = new RandomAccessFile(f, "rw");
-        outFile.write("fail servers".getBytes());
-        outFile.close();
-    }
-
-    private void corruptAllSnapshots(File snapDir) throws IOException {
-        File[] listFiles = snapDir.listFiles();
-        for (File f: listFiles) {
-            if (f.getName().startsWith("snapshot")) {
-                corruptFile(f);
-            }
-        }
-    }
-
-    private class NoopStringCallback implements AsyncCallback.StringCallback {
-        @Override
-        public void processResult(int rc, String path, Object ctx,
-                                  String name) {
-        }
-    }
-
-    @Test
-    public void testCorruption() throws Exception {
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        ZooKeeper zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        SyncRequestProcessor.setSnapCount(100);
-        for (int i = 0; i < 2000; i++) {
-            zk.create("/0-" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                      CreateMode.PERSISTENT, new NoopStringCallback(), null);
-        }
-        zk.close();
-
-        long leaderSid = 1;
-        QuorumPeer leader = null;
-        //find out who is the leader and kill it
-        for (QuorumPeer quorumPeer : Arrays.asList(qb.s1, qb.s2, qb.s3, qb.s4, qb.s5)) {
-            if (quorumPeer.getPeerState() == ServerState.LEADING) {
-                leader = quorumPeer;
-                break;
-            }
-            ++leaderSid;
-        }
-
-        Assert.assertNotNull("Cannot find the leader.", leader);
-        leader.shutdown();
-
-        // now corrupt the leader's database
-        FileTxnSnapLog snapLog = leader.getTxnFactory();
-        File snapDir= snapLog.getSnapDir();
-        //corrupt all the snapshot in the snapshot directory
-        corruptAllSnapshots(snapDir);
-        qb.shutdownServers();
-        qb.setupServers();
-
-        if (leaderSid != 1)qb.s1.start(); else leader = qb.s1;
-        if (leaderSid != 2)qb.s2.start(); else leader = qb.s2;
-        if (leaderSid != 3)qb.s3.start(); else leader = qb.s3;
-        if (leaderSid != 4)qb.s4.start(); else leader = qb.s4;
-        if (leaderSid != 5)qb.s5.start(); else leader = qb.s5;
-
-        try {
-            leader.start();
-            Assert.assertTrue(false);
-        } catch(RuntimeException re) {
-            LOG.info("Got an error: expected", re);
-        }
-        //wait for servers to be up
-        String[] list = qb.hostPort.split(",");
-        for (int i = 0; i < 5; i++) {
-            if(leaderSid != (i + 1)) {
-                String hp = list[i];
-                Assert.assertTrue("waiting for server up",
-                        ClientBase.waitForServerUp(hp,
-                                CONNECTION_TIMEOUT));
-                LOG.info("{} is accepting client connections", hp);
-            } else {
-                LOG.info("Skipping the leader");
-            }
-        }
-
-        zk = qb.createClient();
-        SyncRequestProcessor.setSnapCount(100);
-        for (int i = 2000; i < 4000; i++) {
-            zk.create("/0-" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                      CreateMode.PERSISTENT, new NoopStringCallback(), null);
-        }
-        zk.close();
-
-        if (leaderSid != 1)QuorumBase.shutdown(qb.s1);
-        if (leaderSid != 2)QuorumBase.shutdown(qb.s2);
-        if (leaderSid != 3)QuorumBase.shutdown(qb.s3);
-        if (leaderSid != 4)QuorumBase.shutdown(qb.s4);
-        if (leaderSid != 5)QuorumBase.shutdown(qb.s5);
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
deleted file mode 100644
index fbf09b3..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.Quotas;
-import org.apache.zookeeper.StatsTrack;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooKeeperMain;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZooKeeperQuotaTest extends ClientBase {
-
-
-    private static final Logger LOG = LoggerFactory.getLogger(
-            ZooKeeperQuotaTest.class);
-
-    @Test
-    public void testQuota() throws IOException,
-        InterruptedException, KeeperException, Exception {
-        final ZooKeeper zk = createClient();
-        final String path = "/a/b/v";
-        // making sure setdata works on /
-        zk.setData("/", "some".getBytes(), -1);
-        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        zk.create("/a/b/v/d", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        ZooKeeperMain.createQuota(zk, path, 5L, 10);
-
-        // see if its set
-        String absolutePath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
-        byte[] data = zk.getData(absolutePath, false, new Stat());
-        StatsTrack st = new StatsTrack(new String(data));
-        Assert.assertTrue("bytes are set", st.getBytes() == 5L);
-        Assert.assertTrue("num count is set", st.getCount() == 10);
-
-        String statPath = Quotas.quotaZookeeper + path + "/" + Quotas.statNode;
-        byte[] qdata = zk.getData(statPath, false, new Stat());
-        StatsTrack qst = new StatsTrack(new String(qdata));
-        Assert.assertTrue("bytes are set", qst.getBytes() == 8L);
-        Assert.assertTrue("count is set", qst.getCount() == 2);
-
-        //force server to restart and load from snapshot, not txn log
-        stopServer();
-        startServer();
-        stopServer();
-        startServer();
-        ZooKeeperServer server = getServer(serverFactory);
-        Assert.assertNotNull("Quota is still set",
-            server.getZKDatabase().getDataTree().getMaxPrefixWithQuota(path) != null);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java
deleted file mode 100644
index 0bbba61..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.KeeperException.Code;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.common.Time;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-
-public class ZooKeeperTestClient extends ZKTestCase implements Watcher {
-  protected String hostPort = "127.0.0.1:22801";
-
-  protected static final String dirOnZK = "/test_dir";
-
-  protected String testDirOnZK = dirOnZK + "/" + Time.currentElapsedTime();
-
-  LinkedBlockingQueue<WatchedEvent> events = new LinkedBlockingQueue<WatchedEvent>();
-
-  private WatchedEvent getEvent(int numTries) throws InterruptedException {
-    WatchedEvent event = null;
-    for (int i = 0; i < numTries; i++) {
-      System.out.println("i = " + i);
-      event = events.poll(10, TimeUnit.SECONDS);
-      if (event != null) {
-        break;
-      }
-      Thread.sleep(5000);
-    }
-    return event;
-
-  }
-
-  private void deleteZKDir(ZooKeeper zk, String nodeName)
-          throws IOException, InterruptedException, KeeperException {
-
-    Stat stat = zk.exists(nodeName, false);
-    if (stat == null) {
-      return;
-    }
-
-    List<String> children1 = zk.getChildren(nodeName, false);
-    List<String> c2 = zk.getChildren(nodeName, false, stat);
-
-    if (!children1.equals(c2)) {
-        Assert.fail("children lists from getChildren()/getChildren2() do not match");
-    }
-
-    if (!stat.equals(stat)) {
-        Assert.fail("stats from exists()/getChildren2() do not match");
-    }
-
-    if (children1.size() == 0) {
-      zk.delete(nodeName, -1);
-      return;
-    }
-    for (String n : children1) {
-      deleteZKDir(zk, n);
-    }
-  }
-
-  private void checkRoot() throws IOException,
-      InterruptedException {
-    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
-
-    try {
-      zk.create(dirOnZK, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-    } catch (KeeperException.NodeExistsException ke) {
-        // expected, sort of
-    } catch (KeeperException ke) {
-        Assert.fail("Unexpected exception code for create " + dirOnZK + ": "
-            + ke.getMessage());
-    }
-
-    try {
-      zk.create(testDirOnZK, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-    } catch (KeeperException.NodeExistsException ke) {
-        // expected, sort of
-    } catch (KeeperException ke) {
-        Assert.fail("Unexpected exception code for create " + testDirOnZK + ": "
-            + ke.getMessage());
-    }
-
-    zk.close();
-  }
-
-  private void enode_test_1() throws IOException,
-          InterruptedException, KeeperException {
-    checkRoot();
-    String parentName = testDirOnZK;
-    String nodeName = parentName + "/enode_abc";
-    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
-
-    Stat stat = zk.exists(parentName, false);
-    if (stat == null) {
-      try {
-        zk.create(parentName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-      } catch (KeeperException ke) {
-        Assert.fail("Creating node " + parentName + ke.getMessage());
-      }
-    }
-
-    try {
-      zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NODEEXISTS;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for createin: " + ke.getMessage());
-      }
-    }
-
-    stat = zk.exists(nodeName, false);
-    if (stat == null) {
-      Assert.fail("node " + nodeName + " should exist");
-    }
-    System.out.println("Closing client with sessionid: 0x"
-            + Long.toHexString(zk.getSessionId()));
-    zk.close();
-    zk = new ZooKeeper(hostPort, 10000, this);
-
-    for (int i = 0; i < 10; i++) {
-      System.out.println("i = " + i);
-      stat = zk.exists(nodeName, false);
-      if (stat != null) {
-        System.out.println("node " + nodeName
-            + " should not exist after reconnection close");
-      } else {
-        System.out.println("node " + nodeName
-            + " is gone after reconnection close!");
-        break;
-      }
-      Thread.sleep(5000);
-    }
-    deleteZKDir(zk, nodeName);
-    zk.close();
-
-  }
-
-  private void enode_test_2() throws IOException,
-          InterruptedException, KeeperException {
-    checkRoot();
-    String parentName = testDirOnZK;
-    String nodeName = parentName + "/enode_abc";
-    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
-    ZooKeeper zk_1 = new ZooKeeper(hostPort, 10000, this);
-
-    Stat stat_parent = zk_1.exists(parentName, false);
-    if (stat_parent == null) {
-      try {
-        zk.create(parentName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-      } catch (KeeperException ke) {
-        Assert.fail("Creating node " + parentName + ke.getMessage());
-      }
-    }
-
-    Stat stat_node = zk_1.exists(nodeName, false);
-    if (stat_node != null) {
-
-      try {
-        zk.delete(nodeName, -1);
-      } catch (KeeperException ke) {
-        Code code = ke.code();
-        boolean valid = code == KeeperException.Code.NONODE
-            || code == KeeperException.Code.NOTEMPTY;
-        if (!valid) {
-          Assert.fail("Unexpected exception code for delete: " + ke.getMessage());
-        }
-      }
-    }
-
-    List<String> firstGen1 = zk_1.getChildren(parentName, true);
-    Stat stat = new Stat();
-    List<String> firstGen2 = zk_1.getChildren(parentName, true, stat);
-
-    if (!firstGen1.equals(firstGen2)) {
-        Assert.fail("children lists from getChildren()/getChildren2() do not match");
-    }
-
-    if (!stat_parent.equals(stat)) {
-        Assert.fail("stat from exists()/getChildren() do not match");
-    }
-
-    try {
-      zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NODEEXISTS;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for createin: " + ke.getMessage());
-      }
-    }
-
-    Thread.sleep(5000);
-    WatchedEvent event = events.poll(10, TimeUnit.SECONDS);
-    if (event == null) {
-      throw new IOException("No event was delivered promptly");
-    }
-    if (event.getType() != EventType.NodeChildrenChanged
-        || !event.getPath().equalsIgnoreCase(parentName)) {
-      Assert.fail("Unexpected event was delivered: " + event.toString());
-    }
-
-    stat_node = zk_1.exists(nodeName, false);
-    if (stat_node == null) {
-      Assert.fail("node " + nodeName + " should exist");
-    }
-
-    try {
-      zk.delete(parentName, -1);
-      Assert.fail("Should be impossible to delete a non-empty node " + parentName);
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NOTEMPTY;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for delete: " + code);
-      }
-    }
-
-    try {
-      zk.create(nodeName + "/def", null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-      Assert.fail("Should be impossible to create child off Ephemeral node " + nodeName);
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NOCHILDRENFOREPHEMERALS;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for createin: " + code);
-      }
-    }
-
-    try {
-      List<String> children1 = zk.getChildren(nodeName, false);
-      List<String> children2 = zk.getChildren(nodeName, false, null);
-
-      if (!children1.equals(children2)) {
-          Assert.fail("children lists from getChildren()/getChildren2() does not match");
-      }
-
-      if (children1.size() > 0) {
-        Assert.fail("ephemeral node " + nodeName + " should not have children");
-      }
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NONODE;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for createin: " + code);
-      }
-    }
-    firstGen1 = zk_1.getChildren(parentName, true);
-    firstGen2 = zk_1.getChildren(parentName, true, null);
-
-    if (!firstGen1.equals(firstGen2)) {
-        Assert.fail("children list from getChildren()/getChildren2() does not match");
-    }
-
-    stat_node = zk_1.exists(nodeName, true);
-    if (stat_node == null) {
-      Assert.fail("node " + nodeName + " should exist");
-    }
-    System.out.println("session id of zk: " + zk.getSessionId());
-    System.out.println("session id of zk_1: " + zk_1.getSessionId());
-    zk.close();
-
-    Stat no_stat = zk_1.exists("nosuchnode", false);
-
-    event = this.getEvent(10);
-    if (event == null) {
-      throw new Error("First event was not delivered promptly");
-    }
-    if (!((event.getType() == EventType.NodeChildrenChanged &&
-           event.getPath().equalsIgnoreCase(parentName)) ||
-         (event.getType() == EventType.NodeDeleted &&
-           event.getPath().equalsIgnoreCase(nodeName)))) {
-      System.out.print(parentName + " "
-          + EventType.NodeChildrenChanged + " " + nodeName + " " + EventType.NodeDeleted);
-      Assert.fail("Unexpected first event was delivered: " + event.toString());
-    }
-
-    event = this.getEvent(10);
-
-    if (event == null) {
-      throw new Error("Second event was not delivered promptly");
-    }
-    if (!((event.getType() == EventType.NodeChildrenChanged &&
-        event.getPath().equalsIgnoreCase(parentName)) ||
-      (event.getType() == EventType.NodeDeleted &&
-        event.getPath().equalsIgnoreCase(nodeName)))) {
-      System.out.print(parentName + " "
-          + EventType.NodeChildrenChanged + " " + nodeName + " " + EventType.NodeDeleted);
-      Assert.fail("Unexpected second event was delivered: " + event.toString());
-    }
-
-    firstGen1 = zk_1.getChildren(parentName, false);
-    stat_node = zk_1.exists(nodeName, false);
-    if (stat_node != null) {
-      Assert.fail("node " + nodeName + " should have been deleted");
-    }
-    if (firstGen1.contains(nodeName)) {
-      Assert.fail("node " + nodeName + " should not be a children");
-    }
-    deleteZKDir(zk_1, nodeName);
-    zk_1.close();
-  }
-
-  private void delete_create_get_set_test_1() throws
-          IOException, InterruptedException, KeeperException {
-    checkRoot();
-    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
-    String parentName = testDirOnZK;
-    String nodeName = parentName + "/benwashere";
-    try {
-      zk.delete(nodeName, -1);
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NONODE
-          || code == KeeperException.Code.NOTEMPTY;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for delete: " + ke.getMessage());
-      }
-    }
-    try {
-      zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NODEEXISTS;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for create: " + ke.getMessage());
-      }
-    }
-    try {
-      zk.setData(nodeName, "hi".getBytes(), 5700);
-      Assert.fail("Should have gotten BadVersion exception");
-    } catch (KeeperException ke) {
-      if (ke.code() != Code.BADVERSION) {
-        Assert.fail("Should have gotten BadVersion exception");
-      }
-    }
-    zk.setData(nodeName, "hi".getBytes(), -1);
-    Stat st = new Stat();
-    byte[] bytes = zk.getData(nodeName, false, st);
-    String retrieved = new String(bytes);
-    if (!"hi".equals(retrieved)) {
-      Assert.fail("The retrieved data [" + retrieved
-          + "] is differented than the expected [hi]");
-    }
-    try {
-      zk.delete(nodeName, 6800);
-      Assert.fail("Should have gotten BadVersion exception");
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NOTEMPTY
-          || code == KeeperException.Code.BADVERSION;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for delete: " + ke.getMessage());
-      }
-    }
-    try {
-      zk.delete(nodeName, -1);
-    } catch (KeeperException ke) {
-      Code code = ke.code();
-      boolean valid = code == KeeperException.Code.NOTEMPTY;
-      if (!valid) {
-        Assert.fail("Unexpected exception code for delete: " + code);
-      }
-    }
-    deleteZKDir(zk, nodeName);
-    zk.close();
-  }
-
-  public void my_test_1() throws IOException,
-          InterruptedException, KeeperException {
-    enode_test_1();
-    enode_test_2();
-    delete_create_get_set_test_1();
-  }
-
-  synchronized public void process(WatchedEvent event) {
-    try {
-      System.out.println("Got an event " + event.toString());
-      events.put(event);
-    } catch (InterruptedException e) {
-      e.printStackTrace();
-    }
-  }
-
-  public static void main(String[] args) {
-    ZooKeeperTestClient zktc = new ZooKeeperTestClient();
-    try {
-      zktc.my_test_1();
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/check_compatibility.py
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/check_compatibility.py b/zookeeper-common/src/test/resources/check_compatibility.py
deleted file mode 100644
index cad8195..0000000
--- a/zookeeper-common/src/test/resources/check_compatibility.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-
-# Script which checks Java API compatibility between two revisions of the
-# Java client.
-#
-# Based on the compatibility checker from the HBase project, but ported to
-# Python for better readability.
-
-# Lifted from Kudu: https://github.com/apache/kudu/blob/master/build-support/check_compatibility.py
-
-import logging
-import optparse
-import os
-import shutil
-import subprocess
-import sys
-
-JAVA_ACC_GIT_URL = "https://github.com/lvc/japi-compliance-checker.git"
-
-# The annotations for what we consider our public API.
-PUBLIC_ANNOTATIONS = ["org.apache.yetus.audience.InterfaceAudience.LimitedPrivate",
-                      "org.apache.yetus.audience.InterfaceAudience.Public"]
-
-# Various relative paths
-PATH_TO_REPO_DIR = "../../../../"
-PATH_TO_BUILD_DIR = PATH_TO_REPO_DIR + "build/compat-check"
-PATH_TO_JACC_DIR = PATH_TO_REPO_DIR + "build/jacc"
-
-def check_output(*popenargs, **kwargs):
-    # r"""Run command with arguments and return its output as a byte string.
-    # Backported from Python 2.7 as it's implemented as pure python on stdlib.
-    # >>> check_output(['/usr/bin/python', '--version'])
-    # Python 2.6.2
-    # """
-    process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
-    output, unused_err = process.communicate()
-    retcode = process.poll()
-    if retcode:
-        cmd = kwargs.get("args")
-        if cmd is None:
-            cmd = popenargs[0]
-        error = subprocess.CalledProcessError(retcode, cmd)
-        error.output = output
-        raise error
-    return output
-
-def get_repo_dir():
-    """ Return the path to the top of the repo. """
-    dirname, _ = os.path.split(os.path.abspath(__file__))
-    return os.path.abspath(os.path.join(dirname, PATH_TO_REPO_DIR))
-
-
-def get_scratch_dir():
-    """ Return the path to the scratch dir that we build within. """
-    dirname, _ = os.path.split(os.path.abspath(__file__))
-    return os.path.abspath(os.path.join(dirname, PATH_TO_BUILD_DIR))
-
-
-def get_java_acc_dir():
-    dirname, _ = os.path.split(os.path.abspath(__file__))
-    return os.path.abspath(os.path.join(dirname, PATH_TO_JACC_DIR))
-
-
-def clean_scratch_dir(scratch_dir):
-    """ Clean up and re-create the scratch directory. """
-    if os.path.exists(scratch_dir):
-        logging.info("Removing scratch dir %s...", scratch_dir)
-        shutil.rmtree(scratch_dir)
-    logging.info("Creating empty scratch dir %s...", scratch_dir)
-    os.makedirs(scratch_dir)
-
-
-def checkout_tree(rev, path):
-    """ Check out the Java source tree for the given revision into the given path. """
-    logging.info("Checking out %s in %s", rev, path)
-    os.makedirs(path)
-    # Extract java source
-    subprocess.check_call(["bash", '-o', 'pipefail', "-c",
-                           ("git archive --format=tar %s | " +
-                            "tar -C \"%s\" -xf -") % (rev, path)],
-                          cwd=get_repo_dir())
-
-
-def get_git_hash(revname):
-    """ Convert 'revname' to its SHA-1 hash. """
-    return check_output(["git", "rev-parse", revname],
-                        cwd=get_repo_dir()).strip()
-
-
-def build_tree(path):
-    """ Run the Java build within 'path'. """
-    logging.info("Building in %s...", path)
-    subprocess.check_call(["ant", "jar"], cwd=path)
-
-
-def checkout_java_acc(force):
-    """
-    Check out the Java API Compliance Checker. If 'force' is true, will re-download even if the
-    directory exists.
-    """
-    acc_dir = get_java_acc_dir()
-    if os.path.exists(acc_dir):
-        logging.info("Java JAVA_ACC is already downloaded.")
-        if not force:
-            return
-        logging.info("Forcing re-download.")
-        shutil.rmtree(acc_dir)
-    logging.info("Checking out Java JAVA_ACC...")
-    subprocess.check_call(["git", "clone", "-b", "2.1", "--single-branch", "--depth=1", JAVA_ACC_GIT_URL, acc_dir])
-
-
-def find_client_jars(path):
-    """ Return a list of jars within 'path' to be checked for compatibility. """
-    return check_output(["find", path, "-name", "zookeeper*.jar"]).rstrip('\n')
-
-
-def run_java_acc(src_name, src, dst_name, dst):
-    """ Run the compliance checker to compare 'src' and 'dst'. """
-    src_jar = find_client_jars(src)
-    dst_jar = find_client_jars(dst)
-    logging.info("Will check compatibility between original jars:\n%s\n" +
-                 "and new jars:\n%s",
-                 src_jar, dst_jar)
-
-    annotations_path = os.path.join(get_scratch_dir(), "annotations.txt")
-    with file(annotations_path, "w") as f:
-        for ann in PUBLIC_ANNOTATIONS:
-            print >>f,  ann
-
-    java_acc_path = os.path.join(get_java_acc_dir(), "japi-compliance-checker.pl")
-
-    out_path = os.path.join(get_scratch_dir(), "report.html")
-    subprocess.check_call(["perl", java_acc_path,
-                           "-lib", "ZooKeeper",
-                           "-v1", src_name,
-                           "-v2", dst_name,
-                           "-d1", src_jar,
-                           "-d2", dst_jar,
-                           "-annotations-list", annotations_path,
-                           "-report-path", out_path])
-
-
-def main(argv):
-    logging.basicConfig(level=logging.INFO)
-    parser = optparse.OptionParser(
-        usage="usage: %prog SRC..[DST]")
-    parser.add_option("-f", "--force-download", dest="force_download_deps",
-                      help=("Download dependencies (i.e. Java JAVA_ACC) even if they are " +
-                            "already present"))
-    opts, args = parser.parse_args()
-
-    if len(args) != 1:
-        parser.error("no src/dst revision specified")
-        sys.exit(1)
-
-    src_rev, dst_rev = args[0].split("..", 1)
-    if dst_rev == "":
-        dst_rev = "HEAD"
-    src_rev = get_git_hash(src_rev)
-    dst_rev = get_git_hash(dst_rev)
-
-    logging.info("Source revision: %s", src_rev)
-    logging.info("Destination revision: %s", dst_rev)
-
-    # Download deps.
-    checkout_java_acc(opts.force_download_deps)
-
-    # Set up the build.
-    scratch_dir = get_scratch_dir()
-    clean_scratch_dir(scratch_dir)
-
-    # Check out the src and dst source trees.
-    src_dir = os.path.join(scratch_dir, "src")
-    dst_dir = os.path.join(scratch_dir, "dst")
-    checkout_tree(src_rev, src_dir)
-    checkout_tree(dst_rev, dst_dir)
-
-    # Run the build in each.
-    build_tree(src_dir)
-    build_tree(dst_dir)
-
-    run_java_acc(src_rev, src_dir + "/build",
-                 dst_rev, dst_dir + "/build")
-
-
-if __name__ == "__main__":
-    main(sys.argv)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/checkstyle-noframes-sorted.xsl
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/checkstyle-noframes-sorted.xsl b/zookeeper-common/src/test/resources/checkstyle-noframes-sorted.xsl
deleted file mode 100644
index 5f9e93b..0000000
--- a/zookeeper-common/src/test/resources/checkstyle-noframes-sorted.xsl
+++ /dev/null
@@ -1,178 +0,0 @@
-<xsl:stylesheet	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-<xsl:output method="html" indent="yes"/>
-<xsl:decimal-format decimal-separator="." grouping-separator="," />
-
-<xsl:key name="files" match="file" use="@name" />
-
-<!-- Checkstyle XML Style Sheet by Stephane Bailliez <sb...@apache.org>         -->
-<!-- Part of the Checkstyle distribution found at http://checkstyle.sourceforge.net -->
-<!-- Usage (generates checkstyle_report.html):                                      -->
-<!--    <checkstyle failonviolation="false" config="${check.config}">               -->
-<!--      <fileset dir="${src.dir}" includes="**/*.java"/>                          -->
-<!--      <formatter type="xml" toFile="${doc.dir}/checkstyle_report.xml"/>         -->
-<!--    </checkstyle>                                                               -->
-<!--    <style basedir="${doc.dir}" destdir="${doc.dir}"                            -->
-<!--            includes="checkstyle_report.xml"                                    -->
-<!--            style="${doc.dir}/checkstyle-noframes-sorted.xsl"/>                 -->
-
-<xsl:template match="checkstyle">
-	<html>
-		<head>
-		<style type="text/css">
-    .bannercell {
-      border: 0px;
-      padding: 0px;
-    }
-    body {
-      margin-left: 10;
-      margin-right: 10;
-      font:normal 80% arial,helvetica,sanserif;
-      background-color:#FFFFFF;
-      color:#000000;
-    }
-    .a td {
-      background: #efefef;
-    }
-    .b td {
-      background: #fff;
-    }
-    th, td {
-      text-align: left;
-      vertical-align: top;
-    }
-    th {
-      font-weight:bold;
-      background: #ccc;
-      color: black;
-    }
-    table, th, td {
-      font-size:100%;
-      border: none
-    }
-    table.log tr td, tr th {
-
-    }
-    h2 {
-      font-weight:bold;
-      font-size:140%;
-      margin-bottom: 5;
-    }
-    h3 {
-      font-size:100%;
-      font-weight:bold;
-      background: #525D76;
-      color: white;
-      text-decoration: none;
-      padding: 5px;
-      margin-right: 2px;
-      margin-left: 2px;
-      margin-bottom: 0;
-    }
-		</style>
-		</head>
-		<body>
-			<a name="top"></a>
-      <!-- jakarta logo -->
-      <table border="0" cellpadding="0" cellspacing="0" width="100%">
-      <tr>
-        <td class="bannercell" rowspan="2">
-          <!--a href="http://jakarta.apache.org/">
-          <img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
-          </a-->
-        </td>
-    		<td class="text-align:right"><h2>CheckStyle Audit</h2></td>
-    		</tr>
-    		<tr>
-    		<td class="text-align:right">Designed for use with <a href='http://checkstyle.sourceforge.net/'>CheckStyle</a> and <a href='http://jakarta.apache.org'>Ant</a>.</td>
-    		</tr>
-      </table>
-    	<hr size="1"/>
-
-			<!-- Summary part -->
-			<xsl:apply-templates select="." mode="summary"/>
-			<hr size="1" width="100%" align="left"/>
-
-			<!-- Package List part -->
-			<xsl:apply-templates select="." mode="filelist"/>
-			<hr size="1" width="100%" align="left"/>
-
-			<!-- For each package create its part -->
-            <xsl:apply-templates select="file[@name and generate-id(.) = generate-id(key('files', @name))]" />
-
-			<hr size="1" width="100%" align="left"/>
-
-
-		</body>
-	</html>
-</xsl:template>
-
-
-
-	<xsl:template match="checkstyle" mode="filelist">
-		<h3>Files</h3>
-		<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
-      <tr>
-        <th>Name</th>
-        <th>Errors</th>
-      </tr>
-          <xsl:for-each select="file[@name and generate-id(.) = generate-id(key('files', @name))]">
-                <xsl:sort data-type="number" order="descending" select="count(key('files', @name)/error)"/>
-				<xsl:variable name="errorCount" select="count(error)"/>
-				<tr>
-          <xsl:call-template name="alternated-row"/>
-					<td><a href="#f-{@name}"><xsl:value-of select="@name"/></a></td>
-					<td><xsl:value-of select="$errorCount"/></td>
-				</tr>
-			</xsl:for-each>
-		</table>
-	</xsl:template>
-
-
-	<xsl:template match="file">
-    <a name="f-{@name}"></a>
-    <h3>File <xsl:value-of select="@name"/></h3>
-
-    <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
-    	<tr>
-    	  <th>Error Description</th>
-    	  <th>Line</th>
-      </tr>
-        <xsl:for-each select="key('files', @name)/error">
-          <xsl:sort data-type="number" order="ascending" select="@line"/>
-    	<tr>
-        <xsl:call-template name="alternated-row"/>
-    	  <td><xsl:value-of select="@message"/></td>
-    	  <td><xsl:value-of select="@line"/></td>
-    	</tr>
-    	</xsl:for-each>
-    </table>
-    <a href="#top">Back to top</a>
-	</xsl:template>
-
-
-	<xsl:template match="checkstyle" mode="summary">
-		<h3>Summary</h3>
-        <xsl:variable name="fileCount" select="count(file[@name and generate-id(.) = generate-id(key('files', @name))])"/>
-		<xsl:variable name="errorCount" select="count(file/error)"/>
-		<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
-		<tr>
-			<th>Files</th>
-			<th>Errors</th>
-		</tr>
-		<tr>
-		  <xsl:call-template name="alternated-row"/>
-			<td><xsl:value-of select="$fileCount"/></td>
-			<td><xsl:value-of select="$errorCount"/></td>
-		</tr>
-		</table>
-	</xsl:template>
-
-  <xsl:template name="alternated-row">
-    <xsl:attribute name="class">
-      <xsl:if test="position() mod 2 = 1">a</xsl:if>
-      <xsl:if test="position() mod 2 = 0">b</xsl:if>
-    </xsl:attribute>
-  </xsl:template>
-</xsl:stylesheet>
-
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/checkstyle.xml
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/checkstyle.xml b/zookeeper-common/src/test/resources/checkstyle.xml
deleted file mode 100644
index a5d5182..0000000
--- a/zookeeper-common/src/test/resources/checkstyle.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE module PUBLIC
-    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
-    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
-
-<!--
-   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.
--->
-<!--
-  [Forked from Hadoop@2d7363b27360e36fdd62546c0f9d0b1d78133f29]
-
-  Checkstyle configuration for Zookeeper that is based on the sun_checks.xml file
-  that is bundled with Checkstyle and includes checks for:
-
-    - the Java Language Specification at
-      http://java.sun.com/docs/books/jls/second_edition/html/index.html
-
-    - the Sun Code Conventions at http://java.sun.com/docs/codeconv/
-
-    - the Javadoc guidelines at
-      http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
-
-    - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
-
-    - some best practices
-
-  Checkstyle is very configurable. Be sure to read the documentation at
-  http://checkstyle.sf.net (or in your downloaded distribution).
-
-  Most Checks are configurable, be sure to consult the documentation.
-
-  To completely disable a check, just comment it out or delete it from the file.
-
-  Finally, it is worth reading the documentation.
-
--->
-
-<module name="Checker">
-
-    <!-- Checks that a package.html file exists for each package.     -->
-    <!-- See http://checkstyle.sf.net/config_javadoc.html#PackageHtml -->
-    <module name="JavadocPackage"/>
-
-    <!-- Checks whether files end with a new line.                        -->
-    <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
-    <!-- module name="NewlineAtEndOfFile"/-->
-
-    <!-- Checks that property files contain the same keys.         -->
-    <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
-    <module name="Translation"/>
-
-    <module name="FileLength"/>
-    <module name="FileTabCharacter"/>
-
-    <module name="TreeWalker">
-
-        <!-- Checks for Javadoc comments.                     -->
-        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
-        <module name="JavadocType">
-          <property name="scope" value="public"/>
-          <property name="allowMissingParamTags" value="true"/>
-        </module>
-        <module name="JavadocStyle"/>
-
-        <!-- Checks for Naming Conventions.                  -->
-        <!-- See http://checkstyle.sf.net/config_naming.html -->
-        <module name="ConstantName"/>
-        <module name="LocalFinalVariableName"/>
-        <module name="LocalVariableName"/>
-        <module name="MemberName"/>
-        <module name="MethodName"/>
-        <module name="PackageName"/>
-        <module name="ParameterName"/>
-        <module name="StaticVariableName"/>
-        <module name="TypeName"/>
-
-
-        <!-- Checks for Headers                                -->
-        <!-- See http://checkstyle.sf.net/config_header.html   -->
-        <!-- <module name="Header">                            -->
-            <!-- The follow property value demonstrates the ability     -->
-            <!-- to have access to ANT properties. In this case it uses -->
-            <!-- the ${basedir} property to allow Checkstyle to be run  -->
-            <!-- from any directory within a project. See property      -->
-            <!-- expansion,                                             -->
-            <!-- http://checkstyle.sf.net/config.html#properties        -->
-            <!-- <property                                              -->
-            <!--     name="headerFile"                                  -->
-            <!--     value="${basedir}/java.header"/>                   -->
-        <!-- </module> -->
-
-        <!-- Following interprets the header file as regular expressions. -->
-        <!-- <module name="RegexpHeader"/>                                -->
-
-
-        <!-- Checks for imports                              -->
-        <!-- See http://checkstyle.sf.net/config_import.html -->
-        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
-        <module name="RedundantImport"/>
-        <module name="UnusedImports"/>
-
-
-        <!-- Checks for Size Violations.                    -->
-        <!-- See http://checkstyle.sf.net/config_sizes.html -->
-        <module name="LineLength">
-          <property name="ignorePattern" value="^import"/>
-        </module>
-        <module name="MethodLength"/>
-        <module name="ParameterNumber"/>
-
-
-        <!-- Checks for whitespace                               -->
-        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
-        <module name="EmptyForIteratorPad"/>
-        <module name="MethodParamPad"/>
-        <module name="NoWhitespaceAfter"/>
-        <module name="NoWhitespaceBefore"/>
-        <module name="ParenPad"/>
-        <module name="TypecastParenPad"/>
-        <module name="WhitespaceAfter">
-	    	<property name="tokens" value="COMMA, SEMI"/>
-		</module>
-
-
-        <!-- Modifier Checks                                    -->
-        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
-        <module name="ModifierOrder"/>
-        <module name="RedundantModifier"/>
-
-
-        <!-- Checks for blocks. You know, those {}'s         -->
-        <!-- See http://checkstyle.sf.net/config_blocks.html -->
-        <module name="AvoidNestedBlocks"/>
-        <module name="EmptyBlock"/>
-        <module name="LeftCurly"/>
-        <module name="NeedBraces"/>
-        <module name="RightCurly"/>
-
-
-        <!-- Checks for common coding problems               -->
-        <!-- See http://checkstyle.sf.net/config_coding.html -->
-        <!-- module name="AvoidInlineConditionals"/-->
-        <module name="EmptyStatement"/>
-        <module name="EqualsHashCode"/>
-        <module name="HiddenField">
-          <property name="ignoreConstructorParameter" value="true"/>
-        </module>
-        <module name="IllegalInstantiation"/>
-        <module name="InnerAssignment"/>
-        <module name="MissingSwitchDefault"/>
-        <module name="SimplifyBooleanExpression"/>
-        <module name="SimplifyBooleanReturn"/>
-
-        <!-- Checks for class design                         -->
-        <!-- See http://checkstyle.sf.net/config_design.html -->
-        <module name="FinalClass"/>
-        <module name="HideUtilityClassConstructor"/>
-        <module name="InterfaceIsType"/>
-        <module name="VisibilityModifier"/>
-
-
-        <!-- Miscellaneous other checks.                   -->
-        <!-- See http://checkstyle.sf.net/config_misc.html -->
-        <module name="ArrayTypeStyle"/>
-        <module name="Indentation">
-            <property name="basicOffset" value="4" />
-            <property name="caseIndent" value="0" />
-        </module> 
-        <module name="TodoComment"/>
-        <module name="UpperEll"/>
-
-    </module>
-
-</module>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/buffersize/create/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/buffersize/create/version-2/log.1 b/zookeeper-common/src/test/resources/data/buffersize/create/version-2/log.1
deleted file mode 100644
index 4f05bc1..0000000
Binary files a/zookeeper-common/src/test/resources/data/buffersize/create/version-2/log.1 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/buffersize/create/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/buffersize/create/version-2/snapshot.0 b/zookeeper-common/src/test/resources/data/buffersize/create/version-2/snapshot.0
deleted file mode 100644
index 49b512e..0000000
Binary files a/zookeeper-common/src/test/resources/data/buffersize/create/version-2/snapshot.0 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/buffersize/set/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/buffersize/set/version-2/log.1 b/zookeeper-common/src/test/resources/data/buffersize/set/version-2/log.1
deleted file mode 100644
index 8586f16..0000000
Binary files a/zookeeper-common/src/test/resources/data/buffersize/set/version-2/log.1 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/buffersize/set/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/buffersize/set/version-2/snapshot.0 b/zookeeper-common/src/test/resources/data/buffersize/set/version-2/snapshot.0
deleted file mode 100644
index 49b512e..0000000
Binary files a/zookeeper-common/src/test/resources/data/buffersize/set/version-2/snapshot.0 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/log.1 b/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/log.1
deleted file mode 100644
index 2f145a6..0000000
Binary files a/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/log.1 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0 b/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0
deleted file mode 100644
index 49b512e..0000000
Binary files a/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2 b/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2
deleted file mode 100644
index 59dfa70..0000000
Binary files a/zookeeper-common/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.1 b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.1
deleted file mode 100644
index 9dc15ae..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.1 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.274
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.274 b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.274
deleted file mode 100644
index 3bb868e..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.274 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.42
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.42 b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.42
deleted file mode 100644
index 5385be5..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.42 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.63b
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.63b b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.63b
deleted file mode 100644
index 4ee0a98..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/log.63b and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.0 b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.0
deleted file mode 100644
index 49b512e..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.0 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.272
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.272 b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.272
deleted file mode 100644
index 71f32a5..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.272 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.273
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.273 b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.273
deleted file mode 100644
index 3146f56..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.273 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.639
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.639 b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.639
deleted file mode 100644
index cf9e389..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.639 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.83f
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.83f b/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.83f
deleted file mode 100644
index 26dc5f6..0000000
Binary files a/zookeeper-common/src/test/resources/data/invalidsnap/version-2/snapshot.83f and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/kerberos/minikdc-krb5.conf
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/kerberos/minikdc-krb5.conf b/zookeeper-common/src/test/resources/data/kerberos/minikdc-krb5.conf
deleted file mode 100644
index 43ec7c4..0000000
--- a/zookeeper-common/src/test/resources/data/kerberos/minikdc-krb5.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# 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.
-#
-# This resource is originally from HDFS, see the similarly named files there
-# in case of bug fixing, history, etc.
-# Branch : trunk
-# Github Revision: 1d1ab587e4e92ce3aea4cb144811f69145cb3b33
-#
-[libdefaults]
-    default_realm = {0}
-    udp_preference_limit = 1
-
-[realms]
-    {0} = '{'
-        kdc = {1}:{2}
-    '}'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/kerberos/minikdc.ldiff
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/kerberos/minikdc.ldiff b/zookeeper-common/src/test/resources/data/kerberos/minikdc.ldiff
deleted file mode 100644
index 20c8d77..0000000
--- a/zookeeper-common/src/test/resources/data/kerberos/minikdc.ldiff
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# 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.
-#
-# This resource is originally from HDFS, see the similarly named files there
-# in case of bug fixing, history, etc.
-# Branch : trunk
-# Github Revision: 1d1ab587e4e92ce3aea4cb144811f69145cb3b33
-#
-dn: ou=users,dc=${0},dc=${1}
-objectClass: organizationalUnit
-objectClass: top
-ou: users
-
-dn: uid=krbtgt,ou=users,dc=${0},dc=${1}
-objectClass: top
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: krb5principal
-objectClass: krb5kdcentry
-cn: KDC Service
-sn: Service
-uid: krbtgt
-userPassword: secret
-krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3}
-krb5KeyVersionNumber: 0
-
-dn: uid=ldap,ou=users,dc=${0},dc=${1}
-objectClass: top
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: krb5principal
-objectClass: krb5kdcentry
-cn: LDAP
-sn: Service
-uid: ldap
-userPassword: secret
-krb5PrincipalName: ldap/${4}@${2}.${3}
-krb5KeyVersionNumber: 0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/upgrade/log.100000001
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/upgrade/log.100000001 b/zookeeper-common/src/test/resources/data/upgrade/log.100000001
deleted file mode 100644
index 00655f1..0000000
Binary files a/zookeeper-common/src/test/resources/data/upgrade/log.100000001 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/upgrade/log.100001bf0
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/upgrade/log.100001bf0 b/zookeeper-common/src/test/resources/data/upgrade/log.100001bf0
deleted file mode 100644
index 83fa697..0000000
Binary files a/zookeeper-common/src/test/resources/data/upgrade/log.100001bf0 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/upgrade/snapshot.100000000
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/upgrade/snapshot.100000000 b/zookeeper-common/src/test/resources/data/upgrade/snapshot.100000000
deleted file mode 100644
index 56f9015..0000000
Binary files a/zookeeper-common/src/test/resources/data/upgrade/snapshot.100000000 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/data/upgrade/snapshot.100001bec
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/data/upgrade/snapshot.100001bec b/zookeeper-common/src/test/resources/data/upgrade/snapshot.100001bec
deleted file mode 100644
index 0010d1e..0000000
Binary files a/zookeeper-common/src/test/resources/data/upgrade/snapshot.100001bec and /dev/null differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/findbugsExcludeFile.xml
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/findbugsExcludeFile.xml b/zookeeper-common/src/test/resources/findbugsExcludeFile.xml
deleted file mode 100644
index c023f4f..0000000
--- a/zookeeper-common/src/test/resources/findbugsExcludeFile.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<FindBugsFilter>
-  <!-- Allow command line utilities, which follow pattern *Main.java, to call
-       system exit -->
-  <Match>
-    <Class name="~org\.apache\.zookeeper\..*Main" />
-    <Bug pattern="DM_EXIT" />
-  </Match>
-
-  <!-- This is too complicated to resolve/ingrained into the architecture
-       In particular we want to make sure we exit if this occurs
-       Also notice logged as fatal error -->
-  <Match>
-    <Class name="org.apache.zookeeper.server.ZooKeeperCriticalThread" />
-    <Method name="handleException" />
-    <Bug pattern="DM_EXIT" />
-  </Match>
-
-  <!-- In particular we want to make sure we exit if this occurs, unrecoverable.
-       Also notice logged as fatal error -->
-  <Match>
-    <Class name="org.apache.zookeeper.server.ZooKeeperServer" />
-    <Method name="takeSnapshot" />
-    <Bug pattern="DM_EXIT" />
-  </Match>
-
-
-  <!-- We want to catch all exceptions and cleanup, regardless of source
-       (incl runtime) -->
-  <Match>
-    <Class name="org.apache.zookeeper.ClientCnxn$SendThread" />
-    <Method name="run" />
-    <Bug pattern="REC_CATCH_EXCEPTION" />
-  </Match>
-
-   <!-- If we cannot open a socket to elect a leader, then we should
-            simply exit -->
-   <Match>
-     <Class name="org.apache.zookeeper.server.quorum.LeaderElection" />
-       <Method name="lookForLeader" />
-       <Bug pattern="DM_EXIT" />
-   </Match>
-
-   <!-- Committing out of order is an unrecoverable error, so we should
-              really exit  -->
-   <Match>
-     <Class name="org.apache.zookeeper.server.quorum.FollowerZooKeeperServer" />
-       <Method name="commit" />
-       <Bug pattern="DM_EXIT" />
-     </Match>
-
-   <!-- Two unrecoverable errors while following the leader  -->
-   <Match>
-     <Class name="org.apache.zookeeper.server.quorum.Learner" />
-       <Method name="syncWithLeader" />
-       <Bug pattern="DM_EXIT" />
-   </Match>
-
-  <Match>
-    <Package name="org.apache.jute.compiler.generated" />
-  </Match>
-
-  <Match>
-    <Package name="~org\.apache\.zookeeper\.(proto|data|txn)" />
-    <Bug code="EI, EI2" />
-  </Match>
-
-  <Match>
-    <Class name="org.apache.zookeeper.server.DataNode" />
-      <Bug code="EI2"/>
-  </Match>
-
-  <Match>
-    <Class name="org.apache.zookeeper.server.quorum.QuorumPacket" />
-       <Bug code="EI2, EI" />
-  </Match>
-
-  <Match>
-    <Class name="org.apache.zookeeper.server.quorum.QuorumAuthPacket" />
-      <Bug code="EI2, EI" />
-  </Match>
-
-  <Match>
-    <Class name="org.apache.zookeeper.ClientCnxn"/>
-      <Bug code="EI, EI2" />
-  </Match>
-
-  <Match>
-    <Class name="org.apache.zookeeper.server.DataNode"/>
-      <Field name="children"/> 
-      <Bug code="IS"/>
-  </Match>
- <Match>
-   <Class name="org.apache.zookeeper.server.quorum.Leader"/>
-     <Field name="lastProposed"/>
-     <Bug code="IS"/>
-  </Match>
-  <Match>
-    <Class name="org.apache.zookeeper.server.persistence.FileTxnLog"/>
-    <Field name="serverStats"/>
-    <Bug code="IS"/>
-  </Match>
-  <Match>
-     <Class name="org.apache.zookeeper.server.quorum.LearnerSessionTracker"/>
-       <Bug code="UrF"/>
-  </Match>
-  <Match>
-    <Class name="org.apache.zookeeper.server.quorum.AuthFastLeaderElection$Messenger$WorkerSender"/>
-    <Method name="process"/>
-    <Bug code="RV,SF"/>
-  </Match>
-  <Match>
-    <Class name="org.apache.zookeeper.server.quorum.AuthFastLeaderElection$Messenger$WorkerReceiver"/>
-    <Method name="run"/>
-    <Bug code="SF"/>
-  </Match>
-
-  <!-- these are old classes just for upgrading and should go away -->
-  <Match>
-    <Class name="org.apache.zookeeper.server.quorum.AuthFastLeaderElection"/>
-  </Match>
-  <Match>
-    <Class name="org.apache.zookeeper.server.upgrade.DataNodeV1"/>
-  </Match> 
-
-  <Match>
-    <Class name="org.apache.zookeeper.server.upgrade.DataTreeV1"/>
-  </Match>
-
-  <!-- References code in a generated file that may or maynot be null -->
-  <Match>
-    <Class name="org.apache.zookeeper.Version" />
-    <Method name="getVersion" />
-    <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE" />
-  </Match>
-
-  <!-- sync'd object is also being used to protect the isrunning flag, this is ok -->
-  <Match>
-    <Class name="org.apache.zookeeper.ClientCnxn$EventThread"/>
-    <Bug code="JLM"/>
-    <Or>
-      <Method name="queuePacket" />
-      <Method name="run" />
-    </Or>
-  </Match>
-
-  <Match>
-    <Class name="org.apache.zookeeper.server.quorum.QuorumPeer"/>
-    <Bug pattern="OS_OPEN_STREAM" />
-    <Method name="writeLongToFile" />
-  </Match>
-
-  <!-- Disable 'Malicious code vulnerability warnings' due to mutable collection types in interface.
-       Undo this when ZOOKEEPER-1362 is done. -->
-  <Match>
-    <Class name="org.apache.zookeeper.ZooDefs$Ids"/>
-      <Bug pattern="MS_MUTABLE_COLLECTION" />
-  </Match>
-
-  <!-- Disable 'Found reliance on default encoding in' warnings. Ideally this should be fixed
-       by fixing the underlying cause - reliance on 'default' encoding in IO operations.
-       Please see ZOOKEEPER-1976 for detailed discussion. -->
-  <Match>
-    <Bug pattern="DM_DEFAULT_ENCODING" />
-  </Match>
-
-</FindBugsFilter>


[03/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/StandaloneTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/StandaloneTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StandaloneTest.java
new file mode 100644
index 0000000..f305423
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StandaloneTest.java
@@ -0,0 +1,65 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Standalone server tests.
+ */
+public class StandaloneTest extends QuorumPeerTestBase implements Watcher{
+    protected static final Logger LOG =
+        LoggerFactory.getLogger(StandaloneTest.class);    
+      
+    /**
+     * Ensure that a single standalone server comes up when misconfigured
+     * with a single server.# line in the configuration. This handles the
+     * case of HBase, which configures zoo.cfg in this way. Maintain b/w
+     * compatibility.
+     * TODO remove in a future version (4.0.0 hopefully)
+     */
+    @Test
+    public void testStandaloneQuorum() throws Exception {
+        ClientBase.setupTestEnv();
+        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
+        
+        String quorumCfgSection =
+            "server.1=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + "\n";
+                    
+        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
+        q1.start();
+        try {
+            Assert.assertTrue("waiting for server 1 being up",
+                    ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1,
+                            CONNECTION_TIMEOUT));
+        } finally {
+            q1.shutdown();
+        }
+    }    
+    
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/StatTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/StatTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StatTest.java
new file mode 100644
index 0000000..f4c01aa
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StatTest.java
@@ -0,0 +1,205 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class StatTest extends ClientBase {
+    private ZooKeeper zk;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        zk = createClient();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        zk.close();
+    }
+
+    /**
+     * Create a new Stat, fill in dummy values trying to catch Assert.failure
+     * to copy in client or server code.
+     *
+     * @return a new stat with dummy values
+     */
+    private Stat newStat() {
+        Stat stat = new Stat();
+
+        stat.setAversion(100);
+        stat.setCtime(100);
+        stat.setCversion(100);
+        stat.setCzxid(100);
+        stat.setDataLength(100);
+        stat.setEphemeralOwner(100);
+        stat.setMtime(100);
+        stat.setMzxid(100);
+        stat.setNumChildren(100);
+        stat.setPzxid(100);
+        stat.setVersion(100);
+
+        return stat;
+    }
+
+    @Test
+    public void testBasic()
+        throws IOException, KeeperException, InterruptedException
+    {
+        String name = "/foo";
+        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        Stat stat;
+
+        stat = newStat();
+        zk.getData(name, false, stat);
+
+        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
+        Assert.assertEquals(stat.getCtime(), stat.getMtime());
+        Assert.assertEquals(0, stat.getCversion());
+        Assert.assertEquals(0, stat.getVersion());
+        Assert.assertEquals(0, stat.getAversion());
+        Assert.assertEquals(0, stat.getEphemeralOwner());
+        Assert.assertEquals(name.length(), stat.getDataLength());
+        Assert.assertEquals(0, stat.getNumChildren());
+    }
+
+    @Test
+    public void testChild()
+        throws IOException, KeeperException, InterruptedException
+    {
+        String name = "/foo";
+        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        String childname = name + "/bar";
+        zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.EPHEMERAL);
+
+        Stat stat;
+
+        stat = newStat();
+        zk.getData(name, false, stat);
+
+        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+        Assert.assertEquals(stat.getCzxid() + 1, stat.getPzxid());
+        Assert.assertEquals(stat.getCtime(), stat.getMtime());
+        Assert.assertEquals(1, stat.getCversion());
+        Assert.assertEquals(0, stat.getVersion());
+        Assert.assertEquals(0, stat.getAversion());
+        Assert.assertEquals(0, stat.getEphemeralOwner());
+        Assert.assertEquals(name.length(), stat.getDataLength());
+        Assert.assertEquals(1, stat.getNumChildren());
+
+        stat = newStat();
+        zk.getData(childname, false, stat);
+
+        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
+        Assert.assertEquals(stat.getCtime(), stat.getMtime());
+        Assert.assertEquals(0, stat.getCversion());
+        Assert.assertEquals(0, stat.getVersion());
+        Assert.assertEquals(0, stat.getAversion());
+        Assert.assertEquals(zk.getSessionId(), stat.getEphemeralOwner());
+        Assert.assertEquals(childname.length(), stat.getDataLength());
+        Assert.assertEquals(0, stat.getNumChildren());
+    }
+
+    @Test
+    public void testChildren()
+        throws IOException, KeeperException, InterruptedException
+    {
+        String name = "/foo";
+        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        for(int i = 0; i < 10; i++) {
+            String childname = name + "/bar" + i;
+            zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.EPHEMERAL);
+
+            Stat stat;
+
+            stat = newStat();
+            zk.getData(name, false, stat);
+
+            Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+            Assert.assertEquals(stat.getCzxid() + i + 1, stat.getPzxid());
+            Assert.assertEquals(stat.getCtime(), stat.getMtime());
+            Assert.assertEquals(i + 1, stat.getCversion());
+            Assert.assertEquals(0, stat.getVersion());
+            Assert.assertEquals(0, stat.getAversion());
+            Assert.assertEquals(0, stat.getEphemeralOwner());
+            Assert.assertEquals(name.length(), stat.getDataLength());
+            Assert.assertEquals(i + 1, stat.getNumChildren());
+        }
+    }
+
+    @Test
+    public void testDataSizeChange()
+        throws IOException, KeeperException, InterruptedException
+    {
+        String name = "/foo";
+        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        Stat stat;
+
+        stat = newStat();
+        zk.getData(name, false, stat);
+
+        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
+        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
+        Assert.assertEquals(stat.getCtime(), stat.getMtime());
+        Assert.assertEquals(0, stat.getCversion());
+        Assert.assertEquals(0, stat.getVersion());
+        Assert.assertEquals(0, stat.getAversion());
+        Assert.assertEquals(0, stat.getEphemeralOwner());
+        Assert.assertEquals(name.length(), stat.getDataLength());
+        Assert.assertEquals(0, stat.getNumChildren());
+
+        zk.setData(name, (name + name).getBytes(), -1);
+
+        stat = newStat();
+        zk.getData(name, false, stat);
+
+        Assert.assertNotSame(stat.getCzxid(), stat.getMzxid());
+        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
+        Assert.assertNotSame(stat.getCtime(), stat.getMtime());
+        Assert.assertEquals(0, stat.getCversion());
+        Assert.assertEquals(1, stat.getVersion());
+        Assert.assertEquals(0, stat.getAversion());
+        Assert.assertEquals(0, stat.getEphemeralOwner());
+        Assert.assertEquals(name.length() * 2, stat.getDataLength());
+        Assert.assertEquals(0, stat.getNumChildren());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java
new file mode 100644
index 0000000..a4107a5
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java
@@ -0,0 +1,362 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.client.HostProvider;
+import org.apache.zookeeper.client.StaticHostProvider;
+import org.apache.zookeeper.common.Time;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.hasItems;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class StaticHostProviderTest extends ZKTestCase {
+    private static final Logger LOG = LoggerFactory.getLogger(StaticHostProviderTest.class);
+
+    @Test
+    public void testNextGoesRound() {
+        HostProvider hostProvider = getHostProvider((byte) 2);
+        InetSocketAddress first = hostProvider.next(0);
+        assertTrue(first instanceof InetSocketAddress);
+        hostProvider.next(0);
+        assertEquals(first, hostProvider.next(0));
+    }
+
+    @Test
+    public void testNextGoesRoundAndSleeps() {
+        byte size = 2;
+        HostProvider hostProvider = getHostProvider(size);
+        while (size > 0) {
+            hostProvider.next(0);
+            --size;
+        }
+        long start = Time.currentElapsedTime();
+        hostProvider.next(1000);
+        long stop = Time.currentElapsedTime();
+        assertTrue(900 <= stop - start);
+    }
+
+    @Test
+    public void testNextDoesNotSleepForZero() {
+        byte size = 2;
+        HostProvider hostProvider = getHostProvider(size);
+        while (size > 0) {
+            hostProvider.next(0);
+            --size;
+        }
+        long start = Time.currentElapsedTime();
+        hostProvider.next(0);
+        long stop = Time.currentElapsedTime();
+        assertTrue(5 > stop - start);
+    }
+
+    @Test
+    public void testTwoConsequitiveCallsToNextReturnDifferentElement() {
+        HostProvider hostProvider = getHostProvider((byte) 2);
+        assertNotSame(hostProvider.next(0), hostProvider.next(0));
+    }
+
+    @Test
+    public void testOnConnectDoesNotReset() {
+        HostProvider hostProvider = getHostProvider((byte) 2);
+        InetSocketAddress first = hostProvider.next(0);
+        hostProvider.onConnected();
+        InetSocketAddress second = hostProvider.next(0);
+        assertNotSame(first, second);
+    }
+
+    @Test
+    public void testLiteralIPNoReverseNS() {
+        byte size = 30;
+        HostProvider hostProvider = getHostProviderUnresolved(size);
+        for (int i = 0; i < size; i++) {
+            InetSocketAddress next = hostProvider.next(0);
+            assertTrue(next instanceof InetSocketAddress);
+            assertTrue(!next.isUnresolved());
+            assertTrue("InetSocketAddress must not have hostname part " +
+                    next.toString(), next.toString().startsWith("/"));
+            // Do NOT trigger the reverse name service lookup.
+            String hostname = next.getHostName();
+            // In this case, the hostname equals literal IP address.
+            hostname.equals(next.getAddress().getHostAddress());
+        }
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testEmptyServerAddressesList() {
+        HostProvider hp = new StaticHostProvider(new ArrayList<InetSocketAddress>());
+    }
+
+    @Test
+    public void testInvalidHostAddresses() {
+        // Arrange
+        final List<InetSocketAddress> invalidAddresses = new ArrayList<InetSocketAddress>();
+        InetSocketAddress unresolved = InetSocketAddress.createUnresolved("a", 1234);
+        invalidAddresses.add(unresolved);
+        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
+            @Override
+            public InetAddress[] getAllByName(String name) throws UnknownHostException {
+                throw new UnknownHostException();
+            }
+        };
+        StaticHostProvider sp = new StaticHostProvider(invalidAddresses, resolver);
+
+        // Act & Assert
+        InetSocketAddress n1 = sp.next(0);
+        assertTrue("Provider should return unresolved address is host is unresolvable", n1.isUnresolved());
+        assertSame("Provider should return original address is host is unresolvable", unresolved, n1);
+    }
+
+    @Test
+    public void testReResolvingSingle() throws UnknownHostException {
+        // Arrange
+        byte size = 1;
+        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
+
+        // Test a hostname that resolves to a single address
+        list.add(InetSocketAddress.createUnresolved("issues.apache.org", 1234));
+
+        final InetAddress issuesApacheOrg = mock(InetAddress.class);
+        when(issuesApacheOrg.getHostAddress()).thenReturn("192.168.1.1");
+        when(issuesApacheOrg.toString()).thenReturn("issues.apache.org");
+        when(issuesApacheOrg.getHostName()).thenReturn("issues.apache.org");
+
+        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
+            @Override
+            public InetAddress[] getAllByName(String name) {
+                return new InetAddress[] {
+                        issuesApacheOrg
+                };
+            }
+        };
+        StaticHostProvider.Resolver spyResolver = spy(resolver);
+
+        // Act
+        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
+        for (int i = 0; i < 10; i++) {
+            InetSocketAddress next = hostProvider.next(0);
+            assertEquals(issuesApacheOrg, next.getAddress());
+        }
+
+        // Assert
+        // Resolver called 10 times, because we shouldn't cache the resolved addresses
+        verify(spyResolver, times(10)).getAllByName("issues.apache.org"); // resolution occurred
+    }
+
+    @Test
+    public void testReResolvingMultiple() throws UnknownHostException {
+        // Arrange
+        byte size = 1;
+        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
+
+        // Test a hostname that resolves to multiple addresses
+        list.add(InetSocketAddress.createUnresolved("www.apache.org", 1234));
+
+        final InetAddress apacheOrg1 = mock(InetAddress.class);
+        when(apacheOrg1.getHostAddress()).thenReturn("192.168.1.1");
+        when(apacheOrg1.toString()).thenReturn("www.apache.org");
+        when(apacheOrg1.getHostName()).thenReturn("www.apache.org");
+
+        final InetAddress apacheOrg2 = mock(InetAddress.class);
+        when(apacheOrg2.getHostAddress()).thenReturn("192.168.1.2");
+        when(apacheOrg2.toString()).thenReturn("www.apache.org");
+        when(apacheOrg2.getHostName()).thenReturn("www.apache.org");
+
+        final List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>();
+        resolvedAddresses.add(apacheOrg1);
+        resolvedAddresses.add(apacheOrg2);
+        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
+            @Override
+            public InetAddress[] getAllByName(String name) {
+                return resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
+            }
+        };
+        StaticHostProvider.Resolver spyResolver = spy(resolver);
+
+        // Act & Assert
+        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
+        assertEquals(1, hostProvider.size()); // single address not extracted
+
+        for (int i = 0; i < 10; i++) {
+            InetSocketAddress next = hostProvider.next(0);
+            assertThat("Bad IP address returned", next.getAddress().getHostAddress(), anyOf(equalTo(apacheOrg1.getHostAddress()), equalTo(apacheOrg2.getHostAddress())));
+            assertEquals(1, hostProvider.size()); // resolve() call keeps the size of provider
+        }
+        // Resolver called 10 times, because we shouldn't cache the resolved addresses
+        verify(spyResolver, times(10)).getAllByName("www.apache.org"); // resolution occurred
+    }
+
+    @Test
+    public void testReResolveMultipleOneFailing() throws UnknownHostException {
+        // Arrange
+        final List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
+        list.add(InetSocketAddress.createUnresolved("www.apache.org", 1234));
+        final List<String> ipList = new ArrayList<String>();
+        final List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>();
+        for (int i = 0; i < 3; i++) {
+            ipList.add(String.format("192.168.1.%d", i+1));
+            final InetAddress apacheOrg = mock(InetAddress.class);
+            when(apacheOrg.getHostAddress()).thenReturn(String.format("192.168.1.%d", i+1));
+            when(apacheOrg.toString()).thenReturn(String.format("192.168.1.%d", i+1));
+            when(apacheOrg.getHostName()).thenReturn("www.apache.org");
+            resolvedAddresses.add(apacheOrg);
+        }
+
+        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
+            @Override
+            public InetAddress[] getAllByName(String name) {
+                return resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
+            }
+        };
+        StaticHostProvider.Resolver spyResolver = spy(resolver);
+        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
+
+        // Act & Assert
+        InetSocketAddress resolvedFirst = hostProvider.next(0);
+        assertFalse("HostProvider should return resolved addresses", resolvedFirst.isUnresolved());
+        assertThat("Bad IP address returned", ipList, hasItems(resolvedFirst.getAddress().getHostAddress()));
+
+        hostProvider.onConnected(); // first address worked
+
+        InetSocketAddress resolvedSecond = hostProvider.next(0);
+        assertFalse("HostProvider should return resolved addresses", resolvedSecond.isUnresolved());
+        assertThat("Bad IP address returned", ipList, hasItems(resolvedSecond.getAddress().getHostAddress()));
+
+        // Second address doesn't work, so we don't call onConnected() this time
+        // StaticHostProvider should try to re-resolve the address in this case
+
+        InetSocketAddress resolvedThird = hostProvider.next(0);
+        assertFalse("HostProvider should return resolved addresses", resolvedThird.isUnresolved());
+        assertThat("Bad IP address returned", ipList, hasItems(resolvedThird.getAddress().getHostAddress()));
+
+        verify(spyResolver, times(3)).getAllByName("www.apache.org");  // resolution occured every time
+    }
+
+    @Test
+    public void testEmptyResolution() throws UnknownHostException {
+        // Arrange
+        final List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
+        list.add(InetSocketAddress.createUnresolved("www.apache.org", 1234));
+        list.add(InetSocketAddress.createUnresolved("www.google.com", 1234));
+        final List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>();
+
+        final InetAddress apacheOrg1 = mock(InetAddress.class);
+        when(apacheOrg1.getHostAddress()).thenReturn("192.168.1.1");
+        when(apacheOrg1.toString()).thenReturn("www.apache.org");
+        when(apacheOrg1.getHostName()).thenReturn("www.apache.org");
+
+        resolvedAddresses.add(apacheOrg1);
+
+        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
+            @Override
+            public InetAddress[] getAllByName(String name) {
+                if ("www.apache.org".equalsIgnoreCase(name)) {
+                    return resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
+                } else {
+                    return new InetAddress[0];
+                }
+            }
+        };
+        StaticHostProvider.Resolver spyResolver = spy(resolver);
+        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
+
+        // Act & Assert
+        for (int i = 0; i < 10; i++) {
+            InetSocketAddress resolved = hostProvider.next(0);
+            hostProvider.onConnected();
+            if (resolved.getHostName().equals("www.google.com")) {
+                assertTrue("HostProvider should return unresolved address if host is unresolvable", resolved.isUnresolved());
+            } else {
+                assertFalse("HostProvider should return resolved addresses", resolved.isUnresolved());
+                assertEquals("192.168.1.1", resolved.getAddress().getHostAddress());
+            }
+        }
+
+        verify(spyResolver, times(5)).getAllByName("www.apache.org");
+        verify(spyResolver, times(5)).getAllByName("www.google.com");
+    }
+
+    @Test
+    public void testReResolvingLocalhost() {
+        byte size = 2;
+        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
+
+        // Test a hostname that resolves to multiple addresses
+        list.add(InetSocketAddress.createUnresolved("localhost", 1234));
+        list.add(InetSocketAddress.createUnresolved("localhost", 1235));
+        StaticHostProvider hostProvider = new StaticHostProvider(list);
+        int sizeBefore = hostProvider.size();
+        InetSocketAddress next = hostProvider.next(0);
+        next = hostProvider.next(0);
+        assertTrue("Different number of addresses in the list: " + hostProvider.size() +
+                " (after), " + sizeBefore + " (before)", hostProvider.size() == sizeBefore);
+    }
+
+    private StaticHostProvider getHostProviderUnresolved(byte size) {
+        return new StaticHostProvider(getUnresolvedServerAddresses(size));
+    }
+
+    private Collection<InetSocketAddress> getUnresolvedServerAddresses(byte size) {
+        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
+        while (size > 0) {
+            list.add(InetSocketAddress.createUnresolved("192.0.2." + size, 1234 + size));
+            --size;
+        }
+        return list;
+    }
+
+    private StaticHostProvider getHostProvider(byte size) {
+        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(
+                size);
+        while (size > 0) {
+            try {
+                list.add(new InetSocketAddress(InetAddress.getByAddress(new byte[]{-64, 0, 2, size}), 1234 + size));
+            } catch (UnknownHostException e) {
+                LOG.error("Exception while resolving address", e);
+                fail("Failed to resolve address");
+            }
+            --size;
+        }
+        return new StaticHostProvider(list);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/SyncCallTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/SyncCallTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SyncCallTest.java
new file mode 100644
index 0000000..4fb006a
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/SyncCallTest.java
@@ -0,0 +1,108 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.Children2Callback;
+import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SyncCallTest extends ClientBase
+    implements ChildrenCallback, Children2Callback, StringCallback, VoidCallback
+{
+    private CountDownLatch opsCount;
+    
+    List<Integer> results = new LinkedList<Integer>();
+    Integer limit = 100 + 1 + 100 + 100;
+    
+    @Test
+    public void testSync() throws Exception {
+        try {
+            LOG.info("Starting ZK:" + (new Date()).toString());
+            opsCount = new CountDownLatch(limit);
+            ZooKeeper zk = createClient();
+            
+            LOG.info("Beginning test:" + (new Date()).toString());
+            for(int i = 0; i < 100; i++)
+                zk.create("/test" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT, this, results);
+            zk.sync("/test", this, results);
+            for(int i = 0; i < 100; i++)
+                zk.delete("/test" + i, 0, this, results);
+            for(int i = 0; i < 100; i++)
+                zk.getChildren("/", new NullWatcher(), (ChildrenCallback)this,
+                        results);
+            for(int i = 0; i < 100; i++)
+                zk.getChildren("/", new NullWatcher(), (Children2Callback)this,
+                        results);
+            LOG.info("Submitted all operations:" + (new Date()).toString());
+            
+            if(!opsCount.await(10000, TimeUnit.MILLISECONDS))
+                Assert.fail("Haven't received all confirmations" + opsCount.getCount());
+
+            for(int i = 0; i < limit ; i++){
+                Assert.assertEquals(0, (int) results.get(i));
+            }
+            
+        } catch (IOException e) {
+            System.out.println(e.toString());
+        } 
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx,
+            List<String> children) { 
+        ((List<Integer>)ctx).add(rc);
+        opsCount.countDown();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx,
+            List<String> children, Stat stat) { 
+        ((List<Integer>)ctx).add(rc);
+        opsCount.countDown();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, String name){
+        ((List<Integer>) ctx).add(rc);
+        opsCount.countDown();
+    
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx){
+        ((List<Integer>) ctx).add(rc);    
+        opsCount.countDown();
+    
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestHammer.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestHammer.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestHammer.java
new file mode 100644
index 0000000..a73d6df
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestHammer.java
@@ -0,0 +1,63 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.common.Time;
+
+public class TestHammer implements VoidCallback {
+
+    /**
+     * @param args
+     */
+    static int REPS = 50000;
+    public static void main(String[] args) {
+            long startTime = Time.currentElapsedTime();
+            ZooKeeper zk = null;
+            try {
+                zk = new ZooKeeper(args[0], 10000, null);
+            } catch (IOException e1) {
+                // TODO Auto-generated catch block
+                e1.printStackTrace();
+                throw new RuntimeException(e1);
+            }
+            for(int i = 0; i < REPS; i++) {
+                try {
+                    String name = zk.create("/testFile-", new byte[16], Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.EPHEMERAL_SEQUENTIAL);
+                    zk.delete(name, -1, new TestHammer(), null);
+                } catch(Exception e) {
+                    i--;
+                    e.printStackTrace();
+                }
+            }
+            System.out.println("creates/sec=" + (REPS*1000/(Time.currentElapsedTime()-startTime)));
+    }
+
+    public void processResult(int rc, String path, Object ctx) {
+        // TODO Auto-generated method stub
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestUtils.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestUtils.java
new file mode 100644
index 0000000..fa08b82
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TestUtils.java
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.test;
+
+import java.io.File;
+
+import org.junit.Assert;
+
+/**
+ * This class contains test utility methods
+ */
+public class TestUtils {
+
+    /**
+     * deletes a folder recursively
+     *
+     * @param file
+     *            folder to be deleted
+     * @param failOnError
+     *            if true file deletion success is ensured
+     */
+    public static boolean deleteFileRecursively(File file,
+            final boolean failOnError) {
+        if (file != null) {
+            if (file.isDirectory()) {
+                File[] files = file.listFiles();
+                int size = files.length;
+                for (int i = 0; i < size; i++) {
+                    File f = files[i];
+                    boolean deleted = deleteFileRecursively(files[i], failOnError);
+                    if(!deleted && failOnError)
+                    {
+                        Assert.fail("file '" + f.getAbsolutePath()+"' deletion failed");
+                    }
+                }
+            }
+            return file.delete();
+        }
+        return true;
+    }
+
+    public static boolean deleteFileRecursively(File file) {
+        return deleteFileRecursively(file, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java
new file mode 100644
index 0000000..66ff63d
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java
@@ -0,0 +1,256 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+
+import junit.framework.Assert;
+
+import org.apache.jute.Record;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.Request;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.ZKDatabase;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.persistence.FileTxnLog;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
+import org.apache.zookeeper.server.persistence.TxnLog.TxnIterator;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.txn.SetDataTxn;
+import org.apache.zookeeper.txn.TxnHeader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TruncateTest extends ZKTestCase {
+	private static final Logger LOG = LoggerFactory.getLogger(TruncateTest.class);
+    File dataDir1, dataDir2, dataDir3;
+    final int baseHostPort = PortAssignment.unique();
+    
+    @Before
+    public void setUp() throws IOException {
+        dataDir1 = ClientBase.createTmpDir();
+        dataDir2 = ClientBase.createTmpDir();
+        dataDir3 = ClientBase.createTmpDir();
+    }
+    
+    @After
+    public void tearDown() {
+        ClientBase.recursiveDelete(dataDir1);
+        ClientBase.recursiveDelete(dataDir2);
+        ClientBase.recursiveDelete(dataDir3);
+    }
+    
+    volatile boolean connected;
+    Watcher nullWatcher = new Watcher() {
+        @Override
+        public void process(WatchedEvent event) {
+            connected = event.getState() == Watcher.Event.KeeperState.SyncConnected;
+        }
+    };
+
+    @Test
+    public void testTruncationStreamReset() throws Exception {
+        File tmpdir = ClientBase.createTmpDir();
+        FileTxnSnapLog snaplog = new FileTxnSnapLog(tmpdir, tmpdir);
+        ZKDatabase zkdb = new ZKDatabase(snaplog);
+
+        for (int i = 1; i <= 100; i++) {
+            append(zkdb, i);
+        }
+
+        zkdb.truncateLog(1);
+
+        append(zkdb, 200);
+
+        zkdb.close();
+
+        // verify that the truncation and subsequent append were processed
+        // correctly
+        FileTxnLog txnlog = new FileTxnLog(new File(tmpdir, "version-2"));
+        TxnIterator iter = txnlog.read(1);
+
+        TxnHeader hdr = iter.getHeader();
+        Record txn = iter.getTxn();
+        Assert.assertEquals(1, hdr.getZxid());
+        Assert.assertTrue(txn instanceof SetDataTxn);
+
+        iter.next();
+
+        hdr = iter.getHeader();
+        txn = iter.getTxn();
+        Assert.assertEquals(200, hdr.getZxid());
+        Assert.assertTrue(txn instanceof SetDataTxn);
+        iter.close();
+        ClientBase.recursiveDelete(tmpdir);
+    }
+
+    private void append(ZKDatabase zkdb, int i) throws IOException {
+        TxnHeader hdr = new TxnHeader(1, 1, i, 1, ZooDefs.OpCode.setData);
+        Record txn = new SetDataTxn("/foo" + i, new byte[0], 1);
+        Request req = new Request(null, 0, 0, 0, null, null);
+        req.hdr = hdr;
+        req.txn = txn;
+
+        zkdb.append(req);
+        zkdb.commit();
+    }
+
+    
+    @Test
+    public void testTruncationNullLog() throws Exception {
+        File tmpdir = ClientBase.createTmpDir();
+        FileTxnSnapLog snaplog = new FileTxnSnapLog(tmpdir, tmpdir);
+        ZKDatabase zkdb = new ZKDatabase(snaplog);
+
+        for (int i = 1; i <= 100; i++) {
+            append(zkdb, i);
+        }
+        zkdb.close();
+        File[] logs = snaplog.getDataDir().listFiles();
+        for(int i = 0; i < logs.length; i++) {
+            LOG.debug("Deleting: {}", logs[i].getName());
+            Assert.assertTrue("Failed to delete log file: " + logs[i].getName(), logs[i].delete());
+        }
+        try {
+            zkdb.truncateLog(1);
+            Assert.assertTrue("Should not get here", false);
+        }
+        catch(IOException e) {
+            Assert.assertTrue("Should have received an IOException", true);
+        }
+        catch(NullPointerException npe) {
+            Assert.fail("This should not throw NPE!");
+        }
+ 
+        ClientBase.recursiveDelete(tmpdir);
+    }
+    
+    @Test
+    public void testTruncate() throws IOException, InterruptedException, KeeperException {
+        // Prime the server that is going to come in late with 50 txns
+        String hostPort = "127.0.0.1:" + baseHostPort;
+        int maxCnxns = 100;
+        ServerCnxnFactory factory = ClientBase.createNewServerInstance(null,
+                hostPort, maxCnxns);
+        ClientBase.startServerInstance(dataDir1, factory, hostPort);
+        ClientBase.shutdownServerInstance(factory, hostPort);
+
+        // standalone starts with 0 epoch while quorum starts with 1
+        File origfile = new File(new File(dataDir1, "version-2"), "snapshot.0");
+        File newfile = new File(new File(dataDir1, "version-2"), "snapshot.100000000");
+        origfile.renameTo(newfile);
+
+        factory = ClientBase.createNewServerInstance(null, hostPort, maxCnxns);
+        ClientBase.startServerInstance(dataDir1, factory, hostPort);
+
+        ZooKeeper zk = new ZooKeeper(hostPort, 15000, nullWatcher);
+        for(int i = 0; i < 50; i++) {
+            zk.create("/" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        }
+        zk.close();
+        
+        ZKDatabase zkDb;
+        {
+            ZooKeeperServer zs = ClientBase.getServer(factory);
+    
+            zkDb = zs.getZKDatabase();
+        }
+        factory.shutdown();
+        try {
+            zkDb.close();
+        } catch (IOException ie) {
+            LOG.warn("Error closing logs ", ie);
+        }
+        int tickTime = 2000;
+        int initLimit = 3;
+        int syncLimit = 3;
+        int port1 = baseHostPort+1;
+        int port2 = baseHostPort+2;
+        int port3 = baseHostPort+3;
+        
+        // Start up two of the quorum and add 10 txns
+        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>();
+        peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000, 0, null));
+        peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000, 0, null));
+        peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000, 0, null));
+
+        QuorumPeer s2 = new QuorumPeer(peers, dataDir2, dataDir2, port2, 0, 2, tickTime, initLimit, syncLimit);
+        s2.start();
+        QuorumPeer s3 = new QuorumPeer(peers, dataDir3, dataDir3, port3, 0, 3, tickTime, initLimit, syncLimit);
+        s3.start();
+        connected = false;
+        zk = new ZooKeeper("127.0.0.1:" + port2, 15000, nullWatcher);
+        while(!connected) {
+            Thread.sleep(1000);
+        }
+        for(int i = 0; i < 10; i++) {
+            zk.create("/" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        }
+        zk.close();
+        
+        final ZooKeeper zk2 = new ZooKeeper("127.0.0.1:" + port2, 15000, nullWatcher);
+        zk2.getData("/9", false, new Stat());
+        try {
+            zk2.getData("/10", false, new Stat());
+            Assert.fail("Should have gotten an error");
+        } catch(KeeperException.NoNodeException e) {
+            // this is what we want
+        }
+        QuorumPeer s1 = new QuorumPeer(peers, dataDir1, dataDir1, port1, 0, 1, tickTime, initLimit, syncLimit);
+        s1.start();
+
+        connected = false;
+        ZooKeeper zk1 = new ZooKeeper("127.0.0.1:" + port1, 15000, nullWatcher);
+        while(!connected) {
+            Thread.sleep(1000);
+        }
+        zk1.getData("/9", false, new Stat());
+        try {
+            // /10 wont work because the session expiration
+            // will match the zxid for /10 and so we wont
+            // actually truncate the zxid for /10 creation
+            // due to an artifact of switching the xid of the standalone
+            // /11 is the last entry in the log for the xid
+            // as a result /12 is the first of the truncated znodes to check for
+            zk1.getData("/12", false, new Stat());
+            Assert.fail("Should have gotten an error");
+        } catch(KeeperException.NoNodeException e) {
+            // this is what we want
+        }
+        zk1.close();
+        QuorumBase.shutdown(s1);
+        QuorumBase.shutdown(s2);
+        QuorumBase.shutdown(s3);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/UpgradeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/UpgradeTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/UpgradeTest.java
new file mode 100644
index 0000000..b8db0da
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/UpgradeTest.java
@@ -0,0 +1,105 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.upgrade.UpgradeMain;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UpgradeTest extends ZKTestCase implements Watcher {
+    private final static Logger LOG = LoggerFactory.getLogger(UpgradeTest.class);
+
+    private static String HOSTPORT = "127.0.0.1:" + PortAssignment.unique();
+    private static final File testData = new File(
+            System.getProperty("test.data.dir", "build/test/data"));
+    private CountDownLatch startSignal;
+
+    /**
+     * test the upgrade
+     * @throws Exception
+     */
+    @Test
+    public void testUpgrade() throws Exception {
+        File upgradeDir = new File(testData, "upgrade");
+        UpgradeMain upgrade = new UpgradeMain(upgradeDir, upgradeDir);
+        upgrade.runUpgrade();
+        ZooKeeperServer zks = new ZooKeeperServer(upgradeDir, upgradeDir, 3000);
+        SyncRequestProcessor.setSnapCount(1000);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        LOG.info("starting up the zookeeper server .. waiting");
+        Assert.assertTrue("waiting for server being up",
+                ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+        ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+        Stat stat = zk.exists("/", false);
+        List<String> children = zk.getChildren("/", false);
+        Collections.sort(children);
+        for (int i = 0; i < 10; i++) {
+            Assert.assertTrue("data tree sanity check",
+                    ("test-" + i).equals(children.get(i)));
+        }
+        //try creating one node
+        zk.create("/upgrade", "upgrade".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        // check if its there
+        if (zk.exists("/upgrade", false) == null) {
+            Assert.assertTrue(false);
+        }
+
+        zk.close();
+
+        // bring down the server
+        f.shutdown();
+        Assert.assertTrue("waiting for server down",
+                   ClientBase.waitForServerDown(HOSTPORT,
+                           ClientBase.CONNECTION_TIMEOUT));
+
+    }
+
+    public void process(WatchedEvent event) {
+        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
+        if (event.getState() == KeeperState.SyncConnected
+                && startSignal != null && startSignal.getCount() > 0)
+        {
+            startSignal.countDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java
new file mode 100644
index 0000000..eed02c5
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java
@@ -0,0 +1,212 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import junit.framework.TestCase;
+
+public class WatchEventWhenAutoReset extends TestCase {
+    protected static final Logger LOG = LoggerFactory
+            .getLogger(WatchEventWhenAutoReset.class);
+
+    // waiting time for expected condition
+    private static final int TIMEOUT = 30000;
+
+    static public class EventsWatcher extends CountdownWatcher {
+        private LinkedBlockingQueue<WatchedEvent> dataEvents = new LinkedBlockingQueue<WatchedEvent>();
+
+        @Override
+        public void process(WatchedEvent event) {
+            super.process(event);
+            try {
+                if (event.getType() != Event.EventType.None) {
+                    dataEvents.put(event);
+                }
+            } catch (InterruptedException e) {
+                LOG.warn("ignoring interrupt during EventsWatcher process");
+            }
+        }
+
+        public void assertEvent(long timeout, EventType eventType) {
+            try {
+                WatchedEvent event = dataEvents.poll(timeout,
+                        TimeUnit.MILLISECONDS);
+                Assert.assertNotNull("do not receive a " + eventType, event);
+                Assert.assertEquals(eventType, event.getType());
+            } catch (InterruptedException e) {
+                LOG.warn("ignoring interrupt during EventsWatcher assertEvent");
+            }
+        }
+    }
+
+    private ZooKeeper createClient(QuorumUtil qu, int id, EventsWatcher watcher)
+            throws IOException {
+        String hostPort = "127.0.0.1:" + qu.getPeer(id).clientPort;
+        ZooKeeper zk = new ZooKeeper(hostPort, TIMEOUT, watcher);
+        try {
+            watcher.waitForConnected(TIMEOUT);
+        } catch (InterruptedException e) {
+            // ignoring the interrupt
+        } catch (TimeoutException e) {
+            fail("can not connect to " + hostPort);
+        }
+        return zk;
+    }
+
+    private ZooKeeper createClient(QuorumUtil qu, int id) throws IOException {
+        return createClient(qu, id, new EventsWatcher());
+    }
+
+    @Test
+    public void testNodeDataChanged() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+
+        EventsWatcher watcher = new EventsWatcher();
+        ZooKeeper zk1 = createClient(qu, 1, watcher);
+        ZooKeeper zk2 = createClient(qu, 2);
+
+        String path = "/test-changed";
+
+        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.getData(path, watcher, null);
+        qu.shutdown(1);
+        zk2.delete(path, -1);
+        zk2.create(path, new byte[2], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        qu.start(1);
+        watcher.waitForConnected(TIMEOUT);
+        watcher.assertEvent(TIMEOUT, EventType.NodeDataChanged);
+
+        zk1.exists(path, watcher);
+        qu.shutdown(1);
+        zk2.delete(path, -1);
+        zk2.create(path, new byte[2], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        qu.start(1);
+        watcher.waitForConnected(TIMEOUT * 1000L);
+        watcher.assertEvent(TIMEOUT, EventType.NodeDataChanged);
+
+        qu.shutdownAll();
+    }
+
+    @Test
+    public void testNodeCreated() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+
+        EventsWatcher watcher = new EventsWatcher();
+        ZooKeeper zk1 = createClient(qu, 1, watcher);
+        ZooKeeper zk2 = createClient(qu, 2);
+
+        String path = "/test1-created";
+
+        zk1.exists(path, watcher);
+        qu.shutdown(1);
+        zk2.create(path, new byte[2], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        qu.start(1);
+        watcher.waitForConnected(TIMEOUT * 1000L);
+        watcher.assertEvent(TIMEOUT, EventType.NodeCreated);
+
+        qu.shutdownAll();
+    }
+
+    @Test
+    public void testNodeDeleted() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+
+        EventsWatcher watcher = new EventsWatcher();
+        ZooKeeper zk1 = createClient(qu, 1, watcher);
+        ZooKeeper zk2 = createClient(qu, 2);
+
+        String path = "/test-deleted";
+
+        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.getData(path, watcher, null);
+        qu.shutdown(1);
+        zk2.delete(path, -1);
+        qu.start(1);
+        watcher.waitForConnected(TIMEOUT * 1000L);
+        watcher.assertEvent(TIMEOUT, EventType.NodeDeleted);
+
+        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.exists(path, watcher);
+        qu.shutdown(1);
+        zk2.delete(path, -1);
+        qu.start(1);
+        watcher.waitForConnected(TIMEOUT * 1000L);
+        watcher.assertEvent(TIMEOUT, EventType.NodeDeleted);
+
+        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.getChildren(path, watcher);
+        qu.shutdown(1);
+        zk2.delete(path, -1);
+        qu.start(1);
+        watcher.waitForConnected(TIMEOUT * 1000L);
+        watcher.assertEvent(TIMEOUT, EventType.NodeDeleted);
+
+        qu.shutdownAll();
+    }
+
+    @Test
+    public void testNodeChildrenChanged() throws Exception {
+        QuorumUtil qu = new QuorumUtil(1);
+        qu.startAll();
+
+        EventsWatcher watcher = new EventsWatcher();
+        ZooKeeper zk1 = createClient(qu, 1, watcher);
+        ZooKeeper zk2 = createClient(qu, 2);
+
+        String path = "/test-children-changed";
+
+        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk1.getChildren(path, watcher);
+        qu.shutdown(1);
+        zk2.create(path + "/children-1", new byte[2],
+                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        qu.start(1);
+        watcher.waitForConnected(TIMEOUT * 1000L);
+        watcher.assertEvent(TIMEOUT, EventType.NodeChildrenChanged);
+
+        qu.shutdownAll();
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java
new file mode 100644
index 0000000..0eaea67
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java
@@ -0,0 +1,95 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.util.EnumSet;
+
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.proto.WatcherEvent;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class WatchedEventTest extends ZKTestCase {
+    
+    @Test
+    public void testCreatingWatchedEvent() {
+        // EventWatch is a simple, immutable type, so all we need to do
+       // is make sure we can create all possible combinations of values.
+
+        EnumSet<EventType> allTypes = EnumSet.allOf(EventType.class);
+       EnumSet<KeeperState> allStates = EnumSet.allOf(KeeperState.class);
+       WatchedEvent we;
+
+        for(EventType et : allTypes) {
+           for(KeeperState ks : allStates) {
+               we = new WatchedEvent(et, ks, "blah");
+               Assert.assertEquals(et, we.getType());
+               Assert.assertEquals(ks, we.getState());
+               Assert.assertEquals("blah", we.getPath());
+           }
+            
+        }
+    }
+
+    @Test
+    public void testCreatingWatchedEventFromWrapper() {
+        // Make sure we can handle any type of correct wrapper
+
+        EnumSet<EventType> allTypes = EnumSet.allOf(EventType.class);
+       EnumSet<KeeperState> allStates = EnumSet.allOf(KeeperState.class);
+       WatchedEvent we;
+       WatcherEvent wep;
+
+        for(EventType et : allTypes) {
+           for(KeeperState ks : allStates) {
+               wep = new WatcherEvent(et.getIntValue(), ks.getIntValue(), "blah");
+               we = new WatchedEvent(wep);
+               Assert.assertEquals(et, we.getType());
+               Assert.assertEquals(ks, we.getState());
+               Assert.assertEquals("blah", we.getPath());
+           }
+        }
+    }
+
+    @Test
+    public void testCreatingWatchedEventFromInvalidWrapper() {
+        // Make sure we can't convert from an invalid wrapper
+
+       try {
+           WatcherEvent wep = new WatcherEvent(-2342, -252352, "foo");
+           WatchedEvent we = new WatchedEvent(wep);
+           Assert.fail("Was able to create WatchedEvent from bad wrapper");
+       } catch (RuntimeException re) {
+           // we're good
+       }
+    }
+
+   @Test
+   public void testConvertingToEventWrapper() {
+       WatchedEvent we = new WatchedEvent(EventType.NodeCreated, KeeperState.Expired, "blah");
+       WatcherEvent wew = we.getWrapper();
+       
+       Assert.assertEquals(EventType.NodeCreated.getIntValue(), wew.getType());
+       Assert.assertEquals(KeeperState.Expired.getIntValue(), wew.getState());
+       Assert.assertEquals("blah", wew.getPath());
+   }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java
new file mode 100644
index 0000000..a6c62e4
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java
@@ -0,0 +1,478 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+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.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class WatcherFuncTest extends ClientBase {
+    private static class SimpleWatcher implements Watcher {
+        private LinkedBlockingQueue<WatchedEvent> events =
+            new LinkedBlockingQueue<WatchedEvent>();
+        private CountDownLatch latch;
+
+        public SimpleWatcher(CountDownLatch latch) {
+            this.latch = latch;
+        }
+
+        public void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.SyncConnected) {
+                if (latch != null) {
+                    latch.countDown();
+                }
+            }
+
+            if (event.getType() == EventType.None) {
+                return;
+            }
+            try {
+                events.put(event);
+            } catch (InterruptedException e) {
+                Assert.assertTrue("interruption unexpected", false);
+            }
+        }
+        public void verify(List<EventType> expected) throws InterruptedException{
+            WatchedEvent event;
+            int count = 0;
+            while (count < expected.size()
+                    && (event = events.poll(30, TimeUnit.SECONDS)) != null)
+            {
+                Assert.assertEquals(expected.get(count), event.getType());
+                count++;
+            }
+            Assert.assertEquals(expected.size(), count);
+            events.clear();
+        }
+    }
+    private SimpleWatcher client_dwatch;
+    private volatile CountDownLatch client_latch;
+    private ZooKeeper client;
+    private SimpleWatcher lsnr_dwatch;
+    private volatile CountDownLatch lsnr_latch;
+    private ZooKeeper lsnr;
+
+    private List<EventType> expected;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        client_latch = new CountDownLatch(1);
+        client_dwatch = new SimpleWatcher(client_latch);
+        client = createClient(client_dwatch, client_latch);
+
+        lsnr_latch = new CountDownLatch(1);
+        lsnr_dwatch = new SimpleWatcher(lsnr_latch);
+        lsnr = createClient(lsnr_dwatch, lsnr_latch);
+
+        expected = new ArrayList<EventType>();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        client.close();
+        lsnr.close();
+        super.tearDown();
+    }
+
+    protected ZooKeeper createClient(Watcher watcher, CountDownLatch latch)
+        throws IOException, InterruptedException
+    {
+        ZooKeeper zk = new ZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
+        if(!latch.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)){
+            Assert.fail("Unable to connect to server");
+        }
+        return zk;
+    }
+
+    private void verify() throws InterruptedException {
+        lsnr_dwatch.verify(expected);
+        expected.clear();
+    }
+
+    @Test
+    public void testExistsSync()
+        throws IOException, InterruptedException, KeeperException
+    {
+        Assert.assertNull(lsnr.exists("/foo", true));
+        Assert.assertNull(lsnr.exists("/foo/bar", true));
+
+        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        expected.add(EventType.NodeCreated);
+        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        expected.add(EventType.NodeCreated);
+
+        verify();
+
+        Assert.assertNotNull(lsnr.exists("/foo", true));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", true));
+
+        try {
+            Assert.assertNull(lsnr.exists("/car", true));
+            client.setData("/car", "missing".getBytes(), -1);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/car", e.getPath());
+        }
+
+        try {
+            Assert.assertNull(lsnr.exists("/foo/car", true));
+            client.setData("/foo/car", "missing".getBytes(), -1);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo/car", e.getPath());
+        }
+
+        client.setData("/foo", "parent".getBytes(), -1);
+        expected.add(EventType.NodeDataChanged);
+        client.setData("/foo/bar", "child".getBytes(), -1);
+        expected.add(EventType.NodeDataChanged);
+
+        verify();
+
+        Assert.assertNotNull(lsnr.exists("/foo", true));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", true));
+
+        client.delete("/foo/bar", -1);
+        expected.add(EventType.NodeDeleted);
+        client.delete("/foo", -1);
+        expected.add(EventType.NodeDeleted);
+
+        verify();
+    }
+
+    @Test
+    public void testGetDataSync()
+        throws IOException, InterruptedException, KeeperException
+    {
+        try {
+            lsnr.getData("/foo", true, null);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo", e.getPath());
+        }
+        try {
+            lsnr.getData("/foo/bar", true, null);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo/bar", e.getPath());
+        }
+
+        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Assert.assertNotNull(lsnr.getData("/foo", true, null));
+        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Assert.assertNotNull(lsnr.getData("/foo/bar", true, null));
+
+        client.setData("/foo", "parent".getBytes(), -1);
+        expected.add(EventType.NodeDataChanged);
+        client.setData("/foo/bar", "child".getBytes(), -1);
+        expected.add(EventType.NodeDataChanged);
+
+        verify();
+
+        Assert.assertNotNull(lsnr.getData("/foo", true, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", true, null));
+
+        client.delete("/foo/bar", -1);
+        expected.add(EventType.NodeDeleted);
+        client.delete("/foo", -1);
+        expected.add(EventType.NodeDeleted);
+
+        verify();
+    }
+
+    @Test
+    public void testGetChildrenSync()
+        throws IOException, InterruptedException, KeeperException
+    {
+        try {
+            lsnr.getChildren("/foo", true);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo", e.getPath());
+        }
+        try {
+            lsnr.getChildren("/foo/bar", true);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo/bar", e.getPath());
+        }
+
+        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Assert.assertNotNull(lsnr.getChildren("/foo", true));
+
+        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        expected.add(EventType.NodeChildrenChanged); // /foo
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", true));
+
+
+        client.setData("/foo", "parent".getBytes(), -1);
+        client.setData("/foo/bar", "child".getBytes(), -1);
+
+
+        Assert.assertNotNull(lsnr.exists("/foo", true));
+
+        Assert.assertNotNull(lsnr.getChildren("/foo", true));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", true));
+
+        client.delete("/foo/bar", -1);
+        expected.add(EventType.NodeDeleted); // /foo/bar childwatch
+        expected.add(EventType.NodeChildrenChanged); // /foo
+        client.delete("/foo", -1);
+        expected.add(EventType.NodeDeleted);
+
+        verify();
+    }
+
+    @Test
+    public void testExistsSyncWObj()
+        throws IOException, InterruptedException, KeeperException
+    {
+        SimpleWatcher w1 = new SimpleWatcher(null);
+        SimpleWatcher w2 = new SimpleWatcher(null);
+        SimpleWatcher w3 = new SimpleWatcher(null);
+        SimpleWatcher w4 = new SimpleWatcher(null);
+
+        List<EventType> e2 = new ArrayList<EventType>();
+
+        Assert.assertNull(lsnr.exists("/foo", true));
+        Assert.assertNull(lsnr.exists("/foo", w1));
+
+        Assert.assertNull(lsnr.exists("/foo/bar", w2));
+        Assert.assertNull(lsnr.exists("/foo/bar", w3));
+        Assert.assertNull(lsnr.exists("/foo/bar", w3));
+        Assert.assertNull(lsnr.exists("/foo/bar", w4));
+
+        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        expected.add(EventType.NodeCreated);
+        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        e2.add(EventType.NodeCreated);
+
+        lsnr_dwatch.verify(expected);
+        w1.verify(expected);
+        w2.verify(e2);
+        w3.verify(e2);
+        w4.verify(e2);
+        expected.clear();
+        e2.clear();
+
+        // default not registered
+        Assert.assertNotNull(lsnr.exists("/foo", w1));
+
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w2));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w3));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w4));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w4));
+
+        client.setData("/foo", "parent".getBytes(), -1);
+        expected.add(EventType.NodeDataChanged);
+        client.setData("/foo/bar", "child".getBytes(), -1);
+        e2.add(EventType.NodeDataChanged);
+
+        lsnr_dwatch.verify(new ArrayList<EventType>()); // not reg so should = 0
+        w1.verify(expected);
+        w2.verify(e2);
+        w3.verify(e2);
+        w4.verify(e2);
+        expected.clear();
+        e2.clear();
+
+        Assert.assertNotNull(lsnr.exists("/foo", true));
+        Assert.assertNotNull(lsnr.exists("/foo", w1));
+        Assert.assertNotNull(lsnr.exists("/foo", w1));
+
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w2));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w2));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w3));
+        Assert.assertNotNull(lsnr.exists("/foo/bar", w4));
+
+        client.delete("/foo/bar", -1);
+        expected.add(EventType.NodeDeleted);
+        client.delete("/foo", -1);
+        e2.add(EventType.NodeDeleted);
+
+        lsnr_dwatch.verify(expected);
+        w1.verify(expected);
+        w2.verify(e2);
+        w3.verify(e2);
+        w4.verify(e2);
+        expected.clear();
+        e2.clear();
+
+    }
+
+    @Test
+    public void testGetDataSyncWObj()
+        throws IOException, InterruptedException, KeeperException
+    {
+        SimpleWatcher w1 = new SimpleWatcher(null);
+        SimpleWatcher w2 = new SimpleWatcher(null);
+        SimpleWatcher w3 = new SimpleWatcher(null);
+        SimpleWatcher w4 = new SimpleWatcher(null);
+
+        List<EventType> e2 = new ArrayList<EventType>();
+
+        try {
+            lsnr.getData("/foo", w1, null);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo", e.getPath());
+        }
+        try {
+            lsnr.getData("/foo/bar", w2, null);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo/bar", e.getPath());
+        }
+
+        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Assert.assertNotNull(lsnr.getData("/foo", true, null));
+        Assert.assertNotNull(lsnr.getData("/foo", w1, null));
+        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w2, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w3, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w4, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w4, null));
+
+        client.setData("/foo", "parent".getBytes(), -1);
+        expected.add(EventType.NodeDataChanged);
+        client.setData("/foo/bar", "child".getBytes(), -1);
+        e2.add(EventType.NodeDataChanged);
+
+        lsnr_dwatch.verify(expected);
+        w1.verify(expected);
+        w2.verify(e2);
+        w3.verify(e2);
+        w4.verify(e2);
+        expected.clear();
+        e2.clear();
+
+        Assert.assertNotNull(lsnr.getData("/foo", true, null));
+        Assert.assertNotNull(lsnr.getData("/foo", w1, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w2, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w3, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w3, null));
+        Assert.assertNotNull(lsnr.getData("/foo/bar", w4, null));
+
+        client.delete("/foo/bar", -1);
+        expected.add(EventType.NodeDeleted);
+        client.delete("/foo", -1);
+        e2.add(EventType.NodeDeleted);
+
+        lsnr_dwatch.verify(expected);
+        w1.verify(expected);
+        w2.verify(e2);
+        w3.verify(e2);
+        w4.verify(e2);
+        expected.clear();
+        e2.clear();
+    }
+
+    @Test
+    public void testGetChildrenSyncWObj()
+        throws IOException, InterruptedException, KeeperException
+    {
+        SimpleWatcher w1 = new SimpleWatcher(null);
+        SimpleWatcher w2 = new SimpleWatcher(null);
+        SimpleWatcher w3 = new SimpleWatcher(null);
+        SimpleWatcher w4 = new SimpleWatcher(null);
+
+        List<EventType> e2 = new ArrayList<EventType>();
+
+        try {
+            lsnr.getChildren("/foo", true);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo", e.getPath());
+        }
+        try {
+            lsnr.getChildren("/foo/bar", true);
+            Assert.fail();
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
+            Assert.assertEquals("/foo/bar", e.getPath());
+        }
+
+        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Assert.assertNotNull(lsnr.getChildren("/foo", true));
+        Assert.assertNotNull(lsnr.getChildren("/foo", w1));
+
+        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        expected.add(EventType.NodeChildrenChanged); // /foo
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w2));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w2));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w3));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w4));
+
+
+        client.setData("/foo", "parent".getBytes(), -1);
+        client.setData("/foo/bar", "child".getBytes(), -1);
+
+
+        Assert.assertNotNull(lsnr.exists("/foo", true));
+        Assert.assertNotNull(lsnr.exists("/foo", w1));
+        Assert.assertNotNull(lsnr.exists("/foo", true));
+        Assert.assertNotNull(lsnr.exists("/foo", w1));
+
+        Assert.assertNotNull(lsnr.getChildren("/foo", true));
+        Assert.assertNotNull(lsnr.getChildren("/foo", w1));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w2));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w3));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w4));
+        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w4));
+
+        client.delete("/foo/bar", -1);
+        e2.add(EventType.NodeDeleted); // /foo/bar childwatch
+        expected.add(EventType.NodeChildrenChanged); // /foo
+        client.delete("/foo", -1);
+        expected.add(EventType.NodeDeleted);
+
+        lsnr_dwatch.verify(expected);
+        w1.verify(expected);
+        w2.verify(e2);
+        w3.verify(e2);
+        w4.verify(e2);
+        expected.clear();
+        e2.clear();
+    }
+}


[33/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Op.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Op.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Op.java
deleted file mode 100644
index 1bc2061..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Op.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.jute.Record;
-import org.apache.zookeeper.common.PathUtils;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.proto.CheckVersionRequest;
-import org.apache.zookeeper.proto.CreateRequest;
-import org.apache.zookeeper.proto.DeleteRequest;
-import org.apache.zookeeper.proto.SetDataRequest;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Represents a single operation in a multi-operation transaction.  Each operation can be a create, update
- * or delete or can just be a version check.
- *
- * Sub-classes of Op each represent each detailed type but should not normally be referenced except via
- * the provided factory methods.
- *
- * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode)
- * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode, org.apache.zookeeper.AsyncCallback.StringCallback, Object)
- * @see ZooKeeper#delete(String, int)
- * @see ZooKeeper#setData(String, byte[], int)
- */
-public abstract class Op {
-    private int type;
-    private String path;
-
-    // prevent untyped construction
-    private Op(int type, String path) {
-        this.type = type;
-        this.path = path;
-    }
-
-    /**
-     * Constructs a create operation.  Arguments are as for the ZooKeeper method of the same name.
-     * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode)
-     * @see CreateMode#fromFlag(int)
-     *
-     * @param path
-     *                the path for the node
-     * @param data
-     *                the initial data for the node
-     * @param acl
-     *                the acl for the node
-     * @param flags
-     *                specifying whether the node to be created is ephemeral
-     *                and/or sequential but using the integer encoding.
-     */
-    public static Op create(String path, byte[] data, List<ACL> acl, int flags) {
-        return new Create(path, data, acl, flags);
-    }
-
-    /**
-     * Constructs a create operation.  Arguments are as for the ZooKeeper method of the same name.
-     * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode)
-     *
-     * @param path
-     *                the path for the node
-     * @param data
-     *                the initial data for the node
-     * @param acl
-     *                the acl for the node
-     * @param createMode
-     *                specifying whether the node to be created is ephemeral
-     *                and/or sequential
-     */
-    public static Op create(String path, byte[] data, List<ACL> acl, CreateMode createMode) {
-        return new Create(path, data, acl, createMode);
-    }
-
-    /**
-     * Constructs a delete operation.  Arguments are as for the ZooKeeper method of the same name.
-     * @see ZooKeeper#delete(String, int)
-     *
-     * @param path
-     *                the path of the node to be deleted.
-     * @param version
-     *                the expected node version.
-     */
-    public static Op delete(String path, int version) {
-        return new Delete(path, version);
-    }
-
-    /**
-     * Constructs an update operation.  Arguments are as for the ZooKeeper method of the same name.
-     * @see ZooKeeper#setData(String, byte[], int)
-     *
-     * @param path
-     *                the path of the node
-     * @param data
-     *                the data to set
-     * @param version
-     *                the expected matching version
-     */
-    public static Op setData(String path, byte[] data, int version) {
-        return new SetData(path, data, version);
-    }
-
-
-    /**
-     * Constructs an version check operation.  Arguments are as for the ZooKeeper.setData method except that
-     * no data is provided since no update is intended.  The purpose for this is to allow read-modify-write
-     * operations that apply to multiple znodes, but where some of the znodes are involved only in the read,
-     * not the write.  A similar effect could be achieved by writing the same data back, but that leads to
-     * way more version updates than are necessary and more writing in general.
-     *
-     * @param path
-     *                the path of the node
-     * @param version
-     *                the expected matching version
-     */
-    public static Op check(String path, int version) {
-        return new Check(path, version);
-    }
-
-    /**
-     * Gets the integer type code for an Op.  This code should be as from ZooDefs.OpCode
-     * @see ZooDefs.OpCode
-     * @return  The type code.
-     */
-    public int getType() {
-        return type;
-    }
-
-    /**
-     * Gets the path for an Op.
-     * @return  The path.
-     */
-    public String getPath() {
-        return path;
-    }
-
-    /**
-     * Encodes an op for wire transmission.
-     * @return An appropriate Record structure.
-     */
-    public abstract Record toRequestRecord() ;
-
-    /**
-     * Reconstructs the transaction with the chroot prefix.
-     * 
-     * @return transaction with chroot.
-     */
-    abstract Op withChroot(String addRootPrefix);
-
-    /**
-     * Performs client path validations.
-     * 
-     * @throws IllegalArgumentException
-     *             if an invalid path is specified
-     * @throws KeeperException.BadArgumentsException
-     *             if an invalid create mode flag is specified
-     */
-    void validate() throws KeeperException {
-        PathUtils.validatePath(path);
-    }
-
-    //////////////////
-    // these internal classes are public, but should not generally be referenced.
-    //
-    public static class Create extends Op {
-        private byte[] data;
-        private List<ACL> acl;
-        private int flags;
-
-        private Create(String path, byte[] data, List<ACL> acl, int flags) {
-            super(ZooDefs.OpCode.create, path);
-            this.data = data;
-            this.acl = acl;
-            this.flags = flags;
-        }
-
-        private Create(String path, byte[] data, List<ACL> acl, CreateMode createMode) {
-            super(ZooDefs.OpCode.create, path);
-            this.data = data;
-            this.acl = acl;
-            this.flags = createMode.toFlag();
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof Create)) return false;
-
-            Create op = (Create) o;
-
-            boolean aclEquals = true;
-            Iterator<ACL> i = op.acl.iterator();
-            for (ACL acl : op.acl) {
-                boolean hasMoreData = i.hasNext();
-                if (!hasMoreData) {
-                    aclEquals = false;
-                    break;
-                }
-                ACL otherAcl = i.next();
-                if (!acl.equals(otherAcl)) {
-                    aclEquals = false;
-                    break;
-                }
-            }
-            return !i.hasNext() && getType() == op.getType() && Arrays.equals(data, op.data) && flags == op.flags && aclEquals;
-        }
-
-        @Override
-        public int hashCode() {
-            return getType() + getPath().hashCode() + Arrays.hashCode(data);
-        }
-
-        @Override
-        public Record toRequestRecord() {
-            return new CreateRequest(getPath(), data, acl, flags);
-        }
-
-        @Override
-        Op withChroot(String path) {
-            return new Create(path, data, acl, flags);
-        }
-
-        @Override
-        void validate() throws KeeperException {
-            CreateMode createMode = CreateMode.fromFlag(flags);
-            PathUtils.validatePath(getPath(), createMode.isSequential());
-        }
-    }
-
-    public static class Delete extends Op {
-        private int version;
-
-        private Delete(String path, int version) {
-            super(ZooDefs.OpCode.delete, path);
-            this.version = version;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof Delete)) return false;
-
-            Delete op = (Delete) o;
-
-            return getType() == op.getType() && version == op.version 
-                   && getPath().equals(op.getPath());
-        }
-
-        @Override
-        public int hashCode() {
-            return getType() + getPath().hashCode() + version;
-        }
-
-        @Override
-        public Record toRequestRecord() {
-            return new DeleteRequest(getPath(), version);
-        }
-
-        @Override
-        Op withChroot(String path) {
-            return new Delete(path, version);
-        }
-    }
-
-    public static class SetData extends Op {
-        private byte[] data;
-        private int version;
-
-        private SetData(String path, byte[] data, int version) {
-            super(ZooDefs.OpCode.setData, path);
-            this.data = data;
-            this.version = version;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof SetData)) return false;
-
-            SetData op = (SetData) o;
-
-            return getType() == op.getType() && version == op.version 
-                   && getPath().equals(op.getPath()) && Arrays.equals(data, op.data);
-        }
-
-        @Override
-        public int hashCode() {
-            return getType() + getPath().hashCode() + Arrays.hashCode(data) + version;
-        }
-
-        @Override
-        public Record toRequestRecord() {
-            return new SetDataRequest(getPath(), data, version);
-        }
-
-        @Override
-        Op withChroot(String path) {
-            return new SetData(path, data, version);
-        }
-    }
-
-    public static class Check extends Op {
-        private int version;
-
-        private Check(String path, int version) {
-            super(ZooDefs.OpCode.check, path);
-            this.version = version;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof Check)) return false;
-
-            Check op = (Check) o;
-
-            return getType() == op.getType() && getPath().equals(op.getPath()) && version == op.version;
-        }
-
-        @Override
-        public int hashCode() {
-            return getType() + getPath().hashCode() + version;
-        }
-
-        @Override
-        public Record toRequestRecord() {
-            return new CheckVersionRequest(getPath(), version);
-        }
-
-        @Override
-        Op withChroot(String path) {
-            return new Check(path, version);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/OpResult.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/OpResult.java b/zookeeper-common/src/main/java/org/apache/zookeeper/OpResult.java
deleted file mode 100644
index 45331d1..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/OpResult.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.zookeeper;
-
-
-import org.apache.zookeeper.data.Stat;
-
-/**
- * Encodes the result of a single part of a multiple operation commit.
- */
-public abstract class OpResult {
-    private int type;
-
-    private OpResult(int type) {
-        this.type = type;
-    }
-
-    /**
-     * Encodes the return type as from ZooDefs.OpCode.  Can be used
-     * to dispatch to the correct cast needed for getting the desired
-     * additional result data.
-     * @see ZooDefs.OpCode
-     * @return an integer identifying what kind of operation this result came from.
-     */
-    public int getType() {
-        return type;
-    }
-
-    /**
-     * A result from a create operation.  This kind of result allows the
-     * path to be retrieved since the create might have been a sequential
-     * create.
-     */
-    public static class CreateResult extends OpResult {
-        private String path;
-
-        public CreateResult(String path) {
-            super(ZooDefs.OpCode.create);
-            this.path = path;
-        }
-
-        public String getPath() {
-            return path;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof CreateResult)) return false;
-
-            CreateResult other = (CreateResult) o;
-            return getType() == other.getType() && path.equals(other.getPath());
-        }
-
-        @Override
-        public int hashCode() {
-            return getType() * 35 + path.hashCode();
-        }
-    }
-
-    /**
-     * A result from a delete operation.  No special values are available.
-     */
-    public static class DeleteResult extends OpResult {
-        public DeleteResult() {
-            super(ZooDefs.OpCode.delete);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof DeleteResult)) return false;
-
-            DeleteResult opResult = (DeleteResult) o;
-            return getType() == opResult.getType();
-        }
-
-        @Override
-        public int hashCode() {
-            return getType();
-        }
-    }
-
-    /**
-     * A result from a setData operation.  This kind of result provides access
-     * to the Stat structure from the update.
-     */
-    public static class SetDataResult extends OpResult {
-        private Stat stat;
-
-        public SetDataResult(Stat stat) {
-            super(ZooDefs.OpCode.setData);
-            this.stat = stat;
-        }
-
-        public Stat getStat() {
-            return stat;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof SetDataResult)) return false;
-
-            SetDataResult other = (SetDataResult) o;
-            return getType() == other.getType() && stat.getMzxid() == other.stat.getMzxid();
-        }
-
-        @Override
-        public int hashCode() {
-            return (int) (getType() * 35 + stat.getMzxid());
-        }
-    }
-
-    /**
-     * A result from a version check operation.  No special values are available.
-     */
-    public static class CheckResult extends OpResult {
-        public CheckResult() {
-            super(ZooDefs.OpCode.check);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof CheckResult)) return false;
-
-            CheckResult other = (CheckResult) o;
-            return getType() == other.getType();
-        }
-
-        @Override
-        public int hashCode() {
-            return getType();
-        }
-    }
-
-    /**
-     * An error result from any kind of operation.  The point of error results
-     * is that they contain an error code which helps understand what happened.
-     * @see KeeperException.Code
-     *
-     */
-    public static class ErrorResult extends OpResult {
-        private int err;
-
-        public ErrorResult(int err) {
-            super(ZooDefs.OpCode.error);
-            this.err = err;
-        }
-
-        public int getErr() {
-            return err;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof ErrorResult)) return false;
-
-            ErrorResult other = (ErrorResult) o;
-            return getType() == other.getType() && err == other.getErr();
-        }
-
-        @Override
-        public int hashCode() {
-            return getType() * 35 + err;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Quotas.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Quotas.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Quotas.java
deleted file mode 100644
index b82e339..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Quotas.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-/**
- * this class manages quotas
- * and has many other utils
- * for quota
- */
-public class Quotas {
-
-    /** the zookeeper nodes that acts as the management and status node **/
-    public static final String procZookeeper = "/zookeeper";
-
-    /** the zookeeper quota node that acts as the quota
-     * management node for zookeeper */
-    public static final String quotaZookeeper = "/zookeeper/quota";
-
-    /**
-     * the limit node that has the limit of
-     * a subtree
-     */
-    public static final String limitNode = "zookeeper_limits";
-
-    /**
-     * the stat node that monitors the limit of
-     * a subtree.
-     */
-    public static final String statNode = "zookeeper_stats";
-
-    /**
-     * return the quota path associated with this
-     * prefix
-     * @param path the actual path in zookeeper.
-     * @return the limit quota path
-     */
-    public static String quotaPath(String path) {
-        return quotaZookeeper + path +
-        "/" + limitNode;
-    }
-
-    /**
-     * return the stat quota path associated with this
-     * prefix.
-     * @param path the actual path in zookeeper
-     * @return the stat quota path
-     */
-    public static String statPath(String path) {
-        return quotaZookeeper + path + "/" +
-        statNode;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java b/zookeeper-common/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java
deleted file mode 100644
index d6f5549..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.RealmCallback;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is used by the SASL mechanisms to get further information to complete
- * the authentication. For example, a SASL mechanism might use this callback
- * handler to do verification operation. The CallbackHandler interface here
- * refers to javax.security.auth.callback.CallbackHandler. It should not be
- * confused with ZooKeeper packet callbacks like
- * org.apache.zookeeper.server.auth.SaslServerCallbackHandler.
- */
-public class SaslClientCallbackHandler implements CallbackHandler {
-    private String password = null;
-    private static final Logger LOG = LoggerFactory.getLogger(SaslClientCallbackHandler.class);
-    private final String entity;
-    public SaslClientCallbackHandler(String password, String client) {
-        this.password = password;
-        this.entity = client;
-    }
-
-    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
-        for (Callback callback : callbacks) {
-            if (callback instanceof NameCallback) {
-                NameCallback nc = (NameCallback) callback;
-                nc.setName(nc.getDefaultName());
-            }
-            else {
-                if (callback instanceof PasswordCallback) {
-                    PasswordCallback pc = (PasswordCallback)callback;
-                    if (password != null) {
-                        pc.setPassword(this.password.toCharArray());
-                    } else {
-                        LOG.warn("Could not login: the {} is being asked for a password, but the ZooKeeper {}" +
-                          " code does not currently support obtaining a password from the user." +
-                          " Make sure that the {} is configured to use a ticket cache (using" +
-                          " the JAAS configuration setting 'useTicketCache=true)' and restart the {}. If" +
-                          " you still get this message after that, the TGT in the ticket cache has expired and must" +
-                          " be manually refreshed. To do so, first determine if you are using a password or a" +
-                          " keytab. If the former, run kinit in a Unix shell in the environment of the user who" +
-                          " is running this Zookeeper {} using the command" +
-                          " 'kinit <princ>' (where <princ> is the name of the {}'s Kerberos principal)." +
-                          " If the latter, do" +
-                          " 'kinit -k -t <keytab> <princ>' (where <princ> is the name of the Kerberos principal, and" +
-                          " <keytab> is the location of the keytab file). After manually refreshing your cache," +
-                          " restart this {}. If you continue to see this message after manually refreshing" +
-                          " your cache, ensure that your KDC host's clock is in sync with this host's clock.",
-                          new Object[]{entity, entity, entity, entity, entity, entity, entity});
-                    }
-                }
-                else {
-                    if (callback instanceof RealmCallback) {
-                        RealmCallback rc = (RealmCallback) callback;
-                        rc.setText(rc.getDefaultText());
-                    }
-                    else {
-                        if (callback instanceof AuthorizeCallback) {
-                            AuthorizeCallback ac = (AuthorizeCallback) callback;
-                            String authid = ac.getAuthenticationID();
-                            String authzid = ac.getAuthorizationID();
-                            if (authid.equals(authzid)) {
-                                ac.setAuthorized(true);
-                            } else {
-                                ac.setAuthorized(false);
-                            }
-                            if (ac.isAuthorized()) {
-                                ac.setAuthorizedID(authzid);
-                            }
-                        }
-                        else {
-                            throw new UnsupportedCallbackException(callback, "Unrecognized SASL " + entity + "Callback");
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ServerAdminClient.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ServerAdminClient.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ServerAdminClient.java
deleted file mode 100644
index 9464f1c..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ServerAdminClient.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.ByteBuffer;
-import java.util.StringTokenizer;
-
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.zookeeper.server.ZooTrace;
-
-@InterfaceAudience.Public
-public class ServerAdminClient {
-    private static final Logger LOG = LoggerFactory.getLogger(ServerAdminClient.class);
-
-    private static long getMask(String mask) {
-        long retv = 0;
-        if (mask.equalsIgnoreCase("CLIENT_REQUEST_TRACE_MASK")) {
-            retv = ZooTrace.CLIENT_REQUEST_TRACE_MASK;
-        } else if (mask.equalsIgnoreCase("CLIENT_DATA_PACKET_TRACE_MASK")) {
-            retv = ZooTrace.CLIENT_DATA_PACKET_TRACE_MASK;
-        } else if (mask.equalsIgnoreCase("CLIENT_PING_TRACE_MASK")) {
-            retv = ZooTrace.CLIENT_PING_TRACE_MASK;
-        } else if (mask.equalsIgnoreCase("SERVER_PACKET_TRACE_MASK")) {
-            retv = ZooTrace.SERVER_PACKET_TRACE_MASK;
-        } else if (mask.equalsIgnoreCase("SESSION_TRACE_MASK")) {
-            retv = ZooTrace.SESSION_TRACE_MASK;
-        } else if (mask.equalsIgnoreCase("EVENT_DELIVERY_TRACE_MASK")) {
-            retv = ZooTrace.EVENT_DELIVERY_TRACE_MASK;
-        } else if (mask.equalsIgnoreCase("SERVER_PING_TRACE_MASK")) {
-            retv = ZooTrace.SERVER_PING_TRACE_MASK;
-        } else if (mask.equalsIgnoreCase("WARNING_TRACE_MASK")) {
-            retv = ZooTrace.WARNING_TRACE_MASK;
-        }
-        return retv;
-    }
-
-    private static long getMasks(String masks) {
-        long retv = 0;
-        StringTokenizer st = new StringTokenizer(masks, "|");
-        while (st.hasMoreTokens()) {
-            String mask = st.nextToken().trim();
-            retv = retv | getMask(mask);
-        }
-        return retv;
-    }
-
-    public static void ruok(String host, int port) {
-        Socket s = null;
-        try {
-            byte[] reqBytes = new byte[4];
-            ByteBuffer req = ByteBuffer.wrap(reqBytes);
-            req.putInt(ByteBuffer.wrap("ruok".getBytes()).getInt());
-            s = new Socket();
-            s.setSoLinger(false, 10);
-            s.setSoTimeout(20000);
-            s.connect(new InetSocketAddress(host, port));
-
-            InputStream is = s.getInputStream();
-            OutputStream os = s.getOutputStream();
-
-            os.write(reqBytes);
-
-            byte[] resBytes = new byte[4];
-
-            int rc = is.read(resBytes);
-            String retv = new String(resBytes);
-            System.out.println("rc=" + rc + " retv=" + retv);
-        } catch (IOException e) {
-            LOG.warn("Unexpected exception", e);
-        } finally {
-            if (s != null) {
-                try {
-                    s.close();
-                } catch (IOException e) {
-                    LOG.warn("Unexpected exception", e);
-                }
-            }
-        }
-    }
-
-    public static void dump(String host, int port) {
-        Socket s = null;
-        try {
-            byte[] reqBytes = new byte[4];
-            ByteBuffer req = ByteBuffer.wrap(reqBytes);
-            req.putInt(ByteBuffer.wrap("dump".getBytes()).getInt());
-            s = new Socket();
-            s.setSoLinger(false, 10);
-            s.setSoTimeout(20000);
-            s.connect(new InetSocketAddress(host, port));
-
-            InputStream is = s.getInputStream();
-            OutputStream os = s.getOutputStream();
-
-            os.write(reqBytes);
-
-            byte[] resBytes = new byte[1024];
-
-            int rc = is.read(resBytes);
-            String retv = new String(resBytes);
-            System.out.println("rc=" + rc + " retv=" + retv);
-        } catch (IOException e) {
-            LOG.warn("Unexpected exception", e);
-        } finally {
-            if (s != null) {
-                try {
-                    s.close();
-                } catch (IOException e) {
-                    LOG.warn("Unexpected exception", e);
-                }
-            }
-        }
-    }
-
-    public static void stat(String host, int port) {
-        Socket s = null;
-        try {
-            byte[] reqBytes = new byte[4];
-            ByteBuffer req = ByteBuffer.wrap(reqBytes);
-            req.putInt(ByteBuffer.wrap("stat".getBytes()).getInt());
-            s = new Socket();
-            s.setSoLinger(false, 10);
-            s.setSoTimeout(20000);
-            s.connect(new InetSocketAddress(host, port));
-
-            InputStream is = s.getInputStream();
-            OutputStream os = s.getOutputStream();
-
-            os.write(reqBytes);
-
-            byte[] resBytes = new byte[1024];
-
-            int rc = is.read(resBytes);
-            String retv = new String(resBytes);
-            System.out.println("rc=" + rc + " retv=" + retv);
-        } catch (IOException e) {
-            LOG.warn("Unexpected exception", e);
-        } finally {
-            if (s != null) {
-                try {
-                    s.close();
-                } catch (IOException e) {
-                    LOG.warn("Unexpected exception", e);
-                }
-            }
-        }
-    }
-
-    public static void kill(String host, int port) {
-        Socket s = null;
-        try {
-            byte[] reqBytes = new byte[4];
-            ByteBuffer req = ByteBuffer.wrap(reqBytes);
-            req.putInt(ByteBuffer.wrap("kill".getBytes()).getInt());
-            s = new Socket();
-            s.setSoLinger(false, 10);
-            s.setSoTimeout(20000);
-            s.connect(new InetSocketAddress(host, port));
-
-            InputStream is = s.getInputStream();
-            OutputStream os = s.getOutputStream();
-
-            os.write(reqBytes);
-            byte[] resBytes = new byte[4];
-
-            int rc = is.read(resBytes);
-            String retv = new String(resBytes);
-            System.out.println("rc=" + rc + " retv=" + retv);
-        } catch (IOException e) {
-            LOG.warn("Unexpected exception", e);
-        } finally {
-            if (s != null) {
-                try {
-                    s.close();
-                } catch (IOException e) {
-                    LOG.warn("Unexpected exception", e);
-                }
-            }
-        }
-    }
-
-    public static void setTraceMask(String host, int port, String traceMaskStr) {
-        Socket s = null;
-        try {
-            byte[] reqBytes = new byte[12];
-            ByteBuffer req = ByteBuffer.wrap(reqBytes);
-            long traceMask = Long.parseLong(traceMaskStr, 8);
-            req.putInt(ByteBuffer.wrap("stmk".getBytes()).getInt());
-            req.putLong(traceMask);
-
-            s = new Socket();
-            s.setSoLinger(false, 10);
-            s.setSoTimeout(20000);
-            s.connect(new InetSocketAddress(host, port));
-
-            InputStream is = s.getInputStream();
-            OutputStream os = s.getOutputStream();
-
-            os.write(reqBytes);
-
-            byte[] resBytes = new byte[8];
-
-            int rc = is.read(resBytes);
-            ByteBuffer res = ByteBuffer.wrap(resBytes);
-            long retv = res.getLong();
-            System.out.println("rc=" + rc + " retv=0"
-                    + Long.toOctalString(retv) + " masks=0"
-                    + Long.toOctalString(traceMask));
-            assert (retv == traceMask);
-        } catch (IOException e) {
-            LOG.warn("Unexpected exception", e);
-        } finally {
-            if (s != null) {
-                try {
-                    s.close();
-                } catch (IOException e) {
-                    LOG.warn("Unexpected exception", e);
-                }
-            }
-        }
-    }
-
-    public static void getTraceMask(String host, int port) {
-        Socket s = null;
-        try {
-            byte[] reqBytes = new byte[12];
-            ByteBuffer req = ByteBuffer.wrap(reqBytes);
-            req.putInt(ByteBuffer.wrap("gtmk".getBytes()).getInt());
-
-            s = new Socket();
-            s.setSoLinger(false, 10);
-            s.setSoTimeout(20000);
-            s.connect(new InetSocketAddress(host, port));
-
-            InputStream is = s.getInputStream();
-            OutputStream os = s.getOutputStream();
-
-            os.write(reqBytes);
-
-            byte[] resBytes = new byte[8];
-
-            int rc = is.read(resBytes);
-            ByteBuffer res = ByteBuffer.wrap(resBytes);
-            long retv = res.getLong();
-            System.out.println("rc=" + rc + " retv=0"
-                    + Long.toOctalString(retv));
-        } catch (IOException e) {
-            LOG.warn("Unexpected exception", e);
-        } finally {
-            if (s != null) {
-                try {
-                    s.close();
-                } catch (IOException e) {
-                    LOG.warn("Unexpected exception", e);
-                }
-            }
-        }
-    }
-
-    private static void usage() {
-        System.out
-                .println("usage: java [-cp CLASSPATH] org.apache.zookeeper.ServerAdminClient "
-                        + "host port op (ruok|stat|dump|kill|gettracemask|settracemask) [arguments]");
-
-    }
-
-    public static void main(String[] args) {
-        if (args.length < 3) {
-            usage();
-            return;
-        }
-        String host = args[0];
-        int port = Integer.parseInt(args[1]);
-        String op = args[2];
-        if (op.equalsIgnoreCase("gettracemask")) {
-            getTraceMask(host, port);
-        } else if (op.equalsIgnoreCase("settracemask")) {
-            setTraceMask(host, port, args[3]);
-        } else if (op.equalsIgnoreCase("ruok")) {
-            ruok(host, port);
-        } else if (op.equalsIgnoreCase("kill")) {
-            kill(host, port);
-        } else if (op.equalsIgnoreCase("stat")) {
-            stat(host, port);
-        } else if (op.equalsIgnoreCase("dump")) {
-            dump(host, port);
-        } else {
-            System.out.println("Unrecognized op: " + op);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Shell.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Shell.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Shell.java
deleted file mode 100644
index 246170e..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Shell.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/**
- * 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.
- */
-
-/* This file copied from Hadoop's security branch,
-  * with the following changes:
-  * 1. package changed from org.apache.hadoop.util to
-  *    org.apache.zookeeper.
-  * 2. Usage of Hadoop's Configuration class removed since
-  *    it is not available in Zookeeper: instead, system properties
-  *    are used.
-  * 3. The deprecated getUlimitMemoryCommand() method removed since
-  *    it is not needed.
-  */
-
-
-package org.apache.zookeeper;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.common.Time;
-
-/**
- * A base class for running a Unix command.
- * 
- * <code>Shell</code> can be used to run unix commands like <code>du</code> or
- * <code>df</code>. It also offers facilities to gate commands by 
- * time-intervals.
- */
-abstract public class Shell {
-  
-  Logger LOG = Logger.getLogger(Shell.class);
-  
-  /** a Unix command to get the current user's name */
-  public final static String USER_NAME_COMMAND = "whoami";
-  /** a Unix command to get the current user's groups list */
-  public static String[] getGroupsCommand() {
-    return new String[]{"bash", "-c", "groups"};
-  }
-  /** a Unix command to get a given user's groups list */
-  public static String[] getGroupsForUserCommand(final String user) {
-    //'groups username' command return is non-consistent across different unixes
-    return new String [] {"bash", "-c", "id -Gn " + user};
-  }
-  /** a Unix command to set permission */
-  public static final String SET_PERMISSION_COMMAND = "chmod";
-  /** a Unix command to set owner */
-  public static final String SET_OWNER_COMMAND = "chown";
-  public static final String SET_GROUP_COMMAND = "chgrp";
-  /** Return a Unix command to get permission information. */
-  public static String[] getGET_PERMISSION_COMMAND() {
-    //force /bin/ls, except on windows.
-    return new String[] {(WINDOWS ? "ls" : "/bin/ls"), "-ld"};
-  }
-
-  /**Time after which the executing script would be timedout*/
-  protected long timeOutInterval = 0L;
-  /** If or not script timed out*/
-  private AtomicBoolean timedOut;
-
-  /** a Unix command to get ulimit of a process. */
-  public static final String ULIMIT_COMMAND = "ulimit";
-  
-  /** 
-   * Get the Unix command for setting the maximum virtual memory available
-   * to a given child process. This is only relevant when we are forking a
-   * process from within the Mapper or the Reducer implementations.
-   * Also see Hadoop Pipes and Hadoop Streaming.
-   * 
-   * It also checks to ensure that we are running on a *nix platform else 
-   * (e.g. in Cygwin/Windows) it returns <code>null</code>.
-   * @param memoryLimit virtual memory limit
-   * @return a <code>String[]</code> with the ulimit command arguments or 
-   *         <code>null</code> if we are running on a non *nix platform or
-   *         if the limit is unspecified.
-   */
-  public static String[] getUlimitMemoryCommand(int memoryLimit) {
-    // ulimit isn't supported on Windows
-    if (WINDOWS) {
-      return null;
-    }
-    
-    return new String[] {ULIMIT_COMMAND, "-v", String.valueOf(memoryLimit)};
-  }
-
-  /** Set to true on Windows platforms */
-  public static final boolean WINDOWS /* borrowed from Path.WINDOWS */
-                = System.getProperty("os.name").startsWith("Windows");
-  
-  private long    interval;   // refresh interval in msec
-  private long    lastTime;   // last time the command was performed
-  private Map<String, String> environment; // env for the command execution
-  private File dir;
-  private Process process; // sub process used to execute the command
-  private int exitCode;
-
-  /**If or not script finished executing*/
-  private volatile AtomicBoolean completed;
-  
-  public Shell() {
-    this(0L);
-  }
-  
-  /**
-   * @param interval the minimum duration to wait before re-executing the 
-   *        command.
-   */
-  public Shell( long interval ) {
-    this.interval = interval;
-    this.lastTime = (interval<0) ? 0 : -interval;
-  }
-  
-  /** set the environment for the command 
-   * @param env Mapping of environment variables
-   */
-  protected void setEnvironment(Map<String, String> env) {
-    this.environment = env;
-  }
-
-  /** set the working directory 
-   * @param dir The directory where the command would be executed
-   */
-  protected void setWorkingDirectory(File dir) {
-    this.dir = dir;
-  }
-
-  /** check to see if a command needs to be executed and execute if needed */
-  protected void run() throws IOException {
-    if (lastTime + interval > Time.currentElapsedTime())
-      return;
-    exitCode = 0; // reset for next run
-    runCommand();
-  }
-
-  /** Run a command */
-  private void runCommand() throws IOException { 
-    ProcessBuilder builder = new ProcessBuilder(getExecString());
-    Timer timeOutTimer = null;
-    ShellTimeoutTimerTask timeoutTimerTask = null;
-    timedOut = new AtomicBoolean(false);
-    completed = new AtomicBoolean(false);
-    
-    if (environment != null) {
-      builder.environment().putAll(this.environment);
-    }
-    if (dir != null) {
-      builder.directory(this.dir);
-    }
-    
-    process = builder.start();
-    if (timeOutInterval > 0) {
-      timeOutTimer = new Timer();
-      timeoutTimerTask = new ShellTimeoutTimerTask(
-          this);
-      //One time scheduling.
-      timeOutTimer.schedule(timeoutTimerTask, timeOutInterval);
-    }
-    final BufferedReader errReader = 
-            new BufferedReader(new InputStreamReader(process
-                                                     .getErrorStream()));
-    BufferedReader inReader = 
-            new BufferedReader(new InputStreamReader(process
-                                                     .getInputStream()));
-    final StringBuffer errMsg = new StringBuffer();
-    
-    // read error and input streams as this would free up the buffers
-    // free the error stream buffer
-    Thread errThread = new Thread() {
-      @Override
-      public void run() {
-        try {
-          String line = errReader.readLine();
-          while((line != null) && !isInterrupted()) {
-            errMsg.append(line);
-            errMsg.append(System.getProperty("line.separator"));
-            line = errReader.readLine();
-          }
-        } catch(IOException ioe) {
-          LOG.warn("Error reading the error stream", ioe);
-        }
-      }
-    };
-    try {
-      errThread.start();
-    } catch (IllegalStateException ise) { }
-    try {
-      parseExecResult(inReader); // parse the output
-      // clear the input stream buffer
-      String line = inReader.readLine();
-      while(line != null) { 
-        line = inReader.readLine();
-      }
-      // wait for the process to finish and check the exit code
-      exitCode  = process.waitFor();
-      try {
-        // make sure that the error thread exits
-        errThread.join();
-      } catch (InterruptedException ie) {
-        LOG.warn("Interrupted while reading the error stream", ie);
-      }
-      completed.set(true);
-      //the timeout thread handling
-      //taken care in finally block
-      if (exitCode != 0) {
-        throw new ExitCodeException(exitCode, errMsg.toString());
-      }
-    } catch (InterruptedException ie) {
-      throw new IOException(ie.toString());
-    } finally {
-      if ((timeOutTimer!=null) && !timedOut.get()) {
-        timeOutTimer.cancel();
-      }
-      // close the input stream
-      try {
-        inReader.close();
-      } catch (IOException ioe) {
-        LOG.warn("Error while closing the input stream", ioe);
-      }
-      if (!completed.get()) {
-        errThread.interrupt();
-      }
-      try {
-        errReader.close();
-      } catch (IOException ioe) {
-        LOG.warn("Error while closing the error stream", ioe);
-      }
-      process.destroy();
-      lastTime = Time.currentElapsedTime();
-    }
-  }
-
-  /** return an array containing the command name & its parameters */ 
-  protected abstract String[] getExecString();
-  
-  /** Parse the execution result */
-  protected abstract void parseExecResult(BufferedReader lines)
-  throws IOException;
-
-  /** get the current sub-process executing the given command 
-   * @return process executing the command
-   */
-  public Process getProcess() {
-    return process;
-  }
-
-  /** get the exit code 
-   * @return the exit code of the process
-   */
-  public int getExitCode() {
-    return exitCode;
-  }
-
-  /**
-   * This is an IOException with exit code added.
-   */
-  @SuppressWarnings("serial")
-  public static class ExitCodeException extends IOException {
-    int exitCode;
-    
-    public ExitCodeException(int exitCode, String message) {
-      super(message);
-      this.exitCode = exitCode;
-    }
-    
-    public int getExitCode() {
-      return exitCode;
-    }
-  }
-  
-  /**
-   * A simple shell command executor.
-   * 
-   * <code>ShellCommandExecutor</code>should be used in cases where the output 
-   * of the command needs no explicit parsing and where the command, working 
-   * directory and the environment remains unchanged. The output of the command 
-   * is stored as-is and is expected to be small.
-   */
-  public static class ShellCommandExecutor extends Shell {
-    
-    private String[] command;
-    private StringBuffer output;
-    
-    
-    public ShellCommandExecutor(String[] execString) {
-      this(execString, null);
-    }
-    
-    public ShellCommandExecutor(String[] execString, File dir) {
-      this(execString, dir, null);
-    }
-   
-    public ShellCommandExecutor(String[] execString, File dir, 
-                                 Map<String, String> env) {
-      this(execString, dir, env , 0L);
-    }
-
-    /**
-     * Create a new instance of the ShellCommandExecutor to execute a command.
-     * 
-     * @param execString The command to execute with arguments
-     * @param dir If not-null, specifies the directory which should be set
-     *            as the current working directory for the command.
-     *            If null, the current working directory is not modified.
-     * @param env If not-null, environment of the command will include the
-     *            key-value pairs specified in the map. If null, the current
-     *            environment is not modified.
-     * @param timeout Specifies the time in milliseconds, after which the
-     *                command will be killed and the status marked as timedout.
-     *                If 0, the command will not be timed out. 
-     */
-    public ShellCommandExecutor(String[] execString, File dir, 
-        Map<String, String> env, long timeout) {
-      command = execString.clone();
-      if (dir != null) {
-        setWorkingDirectory(dir);
-      }
-      if (env != null) {
-        setEnvironment(env);
-      }
-      timeOutInterval = timeout;
-    }
-        
-
-    /** Execute the shell command. */
-    public void execute() throws IOException {
-      this.run();    
-    }
-
-    protected String[] getExecString() {
-      return command;
-    }
-
-    protected void parseExecResult(BufferedReader lines) throws IOException {
-      output = new StringBuffer();
-      char[] buf = new char[512];
-      int nRead;
-      while ( (nRead = lines.read(buf, 0, buf.length)) > 0 ) {
-        output.append(buf, 0, nRead);
-      }
-    }
-    
-    /** Get the output of the shell command.*/
-    public String getOutput() {
-      return (output == null) ? "" : output.toString();
-    }
-
-    /**
-     * Returns the commands of this instance.
-     * Arguments with spaces in are presented with quotes round; other
-     * arguments are presented raw
-     *
-     * @return a string representation of the object.
-     */
-    public String toString() {
-      StringBuilder builder = new StringBuilder();
-      String[] args = getExecString();
-      for (String s : args) {
-        if (s.indexOf(' ') >= 0) {
-          builder.append('"').append(s).append('"');
-        } else {
-          builder.append(s);
-        }
-        builder.append(' ');
-      }
-      return builder.toString();
-    }
-  }
-  
-  /**
-   * To check if the passed script to shell command executor timed out or
-   * not.
-   * 
-   * @return if the script timed out.
-   */
-  public boolean isTimedOut() {
-    return timedOut.get();
-  }
-  
-  /**
-   * Set if the command has timed out.
-   * 
-   */
-  private void setTimedOut() {
-    this.timedOut.set(true);
-  }
-  
-  /** 
-   * Static method to execute a shell command. 
-   * Covers most of the simple cases without requiring the user to implement  
-   * the <code>Shell</code> interface.
-   * @param cmd shell command to execute.
-   * @return the output of the executed command.
-   */
-  public static String execCommand(String ... cmd) throws IOException {
-    return execCommand(null, cmd, 0L);
-  }
-  
-  /** 
-   * Static method to execute a shell command. 
-   * Covers most of the simple cases without requiring the user to implement  
-   * the <code>Shell</code> interface.
-   * @param env the map of environment key=value
-   * @param cmd shell command to execute.
-   * @param timeout time in milliseconds after which script should be marked timeout
-   * @return the output of the executed command.o
-   */
-  
-  public static String execCommand(Map<String, String> env, String[] cmd,
-      long timeout) throws IOException {
-    ShellCommandExecutor exec = new ShellCommandExecutor(cmd, null, env, 
-                                                          timeout);
-    exec.execute();
-    return exec.getOutput();
-  }
-
-  /** 
-   * Static method to execute a shell command. 
-   * Covers most of the simple cases without requiring the user to implement  
-   * the <code>Shell</code> interface.
-   * @param env the map of environment key=value
-   * @param cmd shell command to execute.
-   * @return the output of the executed command.
-   */
-  public static String execCommand(Map<String,String> env, String ... cmd) 
-  throws IOException {
-    return execCommand(env, cmd, 0L);
-  }
-  
-  /**
-   * Timer which is used to timeout scripts spawned off by shell.
-   */
-  private static class ShellTimeoutTimerTask extends TimerTask {
-
-    private Shell shell;
-
-    public ShellTimeoutTimerTask(Shell shell) {
-      this.shell = shell;
-    }
-
-    @Override
-    public void run() {
-      Process p = shell.getProcess();
-      try {
-        p.exitValue();
-      } catch (Exception e) {
-        //Process has not terminated.
-        //So check if it has completed 
-        //if not just destroy it.
-        if (p != null && !shell.completed.get()) {
-          shell.setTimedOut();
-          p.destroy();
-        }
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/StatsTrack.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/StatsTrack.java b/zookeeper-common/src/main/java/org/apache/zookeeper/StatsTrack.java
deleted file mode 100644
index 623c6d4..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/StatsTrack.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-/**
- * a class that represents the stats associated with quotas
- */
-public class StatsTrack {
-    private int count;
-    private long bytes;
-    private String countStr = "count";
-    private String byteStr = "bytes";
-
-    /**
-     * a default constructor for
-     * stats
-     */
-    public StatsTrack() {
-        this(null);
-    }
-    /**
-     * the stat string should be of the form count=int,bytes=long
-     * if stats is called with null the count and bytes are initialized
-     * to -1.
-     * @param stats the stat string to be intialized with
-     */
-    public StatsTrack(String stats) {
-        if (stats == null) {
-            stats = "count=-1,bytes=-1";
-        }
-        String[] split = stats.split(",");
-        if (split.length != 2) {
-            throw new IllegalArgumentException("invalid string " + stats);
-        }
-        count = Integer.parseInt(split[0].split("=")[1]);
-        bytes = Long.parseLong(split[1].split("=")[1]);
-    }
-
-
-    /**
-     * get the count of nodes allowed as part of quota
-     *
-     * @return the count as part of this string
-     */
-    public int getCount() {
-        return this.count;
-    }
-
-    /**
-     * set the count for this stat tracker.
-     *
-     * @param count
-     *            the count to set with
-     */
-    public void setCount(int count) {
-        this.count = count;
-    }
-
-    /**
-     * get the count of bytes allowed as part of quota
-     *
-     * @return the bytes as part of this string
-     */
-    public long getBytes() {
-        return this.bytes;
-    }
-
-    /**
-     * set teh bytes for this stat tracker.
-     *
-     * @param bytes
-     *            the bytes to set with
-     */
-    public void setBytes(long bytes) {
-        this.bytes = bytes;
-    }
-
-    @Override
-    /*
-     * returns the string that maps to this stat tracking.
-     */
-    public String toString() {
-        return countStr + "=" + count + "," + byteStr + "=" + bytes;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Testable.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Testable.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Testable.java
deleted file mode 100644
index b38d2c3..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Testable.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-/**
- * Abstraction that exposes various methods useful for testing ZooKeeper
- */
-public interface Testable {
-    /**
-     * Cause the ZooKeeper instance to behave as if the session expired
-     */
-    void injectSessionExpiration();
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Transaction.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Transaction.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Transaction.java
deleted file mode 100644
index d8f0e01..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Transaction.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.apache.zookeeper.AsyncCallback.MultiCallback;
-import org.apache.zookeeper.data.ACL;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides a builder style interface for doing multiple updates.  This is
- * really just a thin layer on top of Zookeeper.multi().
- *
- * @since 3.4.0
- *
- */
-@InterfaceAudience.Public
-public class Transaction {
-    private ZooKeeper zk;
-    private List<Op> ops = new ArrayList<Op>();
-
-    protected Transaction(ZooKeeper zk) {
-        this.zk = zk;
-    }
-
-    public Transaction create(final String path, byte data[], List<ACL> acl,
-                              CreateMode createMode) {
-        ops.add(Op.create(path, data, acl, createMode.toFlag()));
-        return this;
-    }
-
-    public Transaction delete(final String path, int version) {
-        ops.add(Op.delete(path, version));
-        return this;
-    }
-
-    public Transaction check(String path, int version) {
-        ops.add(Op.check(path, version));
-        return this;
-    }
-
-    public Transaction setData(final String path, byte data[], int version) {
-        ops.add(Op.setData(path, data, version));
-        return this;
-    }
-
-    public List<OpResult> commit() throws InterruptedException, KeeperException {
-        return zk.multi(ops);
-    }
-
-    public void commit(MultiCallback cb, Object ctx) {
-        zk.multi(ops, cb, ctx);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Version.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Version.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Version.java
deleted file mode 100644
index 1f5cf1a..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Version.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-public class Version implements org.apache.zookeeper.version.Info {
-
-    /*
-     * Since the SVN to Git port this field doesn't return the revision anymore
-     * TODO: remove this method and associated field declaration in VerGen
-     * @see {@link #getHashRevision()}
-     * @return the default value -1
-     */
-    @Deprecated
-    public static int getRevision() {
-        return REVISION;
-    }
-
-    public static String getRevisionHash() {
-        return REVISION_HASH;
-    }
-
-    public static String getBuildDate() {
-        return BUILD_DATE;
-    }
-
-    public static String getVersion() {
-        return MAJOR + "." + MINOR + "." + MICRO
-            + (QUALIFIER == null ? "" : "-" + QUALIFIER);
-    }
-
-    public static String getVersionRevision() {
-        return getVersion() + "-" + getRevisionHash();
-    }
-
-    public static String getFullVersion() {
-        return getVersionRevision() + ", built on " + getBuildDate();
-    }
-
-    public static void printUsage() {
-        System.out
-                .print("Usage:\tjava -cp ... org.apache.zookeeper.Version "
-                        + "[--full | --short | --revision],\n\tPrints --full version "
-                        + "info if no arg specified.");
-        System.exit(1);
-    }
-
-    /**
-     * Prints the current version, revision and build date to the standard out.
-     * 
-     * @param args
-     *            <ul>
-     *            <li> --short - prints a short version string "1.2.3"
-     *            <li> --revision - prints a short version string with the SVN
-     *            repository revision "1.2.3-94"
-     *            <li> --full - prints the revision and the build date
-     *            </ul>
-     */
-    public static void main(String[] args) {
-        if (args.length > 1) {
-            printUsage();
-        }
-        if (args.length == 0 || (args.length == 1 && args[0].equals("--full"))) {
-            System.out.println(getFullVersion());
-            System.exit(0);
-        }
-        if (args[0].equals("--short"))
-            System.out.println(getVersion());
-        else if (args[0].equals("--revision"))
-            System.out.println(getVersionRevision());
-        else
-            printUsage();
-        System.exit(0);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/WatchedEvent.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/WatchedEvent.java b/zookeeper-common/src/main/java/org/apache/zookeeper/WatchedEvent.java
deleted file mode 100644
index 851fc6c..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/WatchedEvent.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.apache.zookeeper.proto.WatcherEvent;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-
-/**
- *  A WatchedEvent represents a change on the ZooKeeper that a Watcher
- *  is able to respond to.  The WatchedEvent includes exactly what happened,
- *  the current state of the ZooKeeper, and the path of the znode that
- *  was involved in the event.
- */
-@InterfaceAudience.Public
-public class WatchedEvent {
-    final private KeeperState keeperState;
-    final private EventType eventType;
-    private String path;
-    
-    /**
-     * Create a WatchedEvent with specified type, state and path
-     */
-    public WatchedEvent(EventType eventType, KeeperState keeperState, String path) {
-        this.keeperState = keeperState;
-        this.eventType = eventType;
-        this.path = path;
-    }
-    
-    /**
-     * Convert a WatcherEvent sent over the wire into a full-fledged WatcherEvent
-     */
-    public WatchedEvent(WatcherEvent eventMessage) {
-        keeperState = KeeperState.fromInt(eventMessage.getState());
-        eventType = EventType.fromInt(eventMessage.getType());
-        path = eventMessage.getPath();
-    }
-    
-    public KeeperState getState() {
-        return keeperState;
-    }
-    
-    public EventType getType() {
-        return eventType;
-    }
-    
-    public String getPath() {
-        return path;
-    }
-
-    @Override
-    public String toString() {
-        return "WatchedEvent state:" + keeperState
-            + " type:" + eventType + " path:" + path;
-    }
-
-    /**
-     *  Convert WatchedEvent to type that can be sent over network
-     */
-    public WatcherEvent getWrapper() {
-        return new WatcherEvent(eventType.getIntValue(), 
-                                keeperState.getIntValue(), 
-                                path);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Watcher.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Watcher.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Watcher.java
deleted file mode 100644
index 5c21485..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Watcher.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.yetus.audience.InterfaceAudience;
-
-/**
- * This interface specifies the public interface an event handler class must
- * implement. A ZooKeeper client will get various events from the ZooKeeper
- * server it connects to. An application using such a client handles these
- * events by registering a callback object with the client. The callback object
- * is expected to be an instance of a class that implements Watcher interface.
- * 
- */
-@InterfaceAudience.Public
-public interface Watcher {
-
-    /**
-     * This interface defines the possible states an Event may represent
-     */
-    @InterfaceAudience.Public
-    public interface Event {
-        /**
-         * Enumeration of states the ZooKeeper may be at the event
-         */
-        @InterfaceAudience.Public
-        public enum KeeperState {
-            /** Unused, this state is never generated by the server */
-            @Deprecated
-            Unknown (-1),
-
-            /** The client is in the disconnected state - it is not connected
-             * to any server in the ensemble. */
-            Disconnected (0),
-
-            /** Unused, this state is never generated by the server */
-            @Deprecated
-            NoSyncConnected (1),
-
-            /** The client is in the connected state - it is connected
-             * to a server in the ensemble (one of the servers specified
-             * in the host connection parameter during ZooKeeper client
-             * creation). */
-            SyncConnected (3),
-
-            /**
-             * Auth failed state
-             */
-            AuthFailed (4),
-
-            /**
-             * The client is connected to a read-only server, that is the
-             * server which is not currently connected to the majority.
-             * The only operations allowed after receiving this state is
-             * read operations.
-             * This state is generated for read-only clients only since
-             * read/write clients aren't allowed to connect to r/o servers.
-             */
-            ConnectedReadOnly (5),
-
-            /**
-              * SaslAuthenticated: used to notify clients that they are SASL-authenticated,
-              * so that they can perform Zookeeper actions with their SASL-authorized permissions.
-              */
-            SaslAuthenticated(6),
-
-            /** The serving cluster has expired this session. The ZooKeeper
-             * client connection (the session) is no longer valid. You must
-             * create a new client connection (instantiate a new ZooKeeper
-             * instance) if you with to access the ensemble. */
-            Expired (-112);
-
-            private final int intValue;     // Integer representation of value
-                                            // for sending over wire
-
-            KeeperState(int intValue) {
-                this.intValue = intValue;
-            }
-
-            public int getIntValue() {
-                return intValue;
-            }
-
-            public static KeeperState fromInt(int intValue) {
-                switch(intValue) {
-                    case   -1: return KeeperState.Unknown;
-                    case    0: return KeeperState.Disconnected;
-                    case    1: return KeeperState.NoSyncConnected;
-                    case    3: return KeeperState.SyncConnected;
-                    case    4: return KeeperState.AuthFailed;
-                    case    5: return KeeperState.ConnectedReadOnly;
-                    case    6: return KeeperState.SaslAuthenticated;
-                    case -112: return KeeperState.Expired;
-
-                    default:
-                        throw new RuntimeException("Invalid integer value for conversion to KeeperState");
-                }
-            }
-        }
-
-        /**
-         * Enumeration of types of events that may occur on the ZooKeeper
-         */
-        @InterfaceAudience.Public
-        public enum EventType {
-            None (-1),
-            NodeCreated (1),
-            NodeDeleted (2),
-            NodeDataChanged (3),
-            NodeChildrenChanged (4);
-
-            private final int intValue;     // Integer representation of value
-                                            // for sending over wire
-
-            EventType(int intValue) {
-                this.intValue = intValue;
-            }
-
-            public int getIntValue() {
-                return intValue;
-            }
-
-            public static EventType fromInt(int intValue) {
-                switch(intValue) {
-                    case -1: return EventType.None;
-                    case  1: return EventType.NodeCreated;
-                    case  2: return EventType.NodeDeleted;
-                    case  3: return EventType.NodeDataChanged;
-                    case  4: return EventType.NodeChildrenChanged;
-
-                    default:
-                        throw new RuntimeException("Invalid integer value for conversion to EventType");
-                }
-            }           
-        }
-    }
-
-    abstract public void process(WatchedEvent event);
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ZKUtil.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ZKUtil.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ZKUtil.java
deleted file mode 100644
index e901832..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ZKUtil.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper;
-
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.common.PathUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-         
-public class ZKUtil {
-    private static final Logger LOG = LoggerFactory.getLogger(ZKUtil.class);
-    /**
-     * Recursively delete the node with the given path. 
-     * <p>
-     * Important: All versions, of all nodes, under the given node are deleted.
-     * <p>
-     * If there is an error with deleting one of the sub-nodes in the tree, 
-     * this operation would abort and would be the responsibility of the app to handle the same.
-     * 
-     * See {@link #delete(String, int)} for more details.
-     * 
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public static void deleteRecursive(ZooKeeper zk, final String pathRoot)
-        throws InterruptedException, KeeperException
-    {
-        PathUtils.validatePath(pathRoot);
-      
-        List<String> tree = listSubTreeBFS(zk, pathRoot);
-        LOG.debug("Deleting " + tree);
-        LOG.debug("Deleting " + tree.size() + " subnodes ");
-        for (int i = tree.size() - 1; i >= 0 ; --i) {
-            //Delete the leaves first and eventually get rid of the root
-            zk.delete(tree.get(i), -1); //Delete all versions of the node with -1.
-        }
-    }
-    
-
-    /**
-     * Recursively delete the node with the given path. (async version).
-     * 
-     * <p>
-     * Important: All versions, of all nodes, under the given node are deleted.
-     * <p>
-     * If there is an error with deleting one of the sub-nodes in the tree, 
-     * this operation would abort and would be the responsibility of the app to handle the same.
-     * <p>
-     * @param zk the zookeeper handle
-     * @param pathRoot the path to be deleted
-     * @param cb call back method
-     * @param ctx the context the callback method is called with
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public static void deleteRecursive(ZooKeeper zk, final String pathRoot, VoidCallback cb,
-        Object ctx)
-        throws InterruptedException, KeeperException
-    {
-        PathUtils.validatePath(pathRoot);
-      
-        List<String> tree = listSubTreeBFS(zk, pathRoot);
-        LOG.debug("Deleting " + tree);
-        LOG.debug("Deleting " + tree.size() + " subnodes ");
-        for (int i = tree.size() - 1; i >= 0 ; --i) {
-            //Delete the leaves first and eventually get rid of the root
-            zk.delete(tree.get(i), -1, cb, ctx); //Delete all versions of the node with -1.
-        }
-    }
-    
-    /**
-     * BFS Traversal of the system under pathRoot, with the entries in the list, in the 
-     * same order as that of the traversal.
-     * <p>
-     * <b>Important:</b> This is <i>not an atomic snapshot</i> of the tree ever, but the
-     *  state as it exists across multiple RPCs from zkClient to the ensemble.
-     * For practical purposes, it is suggested to bring the clients to the ensemble 
-     * down (i.e. prevent writes to pathRoot) to 'simulate' a snapshot behavior.   
-     * 
-     * @param zk the zookeeper handle
-     * @param pathRoot The znode path, for which the entire subtree needs to be listed.
-     * @throws InterruptedException 
-     * @throws KeeperException 
-     */
-    public static List<String> listSubTreeBFS(ZooKeeper zk, final String pathRoot) throws 
-        KeeperException, InterruptedException {
-        Deque<String> queue = new LinkedList<String>();
-        List<String> tree = new ArrayList<String>();
-        queue.add(pathRoot);
-        tree.add(pathRoot);
-        while (true) {
-            String node = queue.pollFirst();
-            if (node == null) {
-                break;
-            }
-            List<String> children = zk.getChildren(node, false);
-            for (final String child : children) {
-                final String childPath = node + "/" + child;
-                queue.add(childPath);
-                tree.add(childPath);
-            }
-        }
-        return tree;
-    }
-    
-} 

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ZooDefs.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooDefs.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ZooDefs.java
deleted file mode 100644
index 09bc95c..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooDefs.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Id;
-
-@InterfaceAudience.Public
-public class ZooDefs {
-
-    @InterfaceAudience.Public
-    public interface OpCode {
-        public final int notification = 0;
-
-        public final int create = 1;
-
-        public final int delete = 2;
-
-        public final int exists = 3;
-
-        public final int getData = 4;
-
-        public final int setData = 5;
-
-        public final int getACL = 6;
-
-        public final int setACL = 7;
-
-        public final int getChildren = 8;
-
-        public final int sync = 9;
-
-        public final int ping = 11;
-
-        public final int getChildren2 = 12;
-
-        public final int check = 13;
-
-        public final int multi = 14;
-
-        public final int auth = 100;
-
-        public final int setWatches = 101;
-
-        public final int sasl = 102;
-
-        public final int createSession = -10;
-
-        public final int closeSession = -11;
-
-        public final int error = -1;
-    }
-
-    @InterfaceAudience.Public
-    public interface Perms {
-        int READ = 1 << 0;
-
-        int WRITE = 1 << 1;
-
-        int CREATE = 1 << 2;
-
-        int DELETE = 1 << 3;
-
-        int ADMIN = 1 << 4;
-
-        int ALL = READ | WRITE | CREATE | DELETE | ADMIN;
-    }
-
-    @InterfaceAudience.Public
-    public interface Ids {
-        /**
-         * This Id represents anyone.
-         */
-        public final Id ANYONE_ID_UNSAFE = new Id("world", "anyone");
-
-        /**
-         * This Id is only usable to set ACLs. It will get substituted with the
-         * Id's the client authenticated with.
-         */
-        public final Id AUTH_IDS = new Id("auth", "");
-
-        /**
-         * This is a completely open ACL .
-         */
-        public final ArrayList<ACL> OPEN_ACL_UNSAFE = new ArrayList<ACL>(
-                Collections.singletonList(new ACL(Perms.ALL, ANYONE_ID_UNSAFE)));
-
-        /**
-         * This ACL gives the creators authentication id's all permissions.
-         */
-        public final ArrayList<ACL> CREATOR_ALL_ACL = new ArrayList<ACL>(
-                Collections.singletonList(new ACL(Perms.ALL, AUTH_IDS)));
-
-        /**
-         * This ACL gives the world the ability to read.
-         */
-        public final ArrayList<ACL> READ_ACL_UNSAFE = new ArrayList<ACL>(
-                Collections
-                        .singletonList(new ACL(Perms.READ, ANYONE_ID_UNSAFE)));
-    }
-
-    final public static String[] opNames = { "notification", "create",
-            "delete", "exists", "getData", "setData", "getACL", "setACL",
-            "getChildren", "getChildren2", "getMaxChildren", "setMaxChildren", "ping" };
-}


[11/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/resources/lib/log4j-1.2.17.LICENSE.txt
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/resources/lib/log4j-1.2.17.LICENSE.txt b/zookeeper-server/src/main/resources/lib/log4j-1.2.17.LICENSE.txt
new file mode 100644
index 0000000..6279e52
--- /dev/null
+++ b/zookeeper-server/src/main/resources/lib/log4j-1.2.17.LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 1999-2005 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.

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt b/zookeeper-server/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt
new file mode 100644
index 0000000..315bd49
--- /dev/null
+++ b/zookeeper-server/src/main/resources/lib/slf4j-1.7.25.LICENSE.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2004-2017 QOS.ch
+All rights reserved.
+
+Permission is hereby granted, free  of charge, to any person obtaining
+a  copy  of this  software  and  associated  documentation files  (the
+"Software"), to  deal in  the Software without  restriction, including
+without limitation  the rights to  use, copy, modify,  merge, publish,
+distribute,  sublicense, and/or sell  copies of  the Software,  and to
+permit persons to whom the Software  is furnished to do so, subject to
+the following conditions:
+
+The  above  copyright  notice  and  this permission  notice  shall  be
+included in all copies or substantial portions of the Software.
+
+THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/ClientReconnectTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/ClientReconnectTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/ClientReconnectTest.java
new file mode 100644
index 0000000..8d66a7e
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/ClientReconnectTest.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper;
+
+
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.zookeeper.client.HostProvider;
+import org.junit.Test;
+
+public class ClientReconnectTest extends TestCase {
+    private SocketChannel sc;
+    private CountDownLatch countDownLatch = new CountDownLatch(3);
+    
+    class MockCnxn extends ClientCnxnSocketNIO {
+        MockCnxn() throws IOException {
+            super();
+        }
+
+        @Override
+        void registerAndConnect(SocketChannel sock, InetSocketAddress addr) throws
+        IOException {
+            countDownLatch.countDown();
+            throw new IOException("failed to register");
+        }
+
+        @Override
+        SocketChannel createSock() {
+            return sc;
+        }
+    }
+
+    @Test
+    public void testClientReconnect() throws IOException, InterruptedException {
+        HostProvider hostProvider = mock(HostProvider.class);
+        when(hostProvider.size()).thenReturn(1);
+        InetSocketAddress inaddr = new InetSocketAddress(1111);
+        when(hostProvider.next(anyLong())).thenReturn(inaddr);
+        ZooKeeper zk = mock(ZooKeeper.class);
+        sc =  SocketChannel.open();
+
+        ClientCnxnSocketNIO nioCnxn = new MockCnxn();
+        ClientWatchManager watcher = mock(ClientWatchManager.class);
+        ClientCnxn clientCnxn = new ClientCnxn(
+                "tmp", hostProvider, 5000,
+                zk, watcher, nioCnxn, false);
+        clientCnxn.start();
+        countDownLatch.await(5000, TimeUnit.MILLISECONDS);
+        Assert.assertTrue(countDownLatch.getCount() == 0);
+        clientCnxn.close();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java b/zookeeper-server/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java
new file mode 100644
index 0000000..37149cc
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/JUnit4ZKTestRunner.java
@@ -0,0 +1,86 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.junit.Test;
+import org.junit.internal.runners.statements.InvokeMethod;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+/**
+ * The sole responsibility of this class is to print to the log when a test
+ * starts and when it finishes.
+ */
+public class JUnit4ZKTestRunner extends BlockJUnit4ClassRunner {
+    private static final Logger LOG = LoggerFactory.getLogger(JUnit4ZKTestRunner.class);
+
+    public JUnit4ZKTestRunner(Class<?> klass) throws InitializationError {
+        super(klass);
+    }
+
+    public class LoggedInvokeMethod extends InvokeMethod {
+        private final FrameworkMethod method;
+        private final String name;
+
+        public LoggedInvokeMethod(FrameworkMethod method, Object target) {
+            super(method, target);
+            this.method = method;
+            name = method.getName();
+        }
+
+        @Override
+        public void evaluate() throws Throwable {
+            LOG.info("RUNNING TEST METHOD {}", name);
+            try {
+                super.evaluate();
+                Runtime rt = Runtime.getRuntime();
+                long usedKB = (rt.totalMemory() - rt.freeMemory()) / 1024;
+                LOG.info("Memory used {}", usedKB);
+                ThreadGroup tg = Thread.currentThread().getThreadGroup();
+                while (tg.getParent() != null) {
+                    tg = tg.getParent();
+                }
+                LOG.info("Number of threads {}", tg.activeCount());
+            } catch (Throwable t) {
+                // The test method threw an exception, but it might be an
+                // expected exception as defined in the @Test annotation.
+                // Check the annotation and log an appropriate message.
+                Test annotation = this.method.getAnnotation(Test.class);
+                if (annotation != null && annotation.expected() != null &&
+                        annotation.expected().isAssignableFrom(t.getClass())) {
+                    LOG.info("TEST METHOD {} THREW EXPECTED EXCEPTION {}", name,
+                        annotation.expected());
+                } else {
+                    LOG.info("TEST METHOD FAILED {}", name, t);
+                }
+                throw t;
+            }
+            LOG.info("FINISHED TEST METHOD {}", name);
+        }
+    }
+
+    @Override
+    protected Statement methodInvoker(FrameworkMethod method, Object test) {
+        return new LoggedInvokeMethod(method, test);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/JaasConfiguration.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/JaasConfiguration.java b/zookeeper-server/src/test/java/org/apache/zookeeper/JaasConfiguration.java
new file mode 100644
index 0000000..bf145d0
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/JaasConfiguration.java
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+
+/**
+ * This helper class allows to programmatically create a JAAS configuration.
+ * Each section must have a name and a login module, and a set of key/values
+ * to describe login options.
+ *
+ * Example:
+ *   jaas = new JaasConfiguration();
+ *   jaas.addSection("Server", "org.apache.zookeeper.server.auth.DigestLoginModule",
+ *                   "username", "passowrd");
+ */
+public class JaasConfiguration extends javax.security.auth.login.Configuration {
+    private final Map<String, AppConfigurationEntry[]> sections =
+      new HashMap<String, AppConfigurationEntry[]>();
+
+    public JaasConfiguration() {
+    }
+
+    /**
+     * Add a section to the jaas.conf
+     * @param name Section name
+     * @param loginModuleName Login module name
+     * @param args login key/value args
+     */
+    public void addSection(String name, String loginModuleName, String... args) {
+        Map<String, String> conf = new HashMap<String, String>();
+        // loop through the args (must be key/value sequence)
+        for (int i = 0; i < args.length - 1; i += 2) {
+            conf.put(args[i], args[i + 1]);
+        }
+        addSection(name, loginModuleName, conf);
+    }
+
+    /**
+     * Add a section to the jaas.conf
+     * @param name Section name
+     * @param loginModuleName Login module name
+     * @param conf login key/value args
+     */
+    public void addSection(String name, String loginModuleName, final Map<String,String> conf) {
+        AppConfigurationEntry[] entries = new AppConfigurationEntry[1];
+        entries[0] = new AppConfigurationEntry(loginModuleName, LoginModuleControlFlag.REQUIRED, conf);
+        this.sections.put(name, entries);
+    }
+
+    @Override
+    public AppConfigurationEntry[] getAppConfigurationEntry(String appName) {
+        return sections.get(appName);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/MockPacket.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/MockPacket.java b/zookeeper-server/src/test/java/org/apache/zookeeper/MockPacket.java
new file mode 100644
index 0000000..f4bb19a
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/MockPacket.java
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.zookeeper.proto.RequestHeader;
+import org.apache.zookeeper.proto.ReplyHeader;
+import org.apache.jute.Record;
+import org.apache.zookeeper.ZooKeeper.WatchRegistration;
+import java.nio.ByteBuffer;
+
+public class MockPacket extends ClientCnxn.Packet {
+
+    public MockPacket(RequestHeader requestHeader, ReplyHeader replyHeader,
+               Record request, Record response,
+               WatchRegistration watchRegistration) {
+        super(requestHeader, replyHeader, request, response, watchRegistration);
+    }
+
+    public MockPacket(RequestHeader requestHeader, ReplyHeader replyHeader,
+               Record request, Record response,
+               WatchRegistration watchRegistration, boolean readOnly) {
+        super(requestHeader, replyHeader, request, response, watchRegistration, readOnly);
+    }
+
+    public ByteBuffer createAndReturnBB() {
+        createBB();
+        return this.bb;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/MultiResponseTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/MultiResponseTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/MultiResponseTest.java
new file mode 100644
index 0000000..a03feb3
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/MultiResponseTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import junit.framework.TestCase;
+import org.apache.jute.BinaryInputArchive;
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ByteBufferInputStream;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class MultiResponseTest extends TestCase {
+    public void testRoundTrip() throws IOException {
+        MultiResponse response = new MultiResponse();
+
+        response.add(new OpResult.CheckResult());
+        response.add(new OpResult.CreateResult("foo-bar"));
+        response.add(new OpResult.DeleteResult());
+
+        Stat s = new Stat();
+        s.setCzxid(546);
+        response.add(new OpResult.SetDataResult(s));
+
+        MultiResponse decodedResponse = codeDecode(response);
+
+        assertEquals(response, decodedResponse);
+        assertEquals(response.hashCode(), decodedResponse.hashCode());
+    }
+
+    @Test
+    public void testEmptyRoundTrip() throws IOException {
+        MultiResponse result = new MultiResponse();
+        MultiResponse decodedResult = codeDecode(result);
+
+        assertEquals(result, decodedResult);
+        assertEquals(result.hashCode(), decodedResult.hashCode());
+    }
+
+    private MultiResponse codeDecode(MultiResponse request) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+        request.serialize(boa, "result");
+        baos.close();
+        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
+        bb.rewind();
+
+        BinaryInputArchive bia = BinaryInputArchive.getArchive(new ByteBufferInputStream(bb));
+        MultiResponse decodedRequest = new MultiResponse();
+        decodedRequest.deserialize(bia, "result");
+        return decodedRequest;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java
new file mode 100644
index 0000000..3749564
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/MultiTransactionRecordTest.java
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import junit.framework.TestCase;
+import org.apache.jute.BinaryInputArchive;
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.zookeeper.server.ByteBufferInputStream;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class MultiTransactionRecordTest extends TestCase {
+    @Test
+    public void testRoundTrip() throws IOException {
+        MultiTransactionRecord request = new MultiTransactionRecord();
+        request.add(Op.check("check", 1));
+        request.add(Op.create("create", "create data".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, ZooDefs.Perms.ALL));
+        request.add(Op.delete("delete", 17));
+        request.add(Op.setData("setData", "set data".getBytes(), 19));
+
+        MultiTransactionRecord decodedRequest = codeDecode(request);
+
+        assertEquals(request, decodedRequest);
+        assertEquals(request.hashCode(), decodedRequest.hashCode());
+    }
+
+    @Test
+    public void testEmptyRoundTrip() throws IOException {
+        MultiTransactionRecord request = new MultiTransactionRecord();
+        MultiTransactionRecord decodedRequest = codeDecode(request);
+
+        assertEquals(request, decodedRequest);
+        assertEquals(request.hashCode(), decodedRequest.hashCode());
+    }
+
+    private MultiTransactionRecord codeDecode(MultiTransactionRecord request) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+        request.serialize(boa, "request");
+        baos.close();
+        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
+        bb.rewind();
+
+        BinaryInputArchive bia = BinaryInputArchive.getArchive(new ByteBufferInputStream(bb));
+        MultiTransactionRecord decodedRequest = new MultiTransactionRecord();
+        decodedRequest.deserialize(bia, "request");
+        return decodedRequest;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/PortAssignment.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/PortAssignment.java b/zookeeper-server/src/test/java/org/apache/zookeeper/PortAssignment.java
new file mode 100644
index 0000000..06f9361
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/PortAssignment.java
@@ -0,0 +1,35 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Assign ports to tests */
+public class PortAssignment {
+    private static final Logger LOG = LoggerFactory.getLogger(PortAssignment.class);
+
+    private static int nextPort = 11221;
+
+    /** Assign a new, unique port to the test */
+    public synchronized static int unique() {
+        LOG.info("assigning port " + nextPort);
+        return nextPort++;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/SaslAuthTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/SaslAuthTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/SaslAuthTest.java
new file mode 100644
index 0000000..eac0703
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/SaslAuthTest.java
@@ -0,0 +1,213 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.ClientCnxn.SendThread;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.test.ClientBase;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SaslAuthTest extends ClientBase {
+    @BeforeClass
+    public static void init() {
+        System.setProperty("zookeeper.authProvider.1",
+                "org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+        try {
+            File tmpDir = createTmpDir();
+            File saslConfFile = new File(tmpDir, "jaas.conf");
+            String jaasContent = getJaasFileContent();
+            FileWriter fwriter = new FileWriter(saslConfFile);
+            fwriter.write(jaasContent);
+            fwriter.close();
+            System.setProperty("java.security.auth.login.config", saslConfFile.getAbsolutePath());
+        } catch (IOException e) {
+            // could not create tmp directory to hold JAAS conf file : test will
+            // fail now.
+        }
+    }
+
+    private static String getJaasFileContent() {
+        StringBuilder jaasContent=new StringBuilder();
+        String newLine = System.getProperty("line.separator");
+        jaasContent.append("Server {");
+        jaasContent.append(newLine);
+        jaasContent.append("org.apache.zookeeper.server.auth.DigestLoginModule required");
+        jaasContent.append(newLine);
+        jaasContent.append("user_super=\"test\";");
+        jaasContent.append(newLine);
+        jaasContent.append("};");
+        jaasContent.append(newLine);
+        jaasContent.append("Client {");
+        jaasContent.append(newLine);
+        jaasContent.append("org.apache.zookeeper.server.auth.DigestLoginModule required");
+        jaasContent.append(newLine);
+        jaasContent.append("username=\"super\"");
+        jaasContent.append(newLine);
+        jaasContent.append("password=\"test\";");
+        jaasContent.append(newLine);
+        jaasContent.append("};");
+        jaasContent.append(newLine);
+        return jaasContent.toString();
+    }
+
+    @AfterClass
+    public static void clean() {
+        System.clearProperty("zookeeper.authProvider.1");
+        System.clearProperty("java.security.auth.login.config");
+    }
+
+    private AtomicInteger authFailed = new AtomicInteger(0);
+    
+    @Override
+    protected TestableZooKeeper createClient(String hp)
+    throws IOException, InterruptedException
+    {
+        MyWatcher watcher = new MyWatcher();
+        return createClient(watcher, hp);
+    }
+
+    private class MyWatcher extends CountdownWatcher {
+        @Override
+        public synchronized void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.AuthFailed) {
+                authFailed.incrementAndGet();
+            }
+            else {
+                super.process(event);
+            }
+        }
+    }
+
+    @Test
+    public void testAuth() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+            Thread.sleep(1000);
+        } finally {
+            zk.close();
+        }
+    }
+
+    @Test
+    public void testValidSaslIds() throws Exception {
+        ZooKeeper zk = createClient();
+
+        List<String> validIds = new ArrayList<String>();
+        validIds.add("user");
+        validIds.add("service/host.name.com");
+        validIds.add("user@KERB.REALM");
+        validIds.add("service/host.name.com@KERB.REALM");
+
+        int i = 0;
+        for(String validId: validIds) {
+            List<ACL> aclList = new ArrayList<ACL>();
+            ACL acl = new ACL(0,new Id("sasl",validId));
+            aclList.add(acl);
+            zk.create("/valid"+i,null,aclList,CreateMode.PERSISTENT);
+            i++;
+        }
+    }
+
+    @Test
+    public void testInvalidSaslIds() throws Exception {
+        ZooKeeper zk = createClient();
+
+        List<String> invalidIds = new ArrayList<String>();
+        invalidIds.add("user@KERB.REALM/server.com");
+        invalidIds.add("user@KERB.REALM1@KERB.REALM2");
+
+        int i = 0;
+        for(String invalidId: invalidIds) {
+            List<ACL> aclList = new ArrayList<ACL>();
+            try {
+                ACL acl = new ACL(0,new Id("sasl",invalidId));
+                aclList.add(acl);
+                zk.create("/invalid"+i,null,aclList,CreateMode.PERSISTENT);
+                Assert.fail("SASLAuthenticationProvider.isValid() failed to catch invalid Id.");
+            }
+            catch (KeeperException.InvalidACLException e) {
+                // ok.
+            }
+            finally {
+                i++;
+            }
+        }
+    }
+    
+    @Test
+    public void testZKOperationsAfterClientSaslAuthFailure() throws Exception {
+        CountdownWatcher watcher = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
+        watcher.waitForConnected(CONNECTION_TIMEOUT);
+        try {
+            setSaslFailureFlag(zk);
+
+            // try node creation for around 15 second,
+            int totalTry = 10;
+            int tryCount = 0;
+
+            boolean success = false;
+            while (!success && tryCount++ <= totalTry) {
+                try {
+                    zk.create("/saslAuthFail", "data".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                            CreateMode.PERSISTENT_SEQUENTIAL);
+                    success = true;
+                } catch (KeeperException.ConnectionLossException e) {
+                    Thread.sleep(1000);
+                    // do nothing
+                }
+            }
+            assertTrue("ZNode creation is failing continuously after Sasl auth failure.", success);
+
+        } finally {
+            zk.close();
+        }
+    }
+
+    // set saslLoginFailed to true to simulate the LoginException
+    private void setSaslFailureFlag(ZooKeeper zk) throws Exception {
+        Field cnxnField = zk.getClass().getDeclaredField("cnxn");
+        cnxnField.setAccessible(true);
+        ClientCnxn clientCnxn = (ClientCnxn) cnxnField.get(zk);
+        Field sendThreadField = clientCnxn.getClass().getDeclaredField("sendThread");
+        sendThreadField.setAccessible(true);
+        SendThread sendThread = (SendThread) sendThreadField.get(clientCnxn);
+        Field saslLoginFailedField = sendThread.getClass().getDeclaredField("saslLoginFailed");
+        saslLoginFailedField.setAccessible(true);
+        saslLoginFailedField.setBoolean(sendThread, true);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/ServerConfigTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/ServerConfigTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/ServerConfigTest.java
new file mode 100644
index 0000000..27faa74
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/ServerConfigTest.java
@@ -0,0 +1,74 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.zookeeper.server.ServerConfig;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+public class ServerConfigTest {
+
+    private ServerConfig serverConfig;
+
+    @Before
+    public void setUp() {
+        serverConfig = new ServerConfig();
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testFewArguments() {
+        String[] args = {"2181"};
+        serverConfig.parse(args);
+    }
+
+    @Test
+    public void testValidArguments() {
+        String[] args = {"2181", "/data/dir", "60000", "10000"};
+        serverConfig.parse(args);
+
+        assertEquals(2181, serverConfig.getClientPortAddress().getPort());
+        assertTrue(checkEquality("/data/dir", serverConfig.getDataDir()));
+        assertEquals(60000, serverConfig.getTickTime());
+        assertEquals(10000, serverConfig.getMaxClientCnxns());
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testTooManyArguments() {
+        String[] args = {"2181", "/data/dir", "60000", "10000", "9999"};
+        serverConfig.parse(args);
+    }
+
+    boolean checkEquality(String a, String b) {
+        assertNotNull(a);
+        assertNotNull(b);
+        return a.equals(b);
+    }
+
+    boolean checkEquality(String a, File b) {
+        assertNotNull(a);
+        assertNotNull(b);
+        return new File(a).equals(b);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/TestableZooKeeper.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/TestableZooKeeper.java b/zookeeper-server/src/test/java/org/apache/zookeeper/TestableZooKeeper.java
new file mode 100644
index 0000000..dd70056
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/TestableZooKeeper.java
@@ -0,0 +1,133 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.jute.Record;
+import org.apache.zookeeper.proto.ReplyHeader;
+import org.apache.zookeeper.proto.RequestHeader;
+
+public class TestableZooKeeper extends ZooKeeper {
+
+    public TestableZooKeeper(String host, int sessionTimeout,
+            Watcher watcher) throws IOException {
+        super(host, sessionTimeout, watcher);
+    }
+    
+    @Override
+    public List<String> getChildWatches() {
+        return super.getChildWatches();
+    }
+
+
+    @Override
+    public List<String> getDataWatches() {
+        return super.getDataWatches();
+    }
+
+
+    @Override
+    public List<String> getExistWatches() {
+        return super.getExistWatches();
+    }
+
+    /**
+     * Cause this ZooKeeper object to disconnect from the server. It will then
+     * later attempt to reconnect.
+     */
+    public void testableConnloss() throws IOException {
+        synchronized(cnxn) {
+            cnxn.sendThread.testableCloseSocket();
+        }
+    }
+
+    /**
+     * Cause this ZooKeeper object to stop receiving from the ZooKeeperServer
+     * for the given number of milliseconds.
+     * @param ms the number of milliseconds to pause.
+     * @return true if the connection is paused, otherwise false
+     */
+    public boolean pauseCnxn(final long ms) {
+        final CountDownLatch initiatedPause = new CountDownLatch(1);
+        new Thread() {
+            public void run() {
+                synchronized(cnxn) {
+                    try {
+                        try {
+                            cnxn.sendThread.testableCloseSocket();
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        } finally {
+                            initiatedPause.countDown();
+                        }
+                        Thread.sleep(ms);
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }.start();
+
+        try {
+            return initiatedPause.await(ms, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    
+    public boolean testableWaitForShutdown(int wait)
+        throws InterruptedException
+    {
+        return super.testableWaitForShutdown(wait);
+    }
+
+    public SocketAddress testableLocalSocketAddress() {
+        return super.testableLocalSocketAddress();
+    }
+
+    public SocketAddress testableRemoteSocketAddress() {
+        return super.testableRemoteSocketAddress();
+    }
+
+    /**
+     * @return the last zxid as seen by the client session
+     */
+    public long testableLastZxid() {
+        return cnxn.getLastZxid();
+    }
+
+    public ReplyHeader submitRequest(RequestHeader h, Record request,
+            Record response, WatchRegistration watchRegistration) throws InterruptedException {
+        return cnxn.submitRequest(h, request, response, watchRegistration);
+    }
+
+    /** Testing only!!! Really!!!! This is only here to test when the client
+     * disconnects from the server w/o sending a session disconnect (ie
+     * ending the session cleanly). The server will eventually notice the
+     * client is no longer pinging and will timeout the session.
+     */
+    public void disconnect() {
+        cnxn.disconnect();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/VerGenTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/VerGenTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/VerGenTest.java
new file mode 100644
index 0000000..607edbb
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/VerGenTest.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.zookeeper.test.ClientBase;
+import org.apache.zookeeper.version.util.VerGen;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+
+/**
+ * Test VerGen, used during the build.
+ *
+ */
+@RunWith(Parameterized.class)
+public class VerGenTest extends ZKTestCase {
+    @Parameters
+    public static Collection<Object[]> data() {
+            return Arrays.asList(new Object[][] {
+                            {"1.2.3", new Object[] {1, 2, 3, null}},
+                            {"1.2.3-dev", new Object[] {1, 2, 3, "dev"}},
+                            {"1.2.3-SNAPSHOT", new Object[] {1, 2, 3, "SNAPSHOT"}},
+                            {"1.2.3-SNAPSHOT", new Object[] {1, 2, 3, "SNAPSHOT"}},
+                            {"1.2.3-foo-bar+123", new Object[] {1, 2, 3, "foo-bar+123"}},
+                            {"1.2.3.4.5-SNAPSHOT", new Object[] {1, 2, 3, "SNAPSHOT"}},
+                            {"1.2.3.4.5-foo-bar+123", new Object[] {1, 2, 3, "foo-bar+123"}}
+            });
+    }
+
+    private String input;
+
+    private Object[] expected;
+
+    public VerGenTest(String input, Object[] expected) {
+        this.input = input;
+        this.expected = expected;
+    }
+
+    @Test
+    public void testParser() {
+        VerGen.Version v = VerGen.parseVersionString(input);
+        Assert.assertEquals(expected[0], v.maj);
+        Assert.assertEquals(expected[1], v.min);
+        Assert.assertEquals(expected[2], v.micro);
+        Assert.assertEquals(expected[3], v.qualifier);
+    }
+
+    @Test
+    public void testGenFile() throws Exception {
+        VerGen.Version v = VerGen.parseVersionString(input);
+        File outputDir = ClientBase.createTmpDir();
+        VerGen.generateFile(outputDir, v, "1", "Nov1");
+        ClientBase.recursiveDelete(outputDir);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java b/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java
new file mode 100644
index 0000000..9098fc4
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java
@@ -0,0 +1,88 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.junit.Assume;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.junit.Rule;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestWatchman;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.FrameworkMethod;
+
+import java.io.IOException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+
+/**
+ * Base class for a non-parameterized ZK test.
+ *
+ * Basic utilities shared by all tests. Also logging of various events during
+ * the test execution (start/stop/success/failure/etc...)
+ */
+@RunWith(JUnit4ZKTestRunner.class)
+public class ZKTestCase {
+    private static final Logger LOG = LoggerFactory.getLogger(ZKTestCase.class);
+
+    private String testName;
+
+    protected String getTestName() {
+        return testName;
+    }
+
+    @Rule
+    public MethodRule watchman = new TestWatchman() {
+        @Override
+        public void starting(FrameworkMethod method) {
+            testName = method.getName();
+            // ZOOKEEPER-2693 disables all 4lw by default.
+            // Here we enable the 4lw which ZooKeeper tests depends.
+            System.setProperty("zookeeper.4lw.commands.whitelist", "*");
+
+            LOG.info("STARTING " + testName);
+        }
+
+        @Override
+        public void finished(FrameworkMethod method) {
+            LOG.info("FINISHED " + testName);
+        }
+
+        @Override
+        public void succeeded(FrameworkMethod method) {
+            LOG.info("SUCCEEDED " + testName);
+        }
+
+        @Override
+        public void failed(Throwable e, FrameworkMethod method) {
+            LOG.info("FAILED " + testName, e);
+        }
+
+    };
+
+    protected void assumeIPv6Available() {
+        try {
+            InetAddress address = Inet6Address.getByName("0:0:0:0:0:0:0:1");
+            Assume.assumeTrue(address.isReachable(1000));
+        } catch (IOException exception) {
+            Assume.assumeTrue(false);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/ZooKeeperTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/ZooKeeperTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/ZooKeeperTest.java
new file mode 100644
index 0000000..2cdc4cb
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/ZooKeeperTest.java
@@ -0,0 +1,281 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.test.ClientBase;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * 
+ * Testing Zookeeper public methods
+ *
+ */
+public class ZooKeeperTest extends ClientBase {
+
+    @Test
+    public void testDeleteRecursive() throws IOException, InterruptedException,
+            KeeperException {
+        final ZooKeeper zk = createClient();
+        // making sure setdata works on /
+        zk.setData("/", "some".getBytes(), -1);
+        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b/v/1", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/c", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/c/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        List<String> children = zk.getChildren("/a", false);
+
+        Assert.assertEquals("2 children - b & c should be present ", children
+                .size(), 2);
+        Assert.assertTrue(children.contains("b"));
+        Assert.assertTrue(children.contains("c"));
+
+        ZKUtil.deleteRecursive(zk, "/a");
+        Assert.assertNull(zk.exists("/a", null));
+    }
+
+    @Test
+    public void testDeleteRecursiveAsync() throws IOException,
+            InterruptedException, KeeperException {
+        final ZooKeeper zk = createClient();
+        // making sure setdata works on /
+        zk.setData("/", "some".getBytes(), -1);
+        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b/v/1", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/c", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/c/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        for (int i = 0; i < 50; ++i) {
+            zk.create("/a/c/" + i, "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        }
+        List<String> children = zk.getChildren("/a", false);
+
+        Assert.assertEquals("2 children - b & c should be present ", children
+                .size(), 2);
+        Assert.assertTrue(children.contains("b"));
+        Assert.assertTrue(children.contains("c"));
+
+        VoidCallback cb = new VoidCallback() {
+
+            @Override
+            public void processResult(int rc, String path, Object ctx) {
+                synchronized (ctx) {
+                    ((AtomicInteger) ctx).set(4);
+                    ctx.notify();
+                }
+            }
+
+        };
+        final AtomicInteger ctx = new AtomicInteger(3);
+        ZKUtil.deleteRecursive(zk, "/a", cb, ctx);
+        synchronized (ctx) {
+            ctx.wait();
+        }
+        Assert.assertEquals(4, ((AtomicInteger) ctx).get());
+    }
+    
+    @Test
+    public void testStatWhenPathDoesNotExist() throws IOException,
+    		InterruptedException {
+    	final ZooKeeper zk = createClient();
+    	ZooKeeperMain main = new ZooKeeperMain(zk);
+    	String cmdstring = "stat /invalidPath";
+    	main.cl.parseCommand(cmdstring);
+    	try {
+    		main.processZKCmd(main.cl);
+    		Assert.fail("As Node does not exist, command should fail by throwing No Node Exception.");
+    	} catch (KeeperException e) {
+    		Assert.assertEquals("KeeperErrorCode = NoNode for /invalidPath", e.getMessage());
+    	}
+    }
+
+    @Test
+    public void testParseWithExtraSpaces() throws Exception {
+        final ZooKeeper zk = createClient();
+        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+        String cmdstring = "      ls       /  ";
+        zkMain.cl.parseCommand(cmdstring);
+        Assert.assertEquals("Spaces also considered as characters", zkMain.cl.getNumArguments(), 2);
+        Assert.assertEquals("ls is not taken as first argument", zkMain.cl.getCmdArgument(0), "ls");
+        Assert.assertEquals("/ is not taken as second argument", zkMain.cl.getCmdArgument(1), "/");
+    }
+
+    @Test
+    public void testCheckInvalidAcls() throws Exception {
+         final ZooKeeper zk = createClient();
+            ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+            String cmdstring = "create -s -e /node data ip:scheme:gggsd"; //invalid acl's
+            try{
+                 zkMain.executeLine(cmdstring);
+            }catch(KeeperException.InvalidACLException e){
+                fail("For Invalid ACls should not throw exception");
+            }
+    }
+
+    @Test
+    public void testDeleteWithInvalidVersionNo() throws Exception {
+         final ZooKeeper zk = createClient();
+            ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+            String cmdstring = "create -s -e /node1 data "; 
+            String cmdstring1 = "delete /node1 2";//invalid dataversion no
+                 zkMain.executeLine(cmdstring);
+           try{
+               zkMain.executeLine(cmdstring1);
+                     
+            }catch(KeeperException.BadVersionException e){
+                fail("For Invalid dataversion number should not throw exception");
+            }
+    }
+
+    @Test
+    public void testCliCommandsNotEchoingUsage() throws Exception {
+            // setup redirect out/err streams to get System.in/err, use this judiciously!
+           final PrintStream systemErr = System.err; // get current err
+           final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
+           System.setErr(new PrintStream(errContent));
+           final ZooKeeper zk = createClient();
+           ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+           String cmd1 = "printwatches";
+           zkMain.executeLine(cmd1);
+           String cmd2 = "history";
+           zkMain.executeLine(cmd2);
+           String cmd3 = "redo";
+           zkMain.executeLine(cmd3);
+           // revert redirect of out/err streams - important step!
+           System.setErr(systemErr);
+           if (errContent.toString().contains("ZooKeeper -server host:port cmd args")) {
+                fail("CLI commands (history, redo, connect, printwatches) display usage info!");
+            }
+    }
+
+     @Test
+    public void testParseWithQuotes() throws Exception {
+        final ZooKeeper zk = createClient();
+        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+        for (String quoteChar : new String[] {"'", "\""}) {
+            String cmdstring = String.format("create /node %1$squoted data%1$s", quoteChar);
+            zkMain.cl.parseCommand(cmdstring);
+            Assert.assertEquals("quotes combine arguments", zkMain.cl.getNumArguments(), 3);
+            Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
+            Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
+            Assert.assertEquals("quoted data is not taken as third argument", zkMain.cl.getCmdArgument(2), "quoted data");
+        }
+    }
+
+    @Test
+    public void testParseWithMixedQuotes() throws Exception {
+        final ZooKeeper zk = createClient();
+        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+        for (String[] quoteChars : new String[][] {{"'", "\""}, {"\"", "'"}}) {
+            String outerQuotes = quoteChars[0];
+            String innerQuotes = quoteChars[1];
+            String cmdstring = String.format("create /node %1$s%2$squoted data%2$s%1$s", outerQuotes, innerQuotes);
+            zkMain.cl.parseCommand(cmdstring);
+            Assert.assertEquals("quotes combine arguments", zkMain.cl.getNumArguments(), 3);
+            Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
+            Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
+            Assert.assertEquals("quoted data is not taken as third argument", zkMain.cl.getCmdArgument(2), innerQuotes + "quoted data" + innerQuotes);
+        }
+    }
+
+    @Test
+    public void testParseWithEmptyQuotes() throws Exception {
+        final ZooKeeper zk = createClient();
+        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+        String cmdstring = "create /node ''";
+        zkMain.cl.parseCommand(cmdstring);
+        Assert.assertEquals("empty quotes should produce arguments", zkMain.cl.getNumArguments(), 3);
+        Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
+        Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
+        Assert.assertEquals("empty string is not taken as third argument", zkMain.cl.getCmdArgument(2), "");
+    }
+
+    @Test
+    public void testParseWithMultipleQuotes() throws Exception {
+        final ZooKeeper zk = createClient();
+        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+        String cmdstring = "create /node '' ''";
+        zkMain.cl.parseCommand(cmdstring);
+        Assert.assertEquals("expected 5 arguments", zkMain.cl.getNumArguments(), 4);
+        Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
+        Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
+        Assert.assertEquals("empty string is not taken as third argument", zkMain.cl.getCmdArgument(2), "");
+        Assert.assertEquals("empty string is not taken as fourth argument", zkMain.cl.getCmdArgument(3), "");
+    }
+
+    // ZOOKEEPER-2467 : Testing negative number for redo command
+    @Test
+    public void testRedoWithNegativeCmdNumber() throws Exception {
+        final ZooKeeper zk = createClient();
+        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+        String cmd1 = "redo -1";
+
+        // setup redirect out/err streams to get System.in/err, use this
+        // judiciously!
+        final PrintStream systemOut = System.out; // get current out
+        final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+        System.setOut(new PrintStream(outContent));
+        try {
+            zkMain.executeLine(cmd1);
+            Assert.assertEquals("Command index out of range", outContent
+                    .toString().trim());
+        } finally {
+            // revert redirect of out/err streams - important step!
+            System.setOut(systemOut);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/common/TimeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/common/TimeTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/common/TimeTest.java
new file mode 100644
index 0000000..d938556
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/common/TimeTest.java
@@ -0,0 +1,109 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.common;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.test.ClientBase;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Command line program for demonstrating robustness to clock
+ * changes.
+ * <p/>
+ * How to run:
+ * ant clean compile-test
+ * echo build/test/lib/*.jar build/lib/*.jar build/classes build/test/classes | sed -e 's/ /:/g' > cp
+ * java -cp $(cat cp) org.apache.zookeeper.common.TimeTest | tee log-without-patch
+ * <p/>
+ * After test program starts, in another window, do commands:
+ * date -s '+1hour'
+ * date -s '-1hour'
+ * <p/>
+ * As long as there isn't any expired event, the experiment is successful.
+ */
+public class TimeTest extends ClientBase {
+    private static final long mt0 = System.currentTimeMillis();
+    private static final long nt0 = Time.currentElapsedTime();
+
+    private static AtomicInteger watchCount = new AtomicInteger(0);
+
+
+    public static void main(String[] args) throws Exception {
+        System.out.printf("Starting\n");
+        final TimeTest test = new TimeTest();
+        System.out.printf("After construct\n");
+        test.setUp();
+        ZooKeeper zk = test.createClient();
+        zk.create("/ephemeral", new byte[]{1, 2, 3},
+                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+        while (Time.currentElapsedTime() - nt0 < 100000) {
+            System.out.printf("%d\t%s\n", discrepancy(),
+                    zk.exists("/ephemeral",
+                            watchCount.get() == 0 ? createWatcher() : null) != null);
+            waitByYielding(500);
+        }
+    }
+
+    private static Watcher createWatcher() {
+        watchCount.incrementAndGet();
+        return new Watcher() {
+            @Override
+            public void process(WatchedEvent event) {
+                watchCount.decrementAndGet();
+                System.out.printf("%d event = %s\n", discrepancy(), event);
+            }
+        };
+
+    }
+
+    private static void waitByYielding(long delay) {
+        long t0 = Time.currentElapsedTime();
+        while (Time.currentElapsedTime() < t0 + delay) {
+            Thread.yield();
+        }
+    }
+
+    private static long discrepancy() {
+        return (System.currentTimeMillis() - mt0) - (Time.currentElapsedTime() - nt0);
+    }
+
+    @Test
+    public void testElapsedTimeToDate() throws Exception {
+        long walltime = Time.currentWallTime();
+        long elapsedTime = Time.currentElapsedTime();
+        Thread.sleep(200);
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(Time.elapsedTimeToDate(elapsedTime));
+        int calculatedDate = cal.get(Calendar.HOUR_OF_DAY);
+        cal.setTime(new Date(walltime));
+        int realDate = cal.get(Calendar.HOUR_OF_DAY);
+
+        Assert.assertEquals(calculatedDate, realDate);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLCountTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLCountTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLCountTest.java
new file mode 100644
index 0000000..88b8869
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLCountTest.java
@@ -0,0 +1,136 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ACLCountTest extends ZKTestCase implements Watcher {
+    private static final Logger LOG = LoggerFactory.getLogger(ACLTest.class);
+    private static final String HOSTPORT =
+        "127.0.0.1:" + PortAssignment.unique();
+    private volatile CountDownLatch startSignal;
+
+    /**
+     *
+     * Create a node and add 4 ACL values to it, but there are only 2 unique ACL values,
+     * and each is repeated once:
+     *
+     *   ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE);
+     *   ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS);
+     *   ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE);
+     *   ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS);
+     *
+     * Even though we've added 4 ACL values, there should only be 2 ACLs for that node,
+     * since there are only 2 *unique* ACL values.
+     */
+    @Test
+    public void testAclCount() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        SyncRequestProcessor.setSnapCount(1000);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        ZooKeeper zk;
+
+        final ArrayList<ACL> CREATOR_ALL_AND_WORLD_READABLE =
+          new ArrayList<ACL>() { {
+            add(new ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE));
+            add(new ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS));
+            add(new ACL(ZooDefs.Perms.READ,ZooDefs.Ids.ANYONE_ID_UNSAFE));
+            add(new ACL(ZooDefs.Perms.ALL,ZooDefs.Ids.AUTH_IDS));
+        }};
+
+        try {
+            LOG.info("starting up the zookeeper server .. waiting");
+            Assert.assertTrue("waiting for server being up",
+                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+            zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+
+            zk.addAuthInfo("digest", "pat:test".getBytes());
+            zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
+
+            String path = "/path";
+
+            try {
+              Assert.assertEquals(4,CREATOR_ALL_AND_WORLD_READABLE.size());
+            }
+            catch (Exception e) {
+              LOG.error("Something is fundamentally wrong with ArrayList's add() method. add()ing four times to an empty ArrayList should result in an ArrayList with 4 members.");
+              throw e;
+            }
+
+            zk.create(path,path.getBytes(),CREATOR_ALL_AND_WORLD_READABLE,CreateMode.PERSISTENT);
+            List<ACL> acls = zk.getACL("/path", new Stat());
+            Assert.assertEquals(2,acls.size());
+        }
+        catch (Exception e) {
+          // test failed somehow.
+          Assert.assertTrue(false);
+        }
+
+        f.shutdown();
+        zks.shutdown();
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatcherEvent)
+     */
+    public void process(WatchedEvent event) {
+        LOG.info("Event:" + event.getState() + " " + event.getType() + " "
+                 + event.getPath());
+        if (event.getState() == KeeperState.SyncConnected) {
+            if (startSignal != null && startSignal.getCount() > 0) {
+                LOG.info("startsignal.countDown()");
+                startSignal.countDown();
+            } else {
+                LOG.warn("startsignal " + startSignal);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
new file mode 100644
index 0000000..7307cbf
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
@@ -0,0 +1,98 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ACLRootTest extends ClientBase {
+    private static final Logger LOG = LoggerFactory.getLogger(ACLRootTest.class);
+
+    @Test
+    public void testRootAcl() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            // set auth using digest
+            zk.addAuthInfo("digest", "pat:test".getBytes());
+            zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
+            zk.getData("/", false, null);
+            zk.close();
+            // verify no access
+            zk = createClient();
+            try {
+                zk.getData("/", false, null);
+                Assert.fail("validate auth");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            try {
+                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                        CreateMode.PERSISTENT);
+                Assert.fail("validate auth");
+            } catch (KeeperException.InvalidACLException e) {
+                // expected
+            }
+            zk.addAuthInfo("digest", "world:anyone".getBytes());
+            try {
+                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                        CreateMode.PERSISTENT);
+                Assert.fail("validate auth");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify access using original auth
+            zk = createClient();
+            zk.addAuthInfo("digest", "pat:test".getBytes());
+            zk.getData("/", false, null);
+            zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                    CreateMode.PERSISTENT);
+            zk.delete("/apps", -1);
+            // reset acl (back to open) and verify accessible again
+            zk.setACL("/", Ids.OPEN_ACL_UNSAFE, -1);
+            zk.close();
+            zk = createClient();
+            zk.getData("/", false, null);
+            zk.create("/apps", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            try {
+                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                        CreateMode.PERSISTENT);
+                Assert.fail("validate auth");
+            } catch (KeeperException.InvalidACLException e) {
+                // expected
+            }
+            zk.delete("/apps", -1);
+            zk.addAuthInfo("digest", "world:anyone".getBytes());
+            zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                    CreateMode.PERSISTENT);
+            zk.close();
+            zk = createClient();
+            zk.delete("/apps", -1);
+        } finally {
+            zk.close();
+        }
+    }
+}


[31/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperMain.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperMain.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperMain.java
deleted file mode 100644
index 6ca538b..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperMain.java
+++ /dev/null
@@ -1,871 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Id;
-import org.apache.zookeeper.data.Stat;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The command line client to ZooKeeper.
- *
- */
-@InterfaceAudience.Public
-public class ZooKeeperMain {
-    private static final Logger LOG = LoggerFactory.getLogger(ZooKeeperMain.class);
-    static final Map<String,String> commandMap = new HashMap<String,String>( );
-
-    protected MyCommandOptions cl = new MyCommandOptions();
-    protected HashMap<Integer,String> history = new HashMap<Integer,String>( );
-    protected int commandCount = 0;
-    protected boolean printWatches = true;
-
-    protected ZooKeeper zk;
-    protected String host = "";
-
-    public boolean getPrintWatches( ) {
-        return printWatches;
-    }
-
-    static {
-        commandMap.put("connect", "host:port");
-        commandMap.put("close","");
-        commandMap.put("create", "[-s] [-e] path data acl");
-        commandMap.put("delete","path [version]");
-        commandMap.put("rmr","path");
-        commandMap.put("set","path data [version]");
-        commandMap.put("get","path [watch]");
-        commandMap.put("ls","path [watch]");
-        commandMap.put("ls2","path [watch]");
-        commandMap.put("getAcl","path");
-        commandMap.put("setAcl","path acl");
-        commandMap.put("stat","path [watch]");
-        commandMap.put("sync","path");
-        commandMap.put("setquota","-n|-b val path");
-        commandMap.put("listquota","path");
-        commandMap.put("delquota","[-n|-b] path");
-        commandMap.put("history","");
-        commandMap.put("redo","cmdno");
-        commandMap.put("printwatches", "on|off");
-        commandMap.put("quit","");
-        commandMap.put("addauth", "scheme auth");
-    }
-
-    static void usage() {
-        System.err.println("ZooKeeper -server host:port cmd args");
-        for (Map.Entry<String, String> entry : commandMap.entrySet()) {
-            System.err.println("\t" + entry.getKey() + " " + entry.getValue());
-        }
-    }
-
-    private class MyWatcher implements Watcher {
-        public void process(WatchedEvent event) {
-            if (getPrintWatches()) {
-                ZooKeeperMain.printMessage("WATCHER::");
-                ZooKeeperMain.printMessage(event.toString());
-            }
-        }
-    }
-
-    static private int getPermFromString(String permString) {
-        int perm = 0;
-        for (int i = 0; i < permString.length(); i++) {
-            switch (permString.charAt(i)) {
-            case 'r':
-                perm |= ZooDefs.Perms.READ;
-                break;
-            case 'w':
-                perm |= ZooDefs.Perms.WRITE;
-                break;
-            case 'c':
-                perm |= ZooDefs.Perms.CREATE;
-                break;
-            case 'd':
-                perm |= ZooDefs.Perms.DELETE;
-                break;
-            case 'a':
-                perm |= ZooDefs.Perms.ADMIN;
-                break;
-            default:
-                System.err
-                .println("Unknown perm type: " + permString.charAt(i));
-            }
-        }
-        return perm;
-    }
-
-    private static void printStat(Stat stat) {
-        System.err.println("cZxid = 0x" + Long.toHexString(stat.getCzxid()));
-        System.err.println("ctime = " + new Date(stat.getCtime()).toString());
-        System.err.println("mZxid = 0x" + Long.toHexString(stat.getMzxid()));
-        System.err.println("mtime = " + new Date(stat.getMtime()).toString());
-        System.err.println("pZxid = 0x" + Long.toHexString(stat.getPzxid()));
-        System.err.println("cversion = " + stat.getCversion());
-        System.err.println("dataVersion = " + stat.getVersion());
-        System.err.println("aclVersion = " + stat.getAversion());
-        System.err.println("ephemeralOwner = 0x"
-        		+ Long.toHexString(stat.getEphemeralOwner()));
-        System.err.println("dataLength = " + stat.getDataLength());
-        System.err.println("numChildren = " + stat.getNumChildren());
-    }
-
-    /**
-     * A storage class for both command line options and shell commands.
-     *
-     */
-    static class MyCommandOptions {
-
-        private Map<String,String> options = new HashMap<String,String>();
-        private List<String> cmdArgs = null;
-        private String command = null;
-        public static final Pattern ARGS_PATTERN = Pattern.compile("\\s*([^\"\']\\S*|\"[^\"]*\"|'[^']*')\\s*");
-        public static final Pattern QUOTED_PATTERN = Pattern.compile("^([\'\"])(.*)(\\1)$");
-
-        public MyCommandOptions() {
-          options.put("server", "localhost:2181");
-          options.put("timeout", "30000");
-        }
-
-        public String getOption(String opt) {
-            return options.get(opt);
-        }
-
-        public String getCommand( ) {
-            return command;
-        }
-
-        public String getCmdArgument( int index ) {
-            return cmdArgs.get(index);
-        }
-
-        public int getNumArguments( ) {
-            return cmdArgs.size();
-        }
-
-        public String[] getArgArray() {
-            return cmdArgs.toArray(new String[0]);
-        }
-
-        /**
-         * Parses a command line that may contain one or more flags
-         * before an optional command string
-         * @param args command line arguments
-         * @return true if parsing succeeded, false otherwise.
-         */
-        public boolean parseOptions(String[] args) {
-            List<String> argList = Arrays.asList(args);
-            Iterator<String> it = argList.iterator();
-
-            while (it.hasNext()) {
-                String opt = it.next();
-                try {
-                    if (opt.equals("-server")) {
-                        options.put("server", it.next());
-                    } else if (opt.equals("-timeout")) {
-                        options.put("timeout", it.next());
-                    } else if (opt.equals("-r")) {
-                        options.put("readonly", "true");
-                    }
-                } catch (NoSuchElementException e){
-                    System.err.println("Error: no argument found for option "
-                            + opt);
-                    return false;
-                }
-
-                if (!opt.startsWith("-")) {
-                    command = opt;
-                    cmdArgs = new ArrayList<String>( );
-                    cmdArgs.add( command );
-                    while (it.hasNext()) {
-                        cmdArgs.add(it.next());
-                    }
-                    return true;
-                }
-            }
-            return true;
-        }
-
-        /**
-         * Breaks a string into command + arguments.
-         * @param cmdstring string of form "cmd arg1 arg2..etc"
-         * @return true if parsing succeeded.
-         */
-        public boolean parseCommand( String cmdstring ) {
-            Matcher matcher = ARGS_PATTERN.matcher(cmdstring);
-
-            List<String> args = new LinkedList<String>();
-            while (matcher.find()) {
-                String value = matcher.group(1);
-                if (QUOTED_PATTERN.matcher(value).matches()) {
-                    // Strip off the surrounding quotes
-                    value = value.substring(1, value.length() - 1);
-                }
-                args.add(value);
-            }
-            if (args.isEmpty()){
-                return false;
-            }
-            command = args.get(0);
-            cmdArgs = args;
-            return true;
-        }
-    }
-
-
-    /**
-     * Makes a list of possible completions, either for commands
-     * or for zk nodes if the token to complete begins with /
-     *
-     */
-
-
-    protected void addToHistory(int i,String cmd) {
-        history.put(i, cmd);
-    }
-
-    public static List<String> getCommands() {
-        return new LinkedList<String>(commandMap.keySet());
-    }
-
-    protected String getPrompt() {       
-        return "[zk: " + host + "("+zk.getState()+")" + " " + commandCount + "] ";
-    }
-
-    public static void printMessage(String msg) {
-        System.out.println("\n"+msg);
-    }
-
-    protected void connectToZK(String newHost) throws InterruptedException, IOException {
-        if (zk != null && zk.getState().isAlive()) {
-            zk.close();
-        }
-        host = newHost;
-        boolean readOnly = cl.getOption("readonly") != null;
-        zk = new ZooKeeper(host,
-                 Integer.parseInt(cl.getOption("timeout")),
-                 new MyWatcher(), readOnly);
-    }
-    
-    public static void main(String args[])
-        throws KeeperException, IOException, InterruptedException
-    {
-        ZooKeeperMain main = new ZooKeeperMain(args);
-        main.run();
-    }
-
-    public ZooKeeperMain(String args[]) throws IOException, InterruptedException {
-        cl.parseOptions(args);
-        System.out.println("Connecting to " + cl.getOption("server"));
-        connectToZK(cl.getOption("server"));
-        //zk = new ZooKeeper(cl.getOption("server"),
-//                Integer.parseInt(cl.getOption("timeout")), new MyWatcher());
-    }
-
-    public ZooKeeperMain(ZooKeeper zk) {
-      this.zk = zk;
-    }
-
-    @SuppressWarnings("unchecked")
-    void run() throws KeeperException, IOException, InterruptedException {
-        if (cl.getCommand() == null) {
-            System.out.println("Welcome to ZooKeeper!");
-
-            boolean jlinemissing = false;
-            // only use jline if it's in the classpath
-            try {
-                Class<?> consoleC = Class.forName("jline.ConsoleReader");
-                Class<?> completorC =
-                    Class.forName("org.apache.zookeeper.JLineZNodeCompletor");
-
-                System.out.println("JLine support is enabled");
-
-                Object console =
-                    consoleC.getConstructor().newInstance();
-
-                Object completor =
-                    completorC.getConstructor(ZooKeeper.class).newInstance(zk);
-                Method addCompletor = consoleC.getMethod("addCompletor",
-                        Class.forName("jline.Completor"));
-                addCompletor.invoke(console, completor);
-
-                String line;
-                Method readLine = consoleC.getMethod("readLine", String.class);
-                while ((line = (String)readLine.invoke(console, getPrompt())) != null) {
-                    executeLine(line);
-                }
-            } catch (ClassNotFoundException e) {
-                LOG.debug("Unable to start jline", e);
-                jlinemissing = true;
-            } catch (NoSuchMethodException e) {
-                LOG.debug("Unable to start jline", e);
-                jlinemissing = true;
-            } catch (InvocationTargetException e) {
-                LOG.debug("Unable to start jline", e);
-                jlinemissing = true;
-            } catch (IllegalAccessException e) {
-                LOG.debug("Unable to start jline", e);
-                jlinemissing = true;
-            } catch (InstantiationException e) {
-                LOG.debug("Unable to start jline", e);
-                jlinemissing = true;
-            }
-
-            if (jlinemissing) {
-                System.out.println("JLine support is disabled");
-                BufferedReader br =
-                    new BufferedReader(new InputStreamReader(System.in));
-
-                String line;
-                while ((line = br.readLine()) != null) {
-                    executeLine(line);
-                }
-            }
-        } else {
-            // Command line args non-null.  Run what was passed.
-            processCmd(cl);
-        }
-    }
-
-    public void executeLine(String line)
-    throws InterruptedException, IOException, KeeperException {
-      if (!line.equals("")) {
-        cl.parseCommand(line);
-        addToHistory(commandCount,line);
-        processCmd(cl);
-        commandCount++;
-      }
-    }
-
-    private static DataCallback dataCallback = new DataCallback() {
-
-        public void processResult(int rc, String path, Object ctx, byte[] data,
-                Stat stat) {
-            System.out.println("rc = " + rc + " path = " + path + " data = "
-                    + (data == null ? "null" : new String(data)) + " stat = ");
-            printStat(stat);
-        }
-
-    };
-
-    /**
-     * trim the quota tree to recover unwanted tree elements
-     * in the quota's tree
-     * @param zk the zookeeper client
-     * @param path the path to start from and go up and see if their
-     * is any unwanted parent in the path.
-     * @return true if sucessful
-     * @throws KeeperException
-     * @throws IOException
-     * @throws InterruptedException
-     */
-    private static boolean trimProcQuotas(ZooKeeper zk, String path)
-        throws KeeperException, IOException, InterruptedException
-    {
-        if (Quotas.quotaZookeeper.equals(path)) {
-            return true;
-        }
-        List<String> children = zk.getChildren(path, false);
-        if (children.size() == 0) {
-            zk.delete(path, -1);
-            String parent = path.substring(0, path.lastIndexOf('/'));
-            return trimProcQuotas(zk, parent);
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * this method deletes quota for a node.
-     * @param zk the zookeeper client
-     * @param path the path to delete quota for
-     * @param bytes true if number of bytes needs to
-     * be unset
-     * @param numNodes true if number of nodes needs
-     * to be unset
-     * @return true if quota deletion is successful
-     * @throws KeeperException
-     * @throws IOException
-     * @throws InterruptedException
-     */
-    public static boolean delQuota(ZooKeeper zk, String path,
-            boolean bytes, boolean numNodes)
-        throws KeeperException, IOException, InterruptedException
-    {
-        String parentPath = Quotas.quotaZookeeper + path;
-        String quotaPath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
-        if (zk.exists(quotaPath, false) == null) {
-            System.out.println("Quota does not exist for " + path);
-            return true;
-        }
-        byte[] data = null;
-        try {
-            data = zk.getData(quotaPath, false, new Stat());
-        } catch(KeeperException.NoNodeException ne) {
-            System.err.println("quota does not exist for " + path);
-            return true;
-        }
-        StatsTrack strack = new StatsTrack(new String(data));
-        if (bytes && !numNodes) {
-            strack.setBytes(-1L);
-            zk.setData(quotaPath, strack.toString().getBytes(), -1);
-        } else if (!bytes && numNodes) {
-            strack.setCount(-1);
-            zk.setData(quotaPath, strack.toString().getBytes(), -1);
-        } else if (bytes && numNodes) {
-            // delete till you can find a node with more than
-            // one child
-            List<String> children = zk.getChildren(parentPath, false);
-            /// delete the direct children first
-            for (String child: children) {
-                zk.delete(parentPath + "/" + child, -1);
-            }
-            // cut the tree till their is more than one child
-            trimProcQuotas(zk, parentPath);
-        }
-        return true;
-    }
-
-    private static void checkIfParentQuota(ZooKeeper zk, String path)
-        throws InterruptedException, KeeperException
-    {
-        final String[] splits = path.split("/");
-        String quotaPath = Quotas.quotaZookeeper;
-        for (String str: splits) {
-            if (str.length() == 0) {
-                // this should only be for the beginning of the path
-                // i.e. "/..." - split(path)[0] is empty string before first '/'
-                continue;
-            }
-            quotaPath += "/" + str;
-            List<String> children =  null;
-            try {
-                children = zk.getChildren(quotaPath, false);
-            } catch(KeeperException.NoNodeException ne) {
-                LOG.debug("child removed during quota check", ne);
-                return;
-            }
-            if (children.size() == 0) {
-                return;
-            }
-            for (String child: children) {
-                if (Quotas.limitNode.equals(child)) {
-                    throw new IllegalArgumentException(path + " has a parent "
-                            + quotaPath + " which has a quota");
-                }
-            }
-        }
-    }
-
-    /**
-     * this method creates a quota node for the path
-     * @param zk the ZooKeeper client
-     * @param path the path for which quota needs to be created
-     * @param bytes the limit of bytes on this path
-     * @param numNodes the limit of number of nodes on this path
-     * @return true if its successful and false if not.
-     */
-    public static boolean createQuota(ZooKeeper zk, String path,
-            long bytes, int numNodes)
-        throws KeeperException, IOException, InterruptedException
-    {
-        // check if the path exists. We cannot create
-        // quota for a path that already exists in zookeeper
-        // for now.
-        Stat initStat = zk.exists(path, false);
-        if (initStat == null) {
-            throw new IllegalArgumentException(path + " does not exist.");
-        }
-        // now check if their is already existing
-        // parent or child that has quota
-
-        String quotaPath = Quotas.quotaZookeeper;
-        // check for more than 2 children --
-        // if zookeeper_stats and zookeeper_qutoas
-        // are not the children then this path
-        // is an ancestor of some path that
-        // already has quota
-        String realPath = Quotas.quotaZookeeper + path;
-        try {
-            List<String> children = zk.getChildren(realPath, false);
-            for (String child: children) {
-                if (!child.startsWith("zookeeper_")) {
-                    throw new IllegalArgumentException(path + " has child " +
-                            child + " which has a quota");
-                }
-            }
-        } catch(KeeperException.NoNodeException ne) {
-            // this is fine
-        }
-
-        //check for any parent that has been quota
-        checkIfParentQuota(zk, path);
-
-        // this is valid node for quota
-        // start creating all the parents
-        if (zk.exists(quotaPath, false) == null) {
-            try {
-                zk.create(Quotas.procZookeeper, null, Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-                zk.create(Quotas.quotaZookeeper, null, Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-            } catch(KeeperException.NodeExistsException ne) {
-                // do nothing
-            }
-        }
-
-        // now create the direct children
-        // and the stat and quota nodes
-        String[] splits = path.split("/");
-        StringBuilder sb = new StringBuilder();
-        sb.append(quotaPath);
-        for (int i=1; i<splits.length; i++) {
-            sb.append("/" + splits[i]);
-            quotaPath = sb.toString();
-            try {
-                zk.create(quotaPath, null, Ids.OPEN_ACL_UNSAFE ,
-                        CreateMode.PERSISTENT);
-            } catch(KeeperException.NodeExistsException ne) {
-                //do nothing
-            }
-        }
-        String statPath = quotaPath + "/" + Quotas.statNode;
-        quotaPath = quotaPath + "/" + Quotas.limitNode;
-        StatsTrack strack = new StatsTrack(null);
-        strack.setBytes(bytes);
-        strack.setCount(numNodes);
-        try {
-            zk.create(quotaPath, strack.toString().getBytes(),
-                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            StatsTrack stats = new StatsTrack(null);
-            stats.setBytes(0L);
-            stats.setCount(0);
-            zk.create(statPath, stats.toString().getBytes(),
-                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        } catch(KeeperException.NodeExistsException ne) {
-            byte[] data = zk.getData(quotaPath, false , new Stat());
-            StatsTrack strackC = new StatsTrack(new String(data));
-            if (bytes != -1L) {
-                strackC.setBytes(bytes);
-            }
-            if (numNodes != -1) {
-                strackC.setCount(numNodes);
-            }
-            zk.setData(quotaPath, strackC.toString().getBytes(), -1);
-        }
-        return true;
-    }
-
-    protected boolean processCmd(MyCommandOptions co)
-        throws KeeperException, IOException, InterruptedException
-    {
-        try {
-            return processZKCmd(co);
-        } catch (IllegalArgumentException e) {
-            System.err.println("Command failed: " + e);
-        } catch (KeeperException.NoNodeException e) {
-            System.err.println("Node does not exist: " + e.getPath());
-        } catch (KeeperException.NoChildrenForEphemeralsException e) {
-            System.err.println("Ephemerals cannot have children: "
-                    + e.getPath());
-        } catch (KeeperException.NodeExistsException e) {
-            System.err.println("Node already exists: " + e.getPath());
-        } catch (KeeperException.NotEmptyException e) {
-            System.err.println("Node not empty: " + e.getPath());
-        } catch (KeeperException.NotReadOnlyException e) {
-            System.err.println("Not a read-only call: " + e.getPath());
-        }catch (KeeperException.InvalidACLException  e) {
-            System.err.println("Acl is not valid : "+e.getPath());
-        }catch (KeeperException.NoAuthException  e) {
-            System.err.println("Authentication is not valid : "+e.getPath());
-        }catch (KeeperException.BadArgumentsException   e) {
-            System.err.println("Arguments are not valid : "+e.getPath());
-        }catch (KeeperException.BadVersionException e) {
-            System.err.println("version No is not valid : "+e.getPath());
-        }
-        return false;
-    }
-
-    protected boolean processZKCmd(MyCommandOptions co)
-        throws KeeperException, IOException, InterruptedException
-    {
-        Stat stat = new Stat();
-        String[] args = co.getArgArray();
-        String cmd = co.getCommand();
-        if (args.length < 1) {
-            usage();
-            return false;
-        }
-
-        if (!commandMap.containsKey(cmd)) {
-            usage();
-            return false;
-        }
-        
-        boolean watch = args.length > 2;
-        String path = null;
-        List<ACL> acl = Ids.OPEN_ACL_UNSAFE;
-        LOG.debug("Processing " + cmd);
-
-        if (cmd.equals("quit")) {
-            System.out.println("Quitting...");
-            zk.close();
-            System.exit(0);
-        } else if (cmd.equals("redo") && args.length >= 2) {
-            Integer i = Integer.decode(args[1]);
-            if (commandCount <= i || i < 0){ // don't allow redoing this redo
-                System.out.println("Command index out of range");
-                return false;
-            }
-            cl.parseCommand(history.get(i));
-            if (cl.getCommand().equals( "redo" )){
-                System.out.println("No redoing redos");
-                return false;
-            }
-            history.put(commandCount, history.get(i));
-            processCmd( cl);
-        } else if (cmd.equals("history")) {
-            for (int i=commandCount - 10;i<=commandCount;++i) {
-                if (i < 0) continue;
-                System.out.println(i + " - " + history.get(i));
-            }
-        } else if (cmd.equals("printwatches")) {
-            if (args.length == 1) {
-                System.out.println("printwatches is " + (printWatches ? "on" : "off"));
-            } else {
-                printWatches = args[1].equals("on");
-            }
-        } else if (cmd.equals("connect")) {
-            if (args.length >=2) {
-                connectToZK(args[1]);
-            } else {
-                connectToZK(host);
-            }
-        }
-        
-        // Below commands all need a live connection
-        if (zk == null || !zk.getState().isAlive()) {
-            System.out.println("Not connected");
-            return false;
-        }
-        
-        if (cmd.equals("create") && args.length >= 3) {
-            int first = 0;
-            CreateMode flags = CreateMode.PERSISTENT;
-            if ((args[1].equals("-e") && args[2].equals("-s"))
-                    || (args[1]).equals("-s") && (args[2].equals("-e"))) {
-                first+=2;
-                flags = CreateMode.EPHEMERAL_SEQUENTIAL;
-            } else if (args[1].equals("-e")) {
-                first++;
-                flags = CreateMode.EPHEMERAL;
-            } else if (args[1].equals("-s")) {
-                first++;
-                flags = CreateMode.PERSISTENT_SEQUENTIAL;
-            }
-            if (args.length == first + 4) {
-                acl = parseACLs(args[first+3]);
-            }
-            path = args[first + 1];
-            String newPath = zk.create(path, args[first+2].getBytes(), acl,
-                    flags);
-            System.err.println("Created " + newPath);
-        } else if (cmd.equals("delete") && args.length >= 2) {
-            path = args[1];
-            zk.delete(path, watch ? Integer.parseInt(args[2]) : -1);
-        } else if (cmd.equals("rmr") && args.length >= 2) {
-            path = args[1];
-            ZKUtil.deleteRecursive(zk, path);
-        } else if (cmd.equals("set") && args.length >= 3) {
-            path = args[1];
-            stat = zk.setData(path, args[2].getBytes(),
-                    args.length > 3 ? Integer.parseInt(args[3]) : -1);
-            printStat(stat);
-        } else if (cmd.equals("aget") && args.length >= 2) {
-            path = args[1];
-            zk.getData(path, watch, dataCallback, path);
-        } else if (cmd.equals("get") && args.length >= 2) {
-            path = args[1];
-            byte data[] = zk.getData(path, watch, stat);
-            data = (data == null)? "null".getBytes() : data;
-            System.out.println(new String(data));
-            printStat(stat);
-        } else if (cmd.equals("ls") && args.length >= 2) {
-            path = args[1];
-            List<String> children = zk.getChildren(path, watch);
-            System.out.println(children);
-        } else if (cmd.equals("ls2") && args.length >= 2) {
-            path = args[1];
-            List<String> children = zk.getChildren(path, watch, stat);
-            System.out.println(children);
-            printStat(stat);
-        } else if (cmd.equals("getAcl") && args.length >= 2) {
-            path = args[1];
-            acl = zk.getACL(path, stat);
-            for (ACL a : acl) {
-                System.out.println(a.getId() + ": "
-                        + getPermString(a.getPerms()));
-            }
-        } else if (cmd.equals("setAcl") && args.length >= 3) {
-            path = args[1];
-            stat = zk.setACL(path, parseACLs(args[2]),
-                    args.length > 4 ? Integer.parseInt(args[3]) : -1);
-            printStat(stat);
-        } else if (cmd.equals("stat") && args.length >= 2) {
-            path = args[1];
-            stat = zk.exists(path, watch);
-            if (stat == null) {
-              throw new KeeperException.NoNodeException(path);
-            }
-            printStat(stat);
-        } else if (cmd.equals("listquota") && args.length >= 2) {
-            path = args[1];
-            String absolutePath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
-            byte[] data =  null;
-            try {
-                System.err.println("absolute path is " + absolutePath);
-                data = zk.getData(absolutePath, false, stat);
-                StatsTrack st = new StatsTrack(new String(data));
-                System.out.println("Output quota for " + path + " "
-                        + st.toString());
-
-                data = zk.getData(Quotas.quotaZookeeper + path + "/" +
-                        Quotas.statNode, false, stat);
-                System.out.println("Output stat for " + path + " " +
-                        new StatsTrack(new String(data)).toString());
-            } catch(KeeperException.NoNodeException ne) {
-                System.err.println("quota for " + path + " does not exist.");
-            }
-        } else if (cmd.equals("setquota") && args.length >= 4) {
-            String option = args[1];
-            String val = args[2];
-            path = args[3];
-            System.err.println("Comment: the parts are " +
-                               "option " + option +
-                               " val " + val +
-                               " path " + path);
-            if ("-b".equals(option)) {
-                // we are setting the bytes quota
-                createQuota(zk, path, Long.parseLong(val), -1);
-            } else if ("-n".equals(option)) {
-                // we are setting the num quota
-                createQuota(zk, path, -1L, Integer.parseInt(val));
-            } else {
-                usage();
-            }
-
-        } else if (cmd.equals("delquota") && args.length >= 2) {
-            //if neither option -n or -b is specified, we delete
-            // the quota node for thsi node.
-            if (args.length == 3) {
-                //this time we have an option
-                String option = args[1];
-                path = args[2];
-                if ("-b".equals(option)) {
-                    delQuota(zk, path, true, false);
-                } else if ("-n".equals(option)) {
-                    delQuota(zk, path, false, true);
-                }
-            } else if (args.length == 2) {
-                path = args[1];
-                // we dont have an option specified.
-                // just delete whole quota node
-                delQuota(zk, path, true, true);
-            } else if (cmd.equals("help")) {
-                usage();
-            }
-        } else if (cmd.equals("close")) {
-                zk.close();
-        } else if (cmd.equals("sync") && args.length >= 2) {
-            path = args[1];
-            zk.sync(path, new AsyncCallback.VoidCallback() { public void processResult(int rc, String path, Object ctx) { System.out.println("Sync returned " + rc); } }, null );
-        } else if (cmd.equals("addauth") && args.length >=2 ) {
-            byte[] b = null;
-            if (args.length >= 3)
-                b = args[2].getBytes();
-
-            zk.addAuthInfo(args[1], b);
-        } else if (!commandMap.containsKey(cmd)) {
-            usage();
-        }
-        return watch;
-    }
-
-    private static String getPermString(int perms) {
-        StringBuilder p = new StringBuilder();
-        if ((perms & ZooDefs.Perms.CREATE) != 0) {
-            p.append('c');
-        }
-        if ((perms & ZooDefs.Perms.DELETE) != 0) {
-            p.append('d');
-        }
-        if ((perms & ZooDefs.Perms.READ) != 0) {
-            p.append('r');
-        }
-        if ((perms & ZooDefs.Perms.WRITE) != 0) {
-            p.append('w');
-        }
-        if ((perms & ZooDefs.Perms.ADMIN) != 0) {
-            p.append('a');
-        }
-        return p.toString();
-    }
-
-    private static List<ACL> parseACLs(String aclString) {
-        List<ACL> acl;
-        String acls[] = aclString.split(",");
-        acl = new ArrayList<ACL>();
-        for (String a : acls) {
-            int firstColon = a.indexOf(':');
-            int lastColon = a.lastIndexOf(':');
-            if (firstColon == -1 || lastColon == -1 || firstColon == lastColon) {
-                System.err
-                .println(a + " does not have the form scheme:id:perm");
-                continue;
-            }
-            ACL newAcl = new ACL();
-            newAcl.setId(new Id(a.substring(0, firstColon), a.substring(
-                    firstColon + 1, lastColon)));
-            newAcl.setPerms(getPermFromString(a.substring(lastColon + 1)));
-            acl.add(newAcl);
-        }
-        return acl;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java
deleted file mode 100644
index 775d1a2..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class ZooKeeperTestable implements Testable {
-    private static final Logger LOG = LoggerFactory
-            .getLogger(ZooKeeperTestable.class);
-
-    private final ZooKeeper zooKeeper;
-    private final ClientCnxn clientCnxn;
-
-    ZooKeeperTestable(ZooKeeper zooKeeper, ClientCnxn clientCnxn) {
-        this.zooKeeper = zooKeeper;
-        this.clientCnxn = clientCnxn;
-    }
-
-    @Override
-    public void injectSessionExpiration() {
-        LOG.info("injectSessionExpiration() called");
-
-        clientCnxn.eventThread.queueEvent(new WatchedEvent(
-                Watcher.Event.EventType.None,
-                Watcher.Event.KeeperState.Expired, null));
-        clientCnxn.eventThread.queueEventOfDeath();
-        clientCnxn.sendThread.getClientCnxnSocket().wakeupCnxn();
-        clientCnxn.state = ZooKeeper.States.CLOSED;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java b/zookeeper-common/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java
deleted file mode 100644
index 2584d3f..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.common;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/*
- * This code is originally from HDFS, see the similarly named files there
- * in case of bug fixing, history, etc...
- */
-
-/**
- * A FileOutputStream that has the property that it will only show up at its
- * destination once it has been entirely written and flushed to disk. While
- * being written, it will use a .tmp suffix.
- *
- * When the output stream is closed, it is flushed, fsynced, and will be moved
- * into place, overwriting any file that already exists at that location.
- *
- * <b>NOTE</b>: on Windows platforms, it will not atomically replace the target
- * file - instead the target file is deleted before this one is moved into
- * place.
- */
-public class AtomicFileOutputStream extends FilterOutputStream {
-    private static final String TMP_EXTENSION = ".tmp";
-
-    private final static Logger LOG = LoggerFactory
-            .getLogger(AtomicFileOutputStream.class);
-
-    private final File origFile;
-    private final File tmpFile;
-
-    public AtomicFileOutputStream(File f) throws FileNotFoundException {
-        // Code unfortunately must be duplicated below since we can't assign
-        // anything
-        // before calling super
-        super(new FileOutputStream(new File(f.getParentFile(), f.getName()
-                + TMP_EXTENSION)));
-        origFile = f.getAbsoluteFile();
-        tmpFile = new File(f.getParentFile(), f.getName() + TMP_EXTENSION)
-                .getAbsoluteFile();
-    }
-
-    /**
-     * The default write method in FilterOutputStream does not call the write
-     * method of its underlying input stream with the same arguments. Instead
-     * it writes the data byte by byte, override it here to make it more
-     * efficient.
-     */
-    @Override
-    public void write(byte b[], int off, int len) throws IOException {
-        out.write(b, off, len);
-    }
-
-    @Override
-    public void close() throws IOException {
-        boolean triedToClose = false, success = false;
-        try {
-            flush();
-            ((FileOutputStream) out).getChannel().force(true);
-
-            triedToClose = true;
-            super.close();
-            success = true;
-        } finally {
-            if (success) {
-                boolean renamed = tmpFile.renameTo(origFile);
-                if (!renamed) {
-                    // On windows, renameTo does not replace.
-                    if (!origFile.delete() || !tmpFile.renameTo(origFile)) {
-                        throw new IOException(
-                                "Could not rename temporary file " + tmpFile
-                                        + " to " + origFile);
-                    }
-                }
-            } else {
-                if (!triedToClose) {
-                    // If we failed when flushing, try to close it to not leak
-                    // an FD
-                    IOUtils.closeStream(out);
-                }
-                // close wasn't successful, try to delete the tmp file
-                if (!tmpFile.delete()) {
-                    LOG.warn("Unable to delete tmp file " + tmpFile);
-                }
-            }
-        }
-    }
-
-    /**
-     * Close the atomic file, but do not "commit" the temporary file on top of
-     * the destination. This should be used if there is a failure in writing.
-     */
-    public void abort() {
-        try {
-            super.close();
-        } catch (IOException ioe) {
-            LOG.warn("Unable to abort file " + tmpFile, ioe);
-        }
-        if (!tmpFile.delete()) {
-            LOG.warn("Unable to delete tmp file during abort " + tmpFile);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/common/IOUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/common/IOUtils.java b/zookeeper-common/src/main/java/org/apache/zookeeper/common/IOUtils.java
deleted file mode 100644
index 16aea4e..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/common/IOUtils.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.common;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-import org.slf4j.Logger;
-
-/*
- * This code is originally from HDFS, see the similarly named files there
- * in case of bug fixing, history, etc...
- */
-
-public class IOUtils {
-    /**
-     * Closes the stream ignoring {@link IOException}. Must only be called in
-     * cleaning up from exception handlers.
-     * 
-     * @param stream
-     *            the Stream to close
-     */
-    public static void closeStream(Closeable stream) {
-        cleanup(null, stream);
-    }
-
-    /**
-     * Close the Closeable objects and <b>ignore</b> any {@link IOException} or
-     * null pointers. Must only be used for cleanup in exception handlers.
-     * 
-     * @param log
-     *            the log to record problems to at debug level. Can be null.
-     * @param closeables
-     *            the objects to close
-     */
-    public static void cleanup(Logger log, Closeable... closeables) {
-        for (Closeable c : closeables) {
-            if (c != null) {
-                try {
-                    c.close();
-                } catch (IOException e) {
-                    if (log != null) {
-                        log.warn("Exception in closing " + c, e);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Copies from one stream to another.
-     * 
-     * @param in
-     *            InputStrem to read from
-     * @param out
-     *            OutputStream to write to
-     * @param buffSize
-     *            the size of the buffer
-     * @param close
-     *            whether or not close the InputStream and OutputStream at the
-     *            end. The streams are closed in the finally clause.
-     */
-    public static void copyBytes(InputStream in, OutputStream out,
-            int buffSize, boolean close) throws IOException {
-        try {
-            copyBytes(in, out, buffSize);
-            if (close) {
-                out.close();
-                out = null;
-                in.close();
-                in = null;
-            }
-        } finally {
-            if (close) {
-                closeStream(out);
-                closeStream(in);
-            }
-        }
-    }
-
-    /**
-     * Copies from one stream to another.
-     * 
-     * @param in
-     *            InputStrem to read from
-     * @param out
-     *            OutputStream to write to
-     * @param buffSize
-     *            the size of the buffer
-     */
-    public static void copyBytes(InputStream in, OutputStream out, int buffSize)
-            throws IOException {
-        PrintStream ps = out instanceof PrintStream ? (PrintStream) out : null;
-        byte buf[] = new byte[buffSize];
-        int bytesRead = in.read(buf);
-        while (bytesRead >= 0) {
-            out.write(buf, 0, bytesRead);
-            if ((ps != null) && ps.checkError()) {
-                throw new IOException("Unable to write to output stream.");
-            }
-            bytesRead = in.read(buf);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathTrie.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathTrie.java b/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathTrie.java
deleted file mode 100644
index 73053e0..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathTrie.java
+++ /dev/null
@@ -1,293 +0,0 @@
- /**
- * 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.
- */
-
-package org.apache.zookeeper.common;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * a class that implements prefix matching for 
- * components of a filesystem path. the trie
- * looks like a tree with edges mapping to 
- * the component of a path.
- * example /ab/bc/cf would map to a trie
- *           /
- *        ab/
- *        (ab)
- *      bc/
- *       / 
- *      (bc)
- *   cf/
- *   (cf)
- */    
-public class PathTrie {
-    /**
-     * the logger for this class
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(PathTrie.class);
-    
-    /**
-     * the root node of PathTrie
-     */
-    private final TrieNode rootNode ;
-    
-    static class TrieNode {
-        boolean property = false;
-        final HashMap<String, TrieNode> children;
-        TrieNode parent = null;
-        /**
-         * create a trienode with parent
-         * as parameter
-         * @param parent the parent of this trienode
-         */
-        private TrieNode(TrieNode parent) {
-            children = new HashMap<String, TrieNode>();
-            this.parent = parent;
-        }
-        
-        /**
-         * get the parent of this node
-         * @return the parent node
-         */
-        TrieNode getParent() {
-            return this.parent;
-        }
-        
-        /**
-         * set the parent of this node
-         * @param parent the parent to set to
-         */
-        void setParent(TrieNode parent) {
-            this.parent = parent;
-        }
-        
-        /**
-         * a property that is set 
-         * for a node - making it 
-         * special.
-         */
-        void setProperty(boolean prop) {
-            this.property = prop;
-        }
-        
-        /** the property of this
-         * node 
-         * @return the property for this
-         * node
-         */
-        boolean getProperty() {
-            return this.property;
-        }
-        /**
-         * add a child to the existing node
-         * @param childName the string name of the child
-         * @param node the node that is the child
-         */
-        void addChild(String childName, TrieNode node) {
-            synchronized(children) {
-                if (children.containsKey(childName)) {
-                    return;
-                }
-                children.put(childName, node);
-            }
-        }
-     
-        /**
-         * delete child from this node
-         * @param childName the string name of the child to 
-         * be deleted
-         */
-        void deleteChild(String childName) {
-            synchronized(children) {
-                if (!children.containsKey(childName)) {
-                    return;
-                }
-                TrieNode childNode = children.get(childName);
-                // this is the only child node.
-                if (childNode.getChildren().length == 1) { 
-                    childNode.setParent(null);
-                    children.remove(childName);
-                }
-                else {
-                    // their are more child nodes
-                    // so just reset property.
-                    childNode.setProperty(false);
-                }
-            }
-        }
-        
-        /**
-         * return the child of a node mapping
-         * to the input childname
-         * @param childName the name of the child
-         * @return the child of a node
-         */
-        TrieNode getChild(String childName) {
-            synchronized(children) {
-               if (!children.containsKey(childName)) {
-                   return null;
-               }
-               else {
-                   return children.get(childName);
-               }
-            }
-        }
-
-        /**
-         * get the list of children of this 
-         * trienode.
-         * @param node to get its children
-         * @return the string list of its children
-         */
-        String[] getChildren() {
-           synchronized(children) {
-               return children.keySet().toArray(new String[0]);
-           }
-        }
-        
-        /**
-         * get the string representation
-         * for this node
-         */
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append("Children of trienode: ");
-            synchronized(children) {
-                for (String str: children.keySet()) {
-                    sb.append(" " + str);
-                }
-            }
-            return sb.toString();
-        }
-    }
-    
-    /**
-     * construct a new PathTrie with
-     * a root node of /
-     */
-    public PathTrie() {
-        this.rootNode = new TrieNode(null);
-    }
-    
-    /**
-     * add a path to the path trie 
-     * @param path
-     */
-    public void addPath(String path) {
-        if (path == null) {
-            return;
-        }
-        String[] pathComponents = path.split("/");
-        TrieNode parent = rootNode;
-        String part = null;
-        if (pathComponents.length <= 1) {
-            throw new IllegalArgumentException("Invalid path " + path);
-        }
-        for (int i=1; i<pathComponents.length; i++) {
-            part = pathComponents[i];
-            if (parent.getChild(part) == null) {
-                parent.addChild(part, new TrieNode(parent));
-            }
-            parent = parent.getChild(part);
-        }
-        parent.setProperty(true);
-    }
-    
-    /**
-     * delete a path from the trie
-     * @param path the path to be deleted
-     */
-    public void deletePath(String path) {
-        if (path == null) {
-            return;
-        }
-        String[] pathComponents = path.split("/");
-        TrieNode parent = rootNode;
-        String part = null;
-        if (pathComponents.length <= 1) { 
-            throw new IllegalArgumentException("Invalid path " + path);
-        }
-        for (int i=1; i<pathComponents.length; i++) {
-            part = pathComponents[i];
-            if (parent.getChild(part) == null) {
-                //the path does not exist 
-                return;
-            }
-            parent = parent.getChild(part);
-            LOG.info("{}",parent);
-        }
-        TrieNode realParent  = parent.getParent();
-        realParent.deleteChild(part);
-    }
-    
-    /**
-     * return the largest prefix for the input path.
-     * @param path the input path
-     * @return the largest prefix for the input path.
-     */
-    public String findMaxPrefix(String path) {
-        if (path == null) {
-            return null;
-        }
-        if ("/".equals(path)) {
-            return path;
-        }
-        String[] pathComponents = path.split("/");
-        TrieNode parent = rootNode;
-        List<String> components = new ArrayList<String>();
-        if (pathComponents.length <= 1) {
-            throw new IllegalArgumentException("Invalid path " + path);
-        }
-        int i = 1;
-        String part = null;
-        StringBuilder sb = new StringBuilder();
-        int lastindex = -1;
-        while((i < pathComponents.length)) {
-            if (parent.getChild(pathComponents[i]) != null) {
-                part = pathComponents[i];
-                parent = parent.getChild(part);
-                components.add(part);
-                if (parent.getProperty()) {
-                    lastindex = i-1;
-                }
-            }
-            else {
-                break;
-            }
-            i++;
-        }
-        for (int j=0; j< (lastindex+1); j++) {
-            sb.append("/" + components.get(j));
-        }
-        return sb.toString();
-    }
-
-    /**
-     * clear all nodes
-     */
-    public void clear() {
-        for(String child : rootNode.getChildren()) {
-            rootNode.deleteChild(child);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathUtils.java b/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathUtils.java
deleted file mode 100644
index 2a6c7ef..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/common/PathUtils.java
+++ /dev/null
@@ -1,103 +0,0 @@
- /**
- * 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.
- */
-
-package org.apache.zookeeper.common;
-
-
-/**
- * Path related utilities
- */    
-public class PathUtils {
-	
-	/** validate the provided znode path string
-	 * @param path znode path string
-	 * @param isSequential if the path is being created
-	 * with a sequential flag
-	 * @throws IllegalArgumentException if the path is invalid
-	 */
-	public static void validatePath(String path, boolean isSequential) 
-		throws IllegalArgumentException {
-		validatePath(isSequential? path + "1": path);
-	}
-	
-    /**
-     * Validate the provided znode path string
-     * @param path znode path string
-     * @throws IllegalArgumentException if the path is invalid
-     */
-    public static void validatePath(String path) throws IllegalArgumentException {
-        if (path == null) {
-            throw new IllegalArgumentException("Path cannot be null");
-        }
-        if (path.length() == 0) {
-            throw new IllegalArgumentException("Path length must be > 0");
-        }
-        if (path.charAt(0) != '/') {
-            throw new IllegalArgumentException(
-                         "Path must start with / character");
-        }
-        if (path.length() == 1) { // done checking - it's the root
-            return;
-        }
-        if (path.charAt(path.length() - 1) == '/') {
-            throw new IllegalArgumentException(
-                         "Path must not end with / character");
-        }
-
-        String reason = null;
-        char lastc = '/';
-        char chars[] = path.toCharArray();
-        char c;
-        for (int i = 1; i < chars.length; lastc = chars[i], i++) {
-            c = chars[i];
-
-            if (c == 0) {
-                reason = "null character not allowed @" + i;
-                break;
-            } else if (c == '/' && lastc == '/') {
-                reason = "empty node name specified @" + i;
-                break;
-            } else if (c == '.' && lastc == '.') {
-                if (chars[i-2] == '/' &&
-                        ((i + 1 == chars.length)
-                                || chars[i+1] == '/')) {
-                    reason = "relative paths not allowed @" + i;
-                    break;
-                }
-            } else if (c == '.') {
-                if (chars[i-1] == '/' &&
-                        ((i + 1 == chars.length)
-                                || chars[i+1] == '/')) {
-                    reason = "relative paths not allowed @" + i;
-                    break;
-                }
-            } else if (c > '\u0000' && c < '\u001f'
-                    || c > '\u007f' && c < '\u009F'
-                    || c > '\ud800' && c < '\uf8ff'
-                    || c > '\ufff0' && c < '\uffff') {
-                reason = "invalid character @" + i;
-                break;
-            }
-        }
-
-        if (reason != null) {
-            throw new IllegalArgumentException(
-                    "Invalid path string \"" + path + "\" caused by " + reason);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/common/Time.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/common/Time.java b/zookeeper-common/src/main/java/org/apache/zookeeper/common/Time.java
deleted file mode 100644
index 83e53f0..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/common/Time.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.common;
-
-import java.util.Date;
-
-public class Time {
-    /**
-     * Returns time in milliseconds as does System.currentTimeMillis(),
-     * but uses elapsed time from an arbitrary epoch more like System.nanoTime().
-     * The difference is that if somebody changes the system clock,
-     * Time.currentElapsedTime will change but nanoTime won't. On the other hand,
-     * all of ZK assumes that time is measured in milliseconds.
-     * @return  The time in milliseconds from some arbitrary point in time.
-     */
-    public static long currentElapsedTime() {
-        return System.nanoTime() / 1000000;
-    }
-
-    /**
-     * Explicitly returns system dependent current wall time.
-     * @return Current time in msec.
-     */
-    public static long currentWallTime() {
-        return System.currentTimeMillis();
-    }
-
-    /**
-     * This is to convert the elapsedTime to a Date.
-     * @return A date object indicated by the elapsedTime.
-     */
-    public static Date elapsedTimeToDate(long elapsedTime) {
-        long wallTime = currentWallTime() + elapsedTime - currentElapsedTime();
-        return new Date(wallTime);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/util/SecurityUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/util/SecurityUtils.java b/zookeeper-common/src/main/java/org/apache/zookeeper/util/SecurityUtils.java
deleted file mode 100644
index 67484e4..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/util/SecurityUtils.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.util;
-
-import java.security.Principal;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-import org.apache.zookeeper.SaslClientCallbackHandler;
-import org.apache.zookeeper.server.auth.KerberosName;
-import org.ietf.jgss.GSSContext;
-import org.ietf.jgss.GSSCredential;
-import org.ietf.jgss.GSSException;
-import org.ietf.jgss.GSSManager;
-import org.ietf.jgss.GSSName;
-import org.ietf.jgss.Oid;
-import org.slf4j.Logger;
-
-public final class SecurityUtils {
-
-    public static final String QUORUM_HOSTNAME_PATTERN = "_HOST";
-
-    /**
-     * Create an instance of a SaslClient. It will return null if there is an exception.
-     *
-     * @param subject subject
-     * @param servicePrincipal principal
-     * @param protocol name of the protocol for which the authentication is being performed
-     * @param serverName name of the server to authenticate to
-     * @param LOG logger
-     * @param entity can be either zookeeper client or quorum learner
-     *
-     * @return saslclient object
-     * @throws SaslException
-     */
-    public static SaslClient createSaslClient(final Subject subject,
-            final String servicePrincipal, final String protocol,
-            final String serverName, final Logger LOG, final String entity) throws SaslException {
-        SaslClient saslClient;
-        // Use subject.getPrincipals().isEmpty() as an indication of which SASL
-        // mechanism to use: if empty, use DIGEST-MD5; otherwise, use GSSAPI.
-        if (subject.getPrincipals().isEmpty()) {
-            // no principals: must not be GSSAPI: use DIGEST-MD5 mechanism
-            // instead.
-            LOG.info("{} will use DIGEST-MD5 as SASL mechanism.", entity);
-            String[] mechs = { "DIGEST-MD5" };
-            String username = (String) (subject.getPublicCredentials()
-                    .toArray()[0]);
-            String password = (String) (subject.getPrivateCredentials()
-                    .toArray()[0]);
-            // 'domain' parameter is hard-wired between the server and client
-            saslClient = Sasl.createSaslClient(mechs, username, protocol,
-                    serverName, null, new SaslClientCallbackHandler(password, entity));
-            return saslClient;
-        } else { // GSSAPI.
-            final Object[] principals = subject.getPrincipals().toArray();
-            // determine client principal from subject.
-            final Principal clientPrincipal = (Principal) principals[0];
-            boolean usingNativeJgss = Boolean
-                    .getBoolean("sun.security.jgss.native");
-            if (usingNativeJgss) {
-                // http://docs.oracle.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
-                // """
-                // In addition, when performing operations as a particular
-                // Subject, e.g. Subject.doAs(...) or
-                // Subject.doAsPrivileged(...),
-                // the to-be-used GSSCredential should be added to Subject's
-                // private credential set. Otherwise, the GSS operations will
-                // fail since no credential is found.
-                // """
-                try {
-                    GSSManager manager = GSSManager.getInstance();
-                    Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
-                    GSSCredential cred = manager.createCredential(null,
-                            GSSContext.DEFAULT_LIFETIME, krb5Mechanism,
-                            GSSCredential.INITIATE_ONLY);
-                    subject.getPrivateCredentials().add(cred);
-                    LOG.debug("Added private credential to {} principal name: '{}'",
-                            entity, clientPrincipal);
-                } catch (GSSException ex) {
-                    LOG.warn("Cannot add private credential to subject; "
-                                    + "authentication at the server may fail", ex);
-                }
-            }
-            final KerberosName clientKerberosName = new KerberosName(
-                    clientPrincipal.getName());
-            // assume that server and client are in the same realm (by default;
-            // unless the system property
-            // "zookeeper.server.realm" is set).
-            String serverRealm = System.getProperty("zookeeper.server.realm",
-                    clientKerberosName.getRealm());
-            KerberosName serviceKerberosName = new KerberosName(
-                    servicePrincipal + "@" + serverRealm);
-            final String serviceName = serviceKerberosName.getServiceName();
-            final String serviceHostname = serviceKerberosName.getHostName();
-            final String clientPrincipalName = clientKerberosName.toString();
-            try {
-                saslClient = Subject.doAs(subject,
-                        new PrivilegedExceptionAction<SaslClient>() {
-                            public SaslClient run() throws SaslException {
-                                LOG.info("{} will use GSSAPI as SASL mechanism.", entity);
-                                String[] mechs = { "GSSAPI" };
-                                LOG.debug("creating sasl client: {}={};service={};serviceHostname={}",
-                                        new Object[] { entity, clientPrincipalName, serviceName, serviceHostname });
-                                SaslClient saslClient = Sasl.createSaslClient(
-                                        mechs, clientPrincipalName, serviceName,
-                                        serviceHostname, null,
-                                        new SaslClientCallbackHandler(null, entity));
-                                return saslClient;
-                            }
-                        });
-                return saslClient;
-            } catch (Exception e) {
-                LOG.error("Exception while trying to create SASL client", e);
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Create an instance of a SaslServer. It will return null if there is an exception.
-     *
-     * @param subject subject
-     * @param protocol protocol
-     * @param serverName server name
-     * @param callbackHandler login callback handler
-     * @param LOG logger
-     * @return sasl server object
-     */
-    public static SaslServer createSaslServer(final Subject subject,
-            final String protocol, final String serverName,
-            final CallbackHandler callbackHandler, final Logger LOG) {
-        if (subject != null) {
-            // server is using a JAAS-authenticated subject: determine service
-            // principal name and hostname from zk server's subject.
-            if (subject.getPrincipals().size() > 0) {
-                try {
-                    final Object[] principals = subject.getPrincipals()
-                            .toArray();
-                    final Principal servicePrincipal = (Principal) principals[0];
-
-                    // e.g. servicePrincipalNameAndHostname :=
-                    // "zookeeper/myhost.foo.com@FOO.COM"
-                    final String servicePrincipalNameAndHostname = servicePrincipal
-                            .getName();
-
-                    int indexOf = servicePrincipalNameAndHostname.indexOf("/");
-
-                    // e.g. servicePrincipalName := "zookeeper"
-                    final String servicePrincipalName = servicePrincipalNameAndHostname
-                            .substring(0, indexOf);
-
-                    // e.g. serviceHostnameAndKerbDomain :=
-                    // "myhost.foo.com@FOO.COM"
-                    final String serviceHostnameAndKerbDomain = servicePrincipalNameAndHostname
-                            .substring(indexOf + 1,
-                                    servicePrincipalNameAndHostname.length());
-
-                    indexOf = serviceHostnameAndKerbDomain.indexOf("@");
-                    // e.g. serviceHostname := "myhost.foo.com"
-                    final String serviceHostname = serviceHostnameAndKerbDomain
-                            .substring(0, indexOf);
-
-                    // TODO: should depend on zoo.cfg specified mechs, but if
-                    // subject is non-null, it can be assumed to be GSSAPI.
-                    final String mech = "GSSAPI";
-
-                    LOG.debug("serviceHostname is '" + serviceHostname + "'");
-                    LOG.debug("servicePrincipalName is '" + servicePrincipalName
-                            + "'");
-                    LOG.debug("SASL mechanism(mech) is '" + mech + "'");
-
-                    boolean usingNativeJgss = Boolean
-                            .getBoolean("sun.security.jgss.native");
-                    if (usingNativeJgss) {
-                        // http://docs.oracle.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
-                        // """
-                        // In addition, when performing operations as a
-                        // particular
-                        // Subject, e.g. Subject.doAs(...) or
-                        // Subject.doAsPrivileged(...), the to-be-used
-                        // GSSCredential should be added to Subject's
-                        // private credential set. Otherwise, the GSS operations
-                        // will fail since no credential is found.
-                        // """
-                        try {
-                            GSSManager manager = GSSManager.getInstance();
-                            Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
-                            GSSName gssName = manager.createName(
-                                    servicePrincipalName + "@"
-                                            + serviceHostname,
-                                    GSSName.NT_HOSTBASED_SERVICE);
-                            GSSCredential cred = manager.createCredential(
-                                    gssName, GSSContext.DEFAULT_LIFETIME,
-                                    krb5Mechanism, GSSCredential.ACCEPT_ONLY);
-                            subject.getPrivateCredentials().add(cred);
-                            LOG.debug("Added private credential to service principal name: '{}',"
-                                            + " GSSCredential name: {}", servicePrincipalName, cred.getName());
-                        } catch (GSSException ex) {
-                            LOG.warn("Cannot add private credential to subject; "
-                                            + "clients authentication may fail", ex);
-                        }
-                    }
-                    try {
-                        return Subject.doAs(subject,
-                                new PrivilegedExceptionAction<SaslServer>() {
-                                    public SaslServer run() {
-                                        try {
-                                            SaslServer saslServer;
-                                            saslServer = Sasl.createSaslServer(
-                                                    mech, servicePrincipalName,
-                                                    serviceHostname, null,
-                                                    callbackHandler);
-                                            return saslServer;
-                                        } catch (SaslException e) {
-                                            LOG.error("Zookeeper Server failed to create a SaslServer to interact with a client during session initiation: ", e);
-                                            return null;
-                                        }
-                                    }
-                                });
-                    } catch (PrivilegedActionException e) {
-                        // TODO: exit server at this point(?)
-                        LOG.error("Zookeeper Quorum member experienced a PrivilegedActionException exception while creating a SaslServer using a JAAS principal context:", e);
-                    }
-                } catch (IndexOutOfBoundsException e) {
-                    LOG.error("server principal name/hostname determination error: ", e);
-                }
-            } else {
-                // JAAS non-GSSAPI authentication: assuming and supporting only
-                // DIGEST-MD5 mechanism for now.
-                // TODO: use 'authMech=' value in zoo.cfg.
-                try {
-                    SaslServer saslServer = Sasl.createSaslServer("DIGEST-MD5",
-                            protocol, serverName, null, callbackHandler);
-                    return saslServer;
-                } catch (SaslException e) {
-                    LOG.error("Zookeeper Quorum member failed to create a SaslServer to interact with a client during session initiation", e);
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Convert Kerberos principal name pattern to valid Kerberos principal name.
-     * If the principal name contains hostname pattern "_HOST" then it replaces
-     * with the given hostname, which should be fully-qualified domain name.
-     *
-     * @param principalConfig
-     *            the Kerberos principal name conf value to convert
-     * @param hostname
-     *            the fully-qualified domain name used for substitution
-     * @return converted Kerberos principal name
-     */
-    public static String getServerPrincipal(String principalConfig,
-            String hostname) {
-        String[] components = getComponents(principalConfig);
-        if (components == null || components.length != 2
-                || !components[1].equals(QUORUM_HOSTNAME_PATTERN)) {
-            return principalConfig;
-        } else {
-            return replacePattern(components, hostname);
-        }
-    }
-
-    private static String[] getComponents(String principalConfig) {
-        if (principalConfig == null)
-            return null;
-        return principalConfig.split("[/]");
-    }
-
-    private static String replacePattern(String[] components, String hostname) {
-        return components[0] + "/" + hostname.toLowerCase();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/version/util/VerGen.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/version/util/VerGen.java b/zookeeper-common/src/main/java/org/apache/zookeeper/version/util/VerGen.java
deleted file mode 100644
index 7285a2b..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/version/util/VerGen.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.version.util;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class VerGen {
-    private static final String PACKAGE_NAME = "org.apache.zookeeper.version";
-    private static final String TYPE_NAME = "Info";
-
-    static void printUsage() {
-        System.out.print("Usage:\tjava  -cp <classpath> org.apache.zookeeper."
-                + "version.util.VerGen maj.min.micro[-qualifier] rev buildDate");
-        System.exit(1);
-    }
-
-    public static void generateFile(File outputDir, Version version, String rev, String buildDate) throws IOException
-    {
-        String path = PACKAGE_NAME.replaceAll("\\.", "/");
-        File pkgdir = new File(outputDir, path);
-        if (!pkgdir.exists()) {
-            // create the pkg directory
-            boolean ret = pkgdir.mkdirs();
-            if (!ret) {
-                System.out.println("Cannnot create directory: " + path);
-                System.exit(1);
-            }
-        } else if (!pkgdir.isDirectory()) {
-            // not a directory
-            System.out.println(path + " is not a directory.");
-            System.exit(1);
-        }
-        File file = new File(pkgdir, TYPE_NAME + ".java");
-        FileWriter w = null;
-        try {
-            w = new FileWriter(file);
-            w.write("// Do not edit!\n// File generated by org.apache.zookeeper"
-                    + ".version.util.VerGen.\n");
-            w.write("/**\n");
-            w.write("* Licensed to the Apache Software Foundation (ASF) under one\n");
-            w.write("* or more contributor license agreements.  See the NOTICE file\n");
-            w.write("* distributed with this work for additional information\n");
-            w.write("* regarding copyright ownership.  The ASF licenses this file\n");
-            w.write("* to you under the Apache License, Version 2.0 (the\n");
-            w.write("* \"License\"); you may not use this file except in compliance\n");
-            w.write("* with the License.  You may obtain a copy of the License at\n");
-            w.write("*\n");
-            w.write("*     http://www.apache.org/licenses/LICENSE-2.0\n");
-            w.write("*\n");
-            w.write("* Unless required by applicable law or agreed to in writing, software\n");
-            w.write("* distributed under the License is distributed on an \"AS IS\" BASIS,\n");
-            w.write("* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n");
-            w.write("* See the License for the specific language governing permissions and\n");
-            w.write("* limitations under the License.\n");
-            w.write("*/\n");
-            w.write("\n");
-            w.write("package " + PACKAGE_NAME + ";\n\n");
-            w.write("public interface " + TYPE_NAME + " {\n");
-            w.write("    int MAJOR=" + version.maj + ";\n");
-            w.write("    int MINOR=" + version.min + ";\n");
-            w.write("    int MICRO=" + version.micro + ";\n");
-            w.write("    String QUALIFIER="
-                    + (version.qualifier == null ? null :
-                        "\"" + version.qualifier + "\"")
-                    + ";\n");
-            if (rev.equals("-1")) {
-                System.out.println("Unknown REVISION number, using " + rev);
-            }
-            w.write("    int REVISION=-1; //TODO: remove as related to SVN VCS\n");
-            w.write("    String REVISION_HASH=\"" + rev + "\";\n");
-            w.write("    String BUILD_DATE=\"" + buildDate
-                    + "\";\n");
-            w.write("}\n");
-        } finally {
-            if (w != null) {
-                try {
-                    w.close();
-                } catch (IOException e) {
-                    System.out.println("Unable to close file writer"
-                            + e.getMessage());
-                }
-            }
-        }
-    }
-
-    public static class Version {
-        public int maj;
-        public int min;
-        public int micro;
-        public String qualifier;
-    }
-
-    public static Version parseVersionString(String input) {
-        Version result = new Version();
-
-        Pattern p = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)((\\.\\d+)*)(-(.+))?$");
-        Matcher m = p.matcher(input);
-
-        if (!m.matches()) {
-            return null;
-        }
-        result.maj = Integer.parseInt(m.group(1));
-        result.min = Integer.parseInt(m.group(2));
-        result.micro = Integer.parseInt(m.group(3));
-        if (m.groupCount() == 7) {
-            result.qualifier = m.group(7);
-        } else {
-            result.qualifier = null;
-        }
-        return result;
-    }
-
-    /**
-     * Emits a org.apache.zookeeper.version.Info interface file with version and
-     * revision information constants set to the values passed in as command
-     * line parameters. The file is created in the current directory. <br>
-     * Usage: java org.apache.zookeeper.version.util.VerGen maj.min.micro[-qualifier]
-     * rev buildDate
-     *
-     * @param args
-     *            <ul>
-     *            <li>maj - major version number
-     *            <li>min - minor version number
-     *            <li>micro - minor minor version number
-     *            <li>qualifier - optional qualifier (dash followed by qualifier text)
-     *            <li>rev - current Git revision number
-     *            <li>buildDate - date the build
-     *            </ul>
-     */
-    public static void main(String[] args) {
-        if (args.length != 3)
-            printUsage();
-        try {
-            Version version = parseVersionString(args[0]);
-            if (version == null) {
-                System.err.println(
-                        "Invalid version number format, must be \"x.y.z(-.*)?\"");
-                System.exit(1);
-            }
-            String rev = args[1];
-            if (rev == null || rev.trim().isEmpty()) {
-                rev = "-1";
-            } else {
-                rev = rev.trim();
-            }
-            generateFile(new File("."), version, rev, args[2]);
-        } catch (NumberFormatException e) {
-            System.err.println(
-                    "All version-related parameters must be valid integers!");
-            throw e;
-        } catch (IOException e) {
-            System.out.println("Unable to generate version.Info file: "
-                    + e.getMessage());
-            System.exit(1);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/resources/lib/cobertura/README.txt
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/resources/lib/cobertura/README.txt b/zookeeper-common/src/main/resources/lib/cobertura/README.txt
deleted file mode 100644
index f5ba88f..0000000
--- a/zookeeper-common/src/main/resources/lib/cobertura/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Download the cobertura binary from the following location and unpack it into this directory. Run "cobertura-report" target from build.xml to generate coverage report.
-
-http://cobertura.sourceforge.net/download.html


[19/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/test-github-pr.sh
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/test-github-pr.sh b/zookeeper-common/src/test/resources/test-github-pr.sh
deleted file mode 100755
index e155769..0000000
--- a/zookeeper-common/src/test/resources/test-github-pr.sh
+++ /dev/null
@@ -1,616 +0,0 @@
-#!/usr/bin/env bash
-#   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.
-
-
-#set -x
-
-### Setup some variables.
-### GIT_COMMIT and BUILD_URL are set by Hudson if it is run by patch process
-### Read variables from properties file
-. `dirname $0`/test-patch.properties
-
-###############################################################################
-parseArgs() {
-  case "$1" in
-    QABUILD)
-      ### Set QABUILD to true to indicate that this script is being run by Hudson
-      QABUILD=true
-      if [[ $# != 14 ]] ; then
-        echo "ERROR: usage $0 QABUILD <PATCH_DIR> <PS_CMD> <WGET_CMD> <JIRACLI> <GIT_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JIRA_PASSWD> <JAVA5_HOME> <CURL_CMD>"
-        cleanupAndExit 0
-      fi
-      PATCH_DIR=$2
-      PS=$3
-      WGET=$4
-      JIRACLI=$5
-      GIT=$6
-      GREP=$7
-      PATCH=$8
-      FINDBUGS_HOME=$9
-      FORREST_HOME=${10}
-      BASEDIR=${11}
-      JIRA_PASSWD=${12}
-      JAVA5_HOME=${13}
-      CURL=${14}
-      if [ ! -e "$PATCH_DIR" ] ; then
-        mkdir -p $PATCH_DIR
-      fi
-
-      ## Obtain PR number and title
-      PULLREQUEST_ID=${GIT_PR_NUMBER}
-      PULLREQUEST_TITLE="${GIT_PR_TITLE}"
-
-      ## Extract jira number from PR title
-      local prefix=${PULLREQUEST_TITLE%ZOOKEEPER\-[0-9]*}
-      local noprefix=${PULLREQUEST_TITLE#$prefix}
-      local regex='\(ZOOKEEPER-.[0-9]*\)'
-      defect=$(expr "$noprefix" : ${regex})
-
-      echo "Pull request id: ${PULLREQUEST_ID}"
-      echo "Pull request title: ${PULLREQUEST_TITLE}"
-      echo "Defect number: ${defect}"
-
-      JIRA_COMMENT="GitHub Pull Request ${PULLREQUEST_NUMBER} Build
-      "
-      ;;
-    DEVELOPER)
-      ### Set QABUILD to false to indicate that this script is being run by a developer
-      QABUILD=false
-      if [[ $# != 10 ]] ; then
-        echo "ERROR: usage $0 DEVELOPER <GIT_PR_URL> <SCRATCH_DIR> <GIT_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JAVA5_HOME>"
-        cleanupAndExit 0
-      fi
-      PATCH_DIR=$3
-      PATCH_FILE=${PATCH_DIR}/patch
-      curl -L $2.diff > ${PATCH_FILE}
-      ### PATCH_FILE contains the location of the patchfile
-      if [[ ! -e "$PATCH_FILE" ]] ; then
-        echo "Unable to locate the patch file $PATCH_FILE"
-        cleanupAndExit 0
-      fi
-      ### Check if $PATCH_DIR exists. If it does not exist, create a new directory
-      if [[ ! -e "$PATCH_DIR" ]] ; then
-	mkdir "$PATCH_DIR"
-	if [[ $? == 0 ]] ; then
-	  echo "$PATCH_DIR has been created"
-	else
-	  echo "Unable to create $PATCH_DIR"
-	  cleanupAndExit 0
-	fi
-      fi
-      GIT=$4
-      GREP=$5
-      PATCH=$6
-      FINDBUGS_HOME=$7
-      FORREST_HOME=$8
-      BASEDIR=$9
-      JAVA5_HOME=${10}
-      ### Obtain the patch filename to append it to the version number
-      local subject=`grep "Subject:" ${PATCH_FILE}`
-      local length=`expr match ${subject} ZOOKEEPER-[0-9]*`
-      local position=`expr index ${subject} ZOOKEEPER-`
-      defect=${${subject:$position:$length}#ZOOKEEPER-}
-      ;;
-    *)
-      echo "ERROR: usage $0 QABUILD [args] | DEVELOPER [args]"
-      cleanupAndExit 0
-      ;;
-  esac
-}
-
-###############################################################################
-checkout () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Testing patch for pull request ${PULLREQUEST_ID}."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  ### When run by a developer, if the workspace contains modifications, do not continue
-  # Ref http://stackoverflow.com/a/2659808 for details on checking dirty status
-  ${GIT} diff-index --quiet HEAD
-  if [[ $? -ne 0 ]] ; then
-    uncommitted=`${GIT} diff --name-only HEAD`
-    uncommitted="You have the following files with uncommitted changes:${NEWLINE}${uncommitted}"
-  fi
-  untracked="$(${GIT} ls-files --exclude-standard --others)" && test -z "${untracked}"
-  if [[ $? -ne 0 ]] ; then
-    untracked="You have untracked and unignored files:${NEWLINE}${untracked}"
-  fi
-
-  if [[ $QABUILD == "false" ]] ; then
-    if [[ $uncommitted || $untracked ]] ; then
-      echo "ERROR: can't run in a workspace that contains the following modifications"
-      echo ""
-      echo "${uncommitted}"
-      echo ""
-      echo "${untracked}"
-      cleanupAndExit 1
-    fi
-  else
-    # I don't believe we need to do anything here - the jenkins job will
-    # cleanup the environment for us ("cleanup before checkout" action)
-    # on the precommit jenkins job
-    echo
-  fi
-  return $?
-}
-
-###############################################################################
-setup () {
-  ### exit if warnings are NOT defined in the properties file
-  if [ -z "$OK_FINDBUGS_WARNINGS" ] || [[ -z "$OK_JAVADOC_WARNINGS" ]] || [[ -z $OK_RELEASEAUDIT_WARNINGS ]]; then
-    echo "Please define the following properties in test-patch.properties file"
-	 echo  "OK_FINDBUGS_WARNINGS"
-	 echo  "OK_RELEASEAUDIT_WARNINGS"
-	 echo  "OK_JAVADOC_WARNINGS"
-    cleanupAndExit 1
-  fi
-  ### get pull request diff
-  ${CURL} -L ${GIT_PR_URL}.diff > $PATCH_DIR/patch
-
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo " Pre-build trunk to verify trunk stability and javac warnings"
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant  -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1"
- $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1
-  if [[ $? != 0 ]] ; then
-    echo "Trunk compilation is broken?"
-    cleanupAndExit 1
-  fi
-}
-
-###############################################################################
-### Check for @author tags in the patch
-checkAuthor () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Checking there are no @author tags in the patch."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  authorTags=`$GREP -c -i '@author' $PATCH_DIR/patch`
-  echo "There appear to be $authorTags @author tags in the patch."
-  if [[ $authorTags != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 @author.  The patch appears to contain $authorTags @author tags which the Zookeeper community has agreed to not allow in code contributions."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 @author.  The patch does not contain any @author tags."
-  return 0
-}
-
-###############################################################################
-### Check for tests in the patch
-checkTests () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Checking there are new or changed tests in the patch."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  testReferences=`$GREP -c -i '/test' $PATCH_DIR/patch`
-  echo "There appear to be $testReferences test files referenced in the patch."
-  if [[ $testReferences == 0 ]] ; then
-    if [[ $QABUILD == "true" ]] ; then
-      patchIsDoc=`$GREP -c -i 'title="documentation' $PATCH_DIR/jira`
-      if [[ $patchIsDoc != 0 ]] ; then
-        echo "The patch appears to be a documentation patch that doesn't require tests."
-        JIRA_COMMENT="$JIRA_COMMENT
-
-    +0 tests included.  The patch appears to be a documentation patch that doesn't require tests."
-        return 0
-      fi
-    fi
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 tests included.  The patch doesn't appear to include any new or modified tests.
-                        Please justify why no new tests are needed for this patch.
-                        Also please list what manual steps were performed to verify this patch."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 tests included.  The patch appears to include $testReferences new or modified tests."
-  return 0
-}
-
-###############################################################################
-### Check there are no javadoc warnings
-checkJavadocWarnings () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched javadoc warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt
-  javadocWarnings=`$GREP -o '\[javadoc\] [0-9]* warning' $PATCH_DIR/patchJavadocWarnings.txt | awk '{total += $2} END {print total}'`
-  echo ""
-  echo ""
-  echo "There appear to be $javadocWarnings javadoc warnings generated by the patched build."
-
-  ### if current warnings greater than OK_JAVADOC_WARNINGS
-  if [[ $javadocWarnings > $OK_JAVADOC_WARNINGS ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 javadoc.  The javadoc tool appears to have generated `expr $(($javadocWarnings-$OK_JAVADOC_WARNINGS))` warning messages."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 javadoc.  The javadoc tool did not generate any warning messages."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of Javac warnings
-checkJavacWarnings () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched javac warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1"
-  $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1
-  if [[ $? != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 javac.  The patch appears to cause tar ant target to fail."
-    return 1
-  fi
-  ### Compare trunk and patch javac warning numbers
-  if [[ -f $PATCH_DIR/patchJavacWarnings.txt ]] ; then
-    trunkJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/trunkJavacWarnings.txt | awk '{total += $2} END {print total}'`
-    patchJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/patchJavacWarnings.txt | awk '{total += $2} END {print total}'`
-    echo "There appear to be $trunkJavacWarnings javac compiler warnings before the patch and $patchJavacWarnings javac compiler warnings after applying the patch."
-    if [[ $patchJavacWarnings != "" && $trunkJavacWarnings != "" ]] ; then
-      if [[ $patchJavacWarnings -gt $trunkJavacWarnings ]] ; then
-        JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 javac.  The applied patch generated $patchJavacWarnings javac compiler warnings (more than the trunk's current $trunkJavacWarnings warnings)."
-        return 1
-      fi
-    fi
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 javac.  The applied patch does not increase the total number of javac compiler warnings."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of release audit (RAT) warnings
-checkReleaseAuditWarnings () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched release audit warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1"
-  $ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1
-
-  ### Compare trunk and patch release audit warning numbers
-  if [[ -f $PATCH_DIR/patchReleaseAuditWarnings.txt ]] ; then
-    patchReleaseAuditWarnings=`$GREP -c '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt`
-    echo ""
-    echo ""
-    echo "There appear to be $OK_RELEASEAUDIT_WARNINGS release audit warnings before the patch and $patchReleaseAuditWarnings release audit warnings after applying the patch."
-    if [[ $patchReleaseAuditWarnings != "" && $OK_RELEASEAUDIT_WARNINGS != "" ]] ; then
-      if [[ $patchReleaseAuditWarnings -gt $OK_RELEASEAUDIT_WARNINGS ]] ; then
-        JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 release audit.  The applied patch generated $patchReleaseAuditWarnings release audit warnings (more than the trunk's current $OK_RELEASEAUDIT_WARNINGS warnings)."
-        $GREP '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt > $PATCH_DIR/patchReleaseAuditProblems.txt
-        echo "Lines that start with ????? in the release audit report indicate files that do not have an Apache license header." >> $PATCH_DIR/patchReleaseAuditProblems.txt
-        JIRA_COMMENT_FOOTER="Release audit warnings: $BUILD_URL/artifact/trunk/patchprocess/patchReleaseAuditProblems.txt
-$JIRA_COMMENT_FOOTER"
-        return 1
-      fi
-    fi
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 release audit.  The applied patch does not increase the total number of release audit warnings."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of Checkstyle warnings
-checkStyle () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched checkstyle warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "THIS IS NOT IMPLEMENTED YET"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle
-  JIRA_COMMENT_FOOTER="Checkstyle results: $BUILD_URL/artifact/trunk/build/test/checkstyle-errors.html
-$JIRA_COMMENT_FOOTER"
-  ### TODO: calculate actual patchStyleErrors
-#  patchStyleErrors=0
-#  if [[ $patchStyleErrors != 0 ]] ; then
-#    JIRA_COMMENT="$JIRA_COMMENT
-#
-#    -1 checkstyle.  The patch generated $patchStyleErrors code style errors."
-#    return 1
-#  fi
-#  JIRA_COMMENT="$JIRA_COMMENT
-#
-#    +1 checkstyle.  The patch generated 0 code style errors."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of Findbugs warnings
-checkFindbugsWarnings () {
-  findbugs_version=`${FINDBUGS_HOME}/bin/findbugs -version`
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched Findbugs warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs"
-  $ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs
-  if [ $? != 0 ] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 findbugs.  The patch appears to cause Findbugs (version ${findbugs_version}) to fail."
-    return 1
-  fi
-JIRA_COMMENT_FOOTER="Findbugs warnings: $BUILD_URL/artifact/trunk/build/test/findbugs/newPatchFindbugsWarnings.html
-$JIRA_COMMENT_FOOTER"
-  cp $BASEDIR/build/test/findbugs/*.xml $PATCH_DIR/patchFindbugsWarnings.xml
-  $FINDBUGS_HOME/bin/setBugDatabaseInfo -timestamp "01/01/2000" \
-    $PATCH_DIR/patchFindbugsWarnings.xml \
-    $PATCH_DIR/patchFindbugsWarnings.xml
-  findbugsWarnings=`$FINDBUGS_HOME/bin/filterBugs -first "01/01/2000" $PATCH_DIR/patchFindbugsWarnings.xml \
-    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml | /usr/bin/awk '{print $1}'`
-  $FINDBUGS_HOME/bin/convertXmlToText -html \
-    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml \
-    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html
-  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html $PATCH_DIR/newPatchFindbugsWarnings.html
-  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml $PATCH_DIR/newPatchFindbugsWarnings.xml
-
-  ### if current warnings greater than OK_FINDBUGS_WARNINGS
-  if [[ $findbugsWarnings > $OK_FINDBUGS_WARNINGS ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 findbugs.  The patch appears to introduce `expr $(($findbugsWarnings-$OK_FINDBUGS_WARNINGS))` new Findbugs (version ${findbugs_version}) warnings."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 findbugs.  The patch does not introduce any new Findbugs (version ${findbugs_version}) warnings."
-  return 0
-}
-
-###############################################################################
-### Run the test-core target
-runCoreTests () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Running core tests."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-
-  ### Kill any rogue build processes from the last attempt
-  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
-
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dtest.junit.threads=8 -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dtest.junit.threads=8 -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core
-  if [[ $? != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 core tests.  The patch failed core unit tests."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 core tests.  The patch passed core unit tests."
-  return 0
-}
-
-###############################################################################
-### Run the test-contrib target
-runContribTests () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Running contrib tests."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-
-  ### Kill any rogue build processes from the last attempt
-  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
-
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib
-  if [[ $? != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 contrib tests.  The patch failed contrib unit tests."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 contrib tests.  The patch passed contrib unit tests."
-  return 0
-}
-
-###############################################################################
-### Submit a comment to the defect's Jira
-submitJiraComment () {
-  local result=$1
-  ### Do not output the value of JIRA_COMMENT_FOOTER when run by a developer
-  if [[  $QABUILD == "false" ]] ; then
-    JIRA_COMMENT_FOOTER=""
-  fi
-  if [[ $result == 0 ]] ; then
-    comment="+1 overall.  $JIRA_COMMENT
-
-$JIRA_COMMENT_FOOTER"
-  else
-    comment="-1 overall.  $JIRA_COMMENT
-
-$JIRA_COMMENT_FOOTER"
-  fi
-  ### Output the test result to the console
-  echo "
-
-
-
-$comment"
-
-  if [[ $QABUILD == "true" ]] ; then
-    echo ""
-    echo ""
-    echo "======================================================================"
-    echo "======================================================================"
-    echo "    Adding comment to Jira."
-    echo "======================================================================"
-    echo "======================================================================"
-    echo ""
-    echo ""
-    ### Update Jira with a comment
-    export USER=jenkins
-    $JIRACLI -s https://issues.apache.org/jira -a addcomment -u hadoopqa -p $JIRA_PASSWD --comment "$comment" --issue $defect
-    $JIRACLI -s https://issues.apache.org/jira -a logout -u hadoopqa -p $JIRA_PASSWD
-  fi
-}
-
-###############################################################################
-### Cleanup files
-cleanupAndExit () {
-  local result=$1
-  if [[ $QABUILD == "true" ]] ; then
-    if [ -e "$PATCH_DIR" ] ; then
-      mv $PATCH_DIR $BASEDIR
-    fi
-  fi
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Finished build."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  exit $result
-}
-
-###############################################################################
-###############################################################################
-###############################################################################
-
-JIRA_COMMENT=""
-JIRA_COMMENT_FOOTER="Console output: $BUILD_URL/console
-
-This message is automatically generated."
-
-### Check if arguments to the script have been specified properly or not
-echo "----- Going to parser args -----"
-parseArgs $@
-cd $BASEDIR
-
-echo "----- Parsed args, going to checkout -----"
-checkout
-RESULT=$?
-if [[ $QABUILD == "true" ]] ; then
-  if [[ $RESULT != 0 ]] ; then
-    exit 100
-  fi
-fi
-setup
-checkAuthor
-(( RESULT = RESULT + $? ))
-
-checkTests
-checkTestsResult=$?
-(( RESULT = RESULT + $checkTestsResult ))
-if [[ $checkTestsResult != 0 ]] ; then
-  submitJiraComment 1
-  cleanupAndExit 1
-fi
-checkJavadocWarnings
-(( RESULT = RESULT + $? ))
-checkJavacWarnings
-(( RESULT = RESULT + $? ))
-### Checkstyle not implemented yet
-#checkStyle
-#(( RESULT = RESULT + $? ))
-checkFindbugsWarnings
-(( RESULT = RESULT + $? ))
-checkReleaseAuditWarnings
-(( RESULT = RESULT + $? ))
-### Do not call these when run by a developer
-if [[ $QABUILD == "true" ]] ; then
-  runCoreTests
-  (( RESULT = RESULT + $? ))
-  runContribTests
-  (( RESULT = RESULT + $? ))
-fi
-JIRA_COMMENT_FOOTER="Test results: $BUILD_URL/testReport/
-$JIRA_COMMENT_FOOTER"
-
-submitJiraComment $RESULT
-cleanupAndExit $RESULT

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/test-patch.properties
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/test-patch.properties b/zookeeper-common/src/test/resources/test-patch.properties
deleted file mode 100644
index c467e63..0000000
--- a/zookeeper-common/src/test/resources/test-patch.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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.
-
-OK_RELEASEAUDIT_WARNINGS=24
-OK_FINDBUGS_WARNINGS=0
-OK_JAVADOC_WARNINGS=0

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/resources/test-patch.sh
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/resources/test-patch.sh b/zookeeper-common/src/test/resources/test-patch.sh
deleted file mode 100755
index d42789b..0000000
--- a/zookeeper-common/src/test/resources/test-patch.sh
+++ /dev/null
@@ -1,637 +0,0 @@
-#!/usr/bin/env bash
-#   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.
-
-
-#set -x
-ulimit -n 1024
-
-### Setup some variables.  
-### SVN_REVISION and BUILD_URL are set by Hudson if it is run by patch process
-### Read variables from properties file
-. `dirname $0`/test-patch.properties
-
-###############################################################################
-parseArgs() {
-  case "$1" in
-    HUDSON)
-      ### Set HUDSON to true to indicate that this script is being run by Hudson
-      HUDSON=true
-      if [[ $# != 15 ]] ; then
-        echo "ERROR: usage $0 HUDSON <PATCH_DIR> <PS_CMD> <WGET_CMD> <JIRACLI> <SVN_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JIRA_PASSWD> <JAVA5_HOME> <CURL_CMD> <DEFECT> "
-        cleanupAndExit 0
-      fi
-      PATCH_DIR=$2
-      PS=$3
-      WGET=$4
-      JIRACLI=$5
-      SVN=$6
-      GREP=$7
-      PATCH=$8
-      FINDBUGS_HOME=$9
-      FORREST_HOME=${10}
-      BASEDIR=${11}
-      JIRA_PASSWD=${12}
-      JAVA5_HOME=${13}
-      CURL=${14}
-      defect=${15}
-		
-      ### Retrieve the defect number
-      if [ -z "$defect" ] ; then
-        echo "Could not determine the patch to test.  Exiting."
-        cleanupAndExit 0
-      fi
-
-      if [ ! -e "$PATCH_DIR" ] ; then
-        mkdir -p $PATCH_DIR 
-      fi
-
-      ;;
-    DEVELOPER)
-      ### Set HUDSON to false to indicate that this script is being run by a developer
-      HUDSON=false
-      if [[ $# != 10 ]] ; then
-        echo "ERROR: usage $0 DEVELOPER <PATCH_FILE> <SCRATCH_DIR> <SVN_CMD> <GREP_CMD> <PATCH_CMD> <FINDBUGS_HOME> <FORREST_HOME> <WORKSPACE_BASEDIR> <JAVA5_HOME>"
-        cleanupAndExit 0
-      fi
-      ### PATCH_FILE contains the location of the patchfile
-      PATCH_FILE=$2 
-      if [[ ! -e "$PATCH_FILE" ]] ; then
-        echo "Unable to locate the patch file $PATCH_FILE"
-        cleanupAndExit 0
-      fi
-      PATCH_DIR=$3
-      ### Check if $PATCH_DIR exists. If it does not exist, create a new directory
-      if [[ ! -e "$PATCH_DIR" ]] ; then
-	mkdir "$PATCH_DIR"
-	if [[ $? == 0 ]] ; then 
-	  echo "$PATCH_DIR has been created"
-	else
-	  echo "Unable to create $PATCH_DIR"
-	  cleanupAndExit 0
-	fi
-      fi
-      SVN=$4
-      GREP=$5
-      PATCH=$6
-      FINDBUGS_HOME=$7
-      FORREST_HOME=$8
-      BASEDIR=$9
-      JAVA5_HOME=${10}
-      ### Obtain the patch filename to append it to the version number
-      defect=`basename $PATCH_FILE` 
-      ;;
-    *)
-      echo "ERROR: usage $0 HUDSON [args] | DEVELOPER [args]"
-      cleanupAndExit 0
-      ;;
-  esac
-}
-
-###############################################################################
-checkout () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Testing patch for ${defect}."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  ### When run by a developer, if the workspace contains modifications, do not continue
-  status=`$SVN stat --ignore-externals | sed -e '/^X[ ]*/D'`
-  if [[ $HUDSON == "false" ]] ; then
-    if [[ "$status" != "" ]] ; then
-      echo "ERROR: can't run in a workspace that contains the following modifications"
-      echo "$status"
-      cleanupAndExit 1
-    fi
-  else   
-    cd $BASEDIR
-    $SVN revert -R .
-    rm -rf `$SVN status --no-ignore`
-    $SVN update
-  fi
-  return $?
-}
-
-###############################################################################
-setup () {
-  ### Download latest patch file (ignoring .htm and .html) when run from patch process
-  if [[ $HUDSON == "true" ]] ; then
-    $WGET -q -O $PATCH_DIR/jira http://issues.apache.org/jira/browse/$defect
-    if [[ `$GREP -c 'Patch Available' $PATCH_DIR/jira` == 0 ]] ; then
-      echo "$defect is not \"Patch Available\".  Exiting."
-      cleanupAndExit 0
-    fi
-    relativePatchURL=`$GREP -o '"/jira/secure/attachment/[0-9]*/[^"]*' $PATCH_DIR/jira | $GREP -v -e 'htm[l]*$' | sort | tail -1 | $GREP -o '/jira/secure/attachment/[0-9]*/[^"]*'`
-    patchURL="http://issues.apache.org${relativePatchURL}"
-    patchNum=`echo $patchURL | $GREP -o '[0-9]*/' | $GREP -o '[0-9]*'`
-    echo "$defect patch is being downloaded at `date` from"
-    echo "$patchURL"
-    $WGET -q -O $PATCH_DIR/patch $patchURL
-    JIRA_COMMENT="Here are the results of testing the latest attachment 
-  $patchURL
-  against trunk revision ${SVN_REVISION}."
-
-  ### Copy the patch file to $PATCH_DIR
-  else
-    cp $PATCH_FILE $PATCH_DIR/patch
-    if [[ $? == 0 ]] ; then
-      echo "Patch file $PATCH_FILE copied to $PATCH_DIR"
-    else
-      echo "Could not copy $PATCH_FILE to $PATCH_DIR"
-      cleanupAndExit 0
-    fi
-  fi
-  ### exit if warnings are NOT defined in the properties file
-  if [ -z "$OK_FINDBUGS_WARNINGS" ] || [[ -z "$OK_JAVADOC_WARNINGS" ]] || [[ -z $OK_RELEASEAUDIT_WARNINGS ]]; then
-    echo "Please define the following properties in test-patch.properties file"
-	 echo  "OK_FINDBUGS_WARNINGS"
-	 echo  "OK_RELEASEAUDIT_WARNINGS"
-	 echo  "OK_JAVADOC_WARNINGS"
-    cleanupAndExit 1
-  fi
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo " Pre-build trunk to verify trunk stability and javac warnings" 
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant  -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1"
- $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/trunkJavacWarnings.txt 2>&1
-  if [[ $? != 0 ]] ; then
-    echo "Trunk compilation is broken?"
-    cleanupAndExit 1
-  fi
-}
-
-###############################################################################
-### Check for @author tags in the patch
-checkAuthor () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Checking there are no @author tags in the patch."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  authorTags=`$GREP -c -i '@author' $PATCH_DIR/patch`
-  echo "There appear to be $authorTags @author tags in the patch."
-  if [[ $authorTags != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 @author.  The patch appears to contain $authorTags @author tags which the Zookeeper community has agreed to not allow in code contributions."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 @author.  The patch does not contain any @author tags."
-  return 0
-}
-
-###############################################################################
-### Check for tests in the patch
-checkTests () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Checking there are new or changed tests in the patch."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  testReferences=`$GREP -c -i '/test' $PATCH_DIR/patch`
-  echo "There appear to be $testReferences test files referenced in the patch."
-  if [[ $testReferences == 0 ]] ; then
-    if [[ $HUDSON == "true" ]] ; then
-      patchIsDoc=`$GREP -c -i 'title="documentation' $PATCH_DIR/jira`
-      if [[ $patchIsDoc != 0 ]] ; then
-        echo "The patch appears to be a documentation patch that doesn't require tests."
-        JIRA_COMMENT="$JIRA_COMMENT
-
-    +0 tests included.  The patch appears to be a documentation patch that doesn't require tests."
-        return 0
-      fi
-    fi
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 tests included.  The patch doesn't appear to include any new or modified tests.
-                        Please justify why no new tests are needed for this patch.
-                        Also please list what manual steps were performed to verify this patch."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 tests included.  The patch appears to include $testReferences new or modified tests."
-  return 0
-}
-
-###############################################################################
-### Attempt to apply the patch
-applyPatch () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Applying patch."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  $PATCH -E -p0 < $PATCH_DIR/patch
-  if [[ $? != 0 ]] ; then
-    echo "PATCH APPLICATION FAILED"
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 patch.  The patch command could not apply the patch."
-    return 1
-  fi
-  return 0
-}
-
-###############################################################################
-### Check there are no javadoc warnings
-checkJavadocWarnings () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched javadoc warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= clean javadoc | tee $PATCH_DIR/patchJavadocWarnings.txt
-  javadocWarnings=`$GREP -o '\[javadoc\] [0-9]* warning' $PATCH_DIR/patchJavadocWarnings.txt | awk '{total += $2} END {print total}'`
-  echo ""
-  echo ""
-  echo "There appear to be $javadocWarnings javadoc warnings generated by the patched build."
-
-  ### if current warnings greater than OK_JAVADOC_WARNINGS
-  if [[ $javadocWarnings > $OK_JAVADOC_WARNINGS ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 javadoc.  The javadoc tool appears to have generated `expr $(($javadocWarnings-$OK_JAVADOC_WARNINGS))` warning messages."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 javadoc.  The javadoc tool did not generate any warning messages."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of Javac warnings
-checkJavacWarnings () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched javac warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1"
-  $ANT_HOME/bin/ant -Djavac.args="-Xlint -Xmaxwarns 1000" -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= clean tar > $PATCH_DIR/patchJavacWarnings.txt 2>&1
-  if [[ $? != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 javac.  The patch appears to cause tar ant target to fail."
-    return 1
-  fi
-  ### Compare trunk and patch javac warning numbers
-  if [[ -f $PATCH_DIR/patchJavacWarnings.txt ]] ; then
-    trunkJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/trunkJavacWarnings.txt | awk '{total += $2} END {print total}'`
-    patchJavacWarnings=`$GREP -o '\[javac\] [0-9]* warning' $PATCH_DIR/patchJavacWarnings.txt | awk '{total += $2} END {print total}'`
-    echo "There appear to be $trunkJavacWarnings javac compiler warnings before the patch and $patchJavacWarnings javac compiler warnings after applying the patch."
-    if [[ $patchJavacWarnings != "" && $trunkJavacWarnings != "" ]] ; then
-      if [[ $patchJavacWarnings -gt $trunkJavacWarnings ]] ; then
-        JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 javac.  The applied patch generated $patchJavacWarnings javac compiler warnings (more than the trunk's current $trunkJavacWarnings warnings)."
-        return 1
-      fi
-    fi
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 javac.  The applied patch does not increase the total number of javac compiler warnings."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of release audit (RAT) warnings
-checkReleaseAuditWarnings () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched release audit warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1"
-  $ANT_HOME/bin/ant -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= releaseaudit > $PATCH_DIR/patchReleaseAuditWarnings.txt 2>&1
-
-  ### Compare trunk and patch release audit warning numbers
-  if [[ -f $PATCH_DIR/patchReleaseAuditWarnings.txt ]] ; then
-    patchReleaseAuditWarnings=`$GREP -c '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt`
-    echo ""
-    echo ""
-    echo "There appear to be $OK_RELEASEAUDIT_WARNINGS release audit warnings before the patch and $patchReleaseAuditWarnings release audit warnings after applying the patch."
-    if [[ $patchReleaseAuditWarnings != "" && $OK_RELEASEAUDIT_WARNINGS != "" ]] ; then
-      if [[ $patchReleaseAuditWarnings -gt $OK_RELEASEAUDIT_WARNINGS ]] ; then
-        JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 release audit.  The applied patch generated $patchReleaseAuditWarnings release audit warnings (more than the trunk's current $OK_RELEASEAUDIT_WARNINGS warnings)."
-        $GREP '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt > $PATCH_DIR/patchReleaseAuditProblems.txt
-        echo "Lines that start with ????? in the release audit report indicate files that do not have an Apache license header." >> $PATCH_DIR/patchReleaseAuditProblems.txt
-        JIRA_COMMENT_FOOTER="Release audit warnings: $BUILD_URL/artifact/trunk/patchprocess/patchReleaseAuditProblems.txt
-$JIRA_COMMENT_FOOTER"
-        return 1
-      fi
-    fi
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 release audit.  The applied patch does not increase the total number of release audit warnings."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of Checkstyle warnings
-checkStyle () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched checkstyle warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "THIS IS NOT IMPLEMENTED YET"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= checkstyle
-  JIRA_COMMENT_FOOTER="Checkstyle results: $BUILD_URL/artifact/trunk/build/test/checkstyle-errors.html
-$JIRA_COMMENT_FOOTER"
-  ### TODO: calculate actual patchStyleErrors
-#  patchStyleErrors=0
-#  if [[ $patchStyleErrors != 0 ]] ; then
-#    JIRA_COMMENT="$JIRA_COMMENT
-#
-#    -1 checkstyle.  The patch generated $patchStyleErrors code style errors."
-#    return 1
-#  fi
-#  JIRA_COMMENT="$JIRA_COMMENT
-#
-#    +1 checkstyle.  The patch generated 0 code style errors."
-  return 0
-}
-
-###############################################################################
-### Check there are no changes in the number of Findbugs warnings
-checkFindbugsWarnings () {
-  findbugs_version=`${FINDBUGS_HOME}/bin/findbugs -version`
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Determining number of patched Findbugs warnings."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  echo "$ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs"
-  $ANT_HOME/bin/ant -Dfindbugs.home=$FINDBUGS_HOME -Djava5.home=${JAVA5_HOME} -Dforrest.home=${FORREST_HOME} -DZookeeperPatchProcess= findbugs
-  if [ $? != 0 ] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 findbugs.  The patch appears to cause Findbugs (version ${findbugs_version}) to fail."
-    return 1
-  fi
-JIRA_COMMENT_FOOTER="Findbugs warnings: $BUILD_URL/artifact/trunk/build/test/findbugs/newPatchFindbugsWarnings.html
-$JIRA_COMMENT_FOOTER"
-  cp $BASEDIR/build/test/findbugs/*.xml $PATCH_DIR/patchFindbugsWarnings.xml
-  $FINDBUGS_HOME/bin/setBugDatabaseInfo -timestamp "01/01/2000" \
-    $PATCH_DIR/patchFindbugsWarnings.xml \
-    $PATCH_DIR/patchFindbugsWarnings.xml
-  findbugsWarnings=`$FINDBUGS_HOME/bin/filterBugs -first "01/01/2000" $PATCH_DIR/patchFindbugsWarnings.xml \
-    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml | /usr/bin/awk '{print $1}'`
-  $FINDBUGS_HOME/bin/convertXmlToText -html \
-    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml \
-    $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html
-  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.html $PATCH_DIR/newPatchFindbugsWarnings.html
-  cp $BASEDIR/build/test/findbugs/newPatchFindbugsWarnings.xml $PATCH_DIR/newPatchFindbugsWarnings.xml
-
-  ### if current warnings greater than OK_FINDBUGS_WARNINGS
-  if [[ $findbugsWarnings > $OK_FINDBUGS_WARNINGS ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 findbugs.  The patch appears to introduce `expr $(($findbugsWarnings-$OK_FINDBUGS_WARNINGS))` new Findbugs (version ${findbugs_version}) warnings."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 findbugs.  The patch does not introduce any new Findbugs (version ${findbugs_version}) warnings."
-  return 0
-}
-
-###############################################################################
-### Run the test-core target
-runCoreTests () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Running core tests."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  
-  ### Kill any rogue build processes from the last attempt
-  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
-
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME -Djava5.home=$JAVA5_HOME test-core
-  if [[ $? != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 core tests.  The patch failed core unit tests."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 core tests.  The patch passed core unit tests."
-  return 0
-}
-
-###############################################################################
-### Run the test-contrib target
-runContribTests () {
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Running contrib tests."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-
-  ### Kill any rogue build processes from the last attempt
-  $PS auxwww | $GREP ZookeeperPatchProcess | /usr/bin/nawk '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
-
-  echo "$ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib"
-  $ANT_HOME/bin/ant -DZookeeperPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=yes test-contrib
-  if [[ $? != 0 ]] ; then
-    JIRA_COMMENT="$JIRA_COMMENT
-
-    -1 contrib tests.  The patch failed contrib unit tests."
-    return 1
-  fi
-  JIRA_COMMENT="$JIRA_COMMENT
-
-    +1 contrib tests.  The patch passed contrib unit tests."
-  return 0
-}
-
-###############################################################################
-### Submit a comment to the defect's Jira
-submitJiraComment () {
-  local result=$1
-  ### Do not output the value of JIRA_COMMENT_FOOTER when run by a developer
-  if [[  $HUDSON == "false" ]] ; then
-    JIRA_COMMENT_FOOTER=""
-  fi
-  if [[ $result == 0 ]] ; then
-    comment="+1 overall.  $JIRA_COMMENT
-
-$JIRA_COMMENT_FOOTER"
-  else
-    comment="-1 overall.  $JIRA_COMMENT
-
-$JIRA_COMMENT_FOOTER"
-  fi
-  ### Output the test result to the console
-  echo "
-
-
-
-$comment"  
-
-  if [[ $HUDSON == "true" ]] ; then
-    echo ""
-    echo ""
-    echo "======================================================================"
-    echo "======================================================================"
-    echo "    Adding comment to Jira."
-    echo "======================================================================"
-    echo "======================================================================"
-    echo ""
-    echo ""
-    ### Update Jira with a comment
-    export USER=hudson
-    $JIRACLI -s https://issues.apache.org/jira -a addcomment -u hadoopqa -p $JIRA_PASSWD --comment "$comment" --issue $defect
-    $JIRACLI -s https://issues.apache.org/jira -a logout -u hadoopqa -p $JIRA_PASSWD
-  fi
-}
-
-###############################################################################
-### Cleanup files
-cleanupAndExit () {
-  local result=$1
-  if [[ $HUDSON == "true" ]] ; then
-    if [ -e "$PATCH_DIR" ] ; then
-      mv $PATCH_DIR $BASEDIR
-    fi
-  fi
-  echo ""
-  echo ""
-  echo "======================================================================"
-  echo "======================================================================"
-  echo "    Finished build."
-  echo "======================================================================"
-  echo "======================================================================"
-  echo ""
-  echo ""
-  exit $result
-}
-
-###############################################################################
-###############################################################################
-###############################################################################
-
-JIRA_COMMENT=""
-JIRA_COMMENT_FOOTER="Console output: $BUILD_URL/console
-
-This message is automatically generated."
-
-### Check if arguments to the script have been specified properly or not
-parseArgs $@
-cd $BASEDIR
-
-checkout
-RESULT=$?
-if [[ $HUDSON == "true" ]] ; then
-  if [[ $RESULT != 0 ]] ; then
-    exit 100
-  fi
-fi
-setup
-checkAuthor
-RESULT=$?
-
-checkTests
-(( RESULT = RESULT + $? ))
-applyPatch
-if [[ $? != 0 ]] ; then
-  submitJiraComment 1
-  cleanupAndExit 1
-fi
-checkJavadocWarnings
-(( RESULT = RESULT + $? ))
-checkJavacWarnings
-(( RESULT = RESULT + $? ))
-### Checkstyle not implemented yet
-#checkStyle
-#(( RESULT = RESULT + $? ))
-checkFindbugsWarnings
-(( RESULT = RESULT + $? ))
-checkReleaseAuditWarnings
-(( RESULT = RESULT + $? ))
-### Do not call these when run by a developer 
-if [[ $HUDSON == "true" ]] ; then
-  runCoreTests
-  (( RESULT = RESULT + $? ))
-  runContribTests
-  (( RESULT = RESULT + $? ))
-fi
-JIRA_COMMENT_FOOTER="Test results: $BUILD_URL/testReport/
-$JIRA_COMMENT_FOOTER"
-
-submitJiraComment $RESULT
-cleanupAndExit $RESULT

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-contrib/build-contrib.xml
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/build-contrib.xml b/zookeeper-contrib/build-contrib.xml
index a30abd6..7f08a8a 100644
--- a/zookeeper-contrib/build-contrib.xml
+++ b/zookeeper-contrib/build-contrib.xml
@@ -30,7 +30,7 @@
   <property name="src.dir"  location="${root}/src/main/java"/>
   <property name="src.test" location="${root}/src/test"/>
 
-  <property name="lib.dir"  location="${zk.root}/zookeeper-common/src/main/resources/lib"/>
+  <property name="lib.dir"  location="${zk.root}/zookeeper-server/src/main/resources/lib"/>
 
   <property name="build.dir" location="${zk.root}/build/contrib/${name}"/>
   <property name="build.classes" location="${build.dir}/classes"/>
@@ -83,7 +83,7 @@
     <fileset dir="${ivy.test.lib}">
       <include name="**/*.jar" />
     </fileset>
-    <fileset dir="${zk.root}/zookeeper-common/src/main/resources/lib">
+    <fileset dir="${zk.root}/zookeeper-server/src/main/resources/lib">
       <include name="**/*.jar" />
     </fileset>
     <fileset dir="${ant.home}/lib">

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-contrib/zookeeper-contrib-fatjar/build.xml
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-fatjar/build.xml b/zookeeper-contrib/zookeeper-contrib-fatjar/build.xml
index 9d510e4..279cb22 100644
--- a/zookeeper-contrib/zookeeper-contrib-fatjar/build.xml
+++ b/zookeeper-contrib/zookeeper-contrib-fatjar/build.xml
@@ -47,7 +47,7 @@
       <fileset dir="${zk.root}/build/test/classes"/>
       <zipgroupfileset dir="${zk.root}/build/lib" includes="*.jar" />
       <zipgroupfileset dir="${zk.root}/build/test/lib" includes="*.jar" />
-      <zipgroupfileset dir="${zk.root}/zookeeper-common/src/main/resources/lib" includes="*.jar" />
+      <zipgroupfileset dir="${zk.root}/zookeeper-server/src/main/resources/lib" includes="*.jar" />
     </jar>
   </target>
 

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-contrib/zookeeper-contrib-rest/build.xml
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-rest/build.xml b/zookeeper-contrib/zookeeper-contrib-rest/build.xml
index 50186ed..6895ad1 100644
--- a/zookeeper-contrib/zookeeper-contrib-rest/build.xml
+++ b/zookeeper-contrib/zookeeper-contrib-rest/build.xml
@@ -158,7 +158,7 @@
         <fileset dir="${build.dir}/lib" includes="*.jar"/>
         <fileset dir="${zk.root}/build" includes="zookeeper-*.jar"/>
         <pathelement path="${zk.root}/src/contrib/${name}/conf" />
-        <fileset dir="${zk.root}/zookeeper-common/src/main/resources/lib">
+        <fileset dir="${zk.root}/zookeeper-server/src/main/resources/lib">
           <include name="**/*.jar" />
         </fileset>
       </classpath>
@@ -173,7 +173,7 @@
         <tarfileset file="${build.dir}/zookeeper-*-rest.jar" />
         <tarfileset dir="${zk.root}/build" includes="zookeeper-*.jar" prefix="lib" />
         <tarfileset dir="${zk.root}/src/contrib/${name}/conf" prefix="conf" />
-        <tarfileset dir="${zk.root}/zookeeper-common/src/main/resources/lib" prefix="lib" includes="**/*.jar" />
+        <tarfileset dir="${zk.root}/zookeeper-server/src/main/resources/lib" prefix="lib" includes="**/*.jar" />
         <tarfileset file="${zk.root}/src/contrib/${name}/rest.sh" />
       </param.listofitems>
     </macro_tar>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-contrib/zookeeper-contrib-rest/src/test/zkServer.sh
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-rest/src/test/zkServer.sh b/zookeeper-contrib/zookeeper-contrib-rest/src/test/zkServer.sh
index 6299279..4279d34 100755
--- a/zookeeper-contrib/zookeeper-contrib-rest/src/test/zkServer.sh
+++ b/zookeeper-contrib/zookeeper-contrib-rest/src/test/zkServer.sh
@@ -62,7 +62,7 @@ do
     CLASSPATH="$CLASSPATH:$i"
 done
 
-for i in "${zk_base}"/zookeeper-common/src/main/resource/lib/*.jar
+for i in "${zk_base}"/zookeeper-server/src/main/resource/lib/*.jar
 do
     CLASSPATH="$CLASSPATH:$i"
 done

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-contrib/zookeeper-contrib-zkpython/src/test/zkServer.sh
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zkpython/src/test/zkServer.sh b/zookeeper-contrib/zookeeper-contrib-zkpython/src/test/zkServer.sh
index 35b348e..74ead8c 100755
--- a/zookeeper-contrib/zookeeper-contrib-zkpython/src/test/zkServer.sh
+++ b/zookeeper-contrib/zookeeper-contrib-zkpython/src/test/zkServer.sh
@@ -47,7 +47,7 @@ do
     CLASSPATH="$CLASSPATH:$i"
 done
 
-for i in "${zk_base}"/zookeeper-common/src/main/resource/lib/*.jar
+for i in "${zk_base}"/zookeeper-server/src/main/resource/lib/*.jar
 do
     CLASSPATH="$CLASSPATH:$i"
 done

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-recipes/build-recipes.xml
----------------------------------------------------------------------
diff --git a/zookeeper-recipes/build-recipes.xml b/zookeeper-recipes/build-recipes.xml
index 651b3d3..6804adc 100644
--- a/zookeeper-recipes/build-recipes.xml
+++ b/zookeeper-recipes/build-recipes.xml
@@ -72,7 +72,7 @@
     <fileset dir="${zk.root}/build/test/lib">
       <include name="**/*.jar"/>
     </fileset>
-    <fileset dir="${zk.root}/zookeeper-common/src/main/resources/lib">
+    <fileset dir="${zk.root}/zookeeper-server/src/main/resources/lib">
       <include name="**/*.jar" />
     </fileset>
   </path>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/tests/zkServer.sh
----------------------------------------------------------------------
diff --git a/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/tests/zkServer.sh b/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/tests/zkServer.sh
index b152380..4836612 100755
--- a/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/tests/zkServer.sh
+++ b/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/tests/zkServer.sh
@@ -51,7 +51,7 @@ do
     CLASSPATH="$CLASSPATH:$i"
 done
 
-for i in "${base_dir}"/zookeeper-common/src/main/resource/lib/*.jar
+for i in "${base_dir}"/zookeeper-server/src/main/resource/lib/*.jar
 do
     CLASSPATH="$CLASSPATH:$i"
 done

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/tests/zkServer.sh
----------------------------------------------------------------------
diff --git a/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/tests/zkServer.sh b/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/tests/zkServer.sh
index b152380..4836612 100755
--- a/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/tests/zkServer.sh
+++ b/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/tests/zkServer.sh
@@ -51,7 +51,7 @@ do
     CLASSPATH="$CLASSPATH:$i"
 done
 
-for i in "${base_dir}"/zookeeper-common/src/main/resource/lib/*.jar
+for i in "${base_dir}"/zookeeper-server/src/main/resource/lib/*.jar
 do
     CLASSPATH="$CLASSPATH:$i"
 done

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/AsyncCallback.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/AsyncCallback.java b/zookeeper-server/src/main/java/org/apache/zookeeper/AsyncCallback.java
new file mode 100644
index 0000000..f02a824
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/AsyncCallback.java
@@ -0,0 +1,309 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper;
+
+import java.util.List;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+/**
+ * Interface definitions of asynchronous callbacks.
+ * An asynchronous callback is deferred to invoke after a function returns.
+ * Asynchronous calls usually improve system efficiency on IO-related APIs.
+ * <p/>
+ * ZooKeeper provides asynchronous version as equivalent to synchronous APIs.
+ */
+@InterfaceAudience.Public
+public interface AsyncCallback {
+
+    /**
+     * This callback is used to retrieve the stat of the node.
+     */
+    @InterfaceAudience.Public
+    interface StatCallback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * <p/>
+         * On success, rc is
+         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
+         * <p/>
+         * On failure, rc is set to the corresponding failure code in
+         * {@link org.apache.zookeeper.KeeperException}.
+         * <ul>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
+         * - The node on given path doesn't exist for some API calls.
+         * </li>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#BADVERSION}
+         * - The given version doesn't match the node's version
+         * for some API calls.
+         * </li>
+         * </ul>
+         *
+         * @param rc   The return code or the result of the call.
+         * @param path The path that we passed to asynchronous calls.
+         * @param ctx  Whatever context object that we passed to
+         *             asynchronous calls.
+         * @param stat {@link org.apache.zookeeper.data.Stat} object of
+         *             the node on given path.
+         */
+        public void processResult(int rc, String path, Object ctx, Stat stat);
+    }
+
+    /**
+     * This callback is used to retrieve the data and stat of the node.
+     */
+    @InterfaceAudience.Public
+    interface DataCallback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * <p/>
+         * On success, rc is
+         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
+         * <p/>
+         * On failure, rc is set to the corresponding failure code in
+         * {@link org.apache.zookeeper.KeeperException}.
+         * <ul>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
+         * - The node on given path doesn't exist for some API calls.
+         * </li>
+         * </ul>
+         *
+         * @param rc   The return code or the result of the call.
+         * @param path The path that we passed to asynchronous calls.
+         * @param ctx  Whatever context object that we passed to
+         *             asynchronous calls.
+         * @param data The {@link org.apache.zookeeper.server.DataNode#data}
+         *             of the node.
+         * @param stat {@link org.apache.zookeeper.data.Stat} object of
+         *             the node on given path.
+         */
+        public void processResult(int rc, String path, Object ctx, byte data[],
+                Stat stat);
+    }
+
+    /**
+     * This callback is used to retrieve the ACL and stat of the node.
+     */
+    @InterfaceAudience.Public
+    interface ACLCallback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * <p/>
+         * On success, rc is
+         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
+         * <p/>
+         * On failure, rc is set to the corresponding failure code in
+         * {@link org.apache.zookeeper.KeeperException}.
+         * <ul>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
+         * - The node on given path doesn't exist for some API calls.
+         * </li>
+         * </ul>
+         *
+         * @param rc   The return code or the result of the call.
+         * @param path The path that we passed to asynchronous calls.
+         * @param ctx  Whatever context object that we passed to
+         *             asynchronous calls.
+         * @param acl  ACL Id in
+         *             {@link org.apache.zookeeper.ZooDefs.Ids}.
+         * @param stat {@link org.apache.zookeeper.data.Stat} object of
+         *             the node on given path.
+         */
+        public void processResult(int rc, String path, Object ctx,
+                List<ACL> acl, Stat stat);
+    }
+
+    /**
+     * This callback is used to retrieve the children of the node.
+     */
+    @InterfaceAudience.Public
+    interface ChildrenCallback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * <p/>
+         * On success, rc is
+         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
+         * <p/>
+         * On failure, rc is set to the corresponding failure code in
+         * {@link org.apache.zookeeper.KeeperException}.
+         * <ul>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
+         * - The node on given path doesn't exist for some API calls.
+         * </li>
+         * </ul>
+         *
+         * @param rc       The return code or the result of the call.
+         * @param path     The path that we passed to asynchronous calls.
+         * @param ctx      Whatever context object that we passed to
+         *                 asynchronous calls.
+         * @param children An unordered array of children of the node on
+         *                 given path.
+         */
+        public void processResult(int rc, String path, Object ctx,
+                List<String> children);
+    }
+
+    /**
+     * This callback is used to retrieve the children and stat of the node.
+     */
+    @InterfaceAudience.Public
+    interface Children2Callback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * See {@link org.apache.zookeeper.AsyncCallback.ChildrenCallback}.
+         *
+         * @param rc       The return code or the result of the call.
+         * @param path     The path that we passed to asynchronous calls.
+         * @param ctx      Whatever context object that we passed to
+         *                 asynchronous calls.
+         * @param children An unordered array of children of the node on
+         *                 given path.
+         * @param stat     {@link org.apache.zookeeper.data.Stat} object of
+         *                 the node on given path.
+         */
+        public void processResult(int rc, String path, Object ctx,
+                List<String> children, Stat stat);
+    }
+
+    /**
+     * This callback is used to retrieve the name of the node.
+     */
+    @InterfaceAudience.Public
+    interface StringCallback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * <p/>
+         * On success, rc is
+         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
+         * <p/>
+         * On failure, rc is set to the corresponding failure code in
+         * {@link org.apache.zookeeper.KeeperException}.
+         * <ul>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NODEEXISTS}
+         * - The node on give path already exists for some API calls.
+         * </li>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
+         * - The node on given path doesn't exist for some API calls.
+         * </li>
+         * <li>
+         * {@link
+         * org.apache.zookeeper.KeeperException.Code#NOCHILDRENFOREPHEMERALS}
+         * - an ephemeral node cannot have children. There is discussion in
+         * community. It might be changed in the future.
+         * </li>
+         * </ul>
+         *
+         * @param rc   The return code or the result of the call.
+         * @param path The path that we passed to asynchronous calls.
+         * @param ctx  Whatever context object that we passed to
+         *             asynchronous calls.
+         * @param name The name of the Znode that was created.
+         *             On success, <i>name</i> and <i>path</i> are usually
+         *             equal, unless a sequential node has been created.
+         */
+        public void processResult(int rc, String path, Object ctx, String name);
+    }
+
+    /**
+     * This callback doesn't retrieve anything from the node. It is useful
+     * for some APIs that doesn't want anything sent back, e.g. {@link
+     * org.apache.zookeeper.ZooKeeper#sync(String,
+     * org.apache.zookeeper.AsyncCallback.VoidCallback, Object)}.
+     */
+    @InterfaceAudience.Public
+    interface VoidCallback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * <p/>
+         * On success, rc is
+         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
+         * <p/>
+         * On failure, rc is set to the corresponding failure code in
+         * {@link org.apache.zookeeper.KeeperException}.
+         * <ul>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NONODE}
+         * - The node on given path doesn't exist for some API calls.
+         * </li>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#BADVERSION}
+         * - The given version doesn't match the node's version
+         * for some API calls.
+         * </li>
+         * <li>
+         * {@link org.apache.zookeeper.KeeperException.Code#NOTEMPTY}
+         * - the node has children and some API calls cannnot succeed,
+         * e.g. {@link
+         * org.apache.zookeeper.ZooKeeper#delete(String, int,
+         * org.apache.zookeeper.AsyncCallback.VoidCallback, Object)}.
+         * </li>
+         * </ul>
+         *
+         * @param rc   The return code or the result of the call.
+         * @param path The path that we passed to asynchronous calls.
+         * @param ctx  Whatever context object that we passed to
+         *             asynchronous calls.
+         */
+        public void processResult(int rc, String path, Object ctx);
+    }
+
+    /**
+     * This callback is used to process the multiple results from
+     * a single multi call.
+     * See {@link org.apache.zookeeper.ZooKeeper#multi} for more information.
+     * @since 3.4.7
+     */
+    @InterfaceAudience.Public
+    interface MultiCallback extends AsyncCallback {
+        /**
+         * Process the result of the asynchronous call.
+         * <p/>
+         * On success, rc is
+         * {@link org.apache.zookeeper.KeeperException.Code#OK}.
+         * All opResults are
+         * non-{@link org.apache.zookeeper.OpResult.ErrorResult},
+         *
+         * <p/>
+         * On failure, rc is a failure code in
+         * {@link org.apache.zookeeper.KeeperException.Code}.
+         * All opResults are
+         * {@link org.apache.zookeeper.OpResult.ErrorResult}.
+         * All operations will be rollback-ed even if operations
+         * before the failing one were successful.
+         *
+         * @param rc   The return code or the result of the call.
+         * @param path The path that we passed to asynchronous calls.
+         * @param ctx  Whatever context object that we passed to
+         *             asynchronous calls.
+         * @param opResults The list of results.
+         *                  One result for each operation,
+         *                  and the order matches that of input.
+         */
+        public void processResult(int rc, String path, Object ctx,
+                List<OpResult> opResults);
+    }
+}


[25/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerTest.java
deleted file mode 100644
index fa6b4a3..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.quorum.Leader;
-import org.apache.zookeeper.server.quorum.LearnerHandler;
-import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FollowerTest extends ZKTestCase {
-    private static final Logger LOG = LoggerFactory.getLogger(FollowerTest.class);
-    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
-
-    volatile int counter = 0;
-    volatile int errors = 0;
-
-    /** 
-     * See ZOOKEEPER-790 for details 
-     * */
-    @Test
-    public void testFollowersStartAfterLeader() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        CountdownWatcher watcher = new CountdownWatcher();
-        qu.startQuorum();
-        
-        int index = 1;
-        while(qu.getPeer(index).peer.leader == null) {
-            index++;
-        }
-        
-        ZooKeeper zk = new ZooKeeper(
-                "127.0.0.1:" + qu.getPeer((index == 1)?2:1).peer.getClientPort(),
-                ClientBase.CONNECTION_TIMEOUT, watcher);
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-        
-        // break the quorum
-        qu.shutdown(index);
-
-        // Wait until we disconnect to proceed
-        watcher.waitForDisconnected(CONNECTION_TIMEOUT);
-        
-        // try to reestablish the quorum
-        qu.start(index);
-
-        try{
-            watcher.waitForConnected(30000);      
-        } catch(TimeoutException e) {
-            Assert.fail("client could not connect to reestablished quorum: giving up after 30+ seconds.");
-        }
-
-        zk.close();
-
-        qu.tearDown();
-    }
-
-    // skip superhammer and clientcleanup as they are too expensive for quorum
-    
-    /**
-     * Tests if a multiop submitted to a non-leader propagates to the leader properly
-     * (see ZOOKEEPER-1124).
-     * 
-     * The test works as follows. It has a client connect to a follower and submit a multiop
-     * to the follower. It then verifies that the multiop successfully gets committed by the leader.
-     *
-     * Without the fix in ZOOKEEPER-1124, this fails with a ConnectionLoss KeeperException.
-     */
-    @Test
-    public void testMultiToFollower() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        CountdownWatcher watcher = new CountdownWatcher();
-        qu.startQuorum();
-        
-        int index = 1;
-        while(qu.getPeer(index).peer.leader == null) {
-            index++;
-        }
-        
-        ZooKeeper zk = new ZooKeeper(
-                "127.0.0.1:" + qu.getPeer((index == 1)?2:1).peer.getClientPort(),
-                ClientBase.CONNECTION_TIMEOUT, watcher);
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-        
-        List<OpResult> results = new ArrayList<OpResult>();
-
-        results = zk.multi(Arrays.asList(
-                Op.create("/multi0", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.create("/multi1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.create("/multi2", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
-                ));
-        zk.getData("/multi0", false, null);
-        zk.getData("/multi1", false, null);
-        zk.getData("/multi2", false, null);
-
-        zk.close();
-
-        qu.tearDown();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
deleted file mode 100644
index 49d90f7..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.TestableZooKeeper;
-import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class FourLetterWordsQuorumTest extends QuorumBase {
-    protected static final Logger LOG =
-        LoggerFactory.getLogger(FourLetterWordsQuorumTest.class);
-
-    /** Test the various four letter words */
-    @Test
-    public void testFourLetterWords() throws Exception {
-        String servers[] = hostPort.split(",");
-        for (String hp : servers) {
-            verify(hp, "ruok", "imok");
-            verify(hp, "envi", "java.version");
-            verify(hp, "conf", "clientPort");
-            verify(hp, "stat", "Outstanding");
-            verify(hp, "srvr", "Outstanding");
-            verify(hp, "cons", "queued");
-            verify(hp, "dump", "Session");
-            verify(hp, "wchs", "watches");
-            verify(hp, "wchp", "");
-            verify(hp, "wchc", "");
-
-            verify(hp, "srst", "reset");
-            verify(hp, "crst", "reset");
-
-            verify(hp, "stat", "Outstanding");
-            verify(hp, "srvr", "Outstanding");
-            verify(hp, "cons", "queued");
-
-            TestableZooKeeper zk = createClient(hp);
-            String sid = getHexSessionId(zk.getSessionId());
-
-            verify(hp, "stat", "queued");
-            verify(hp, "srvr", "Outstanding");
-            verify(hp, "cons", sid);
-            verify(hp, "dump", sid);
-
-            zk.getData("/", true, null);
-
-            verify(hp, "stat", "queued");
-            verify(hp, "srvr", "Outstanding");
-            verify(hp, "cons", sid);
-            verify(hp, "dump", sid);
-            verify(hp, "wchs", "watching 1");
-            verify(hp, "wchp", sid);
-            verify(hp, "wchc", sid);
-
-            zk.close();
-
-            verify(hp, "ruok", "imok");
-            verify(hp, "envi", "java.version");
-            verify(hp, "conf", "clientPort");
-            verify(hp, "stat", "Outstanding");
-            verify(hp, "srvr", "Outstanding");
-            verify(hp, "cons", "queued");
-            verify(hp, "dump", "Session");
-            verify(hp, "wchs", "watch");
-            verify(hp, "wchp", "");
-            verify(hp, "wchc", "");
-
-            verify(hp, "srst", "reset");
-            verify(hp, "crst", "reset");
-
-            verify(hp, "stat", "Outstanding");
-            verify(hp, "srvr", "Outstanding");
-            verify(hp, "cons", "queued");
-
-            verify(hp, "mntr", "zk_version\t");
-        }
-    }
-
-    private void verify(String hp, String cmd, String expected)
-        throws IOException
-    {
-        for(HostPort hpobj: parseHostPortList(hp)) {
-            String resp = send4LetterWord(hpobj.host, hpobj.port, cmd);
-            LOG.info("cmd " + cmd + " expected " + expected + " got " + resp);
-            if (cmd.equals("dump")) {
-                Assert.assertTrue(resp.contains(expected)
-                        || resp.contains("Sessions with Ephemerals"));
-            } else {
-                Assert.assertTrue(resp.contains(expected));
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java
deleted file mode 100644
index bc8d071..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsTest.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.regex.Pattern;
-
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.common.IOUtils;
-import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.Timeout;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FourLetterWordsTest extends ClientBase {
-    protected static final Logger LOG =
-        LoggerFactory.getLogger(FourLetterWordsTest.class);
-
-    @Rule
-    public Timeout timeout = new Timeout(30000);
-
-    /** Test the various four letter words */
-    @Test
-    public void testFourLetterWords() throws Exception {
-        verify("ruok", "imok");
-        verify("envi", "java.version");
-        verify("conf", "clientPort");
-        verify("stat", "Outstanding");
-        verify("srvr", "Outstanding");
-        verify("cons", "queued");
-        verify("dump", "Session");
-        verify("wchs", "watches");
-        verify("wchp", "");
-        verify("wchc", "");
-
-        verify("srst", "reset");
-        verify("crst", "reset");
-
-        verify("stat", "Outstanding");
-        verify("srvr", "Outstanding");
-        verify("cons", "queued");
-
-        TestableZooKeeper zk = createClient();
-        String sid = getHexSessionId(zk.getSessionId());
-
-        verify("stat", "queued");
-        verify("srvr", "Outstanding");
-        verify("cons", sid);
-        verify("dump", sid);
-
-        zk.getData("/", true, null);
-
-        verify("stat", "queued");
-        verify("srvr", "Outstanding");
-        verify("cons", sid);
-        verify("dump", sid);
-
-        verify("wchs", "watching 1");
-        verify("wchp", sid);
-        verify("wchc", sid);
-        zk.close();
-
-        verify("ruok", "imok");
-        verify("envi", "java.version");
-        verify("conf", "clientPort");
-        verify("stat", "Outstanding");
-        verify("srvr", "Outstanding");
-        verify("cons", "queued");
-        verify("dump", "Session");
-        verify("wchs", "watch");
-        verify("wchp", "");
-        verify("wchc", "");
-
-        verify("srst", "reset");
-        verify("crst", "reset");
-
-        verify("stat", "Outstanding");
-        verify("srvr", "Outstanding");
-        verify("cons", "queued");
-        verify("mntr", "zk_server_state\tstandalone");
-        verify("mntr", "num_alive_connections");
-        verify("mntr", "fsync_threshold_exceed_count");
-        verify("stat", "Connections");
-        verify("srvr", "Connections");
-    }
-
-    private String sendRequest(String cmd) throws IOException {
-      HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
-      return send4LetterWord(hpobj.host, hpobj.port, cmd);
-    }
-    private String sendRequest(String cmd, int timeout) throws IOException {
-        HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
-        return send4LetterWord(hpobj.host, hpobj.port, cmd, timeout);
-      }
-
-    private void verify(String cmd, String expected) throws IOException {
-        String resp = sendRequest(cmd);
-        LOG.info("cmd " + cmd + " expected " + expected + " got " + resp);
-        Assert.assertTrue(resp.contains(expected));
-    }
-    
-    @Test
-    public void testValidateStatOutput() throws Exception {
-        ZooKeeper zk1 = createClient();
-        ZooKeeper zk2 = createClient();
-        
-        String resp = sendRequest("stat");
-        BufferedReader in = new BufferedReader(new StringReader(resp));
-
-        String line;
-        // first line should be version info
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^.*\\s\\d+\\.\\d+\\.\\d+-.*$", line));
-        Assert.assertTrue(Pattern.matches("^Clients:$", in.readLine()));
-
-        int count = 0;
-        while ((line = in.readLine()).length() > 0) {
-            count++;
-            Assert.assertTrue(Pattern.matches("^ /.*:\\d+\\[\\d+\\]\\(queued=\\d+,recved=\\d+,sent=\\d+\\)$", line));
-        }
-        // ensure at least the two clients we created are accounted for
-        Assert.assertTrue(count >= 2);
-
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Latency min/avg/max: \\d+/\\d+/\\d+$", line));
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Received: \\d+$", line));
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Sent: \\d+$", line));
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Connections: \\d+$", line));
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Outstanding: \\d+$", line));
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Zxid: 0x[\\da-fA-F]+$", line));
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Mode: .*$", line));
-        line = in.readLine();
-        Assert.assertTrue(Pattern.matches("^Node count: \\d+$", line));
-
-        zk1.close();
-        zk2.close();
-    }
-
-    @Test
-    public void testValidateConsOutput() throws Exception {
-        ZooKeeper zk1 = createClient();
-        ZooKeeper zk2 = createClient();
-        
-        String resp = sendRequest("cons");
-        BufferedReader in = new BufferedReader(new StringReader(resp));
-
-        String line;
-        int count = 0;
-        while ((line = in.readLine()) != null && line.length() > 0) {
-            count++;
-            Assert.assertTrue(line, Pattern.matches("^ /.*:\\d+\\[\\d+\\]\\(queued=\\d+,recved=\\d+,sent=\\d+.*\\)$", line));
-        }
-        // ensure at least the two clients we created are accounted for
-        Assert.assertTrue(count >= 2);
-
-        zk1.close();
-        zk2.close();
-    }
-
-    @Test(timeout=60000)
-    public void testValidateSocketTimeout() throws Exception {
-        /**
-         * testing positive scenario that even with timeout parameter the
-         * functionality works fine
-         */
-        String resp = sendRequest("isro", 2000);
-        Assert.assertTrue(resp.contains("rw"));
-    }
-
-    @Test
-    public void testSetTraceMask() throws Exception {
-        String gtmkResp = sendRequest("gtmk");
-        Assert.assertNotNull(gtmkResp);
-        gtmkResp = gtmkResp.trim();
-        Assert.assertFalse(gtmkResp.isEmpty());
-        long formerMask = Long.valueOf(gtmkResp);
-        try {
-            verify(buildSetTraceMaskRequest(0), "0");
-            verify("gtmk", "0");
-        } finally {
-            // Restore former value.
-            sendRequest(buildSetTraceMaskRequest(formerMask));
-        }
-    }
-
-    /**
-     * Builds a SetTraceMask request to be sent to the server, consisting of
-     * "stmk" followed by the 8-byte long representation of the trace mask.
-     *
-     * @param mask trace mask to set
-     * @return built request
-     * @throws IOException if there is an I/O error
-     */
-    private String buildSetTraceMaskRequest(long mask) throws IOException {
-        ByteArrayOutputStream baos = null;
-        DataOutputStream dos = null;
-        try {
-            baos = new ByteArrayOutputStream();
-            dos = new DataOutputStream(baos);
-            dos.writeBytes("stmk");
-            dos.writeLong(mask);
-        } finally {
-            IOUtils.closeStream(dos);
-            IOUtils.closeStream(baos);
-        }
-        return new String(baos.toByteArray());
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java
deleted file mode 100644
index 515cbdc..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FourLetterWordsWhiteListTest.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.server.ServerCnxn;
-import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.Timeout;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FourLetterWordsWhiteListTest extends ClientBase {
-    protected static final Logger LOG =
-        LoggerFactory.getLogger(FourLetterWordsTest.class);
-
-    @Rule
-    public Timeout timeout = new Timeout(30000);
-
-    /*
-     * ZOOKEEPER-2693: test white list of four letter words.
-     * For 3.5.x default white list is empty. Verify that is
-     * the case (except 'stat' command which is enabled in ClientBase
-     * which other tests depend on.).
-     */
-    @Test(timeout=30000)
-    public void testFourLetterWordsAllDisabledByDefault() throws Exception {
-        stopServer();
-        ServerCnxn.resetWhiteList();
-        System.setProperty("zookeeper.4lw.commands.whitelist", "stat");
-        startServer();
-
-        // Default white list for 3.5.x is empty, so all command should fail.
-        verifyAllCommandsFail();
-
-        TestableZooKeeper zk = createClient();
-
-        verifyAllCommandsFail();
-
-        zk.getData("/", true, null);
-
-        verifyAllCommandsFail();
-
-        zk.close();
-
-        verifyFuzzyMatch("stat", "Outstanding");
-        verifyAllCommandsFail();
-    }
-
-    @Test(timeout=30000)
-    public void testFourLetterWordsEnableSomeCommands() throws Exception {
-        stopServer();
-        ServerCnxn.resetWhiteList();
-        System.setProperty("zookeeper.4lw.commands.whitelist", "stat, ruok, isro");
-        startServer();
-        // stat, ruok and isro are white listed.
-        verifyFuzzyMatch("stat", "Outstanding");
-        verifyExactMatch("ruok", "imok");
-        verifyExactMatch("isro", "rw");
-
-        // Rest of commands fail.
-        verifyExactMatch("conf", generateExpectedMessage("conf"));
-        verifyExactMatch("cons", generateExpectedMessage("cons"));
-        verifyExactMatch("crst", generateExpectedMessage("crst"));
-        verifyExactMatch("dump", generateExpectedMessage("dump"));
-        verifyExactMatch("envi", generateExpectedMessage("envi"));
-        verifyExactMatch("gtmk", generateExpectedMessage("gtmk"));
-        verifyExactMatch("stmk", generateExpectedMessage("stmk"));
-        verifyExactMatch("srst", generateExpectedMessage("srst"));
-        verifyExactMatch("wchc", generateExpectedMessage("wchc"));
-        verifyExactMatch("wchp", generateExpectedMessage("wchp"));
-        verifyExactMatch("wchs", generateExpectedMessage("wchs"));
-        verifyExactMatch("mntr", generateExpectedMessage("mntr"));
-    }
-
-    @Test(timeout=30000)
-    public void testISROEnabledWhenReadOnlyModeEnabled() throws Exception {
-        stopServer();
-        ServerCnxn.resetWhiteList();
-        System.setProperty("zookeeper.4lw.commands.whitelist", "stat");
-        System.setProperty("readonlymode.enabled", "true");
-        startServer();
-        verifyExactMatch("isro", "rw");
-        System.clearProperty("readonlymode.enabled");
-    }
-
-    @Test(timeout=30000)
-    public void testFourLetterWordsInvalidConfiguration() throws Exception {
-        stopServer();
-        ServerCnxn.resetWhiteList();
-        System.setProperty("zookeeper.4lw.commands.whitelist", "foo bar" +
-                " foo,,, " +
-                "bar :.,@#$%^&*() , , , , bar, bar, stat,        ");
-        startServer();
-
-        // Just make sure we are good when admin made some mistakes in config file.
-        verifyAllCommandsFail();
-        // But still, what's valid in white list will get through.
-        verifyFuzzyMatch("stat", "Outstanding");
-    }
-
-    @Test(timeout=30000)
-    public void testFourLetterWordsEnableAllCommandsThroughAsterisk() throws Exception {
-        stopServer();
-        ServerCnxn.resetWhiteList();
-        System.setProperty("zookeeper.4lw.commands.whitelist", "*");
-        startServer();
-        verifyAllCommandsSuccess();
-    }
-
-    @Test(timeout=30000)
-    public void testFourLetterWordsEnableAllCommandsThroughExplicitList() throws Exception {
-        stopServer();
-        ServerCnxn.resetWhiteList();
-        System.setProperty("zookeeper.4lw.commands.whitelist",
-                "ruok, envi, conf, stat, srvr, cons, dump," +
-                        "wchs, wchp, wchc, srst, crst, " +
-                        "mntr, gtmk, isro, stmk");
-        startServer();
-        verifyAllCommandsSuccess();
-    }
-
-    private void verifyAllCommandsSuccess() throws Exception {
-        verifyExactMatch("ruok", "imok");
-        verifyFuzzyMatch("envi", "java.version");
-        verifyFuzzyMatch("conf", "clientPort");
-        verifyFuzzyMatch("stat", "Outstanding");
-        verifyFuzzyMatch("srvr", "Outstanding");
-        verifyFuzzyMatch("cons", "queued");
-        verifyFuzzyMatch("dump", "Session");
-        verifyFuzzyMatch("wchs", "watches");
-        verifyFuzzyMatch("wchp", "");
-        verifyFuzzyMatch("wchc", "");
-
-        verifyFuzzyMatch("srst", "reset");
-        verifyFuzzyMatch("crst", "reset");
-
-        verifyFuzzyMatch("stat", "Outstanding");
-        verifyFuzzyMatch("srvr", "Outstanding");
-        verifyFuzzyMatch("cons", "queued");
-        verifyFuzzyMatch("gtmk", "306");
-        verifyFuzzyMatch("isro", "rw");
-
-        TestableZooKeeper zk = createClient();
-        String sid = getHexSessionId(zk.getSessionId());
-
-        verifyFuzzyMatch("stat", "queued");
-        verifyFuzzyMatch("srvr", "Outstanding");
-        verifyFuzzyMatch("cons", sid);
-        verifyFuzzyMatch("dump", sid);
-
-        zk.getData("/", true, null);
-
-        verifyFuzzyMatch("stat", "queued");
-        verifyFuzzyMatch("srvr", "Outstanding");
-        verifyFuzzyMatch("cons", sid);
-        verifyFuzzyMatch("dump", sid);
-
-        verifyFuzzyMatch("wchs", "watching 1");
-        verifyFuzzyMatch("wchp", sid);
-        verifyFuzzyMatch("wchc", sid);
-        zk.close();
-
-        verifyExactMatch("ruok", "imok");
-        verifyFuzzyMatch("envi", "java.version");
-        verifyFuzzyMatch("conf", "clientPort");
-        verifyFuzzyMatch("stat", "Outstanding");
-        verifyFuzzyMatch("srvr", "Outstanding");
-        verifyFuzzyMatch("cons", "queued");
-        verifyFuzzyMatch("dump", "Session");
-        verifyFuzzyMatch("wchs", "watch");
-        verifyFuzzyMatch("wchp", "");
-        verifyFuzzyMatch("wchc", "");
-
-        verifyFuzzyMatch("srst", "reset");
-        verifyFuzzyMatch("crst", "reset");
-
-        verifyFuzzyMatch("stat", "Outstanding");
-        verifyFuzzyMatch("srvr", "Outstanding");
-        verifyFuzzyMatch("cons", "queued");
-        verifyFuzzyMatch("mntr", "zk_server_state\tstandalone");
-        verifyFuzzyMatch("mntr", "num_alive_connections");
-        verifyFuzzyMatch("mntr", "fsync_threshold_exceed_count");
-        verifyFuzzyMatch("stat", "Connections");
-        verifyFuzzyMatch("srvr", "Connections");
-    }
-
-    private void verifyAllCommandsFail() throws Exception {
-        verifyExactMatch("ruok", generateExpectedMessage("ruok"));
-        verifyExactMatch("conf", generateExpectedMessage("conf"));
-        verifyExactMatch("cons", generateExpectedMessage("cons"));
-        verifyExactMatch("crst", generateExpectedMessage("crst"));
-        verifyExactMatch("dump", generateExpectedMessage("dump"));
-        verifyExactMatch("envi", generateExpectedMessage("envi"));
-        verifyExactMatch("gtmk", generateExpectedMessage("gtmk"));
-        verifyExactMatch("stmk", generateExpectedMessage("stmk"));
-        verifyExactMatch("srst", generateExpectedMessage("srst"));
-        verifyExactMatch("wchc", generateExpectedMessage("wchc"));
-        verifyExactMatch("wchp", generateExpectedMessage("wchp"));
-        verifyExactMatch("wchs", generateExpectedMessage("wchs"));
-        verifyExactMatch("mntr", generateExpectedMessage("mntr"));
-        verifyExactMatch("isro", generateExpectedMessage("isro"));
-
-        // srvr is enabled by default due to the sad fact zkServer.sh uses it.
-        verifyFuzzyMatch("srvr", "Outstanding");
-    }
-
-    private void verifyFuzzyMatch(String cmd, String expected) throws IOException {
-        String resp = sendRequest(cmd);
-        LOG.info("cmd " + cmd + " expected " + expected + " got " + resp);
-        Assert.assertTrue(resp.contains(expected));
-    }
-
-    private String generateExpectedMessage(String command) {
-        return command + " is not executed because it is not in the whitelist.";
-    }
-
-    private void verifyExactMatch(String cmd, String expected) throws IOException {
-        String resp = sendRequest(cmd);
-        LOG.info("cmd " + cmd + " expected an exact match of " + expected + "; got " + resp);
-        Assert.assertTrue(resp.trim().equals(expected));
-    }
-
-    private String sendRequest(String cmd) throws IOException {
-      HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
-      return send4LetterWord(hpobj.host, hpobj.port, cmd);
-    }
-
-    private String sendRequest(String cmd, int timeout) throws IOException {
-        HostPort hpobj = ClientBase.parseHostPortList(hostPort).get(0);
-        return send4LetterWord(hpobj.host, hpobj.port, cmd, timeout);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java
deleted file mode 100644
index e41fffe..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/GetChildren2Test.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class GetChildren2Test extends ClientBase {
-    private ZooKeeper zk;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        zk = createClient();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        zk.close();
-    }
-
-    @Test
-    public void testChild()
-        throws IOException, KeeperException, InterruptedException
-    {
-        String name = "/foo";
-        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        String childname = name + "/bar";
-        zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.EPHEMERAL);
-
-        Stat stat = new Stat();
-        List<String> s = zk.getChildren(name, false, stat);
-
-        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-        Assert.assertEquals(stat.getCzxid() + 1, stat.getPzxid());
-        Assert.assertEquals(stat.getCtime(), stat.getMtime());
-        Assert.assertEquals(1, stat.getCversion());
-        Assert.assertEquals(0, stat.getVersion());
-        Assert.assertEquals(0, stat.getAversion());
-        Assert.assertEquals(0, stat.getEphemeralOwner());
-        Assert.assertEquals(name.length(), stat.getDataLength());
-        Assert.assertEquals(1, stat.getNumChildren());
-        Assert.assertEquals(s.size(), stat.getNumChildren());
-
-        s = zk.getChildren(childname, false, stat);
-
-        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
-        Assert.assertEquals(stat.getCtime(), stat.getMtime());
-        Assert.assertEquals(0, stat.getCversion());
-        Assert.assertEquals(0, stat.getVersion());
-        Assert.assertEquals(0, stat.getAversion());
-        Assert.assertEquals(zk.getSessionId(), stat.getEphemeralOwner());
-        Assert.assertEquals(childname.length(), stat.getDataLength());
-        Assert.assertEquals(0, stat.getNumChildren());
-        Assert.assertEquals(s.size(), stat.getNumChildren());
-    }
-
-    @Test
-    public void testChildren()
-        throws IOException, KeeperException, InterruptedException
-    {
-        String name = "/foo";
-        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        List<String> children = new ArrayList<String>();
-        List<String> children_s = new ArrayList<String>();
-
-        for (int i = 0; i < 10; i++) {
-            String childname = name + "/bar" + i;
-            String childname_s = "bar" + i;
-            children.add(childname);
-            children_s.add(childname_s);
-        }
-
-        for(int i = 0; i < children.size(); i++) {
-            String childname = children.get(i);
-            zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.EPHEMERAL);
-
-            Stat stat = new Stat();
-            List<String> s = zk.getChildren(name, false, stat);
-
-            Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-            Assert.assertEquals(stat.getCzxid() + i + 1, stat.getPzxid());
-            Assert.assertEquals(stat.getCtime(), stat.getMtime());
-            Assert.assertEquals(i + 1, stat.getCversion());
-            Assert.assertEquals(0, stat.getVersion());
-            Assert.assertEquals(0, stat.getAversion());
-            Assert.assertEquals(0, stat.getEphemeralOwner());
-            Assert.assertEquals(name.length(), stat.getDataLength());
-            Assert.assertEquals(i + 1, stat.getNumChildren());
-            Assert.assertEquals(s.size(), stat.getNumChildren());
-        }
-        List<String> p = zk.getChildren(name, false, null);
-        List<String> c_a = children_s;
-        List<String> c_b = p;
-        Collections.sort(c_a);
-        Collections.sort(c_b);
-        Assert.assertEquals(c_a.size(), 10);
-        Assert.assertEquals(c_a, c_b);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java
deleted file mode 100644
index 051da13..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/HierarchicalQuorumTest.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/* 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.jmx.CommonNames;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class HierarchicalQuorumTest extends ClientBase {
-    private static final Logger LOG = LoggerFactory.getLogger(QuorumBase.class);
-
-    File s1dir, s2dir, s3dir, s4dir, s5dir;
-    QuorumPeer s1, s2, s3, s4, s5;
-    protected int port1;
-    protected int port2;
-    protected int port3;
-    protected int port4;
-    protected int port5;
-
-    protected int leport1;
-    protected int leport2;
-    protected int leport3;
-    protected int leport4;
-    protected int leport5;
-
-    Properties qp;
-    protected final ClientHammerTest cht = new ClientHammerTest();
-    
-    @Override
-    public void setUp() throws Exception {
-        setupTestEnv();
-
-        JMXEnv.setUp();
-
-        setUpAll();
-
-        port1 = PortAssignment.unique();
-        port2 = PortAssignment.unique();
-        port3 = PortAssignment.unique();
-        port4 = PortAssignment.unique();
-        port5 = PortAssignment.unique();
-        leport1 = PortAssignment.unique();
-        leport2 = PortAssignment.unique();
-        leport3 = PortAssignment.unique();
-        leport4 = PortAssignment.unique();
-        leport5 = PortAssignment.unique();
-
-        hostPort = "127.0.0.1:" + port1 
-            + ",127.0.0.1:" + port2 
-            + ",127.0.0.1:" + port3 
-            + ",127.0.0.1:" + port4 
-            + ",127.0.0.1:" + port5;
-        LOG.info("Ports are: " + hostPort);
-
-        s1dir = ClientBase.createTmpDir();
-        s2dir = ClientBase.createTmpDir();
-        s3dir = ClientBase.createTmpDir();
-        s4dir = ClientBase.createTmpDir();
-        s5dir = ClientBase.createTmpDir();
-
-        String config = "group.1=1:2:3\n" +
-        "group.2=4:5\n" +
-        "weight.1=1\n" +
-        "weight.2=1\n" +
-        "weight.3=1\n" +
-        "weight.4=0\n" +
-        "weight.5=0\n";
-
-        ByteArrayInputStream is = new ByteArrayInputStream(config.getBytes());
-        this.qp = new Properties();
-        
-        qp.load(is);
-        startServers();
-
-        cht.hostPort = hostPort;
-        cht.setUpAll();
-        
-        LOG.info("Setup finished");
-    }
-    
-    /**
-     * This method is here to keep backwards compatibility with the test code 
-     * written before observers. 
-     * @throws Exception
-     */
-    void startServers() throws Exception {
-        startServers(false);
-    }
-    
-    /**
-     * Starts 5 Learners. When withObservers == false, all 5 are Followers.
-     * When withObservers == true, 3 are Followers and 2 Observers.
-     * @param withObservers
-     * @throws Exception
-     */
-    void startServers(boolean withObservers) throws Exception {
-        int tickTime = 2000;
-        int initLimit = 3;
-        int syncLimit = 3;
-        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>();
-        peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000, leport1 + 1000, null));
-        peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000, leport2 + 1000, null));
-        peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000, leport3 + 1000, null));
-        peers.put(Long.valueOf(4), new QuorumServer(4, "127.0.0.1", port4 + 1000, leport4 + 1000,
-                withObservers ? QuorumPeer.LearnerType.OBSERVER
-                        : QuorumPeer.LearnerType.PARTICIPANT));
-        peers.put(Long.valueOf(5), new QuorumServer(5, "127.0.0.1", port5 + 1000, leport5 + 1000,
-                withObservers ? QuorumPeer.LearnerType.OBSERVER
-                        : QuorumPeer.LearnerType.PARTICIPANT));
-
-        LOG.info("creating QuorumPeer 1 port " + port1);
-        List <QuorumPeer> qps = new ArrayList<QuorumPeer>();
-        QuorumHierarchical hq1 = new QuorumHierarchical(qp); 
-        s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit, hq1);
-        qps.add(s1);
-        Assert.assertEquals(port1, s1.getClientPort());
-        
-        LOG.info("creating QuorumPeer 2 port " + port2);
-        QuorumHierarchical hq2 = new QuorumHierarchical(qp); 
-        s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit, hq2);
-        qps.add(s2);
-        Assert.assertEquals(port2, s2.getClientPort());
-        
-        LOG.info("creating QuorumPeer 3 port " + port3);
-        QuorumHierarchical hq3 = new QuorumHierarchical(qp); 
-        s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit, hq3);
-        qps.add(s3);
-        Assert.assertEquals(port3, s3.getClientPort());
-        
-        LOG.info("creating QuorumPeer 4 port " + port4);
-        QuorumHierarchical hq4 = new QuorumHierarchical(qp); 
-        s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit, hq4);
-        qps.add(s4);
-        if (withObservers) {
-            s4.setLearnerType(QuorumPeer.LearnerType.OBSERVER);
-        }
-        Assert.assertEquals(port4, s4.getClientPort());
-                       
-        LOG.info("creating QuorumPeer 5 port " + port5);
-        QuorumHierarchical hq5 = new QuorumHierarchical(qp); 
-        s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit, hq5);
-        qps.add(s5);
-        if (withObservers) {
-            s5.setLearnerType(QuorumPeer.LearnerType.OBSERVER);
-        }
-        Assert.assertEquals(port5, s5.getClientPort());
-        
-        // Observers are currently only compatible with LeaderElection
-        if (withObservers) {
-            s1.setElectionType(0);
-            s2.setElectionType(0);
-            s3.setElectionType(0);
-            s4.setElectionType(0);
-            s5.setElectionType(0);
-        }
-        
-        LOG.info("start QuorumPeer 1");
-        s1.start();
-        LOG.info("start QuorumPeer 2");
-        s2.start();
-        LOG.info("start QuorumPeer 3");
-        s3.start();
-        LOG.info("start QuorumPeer 4" + (withObservers ? "(observer)" : ""));
-        s4.start();
-        LOG.info("start QuorumPeer 5" + (withObservers ? "(observer)" : ""));
-        s5.start();
-        LOG.info("started QuorumPeer 5");
-
-        LOG.info ("Closing ports " + hostPort);
-        for (String hp : hostPort.split(",")) {
-            Assert.assertTrue("waiting for server up",
-                       ClientBase.waitForServerUp(hp,
-                                    CONNECTION_TIMEOUT));
-            LOG.info(hp + " is accepting client connections");
-        }
-
-        // interesting to see what's there...
-        JMXEnv.dump();
-        // make sure we have these 5 servers listed
-        Set<String> ensureNames = new LinkedHashSet<String>();
-        for (int i = 1; i <= 5; i++) {
-            ensureNames.add("InMemoryDataTree");
-        }
-        for (int i = 1; i <= 5; i++) {
-            ensureNames.add("name0=ReplicatedServer_id" + i
-                 + ",name1=replica." + i + ",name2=");
-        }
-        for (int i = 1; i <= 5; i++) {
-            for (int j = 1; j <= 5; j++) {
-                ensureNames.add("name0=ReplicatedServer_id" + i
-                     + ",name1=replica." + j);
-            }
-        }
-        for (int i = 1; i <= 5; i++) {
-            ensureNames.add("name0=ReplicatedServer_id" + i);
-        }
-        JMXEnv.ensureAll(ensureNames.toArray(new String[ensureNames.size()]));
-        verifyElectionTimeTakenJMXAttribute(qps);
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        LOG.info("TearDown started");
-        cht.tearDownAll();
-
-        LOG.info("Shutting down server 1");
-        shutdown(s1);
-        LOG.info("Shutting down server 2");
-        shutdown(s2);
-        LOG.info("Shutting down server 3");
-        shutdown(s3);
-        LOG.info("Shutting down server 4");
-        shutdown(s4);
-        LOG.info("Shutting down server 5");
-        shutdown(s5);
-        
-        for (String hp : hostPort.split(",")) {
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown(hp,
-                                           ClientBase.CONNECTION_TIMEOUT));
-            LOG.info(hp + " is no longer accepting client connections");
-        }
-
-        JMXEnv.tearDown();
-    }
-
-    protected void shutdown(QuorumPeer qp) {
-        QuorumBase.shutdown(qp);
-    }
-
-    protected TestableZooKeeper createClient()
-        throws IOException, InterruptedException
-    {
-        return createClient(hostPort);
-    }
-
-    protected TestableZooKeeper createClient(String hp)
-        throws IOException, InterruptedException
-    {
-        CountdownWatcher watcher = new CountdownWatcher();
-        return createClient(watcher, hp);
-    }
-
-    private void verifyElectionTimeTakenJMXAttribute(List<QuorumPeer> peers)
-            throws Exception {
-        LOG.info("Verify QuorumPeer#electionTimeTaken jmx bean attribute");
-
-        for (int i = 1; i <= peers.size(); i++) {
-            QuorumPeer qp = peers.get(i - 1);
-            if (qp.getLearnerType() == LearnerType.OBSERVER) {
-                continue; // Observer don't have electionTimeTaken attribute.
-            }
-            Long electionTimeTaken = -1L;
-            String bean = "";
-            if (qp.getPeerState() == ServerState.FOLLOWING) {
-                bean = String.format(
-                        "%s:name0=ReplicatedServer_id%d,name1=replica.%d,name2=Follower",
-                        CommonNames.DOMAIN, i, i);
-            } else if (qp.getPeerState() == ServerState.LEADING) {
-                bean = String.format(
-                        "%s:name0=ReplicatedServer_id%d,name1=replica.%d,name2=Leader",
-                        CommonNames.DOMAIN, i, i);
-            }
-            electionTimeTaken = (Long) JMXEnv.ensureBeanAttribute(bean,
-                    "ElectionTimeTaken");
-            Assert.assertTrue("Wrong electionTimeTaken value!",
-                    electionTimeTaken >= 0);
-        }
-    }
-
-    @Test
-    public void testHierarchicalQuorum() throws Throwable {
-        cht.runHammer(5, 10);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java
deleted file mode 100644
index 9a01a65..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/IntegrityCheck.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-/**
- * This is a simple test to check the integrity of ZooKeeper servers. The client
- * simply cycles through blasting changes to ZooKeeper and the checking what it
- * gets back.
- *
- * The check is very simple. The value of the last successful read or write is
- * stored in lastValue. When we issue a request, that value becomes a possible
- * value. The difficulty is that when a communication error happens, the client
- * doesn't know if the set actually went through. So, our invariant that we
- * check for is that we always read a value that is greater than or equal to
- * a value that we have previously read or set. (Each time we set a value, the
- * value will be one more than the previous set.)
- */
-import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.AsyncCallback.StatCallback;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.data.Stat;
-
-public class IntegrityCheck implements Watcher, StatCallback, DataCallback {
-    private static final Logger LOG = LoggerFactory.getLogger(IntegrityCheck.class);
-
-    ZooKeeper zk;
-
-    HashMap<String, byte[]> lastValue = new HashMap<String, byte[]>();
-
-    int count;
-
-    String path;
-
-    int iteration;
-
-    int outstanding;
-
-    int errorCount;
-
-    synchronized void incOutstanding() {
-        outstanding++;
-    }
-
-    synchronized void decOutstanding() {
-        outstanding--;
-        notifyAll();
-    }
-
-    synchronized void waitOutstanding() throws InterruptedException {
-        while (outstanding > 0) {
-            wait();
-        }
-    }
-
-    IntegrityCheck(String hostPort, String path, int count) throws
-            IOException {
-        zk = new ZooKeeper(hostPort, 30000, this);
-        this.path = path;
-        this.count = count;
-    }
-
-    public void run() throws InterruptedException, KeeperException {
-        try{
-            LOG.warn("Creating znodes for "+path);
-            doCreate();
-            LOG.warn("Staring the test loop for "+path);
-            while (true) {
-                LOG.warn("Staring write cycle for "+path);
-                doPopulate();
-                waitOutstanding();
-                LOG.warn("Staring read cycle for "+path);
-                readAll();
-                waitOutstanding();
-            }
-        }finally{
-            LOG.warn("Test loop terminated for "+path);
-        }
-    }
-
-    void readAll() {
-        for (int i = 0; i < count; i++) {
-            String cpath = path + "/" + i;
-            zk.getData(cpath, false, this, null);
-            incOutstanding();
-        }
-
-    }
-
-    void doCreate() throws InterruptedException, KeeperException {
-        // create top level znode
-        try{
-            zk.create(path, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        }catch(KeeperException.NodeExistsException e){
-            // ignore duplicate create
-        }
-        iteration++;
-        byte v[] = ("" + iteration).getBytes();
-        // create child znodes
-        for (int i = 0; i < count; i++) {
-            String cpath = path + "/" + i;
-            try{
-                if(i%10==0)
-                    LOG.warn("Creating znode "+cpath);
-                zk.create(cpath, v, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            }catch(KeeperException.NodeExistsException e){
-                // ignore duplicate create
-            }
-            lastValue.put(cpath, v);
-        }
-    }
-
-    void doPopulate() {
-        iteration++;
-        byte v[] = ("" + iteration).getBytes();
-        for (int i = 0; i < count; i++) {
-            String cpath = path + "/" + i;
-            zk.setData(cpath, v, -1, this, v);
-            incOutstanding();
-        }
-    }
-
-    // watcher callback
-    public void process(WatchedEvent event) {
-        if(event.getState()==KeeperState.SyncConnected){
-            synchronized(this){
-                notifyAll();
-            }
-        }
-    }
-
-    synchronized void ensureConnected(){
-        while(zk.getState()!=ZooKeeper.States.CONNECTED){
-            try {
-                wait();
-            } catch (InterruptedException e) {
-                return;
-            }
-        }
-    }
-
-    /**
-     * @param args
-     */
-    public static void main(String[] args) {
-        if (args.length < 3) {
-            System.err.println("USAGE: IntegrityCheck zookeeperHostPort znode #children");
-            return;
-        }
-        int childrenCount=0;
-        try {
-            childrenCount=Integer.parseInt(args[2]);
-        } catch (NumberFormatException e) {
-            e.printStackTrace();
-            System.exit(1);
-        }
-
-        try{
-            final IntegrityCheck ctest = new IntegrityCheck(args[0], args[1],childrenCount);
-            Runtime.getRuntime().addShutdownHook(new Thread() {
-                public void run() {
-                    System.out.println(new Date().toString()+": Error count = " + ctest.errorCount);
-                }
-            });
-            while(true){
-                try{
-                    ctest.ensureConnected();
-                    ctest.run();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            System.exit(2);
-        }
-    }
-
-    public void processResult(int rc, String path, Object ctx, Stat stat) {
-        if (rc == 0) {
-            lastValue.put(path, (byte[]) ctx);
-        }
-        decOutstanding();
-    }
-
-    public void processResult(int rc, String path, Object ctx, byte[] data,
-            Stat stat) {
-        if (rc == 0) {
-            String string = new String(data);
-            String lastString = null;
-            byte[] v = lastValue.get(path);
-            if (v != null) {
-                lastString = new String(v);
-            }
-            if (lastString != null
-                    && Integer.parseInt(string) < Integer.parseInt(lastString)) {
-                LOG.error("ERROR: Got " + string + " expected >= "
-                        + lastString);
-                errorCount++;
-            }
-            lastValue.put(path, (byte[]) ctx);
-        }
-        decOutstanding();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java
deleted file mode 100644
index c5a7b4f..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/InvalidSnapshotTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.server.LogFormatter;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.SnapshotFormatter;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class InvalidSnapshotTest extends ZKTestCase implements Watcher {
-    private final static Logger LOG = LoggerFactory.getLogger(UpgradeTest.class);
-    private static final String HOSTPORT =
-            "127.0.0.1:" + PortAssignment.unique();
-
-    private static final File testData = new File(
-            System.getProperty("test.data.dir", "build/test/data"));
-    private CountDownLatch startSignal;
-
-    /**
-     * Verify the LogFormatter by running it on a known file.
-     */
-    @Test
-    public void testLogFormatter() throws Exception {
-        File snapDir = new File(testData, "invalidsnap");
-        File logfile = new File(new File(snapDir, "version-2"), "log.274");
-        String[] args = {logfile.getCanonicalFile().toString()};
-        LogFormatter.main(args);
-    }
-    
-
-    /**
-     * Verify the SnapshotFormatter by running it on a known file.
-     */
-    @Test
-    public void testSnapshotFormatter() throws Exception {
-        File snapDir = new File(testData, "invalidsnap");
-        File snapfile = new File(new File(snapDir, "version-2"), "snapshot.272");
-        String[] args = {snapfile.getCanonicalFile().toString()};
-        SnapshotFormatter.main(args);
-    }
-    
-    /**
-     * Verify the SnapshotFormatter by running it on a known file with one null data.
-     */
-    @Test
-    public void testSnapshotFormatterWithNull() throws Exception {
-        File snapDir = new File(testData, "invalidsnap");
-        File snapfile = new File(new File(snapDir, "version-2"), "snapshot.273");
-        String[] args = {snapfile.getCanonicalFile().toString()};
-        SnapshotFormatter.main(args);
-    }
-    
-    /**
-     * test the snapshot
-     * @throws Exception an exception could be expected
-     */
-    @Test
-    public void testSnapshot() throws Exception {
-        File snapDir = new File(testData, "invalidsnap");
-        ZooKeeperServer zks = new ZooKeeperServer(snapDir, snapDir, 3000);
-        SyncRequestProcessor.setSnapCount(1000);
-        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-        f.startup(zks);
-        LOG.info("starting up the zookeeper server .. waiting");
-        Assert.assertTrue("waiting for server being up",
-                ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
-        ZooKeeper zk = new ZooKeeper(HOSTPORT, 20000, this);
-        try {
-            // we know this from the data files
-            // this node is the last node in the snapshot
-
-            Assert.assertTrue(zk.exists("/9/9/8", false) != null);
-        } finally {
-            zk.close();
-        }
-        f.shutdown();
-        zks.shutdown();
-        Assert.assertTrue("waiting for server down",
-                   ClientBase.waitForServerDown(HOSTPORT,
-                           ClientBase.CONNECTION_TIMEOUT));
-
-    }
-
-    public void process(WatchedEvent event) {
-        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
-        if (event.getState() == KeeperState.SyncConnected
-                && startSignal != null && startSignal.getCount() > 0)
-        {
-            startSignal.countDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/JMXEnv.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/JMXEnv.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/JMXEnv.java
deleted file mode 100644
index f67c67c..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/JMXEnv.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-import junit.framework.TestCase;
-
-import org.apache.zookeeper.jmx.CommonNames;
-import org.apache.zookeeper.jmx.MBeanRegistry;
-import org.junit.Assert;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class JMXEnv {
-    protected static final Logger LOG = LoggerFactory.getLogger(JMXEnv.class);
-
-    private static JMXConnectorServer cs;
-    private static JMXConnector cc;
-
-    public static void setUp() throws IOException {
-        MBeanServer mbs = MBeanRegistry.getInstance().getPlatformMBeanServer();
-        
-        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
-        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
-        cs.start();
-
-       JMXServiceURL addr = cs.getAddress();
-        
-       cc = JMXConnectorFactory.connect(addr);
-    }
-    
-    public static void tearDown() {
-        try {
-            if (cc != null) {
-                cc.close();
-            }
-        } catch (IOException e) {
-            LOG.warn("Unexpected, ignoring", e);
-            
-        }
-        cc = null;
-        try {
-            if (cs != null) {
-                cs.stop();
-            }
-        } catch (IOException e) {
-            LOG.warn("Unexpected, ignoring", e);
-            
-        }
-        cs = null;
-    }
-    
-    public static MBeanServerConnection conn() throws IOException {
-        return cc.getMBeanServerConnection();
-    }
-
-    /**
-     * Ensure that all of the specified names are registered.
-     * Note that these are components of the name, and in particular
-     * order matters - you want the more specific name (leafs) specified
-     * before their parent(s) (since names are hierarchical)
-     * It waits in a loop up to 60 seconds before failing if there is a
-     * mismatch.
-     * @param expectedNames
-     * @return
-     * @throws IOException
-     * @throws MalformedObjectNameException
-     */
-    public static Set<ObjectName> ensureAll(String... expectedNames)
-        throws IOException, InterruptedException
-    {
-        Set<ObjectName> beans;
-        Set<ObjectName> found;
-        int nTry = 0;
-        do {
-            if (nTry++ > 0) {
-                Thread.sleep(100);
-            }
-            try {
-                beans = conn().queryNames(
-                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
-            } catch (MalformedObjectNameException e) {
-                throw new RuntimeException(e);
-            }
-        
-            found = new HashSet<ObjectName>();
-            for (String name : expectedNames) {
-                LOG.info("expect:" + name);
-                for (ObjectName bean : beans) {
-                    if (bean.toString().contains(name)) {
-                        LOG.info("found:" + name + " " + bean);
-                        found.add(bean);
-                        break;
-                    }
-                }
-                beans.removeAll(found);
-            }
-        } while ((expectedNames.length != found.size()) && (nTry < 600));
-        TestCase.assertEquals("expected " + Arrays.toString(expectedNames),
-                expectedNames.length, found.size());
-        return beans;
-    }
-
-    /**
-     * Ensure that only the specified names are registered.
-     * Note that these are components of the name, and in particular
-     * order matters - you want the more specific name (leafs) specified
-     * before their parent(s) (since names are hierarchical)
-     * @param expectedNames
-     * @return
-     * @throws IOException
-     * @throws MalformedObjectNameException
-     */
-    public static Set<ObjectName> ensureOnly(String... expectedNames)
-        throws IOException, InterruptedException
-    {
-        LOG.info("ensureOnly:" + Arrays.toString(expectedNames));
-        Set<ObjectName> beans = ensureAll(expectedNames);
-        for (ObjectName bean : beans) {
-            LOG.info("unexpected:" + bean.toString());
-        }
-        TestCase.assertEquals(0, beans.size());
-        return beans;
-    }
-    
-    public static void ensureNone(String... expectedNames)
-        throws IOException, InterruptedException
-    {
-        Set<ObjectName> beans;
-        int nTry = 0;
-        boolean foundUnexpected = false;
-        String unexpectedName = "";
-        do {
-            if (nTry++ > 0) {
-                Thread.sleep(100);
-            }
-            try {
-                beans = conn().queryNames(
-                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
-            } catch (MalformedObjectNameException e) {
-                throw new RuntimeException(e);
-            }
-  
-            foundUnexpected = false; 
-            for (String name : expectedNames) {
-                for (ObjectName bean : beans) {
-                    if (bean.toString().contains(name)) {
-                        LOG.info("didntexpect:" + name);
-                        foundUnexpected = true;
-                        unexpectedName = name + " " + bean.toString();
-                        break;
-                    }
-                }
-                if (foundUnexpected) {
-                    break;
-                }
-            }
-        } while ((foundUnexpected) && (nTry < 600));
-        if (foundUnexpected) {
-            LOG.info("List of all beans follows:");
-            for (ObjectName bean : beans) {
-                LOG.info("bean:" + bean.toString());
-            }
-            TestCase.fail(unexpectedName);
-        }
-    }
-
-    public static void dump() throws IOException {
-        LOG.info("JMXEnv.dump() follows");
-        Set<ObjectName> beans;
-        try {
-            beans = conn().queryNames(
-                    new ObjectName(CommonNames.DOMAIN + ":*"), null);
-        } catch (MalformedObjectNameException e) {
-            throw new RuntimeException(e);
-        }
-        for (ObjectName bean : beans) {
-            LOG.info("bean:" + bean.toString());
-        }
-    }
-
-    /**
-     * Ensure that the specified parent names are registered. Note that these
-     * are components of the name. It waits in a loop up to 60 seconds before
-     * failing if there is a mismatch. This will return the beans which are not
-     * matched.
-     * 
-     * {@link https://issues.apache.org/jira/browse/ZOOKEEPER-1858}
-     * 
-     * @param expectedNames
-     *            - expected beans
-     * @return the beans which are not matched with the given expected names
-     * 
-     * @throws IOException
-     * @throws InterruptedException
-     * 
-     */
-    public static Set<ObjectName> ensureParent(String... expectedNames)
-            throws IOException, InterruptedException {
-        LOG.info("ensureParent:" + Arrays.toString(expectedNames));
-
-        Set<ObjectName> beans;
-        int nTry = 0;
-        Set<ObjectName> found = new HashSet<ObjectName>();
-        do {
-            if (nTry++ > 0) {
-                Thread.sleep(500);
-            }
-            try {
-                beans = conn().queryNames(
-                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
-            } catch (MalformedObjectNameException e) {
-                throw new RuntimeException(e);
-            }
-            found.clear();
-            for (String name : expectedNames) {
-                LOG.info("expect:" + name);
-                for (ObjectName bean : beans) {
-                    // check the existence of name in bean
-                    if (compare(bean.toString(), name)) {
-                        LOG.info("found:" + name + " " + bean);
-                        found.add(bean);
-                        break;
-                    }
-                }
-                beans.removeAll(found);
-            }
-        } while (expectedNames.length != found.size() && nTry < 120);
-        TestCase.assertEquals("expected " + Arrays.toString(expectedNames),
-                expectedNames.length, found.size());
-        return beans;
-    }
-
-    /**
-     * Comparing that the given name exists in the bean. For component beans,
-     * the component name will be present at the end of the bean name
-     * 
-     * For example 'StandaloneServer' will present in the bean name like
-     * 'org.apache.ZooKeeperService:name0=StandaloneServer_port-1'
-     */
-    private static boolean compare(String bean, String name) {
-        String[] names = bean.split("=");
-        if (names.length > 0 && names[names.length - 1].contains(name)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Ensure that the specified bean name and its attribute is registered. Note
-     * that these are components of the name. It waits in a loop up to 60
-     * seconds before failing if there is a mismatch. This will return the beans
-     * which are not matched.
-     *
-     * @param expectedName
-     *            - expected bean
-     * @param expectedAttribute
-     *            - expected attribute
-     * @return the value of the attribute
-     *
-     * @throws Exception
-     */
-    public static Object ensureBeanAttribute(String expectedName,
-            String expectedAttribute) throws Exception {
-        String value = "";
-        LOG.info("ensure bean:{}, attribute:{}", new Object[] { expectedName,
-                expectedAttribute });
-
-        Set<ObjectName> beans;
-        int nTry = 0;
-        do {
-            if (nTry++ > 0) {
-                Thread.sleep(500);
-            }
-            try {
-                beans = conn().queryNames(
-                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
-            } catch (MalformedObjectNameException e) {
-                throw new RuntimeException(e);
-            }
-            LOG.info("expect:" + expectedName);
-            for (ObjectName bean : beans) {
-                // check the existence of name in bean
-                if (bean.toString().equals(expectedName)) {
-                    LOG.info("found:{} {}", new Object[] { expectedName, bean });
-                    return conn().getAttribute(bean, expectedAttribute);
-                }
-            }
-        } while (nTry < 120);
-        Assert.fail("Failed to find bean:" + expectedName + ", attribute:"
-                + expectedAttribute);
-        return value;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java
deleted file mode 100644
index 55dc852..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/KeeperStateTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.util.EnumSet;
-
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.KeeperException.Code;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class KeeperStateTest extends ZKTestCase {
-    
-    @Test
-    public void testIntConversion() {
-        // Ensure that we can convert all valid integers to KeeperStates
-        EnumSet<KeeperState> allStates = EnumSet.allOf(KeeperState.class);
-
-        for(KeeperState as : allStates) {
-            Assert.assertEquals(as, KeeperState.fromInt( as.getIntValue() ) );
-        }
-    }
-
-    @Test
-    public void testInvalidIntConversion() {
-        try {
-            KeeperState ks = KeeperState.fromInt(324142);
-            Assert.fail("Was able to create an invalid KeeperState via an integer");
-        } catch(RuntimeException re) {
-            // we're good.
-        }
-
-    }
-
-    /** Validate that the deprecated constant still works. There were issues
-     * found with switch statements - which need compile time constants.
-     */
-    @Test
-    @SuppressWarnings("deprecation")
-    public void testDeprecatedCodeOkInSwitch() {
-        int test = 1;
-        switch (test) {
-        case Code.Ok:
-            Assert.assertTrue(true);
-            break;
-        }
-    }
-
-    /** Verify the enum works (paranoid) */
-    @Test
-    public void testCodeOKInSwitch() {
-        Code test = Code.OK;
-        switch (test) {
-        case OK:
-            Assert.assertTrue(true);
-            break;
-        }
-    }
-}


[15/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeper.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeper.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeper.java
new file mode 100644
index 0000000..3e46ee7
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeper.java
@@ -0,0 +1,1857 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.apache.zookeeper.AsyncCallback.*;
+import org.apache.zookeeper.OpResult.ErrorResult;
+import org.apache.zookeeper.client.ConnectStringParser;
+import org.apache.zookeeper.client.HostProvider;
+import org.apache.zookeeper.client.StaticHostProvider;
+import org.apache.zookeeper.client.ZooKeeperSaslClient;
+import org.apache.zookeeper.common.PathUtils;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.proto.*;
+import org.apache.zookeeper.server.DataTree;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.util.*;
+
+/**
+ * This is the main class of ZooKeeper client library. To use a ZooKeeper
+ * service, an application must first instantiate an object of ZooKeeper class.
+ * All the iterations will be done by calling the methods of ZooKeeper class.
+ * The methods of this class are thread-safe unless otherwise noted.
+ * <p>
+ * Once a connection to a server is established, a session ID is assigned to the
+ * client. The client will send heart beats to the server periodically to keep
+ * the session valid.
+ * <p>
+ * The application can call ZooKeeper APIs through a client as long as the
+ * session ID of the client remains valid.
+ * <p>
+ * If for some reason, the client fails to send heart beats to the server for a
+ * prolonged period of time (exceeding the sessionTimeout value, for instance),
+ * the server will expire the session, and the session ID will become invalid.
+ * The client object will no longer be usable. To make ZooKeeper API calls, the
+ * application must create a new client object.
+ * <p>
+ * If the ZooKeeper server the client currently connects to fails or otherwise
+ * does not respond, the client will automatically try to connect to another
+ * server before its session ID expires. If successful, the application can
+ * continue to use the client.
+ * <p>
+ * The ZooKeeper API methods are either synchronous or asynchronous. Synchronous
+ * methods blocks until the server has responded. Asynchronous methods just queue
+ * the request for sending and return immediately. They take a callback object that
+ * will be executed either on successful execution of the request or on error with
+ * an appropriate return code (rc) indicating the error.
+ * <p>
+ * Some successful ZooKeeper API calls can leave watches on the "data nodes" in
+ * the ZooKeeper server. Other successful ZooKeeper API calls can trigger those
+ * watches. Once a watch is triggered, an event will be delivered to the client
+ * which left the watch at the first place. Each watch can be triggered only
+ * once. Thus, up to one event will be delivered to a client for every watch it
+ * leaves.
+ * <p>
+ * A client needs an object of a class implementing Watcher interface for
+ * processing the events delivered to the client.
+ *
+ * When a client drops the current connection and re-connects to a server, all the
+ * existing watches are considered as being triggered but the undelivered events
+ * are lost. To emulate this, the client will generate a special event to tell
+ * the event handler a connection has been dropped. This special event has
+ * EventType None and KeeperState Disconnected.
+ *
+ */
+@InterfaceAudience.Public
+public class ZooKeeper {
+
+    public static final String ZOOKEEPER_CLIENT_CNXN_SOCKET = "zookeeper.clientCnxnSocket";
+
+    protected final ClientCnxn cnxn;
+    private static final Logger LOG;
+    static {
+        //Keep these two lines together to keep the initialization order explicit
+        LOG = LoggerFactory.getLogger(ZooKeeper.class);
+        Environment.logEnv("Client environment:", LOG);
+    }
+
+
+    public ZooKeeperSaslClient getSaslClient() {
+        return cnxn.zooKeeperSaslClient;
+    }
+
+    private final ZKWatchManager watchManager = new ZKWatchManager();
+
+    List<String> getDataWatches() {
+        synchronized(watchManager.dataWatches) {
+            List<String> rc = new ArrayList<String>(watchManager.dataWatches.keySet());
+            return rc;
+        }
+    }
+    List<String> getExistWatches() {
+        synchronized(watchManager.existWatches) {
+            List<String> rc =  new ArrayList<String>(watchManager.existWatches.keySet());
+            return rc;
+        }
+    }
+    List<String> getChildWatches() {
+        synchronized(watchManager.childWatches) {
+            List<String> rc = new ArrayList<String>(watchManager.childWatches.keySet());
+            return rc;
+        }
+    }
+
+    /**
+     * Manage watchers & handle events generated by the ClientCnxn object.
+     *
+     * We are implementing this as a nested class of ZooKeeper so that
+     * the public methods will not be exposed as part of the ZooKeeper client
+     * API.
+     */
+    private static class ZKWatchManager implements ClientWatchManager {
+        private final Map<String, Set<Watcher>> dataWatches =
+            new HashMap<String, Set<Watcher>>();
+        private final Map<String, Set<Watcher>> existWatches =
+            new HashMap<String, Set<Watcher>>();
+        private final Map<String, Set<Watcher>> childWatches =
+            new HashMap<String, Set<Watcher>>();
+
+        private volatile Watcher defaultWatcher;
+
+        final private void addTo(Set<Watcher> from, Set<Watcher> to) {
+            if (from != null) {
+                to.addAll(from);
+            }
+        }
+
+        /* (non-Javadoc)
+         * @see org.apache.zookeeper.ClientWatchManager#materialize(Event.KeeperState, 
+         *                                                        Event.EventType, java.lang.String)
+         */
+        @Override
+        public Set<Watcher> materialize(Watcher.Event.KeeperState state,
+                                        Watcher.Event.EventType type,
+                                        String clientPath)
+        {
+            Set<Watcher> result = new HashSet<Watcher>();
+
+            switch (type) {
+            case None:
+                result.add(defaultWatcher);
+                boolean clear = ClientCnxn.getDisableAutoResetWatch() &&
+                        state != Watcher.Event.KeeperState.SyncConnected;
+
+                synchronized(dataWatches) {
+                    for(Set<Watcher> ws: dataWatches.values()) {
+                        result.addAll(ws);
+                    }
+                    if (clear) {
+                        dataWatches.clear();
+                    }
+                }
+
+                synchronized(existWatches) {
+                    for(Set<Watcher> ws: existWatches.values()) {
+                        result.addAll(ws);
+                    }
+                    if (clear) {
+                        existWatches.clear();
+                    }
+                }
+
+                synchronized(childWatches) {
+                    for(Set<Watcher> ws: childWatches.values()) {
+                        result.addAll(ws);
+                    }
+                    if (clear) {
+                        childWatches.clear();
+                    }
+                }
+
+                return result;
+            case NodeDataChanged:
+            case NodeCreated:
+                synchronized (dataWatches) {
+                    addTo(dataWatches.remove(clientPath), result);
+                }
+                synchronized (existWatches) {
+                    addTo(existWatches.remove(clientPath), result);
+                }
+                break;
+            case NodeChildrenChanged:
+                synchronized (childWatches) {
+                    addTo(childWatches.remove(clientPath), result);
+                }
+                break;
+            case NodeDeleted:
+                synchronized (dataWatches) {
+                    addTo(dataWatches.remove(clientPath), result);
+                }
+                // XXX This shouldn't be needed, but just in case
+                synchronized (existWatches) {
+                    Set<Watcher> list = existWatches.remove(clientPath);
+                    if (list != null) {
+                        addTo(list, result);
+                        LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!");
+                    }
+                }
+                synchronized (childWatches) {
+                    addTo(childWatches.remove(clientPath), result);
+                }
+                break;
+            default:
+                String msg = "Unhandled watch event type " + type
+                    + " with state " + state + " on path " + clientPath;
+                LOG.error(msg);
+                throw new RuntimeException(msg);
+            }
+
+            return result;
+        }
+    }
+
+    /**
+     * Register a watcher for a particular path.
+     */
+    abstract class WatchRegistration {
+        private Watcher watcher;
+        private String clientPath;
+        public WatchRegistration(Watcher watcher, String clientPath)
+        {
+            this.watcher = watcher;
+            this.clientPath = clientPath;
+        }
+
+        abstract protected Map<String, Set<Watcher>> getWatches(int rc);
+
+        /**
+         * Register the watcher with the set of watches on path.
+         * @param rc the result code of the operation that attempted to
+         * add the watch on the path.
+         */
+        public void register(int rc) {
+            if (shouldAddWatch(rc)) {
+                Map<String, Set<Watcher>> watches = getWatches(rc);
+                synchronized(watches) {
+                    Set<Watcher> watchers = watches.get(clientPath);
+                    if (watchers == null) {
+                        watchers = new HashSet<Watcher>();
+                        watches.put(clientPath, watchers);
+                    }
+                    watchers.add(watcher);
+                }
+            }
+        }
+        /**
+         * Determine whether the watch should be added based on return code.
+         * @param rc the result code of the operation that attempted to add the
+         * watch on the node
+         * @return true if the watch should be added, otw false
+         */
+        protected boolean shouldAddWatch(int rc) {
+            return rc == 0;
+        }
+    }
+
+    /** Handle the special case of exists watches - they add a watcher
+     * even in the case where NONODE result code is returned.
+     */
+    class ExistsWatchRegistration extends WatchRegistration {
+        public ExistsWatchRegistration(Watcher watcher, String clientPath) {
+            super(watcher, clientPath);
+        }
+
+        @Override
+        protected Map<String, Set<Watcher>> getWatches(int rc) {
+            return rc == 0 ?  watchManager.dataWatches : watchManager.existWatches;
+        }
+
+        @Override
+        protected boolean shouldAddWatch(int rc) {
+            return rc == 0 || rc == KeeperException.Code.NONODE.intValue();
+        }
+    }
+
+    class DataWatchRegistration extends WatchRegistration {
+        public DataWatchRegistration(Watcher watcher, String clientPath) {
+            super(watcher, clientPath);
+        }
+
+        @Override
+        protected Map<String, Set<Watcher>> getWatches(int rc) {
+            return watchManager.dataWatches;
+        }
+    }
+
+    class ChildWatchRegistration extends WatchRegistration {
+        public ChildWatchRegistration(Watcher watcher, String clientPath) {
+            super(watcher, clientPath);
+        }
+
+        @Override
+        protected Map<String, Set<Watcher>> getWatches(int rc) {
+            return watchManager.childWatches;
+        }
+    }
+
+    @InterfaceAudience.Public
+    public enum States {
+        CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY,
+        CLOSED, AUTH_FAILED, NOT_CONNECTED;
+
+        public boolean isAlive() {
+            return this != CLOSED && this != AUTH_FAILED;
+        }
+
+        /**
+         * Returns whether we are connected to a server (which
+         * could possibly be read-only, if this client is allowed
+         * to go to read-only mode)
+         * */
+        public boolean isConnected() {
+            return this == CONNECTED || this == CONNECTEDREADONLY;
+        }
+    }
+
+    /**
+     * To create a ZooKeeper client object, the application needs to pass a
+     * connection string containing a comma separated list of host:port pairs,
+     * each corresponding to a ZooKeeper server.
+     * <p>
+     * Session establishment is asynchronous. This constructor will initiate
+     * connection to the server and return immediately - potentially (usually)
+     * before the session is fully established. The watcher argument specifies
+     * the watcher that will be notified of any changes in state. This
+     * notification can come at any point before or after the constructor call
+     * has returned.
+     * <p>
+     * The instantiated ZooKeeper client object will pick an arbitrary server
+     * from the connectString and attempt to connect to it. If establishment of
+     * the connection fails, another server in the connect string will be tried
+     * (the order is non-deterministic, as we random shuffle the list), until a
+     * connection is established. The client will continue attempts until the
+     * session is explicitly closed.
+     * <p>
+     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
+     * connection string. This will run the client commands while interpreting
+     * all paths relative to this root (similar to the unix chroot command).
+     *
+     * @param connectString
+     *            comma separated host:port pairs, each corresponding to a zk
+     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If
+     *            the optional chroot suffix is used the example would look
+     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
+     *            where the client would be rooted at "/app/a" and all paths
+     *            would be relative to this root - ie getting/setting/etc...
+     *            "/foo/bar" would result in operations being run on
+     *            "/app/a/foo/bar" (from the server perspective).
+     * @param sessionTimeout
+     *            session timeout in milliseconds
+     * @param watcher
+     *            a watcher object which will be notified of state changes, may
+     *            also be notified for node events
+     *
+     * @throws IOException
+     *             in cases of network failure
+     * @throws IllegalArgumentException
+     *             if an invalid chroot path is specified
+     */
+    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
+        throws IOException
+    {
+        this(connectString, sessionTimeout, watcher, false);
+    }
+
+    /**
+     * To create a ZooKeeper client object, the application needs to pass a
+     * connection string containing a comma separated list of host:port pairs,
+     * each corresponding to a ZooKeeper server.
+     * <p>
+     * Session establishment is asynchronous. This constructor will initiate
+     * connection to the server and return immediately - potentially (usually)
+     * before the session is fully established. The watcher argument specifies
+     * the watcher that will be notified of any changes in state. This
+     * notification can come at any point before or after the constructor call
+     * has returned.
+     * <p>
+     * The instantiated ZooKeeper client object will pick an arbitrary server
+     * from the connectString and attempt to connect to it. If establishment of
+     * the connection fails, another server in the connect string will be tried
+     * (the order is non-deterministic, as we random shuffle the list), until a
+     * connection is established. The client will continue attempts until the
+     * session is explicitly closed.
+     * <p>
+     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
+     * connection string. This will run the client commands while interpreting
+     * all paths relative to this root (similar to the unix chroot command).
+     *
+     * @param connectString
+     *            comma separated host:port pairs, each corresponding to a zk
+     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If
+     *            the optional chroot suffix is used the example would look
+     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
+     *            where the client would be rooted at "/app/a" and all paths
+     *            would be relative to this root - ie getting/setting/etc...
+     *            "/foo/bar" would result in operations being run on
+     *            "/app/a/foo/bar" (from the server perspective).
+     * @param sessionTimeout
+     *            session timeout in milliseconds
+     * @param watcher
+     *            a watcher object which will be notified of state changes, may
+     *            also be notified for node events
+     * @param canBeReadOnly
+     *            (added in 3.4) whether the created client is allowed to go to
+     *            read-only mode in case of partitioning. Read-only mode
+     *            basically means that if the client can't find any majority
+     *            servers but there's partitioned server it could reach, it
+     *            connects to one in read-only mode, i.e. read requests are
+     *            allowed while write requests are not. It continues seeking for
+     *            majority in the background.
+     *
+     * @throws IOException
+     *             in cases of network failure
+     * @throws IllegalArgumentException
+     *             if an invalid chroot path is specified
+     */
+    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
+            boolean canBeReadOnly)
+        throws IOException
+    {
+        LOG.info("Initiating client connection, connectString=" + connectString
+                + " sessionTimeout=" + sessionTimeout + " watcher=" + watcher);
+
+        watchManager.defaultWatcher = watcher;
+
+        ConnectStringParser connectStringParser = new ConnectStringParser(
+                connectString);
+        HostProvider hostProvider = new StaticHostProvider(
+                connectStringParser.getServerAddresses());
+        cnxn = new ClientCnxn(connectStringParser.getChrootPath(),
+                hostProvider, sessionTimeout, this, watchManager,
+                getClientCnxnSocket(), canBeReadOnly);
+        cnxn.start();
+    }
+
+    /**
+     * To create a ZooKeeper client object, the application needs to pass a
+     * connection string containing a comma separated list of host:port pairs,
+     * each corresponding to a ZooKeeper server.
+     * <p>
+     * Session establishment is asynchronous. This constructor will initiate
+     * connection to the server and return immediately - potentially (usually)
+     * before the session is fully established. The watcher argument specifies
+     * the watcher that will be notified of any changes in state. This
+     * notification can come at any point before or after the constructor call
+     * has returned.
+     * <p>
+     * The instantiated ZooKeeper client object will pick an arbitrary server
+     * from the connectString and attempt to connect to it. If establishment of
+     * the connection fails, another server in the connect string will be tried
+     * (the order is non-deterministic, as we random shuffle the list), until a
+     * connection is established. The client will continue attempts until the
+     * session is explicitly closed (or the session is expired by the server).
+     * <p>
+     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
+     * connection string. This will run the client commands while interpreting
+     * all paths relative to this root (similar to the unix chroot command).
+     * <p>
+     * Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
+     * client connection, these values must be passed as sessionId and
+     * sessionPasswd respectively if reconnecting. Otherwise, if not
+     * reconnecting, use the other constructor which does not require these
+     * parameters.
+     *
+     * @param connectString
+     *            comma separated host:port pairs, each corresponding to a zk
+     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
+     *            If the optional chroot suffix is used the example would look
+     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
+     *            where the client would be rooted at "/app/a" and all paths
+     *            would be relative to this root - ie getting/setting/etc...
+     *            "/foo/bar" would result in operations being run on
+     *            "/app/a/foo/bar" (from the server perspective).
+     * @param sessionTimeout
+     *            session timeout in milliseconds
+     * @param watcher
+     *            a watcher object which will be notified of state changes, may
+     *            also be notified for node events
+     * @param sessionId
+     *            specific session id to use if reconnecting
+     * @param sessionPasswd
+     *            password for this session
+     *
+     * @throws IOException in cases of network failure
+     * @throws IllegalArgumentException if an invalid chroot path is specified
+     * @throws IllegalArgumentException for an invalid list of ZooKeeper hosts
+     */
+    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
+            long sessionId, byte[] sessionPasswd)
+        throws IOException
+    {
+        this(connectString, sessionTimeout, watcher, sessionId, sessionPasswd, false);
+    }
+
+    /**
+     * To create a ZooKeeper client object, the application needs to pass a
+     * connection string containing a comma separated list of host:port pairs,
+     * each corresponding to a ZooKeeper server.
+     * <p>
+     * Session establishment is asynchronous. This constructor will initiate
+     * connection to the server and return immediately - potentially (usually)
+     * before the session is fully established. The watcher argument specifies
+     * the watcher that will be notified of any changes in state. This
+     * notification can come at any point before or after the constructor call
+     * has returned.
+     * <p>
+     * The instantiated ZooKeeper client object will pick an arbitrary server
+     * from the connectString and attempt to connect to it. If establishment of
+     * the connection fails, another server in the connect string will be tried
+     * (the order is non-deterministic, as we random shuffle the list), until a
+     * connection is established. The client will continue attempts until the
+     * session is explicitly closed (or the session is expired by the server).
+     * <p>
+     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
+     * connection string. This will run the client commands while interpreting
+     * all paths relative to this root (similar to the unix chroot command).
+     * <p>
+     * Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
+     * client connection, these values must be passed as sessionId and
+     * sessionPasswd respectively if reconnecting. Otherwise, if not
+     * reconnecting, use the other constructor which does not require these
+     * parameters.
+     *
+     * @param connectString
+     *            comma separated host:port pairs, each corresponding to a zk
+     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
+     *            If the optional chroot suffix is used the example would look
+     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
+     *            where the client would be rooted at "/app/a" and all paths
+     *            would be relative to this root - ie getting/setting/etc...
+     *            "/foo/bar" would result in operations being run on
+     *            "/app/a/foo/bar" (from the server perspective).
+     * @param sessionTimeout
+     *            session timeout in milliseconds
+     * @param watcher
+     *            a watcher object which will be notified of state changes, may
+     *            also be notified for node events
+     * @param sessionId
+     *            specific session id to use if reconnecting
+     * @param sessionPasswd
+     *            password for this session
+     * @param canBeReadOnly
+     *            (added in 3.4) whether the created client is allowed to go to
+     *            read-only mode in case of partitioning. Read-only mode
+     *            basically means that if the client can't find any majority
+     *            servers but there's partitioned server it could reach, it
+     *            connects to one in read-only mode, i.e. read requests are
+     *            allowed while write requests are not. It continues seeking for
+     *            majority in the background.
+     *
+     * @throws IOException in cases of network failure
+     * @throws IllegalArgumentException if an invalid chroot path is specified
+     */
+    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
+            long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
+        throws IOException
+    {
+        LOG.info("Initiating client connection, connectString=" + connectString
+                + " sessionTimeout=" + sessionTimeout
+                + " watcher=" + watcher
+                + " sessionId=" + Long.toHexString(sessionId)
+                + " sessionPasswd="
+                + (sessionPasswd == null ? "<null>" : "<hidden>"));
+
+        watchManager.defaultWatcher = watcher;
+
+        ConnectStringParser connectStringParser = new ConnectStringParser(
+                connectString);
+        HostProvider hostProvider = new StaticHostProvider(
+                connectStringParser.getServerAddresses());
+        cnxn = new ClientCnxn(connectStringParser.getChrootPath(),
+                hostProvider, sessionTimeout, this, watchManager,
+                getClientCnxnSocket(), sessionId, sessionPasswd, canBeReadOnly);
+        cnxn.seenRwServerBefore = true; // since user has provided sessionId
+        cnxn.start();
+    }
+
+    // VisibleForTesting
+    public Testable getTestable() {
+        return new ZooKeeperTestable(this, cnxn);
+    }
+
+    /**
+     * The session id for this ZooKeeper client instance. The value returned is
+     * not valid until the client connects to a server and may change after a
+     * re-connect.
+     *
+     * This method is NOT thread safe
+     *
+     * @return current session id
+     */
+    public long getSessionId() {
+        return cnxn.getSessionId();
+    }
+
+    /**
+     * The session password for this ZooKeeper client instance. The value
+     * returned is not valid until the client connects to a server and may
+     * change after a re-connect.
+     *
+     * This method is NOT thread safe
+     *
+     * @return current session password
+     */
+    public byte[] getSessionPasswd() {
+        return cnxn.getSessionPasswd();
+    }
+
+    /**
+     * The negotiated session timeout for this ZooKeeper client instance. The
+     * value returned is not valid until the client connects to a server and
+     * may change after a re-connect.
+     *
+     * This method is NOT thread safe
+     *
+     * @return current session timeout
+     */
+    public int getSessionTimeout() {
+        return cnxn.getSessionTimeout();
+    }
+
+    /**
+     * Add the specified scheme:auth information to this connection.
+     *
+     * This method is NOT thread safe
+     *
+     * @param scheme
+     * @param auth
+     */
+    public void addAuthInfo(String scheme, byte auth[]) {
+        cnxn.addAuthInfo(scheme, auth);
+    }
+
+    /**
+     * Specify the default watcher for the connection (overrides the one
+     * specified during construction).
+     *
+     * @param watcher
+     */
+    public synchronized void register(Watcher watcher) {
+        watchManager.defaultWatcher = watcher;
+    }
+
+    /**
+     * Close this client object. Once the client is closed, its session becomes
+     * invalid. All the ephemeral nodes in the ZooKeeper server associated with
+     * the session will be removed. The watches left on those nodes (and on
+     * their parents) will be triggered.
+     *
+     * @throws InterruptedException
+     */
+    public synchronized void close() throws InterruptedException {
+        if (!cnxn.getState().isAlive()) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Close called on already closed client");
+            }
+            return;
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Closing session: 0x" + Long.toHexString(getSessionId()));
+        }
+
+        try {
+            cnxn.close();
+        } catch (IOException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Ignoring unexpected exception during close", e);
+            }
+        }
+
+        LOG.info("Session: 0x" + Long.toHexString(getSessionId()) + " closed");
+    }
+
+    /**
+     * Prepend the chroot to the client path (if present). The expectation of
+     * this function is that the client path has been validated before this
+     * function is called
+     * @param clientPath path to the node
+     * @return server view of the path (chroot prepended to client path)
+     */
+    private String prependChroot(String clientPath) {
+        if (cnxn.chrootPath != null) {
+            // handle clientPath = "/"
+            if (clientPath.length() == 1) {
+                return cnxn.chrootPath;
+            }
+            return cnxn.chrootPath + clientPath;
+        } else {
+            return clientPath;
+        }
+    }
+
+    /**
+     * Create a node with the given path. The node data will be the given data,
+     * and node acl will be the given acl.
+     * <p>
+     * The flags argument specifies whether the created node will be ephemeral
+     * or not.
+     * <p>
+     * An ephemeral node will be removed by the ZooKeeper automatically when the
+     * session associated with the creation of the node expires.
+     * <p>
+     * The flags argument can also specify to create a sequential node. The
+     * actual path name of a sequential node will be the given path plus a
+     * suffix "i" where i is the current sequential number of the node. The sequence
+     * number is always fixed length of 10 digits, 0 padded. Once
+     * such a node is created, the sequential number will be incremented by one.
+     * <p>
+     * If a node with the same actual path already exists in the ZooKeeper, a
+     * KeeperException with error code KeeperException.NodeExists will be
+     * thrown. Note that since a different actual path is used for each
+     * invocation of creating sequential node with the same path argument, the
+     * call will never throw "file exists" KeeperException.
+     * <p>
+     * If the parent node does not exist in the ZooKeeper, a KeeperException
+     * with error code KeeperException.NoNode will be thrown.
+     * <p>
+     * An ephemeral node cannot have children. If the parent node of the given
+     * path is ephemeral, a KeeperException with error code
+     * KeeperException.NoChildrenForEphemerals will be thrown.
+     * <p>
+     * This operation, if successful, will trigger all the watches left on the
+     * node of the given path by exists and getData API calls, and the watches
+     * left on the parent node by getChildren API calls.
+     * <p>
+     * If a node is created successfully, the ZooKeeper server will trigger the
+     * watches on the path left by exists calls, and the watches on the parent
+     * of the node by getChildren calls.
+     * <p>
+     * The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
+     * Arrays larger than this will cause a KeeperExecption to be thrown.
+     *
+     * @param path
+     *                the path for the node
+     * @param data
+     *                the initial data for the node
+     * @param acl
+     *                the acl for the node
+     * @param createMode
+     *                specifying whether the node to be created is ephemeral
+     *                and/or sequential
+     * @return the actual path of the created node
+     * @throws KeeperException if the server returns a non-zero error code
+     * @throws KeeperException.InvalidACLException if the ACL is invalid, null, or empty
+     * @throws InterruptedException if the transaction is interrupted
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public String create(final String path, byte data[], List<ACL> acl,
+            CreateMode createMode)
+        throws KeeperException, InterruptedException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath, createMode.isSequential());
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.create);
+        CreateRequest request = new CreateRequest();
+        CreateResponse response = new CreateResponse();
+        request.setData(data);
+        request.setFlags(createMode.toFlag());
+        request.setPath(serverPath);
+        if (acl != null && acl.size() == 0) {
+            throw new KeeperException.InvalidACLException();
+        }
+        request.setAcl(acl);
+        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+        if (cnxn.chrootPath == null) {
+            return response.getPath();
+        } else {
+            return response.getPath().substring(cnxn.chrootPath.length());
+        }
+    }
+
+    /**
+     * The asynchronous version of create.
+     *
+     * @see #create(String, byte[], List, CreateMode)
+     */
+
+    public void create(final String path, byte data[], List<ACL> acl,
+            CreateMode createMode,  StringCallback cb, Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath, createMode.isSequential());
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.create);
+        CreateRequest request = new CreateRequest();
+        CreateResponse response = new CreateResponse();
+        ReplyHeader r = new ReplyHeader();
+        request.setData(data);
+        request.setFlags(createMode.toFlag());
+        request.setPath(serverPath);
+        request.setAcl(acl);
+        cnxn.queuePacket(h, r, request, response, cb, clientPath,
+                serverPath, ctx, null);
+    }
+
+    /**
+     * Delete the node with the given path. The call will succeed if such a node
+     * exists, and the given version matches the node's version (if the given
+     * version is -1, it matches any node's versions).
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if the nodes does not exist.
+     * <p>
+     * A KeeperException with error code KeeperException.BadVersion will be
+     * thrown if the given version does not match the node's version.
+     * <p>
+     * A KeeperException with error code KeeperException.NotEmpty will be thrown
+     * if the node has children.
+     * <p>
+     * This operation, if successful, will trigger all the watches on the node
+     * of the given path left by exists API calls, and the watches on the parent
+     * node left by getChildren API calls.
+     *
+     * @param path
+     *                the path of the node to be deleted.
+     * @param version
+     *                the expected node version.
+     * @throws InterruptedException IF the server transaction is interrupted
+     * @throws KeeperException If the server signals an error with a non-zero
+     *   return code.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public void delete(final String path, int version)
+        throws InterruptedException, KeeperException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath;
+
+        // maintain semantics even in chroot case
+        // specifically - root cannot be deleted
+        // I think this makes sense even in chroot case.
+        if (clientPath.equals("/")) {
+            // a bit of a hack, but delete(/) will never succeed and ensures
+            // that the same semantics are maintained
+            serverPath = clientPath;
+        } else {
+            serverPath = prependChroot(clientPath);
+        }
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.delete);
+        DeleteRequest request = new DeleteRequest();
+        request.setPath(serverPath);
+        request.setVersion(version);
+        ReplyHeader r = cnxn.submitRequest(h, request, null, null);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+    }
+
+    /**
+     * Executes multiple ZooKeeper operations or none of them.
+     * <p>
+     * On success, a list of results is returned.
+     * On failure, an exception is raised which contains partial results and
+     * error details, see {@link KeeperException#getResults}
+     * <p>
+     * Note: The maximum allowable size of all of the data arrays in all of
+     * the setData operations in this single request is typically 1 MB
+     * (1,048,576 bytes). This limit is specified on the server via
+     * <a href="http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#Unsafe+Options">jute.maxbuffer</a>.
+     * Requests larger than this will cause a KeeperException to be
+     * thrown.
+     *
+     * @param ops An iterable that contains the operations to be done.
+     * These should be created using the factory methods on {@link Op}.
+     * @return A list of results, one for each input Op, the order of
+     * which exactly matches the order of the <code>ops</code> input
+     * operations.
+     * @throws InterruptedException If the operation was interrupted.
+     * The operation may or may not have succeeded, but will not have
+     * partially succeeded if this exception is thrown.
+     * @throws KeeperException If the operation could not be completed
+     * due to some error in doing one of the specified ops.
+     * @throws IllegalArgumentException if an invalid path is specified
+     *
+     * @since 3.4.0
+     */
+    public List<OpResult> multi(Iterable<Op> ops) throws InterruptedException, KeeperException {
+        for (Op op : ops) {
+            op.validate();
+        }
+        return multiInternal(generateMultiTransaction(ops));
+    }
+
+    /**
+     * The asynchronous version of multi.
+     *
+     * @see #multi(Iterable)
+     * @since 3.4.7
+     */
+    public void multi(Iterable<Op> ops, MultiCallback cb, Object ctx) {
+        List<OpResult> results = validatePath(ops);
+        if (results.size() > 0) {
+            cb.processResult(KeeperException.Code.BADARGUMENTS.intValue(),
+                             null, ctx, results);
+            return;
+        }
+        multiInternal(generateMultiTransaction(ops), cb, ctx);
+    }
+
+    private List<OpResult> validatePath(Iterable<Op> ops) {
+        List<OpResult> results = new ArrayList<OpResult>();
+        boolean error = false;
+        for (Op op : ops) {
+            try {
+                op.validate();
+            } catch (IllegalArgumentException iae) {
+                LOG.error("IllegalArgumentException: " + iae.getMessage());
+                ErrorResult err = new ErrorResult(
+                        KeeperException.Code.BADARGUMENTS.intValue());
+                results.add(err);
+                error = true;
+                continue;
+            } catch (KeeperException ke) {
+                LOG.error("KeeperException: " + ke.getMessage());
+                ErrorResult err = new ErrorResult(ke.code().intValue());
+                results.add(err);
+                error = true;
+                continue;
+            }
+            ErrorResult err = new ErrorResult(
+                    KeeperException.Code.RUNTIMEINCONSISTENCY.intValue());
+            results.add(err);
+        }
+        if (false == error) {
+            results.clear();
+        }
+        return results;
+    }
+
+    private MultiTransactionRecord generateMultiTransaction(Iterable<Op> ops) {
+        List<Op> transaction = new ArrayList<Op>();
+
+        for (Op op : ops) {
+            transaction.add(withRootPrefix(op));
+        }
+        return new MultiTransactionRecord(transaction);
+    }
+
+    private Op withRootPrefix(Op op) {
+        if (null != op.getPath()) {
+            final String serverPath = prependChroot(op.getPath());
+            if (!op.getPath().equals(serverPath)) {
+                return op.withChroot(serverPath);
+            }
+        }
+        return op;
+    }
+
+    protected void multiInternal(MultiTransactionRecord request, MultiCallback cb, Object ctx) {
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.multi);
+        MultiResponse response = new MultiResponse();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, null, null, ctx, null);
+    }
+
+    protected List<OpResult> multiInternal(MultiTransactionRecord request)
+        throws InterruptedException, KeeperException {
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.multi);
+        MultiResponse response = new MultiResponse();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()));
+        }
+
+        List<OpResult> results = response.getResultList();
+        
+        ErrorResult fatalError = null;
+        for (OpResult result : results) {
+            if (result instanceof ErrorResult && ((ErrorResult)result).getErr() != KeeperException.Code.OK.intValue()) {
+                fatalError = (ErrorResult) result;
+                break;
+            }
+        }
+
+        if (fatalError != null) {
+            KeeperException ex = KeeperException.create(KeeperException.Code.get(fatalError.getErr()));
+            ex.setMultiResults(results);
+            throw ex;
+        }
+
+        return results;
+    }
+
+    /**
+     * A Transaction is a thin wrapper on the {@link #multi} method
+     * which provides a builder object that can be used to construct
+     * and commit an atomic set of operations.
+     *
+     * @since 3.4.0
+     *
+     * @return a Transaction builder object
+     */
+    public Transaction transaction() {
+        return new Transaction(this);
+    }
+
+    /**
+     * The asynchronous version of delete.
+     *
+     * @see #delete(String, int)
+     */
+    public void delete(final String path, int version, VoidCallback cb,
+            Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath;
+
+        // maintain semantics even in chroot case
+        // specifically - root cannot be deleted
+        // I think this makes sense even in chroot case.
+        if (clientPath.equals("/")) {
+            // a bit of a hack, but delete(/) will never succeed and ensures
+            // that the same semantics are maintained
+            serverPath = clientPath;
+        } else {
+            serverPath = prependChroot(clientPath);
+        }
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.delete);
+        DeleteRequest request = new DeleteRequest();
+        request.setPath(serverPath);
+        request.setVersion(version);
+        cnxn.queuePacket(h, new ReplyHeader(), request, null, cb, clientPath,
+                serverPath, ctx, null);
+    }
+
+    /**
+     * Return the stat of the node of the given path. Return null if no such a
+     * node exists.
+     * <p>
+     * If the watch is non-null and the call is successful (no exception is thrown),
+     * a watch will be left on the node with the given path. The watch will be
+     * triggered by a successful operation that creates/delete the node or sets
+     * the data on the node.
+     *
+     * @param path the node path
+     * @param watcher explicit watcher
+     * @return the stat of the node of the given path; return null if no such a
+     *         node exists.
+     * @throws KeeperException If the server signals an error
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public Stat exists(final String path, Watcher watcher)
+        throws KeeperException, InterruptedException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new ExistsWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.exists);
+        ExistsRequest request = new ExistsRequest();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        SetDataResponse response = new SetDataResponse();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
+        if (r.getErr() != 0) {
+            if (r.getErr() == KeeperException.Code.NONODE.intValue()) {
+                return null;
+            }
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+
+        return response.getStat().getCzxid() == -1 ? null : response.getStat();
+    }
+
+    /**
+     * Return the stat of the node of the given path. Return null if no such a
+     * node exists.
+     * <p>
+     * If the watch is true and the call is successful (no exception is thrown),
+     * a watch will be left on the node with the given path. The watch will be
+     * triggered by a successful operation that creates/delete the node or sets
+     * the data on the node.
+     *
+     * @param path
+     *                the node path
+     * @param watch
+     *                whether need to watch this node
+     * @return the stat of the node of the given path; return null if no such a
+     *         node exists.
+     * @throws KeeperException If the server signals an error
+     * @throws InterruptedException If the server transaction is interrupted.
+     */
+    public Stat exists(String path, boolean watch) throws KeeperException,
+        InterruptedException
+    {
+        return exists(path, watch ? watchManager.defaultWatcher : null);
+    }
+
+    /**
+     * The asynchronous version of exists.
+     *
+     * @see #exists(String, Watcher)
+     */
+    public void exists(final String path, Watcher watcher,
+            StatCallback cb, Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new ExistsWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.exists);
+        ExistsRequest request = new ExistsRequest();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        SetDataResponse response = new SetDataResponse();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, wcb);
+    }
+
+    /**
+     * The asynchronous version of exists.
+     *
+     * @see #exists(String, boolean)
+     */
+    public void exists(String path, boolean watch, StatCallback cb, Object ctx) {
+        exists(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
+    }
+
+    /**
+     * Return the data and the stat of the node of the given path.
+     * <p>
+     * If the watch is non-null and the call is successful (no exception is
+     * thrown), a watch will be left on the node with the given path. The watch
+     * will be triggered by a successful operation that sets data on the node, or
+     * deletes the node.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     *
+     * @param path the given path
+     * @param watcher explicit watcher
+     * @param stat the stat of the node
+     * @return the data of the node
+     * @throws KeeperException If the server signals an error with a non-zero error code
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public byte[] getData(final String path, Watcher watcher, Stat stat)
+        throws KeeperException, InterruptedException
+     {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new DataWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getData);
+        GetDataRequest request = new GetDataRequest();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        GetDataResponse response = new GetDataResponse();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+        if (stat != null) {
+            DataTree.copyStat(response.getStat(), stat);
+        }
+        return response.getData();
+    }
+
+    /**
+     * Return the data and the stat of the node of the given path.
+     * <p>
+     * If the watch is true and the call is successful (no exception is
+     * thrown), a watch will be left on the node with the given path. The watch
+     * will be triggered by a successful operation that sets data on the node, or
+     * deletes the node.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     *
+     * @param path the given path
+     * @param watch whether need to watch this node
+     * @param stat the stat of the node
+     * @return the data of the node
+     * @throws KeeperException If the server signals an error with a non-zero error code
+     * @throws InterruptedException If the server transaction is interrupted.
+     */
+    public byte[] getData(String path, boolean watch, Stat stat)
+            throws KeeperException, InterruptedException {
+        return getData(path, watch ? watchManager.defaultWatcher : null, stat);
+    }
+
+    /**
+     * The asynchronous version of getData.
+     *
+     * @see #getData(String, Watcher, Stat)
+     */
+    public void getData(final String path, Watcher watcher,
+            DataCallback cb, Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new DataWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getData);
+        GetDataRequest request = new GetDataRequest();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        GetDataResponse response = new GetDataResponse();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, wcb);
+    }
+
+    /**
+     * The asynchronous version of getData.
+     *
+     * @see #getData(String, boolean, Stat)
+     */
+    public void getData(String path, boolean watch, DataCallback cb, Object ctx) {
+        getData(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
+    }
+
+    /**
+     * Set the data for the node of the given path if such a node exists and the
+     * given version matches the version of the node (if the given version is
+     * -1, it matches any node's versions). Return the stat of the node.
+     * <p>
+     * This operation, if successful, will trigger all the watches on the node
+     * of the given path left by getData calls.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     * <p>
+     * A KeeperException with error code KeeperException.BadVersion will be
+     * thrown if the given version does not match the node's version.
+     * <p>
+     * The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
+     * Arrays larger than this will cause a KeeperException to be thrown.
+     *
+     * @param path
+     *                the path of the node
+     * @param data
+     *                the data to set
+     * @param version
+     *                the expected matching version
+     * @return the state of the node
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws KeeperException If the server signals an error with a non-zero error code.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public Stat setData(final String path, byte data[], int version)
+        throws KeeperException, InterruptedException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.setData);
+        SetDataRequest request = new SetDataRequest();
+        request.setPath(serverPath);
+        request.setData(data);
+        request.setVersion(version);
+        SetDataResponse response = new SetDataResponse();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+        return response.getStat();
+    }
+
+    /**
+     * The asynchronous version of setData.
+     *
+     * @see #setData(String, byte[], int)
+     */
+    public void setData(final String path, byte data[], int version,
+            StatCallback cb, Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.setData);
+        SetDataRequest request = new SetDataRequest();
+        request.setPath(serverPath);
+        request.setData(data);
+        request.setVersion(version);
+        SetDataResponse response = new SetDataResponse();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, null);
+    }
+
+    /**
+     * Return the ACL and stat of the node of the given path.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     *
+     * @param path
+     *                the given path for the node
+     * @param stat
+     *                the stat of the node will be copied to this parameter if
+     *                not null.
+     * @return the ACL array of the given node.
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws KeeperException If the server signals an error with a non-zero error code.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public List<ACL> getACL(final String path, Stat stat)
+        throws KeeperException, InterruptedException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getACL);
+        GetACLRequest request = new GetACLRequest();
+        request.setPath(serverPath);
+        GetACLResponse response = new GetACLResponse();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+        if (stat != null) {
+            DataTree.copyStat(response.getStat(), stat);
+        }
+        return response.getAcl();
+    }
+
+    /**
+     * The asynchronous version of getACL.
+     *
+     * @see #getACL(String, Stat)
+     */
+    public void getACL(final String path, Stat stat, ACLCallback cb,
+            Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getACL);
+        GetACLRequest request = new GetACLRequest();
+        request.setPath(serverPath);
+        GetACLResponse response = new GetACLResponse();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, null);
+    }
+
+    /**
+     * Set the ACL for the node of the given path if such a node exists and the
+     * given aclVersion matches the acl version of the node. Return the stat of the
+     * node.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     * <p>
+     * A KeeperException with error code KeeperException.BadVersion will be
+     * thrown if the given aclVersion does not match the node's aclVersion.
+     *
+     * @param path the given path for the node
+     * @param acl the given acl for the node
+     * @param aclVersion the given acl version of the node
+     * @return the stat of the node.
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws KeeperException If the server signals an error with a non-zero error code.
+     * @throws org.apache.zookeeper.KeeperException.InvalidACLException If the acl is invalide.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public Stat setACL(final String path, List<ACL> acl, int aclVersion)
+        throws KeeperException, InterruptedException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.setACL);
+        SetACLRequest request = new SetACLRequest();
+        request.setPath(serverPath);
+        if (acl != null && acl.size() == 0) {
+            throw new KeeperException.InvalidACLException(clientPath);
+        }
+        request.setAcl(acl);
+        request.setVersion(aclVersion);
+        SetACLResponse response = new SetACLResponse();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+        return response.getStat();
+    }
+
+    /**
+     * The asynchronous version of setACL.
+     *
+     * @see #setACL(String, List, int)
+     */
+    public void setACL(final String path, List<ACL> acl, int version,
+            StatCallback cb, Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.setACL);
+        SetACLRequest request = new SetACLRequest();
+        request.setPath(serverPath);
+        request.setAcl(acl);
+        request.setVersion(version);
+        SetACLResponse response = new SetACLResponse();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, null);
+    }
+
+    /**
+     * Return the list of the children of the node of the given path.
+     * <p>
+     * If the watch is non-null and the call is successful (no exception is thrown),
+     * a watch will be left on the node with the given path. The watch willbe
+     * triggered by a successful operation that deletes the node of the given
+     * path or creates/delete a child under the node.
+     * <p>
+     * The list of children returned is not sorted and no guarantee is provided
+     * as to its natural or lexical order.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     *
+     * @param path
+     * @param watcher explicit watcher
+     * @return an unordered array of children of the node with the given path
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws KeeperException If the server signals an error with a non-zero error code.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public List<String> getChildren(final String path, Watcher watcher)
+        throws KeeperException, InterruptedException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new ChildWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getChildren);
+        GetChildrenRequest request = new GetChildrenRequest();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        GetChildrenResponse response = new GetChildrenResponse();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+        return response.getChildren();
+    }
+
+    /**
+     * Return the list of the children of the node of the given path.
+     * <p>
+     * If the watch is true and the call is successful (no exception is thrown),
+     * a watch will be left on the node with the given path. The watch willbe
+     * triggered by a successful operation that deletes the node of the given
+     * path or creates/delete a child under the node.
+     * <p>
+     * The list of children returned is not sorted and no guarantee is provided
+     * as to its natural or lexical order.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     *
+     * @param path
+     * @param watch
+     * @return an unordered array of children of the node with the given path
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws KeeperException If the server signals an error with a non-zero error code.
+     */
+    public List<String> getChildren(String path, boolean watch)
+            throws KeeperException, InterruptedException {
+        return getChildren(path, watch ? watchManager.defaultWatcher : null);
+    }
+
+    /**
+     * The asynchronous version of getChildren.
+     *
+     * @see #getChildren(String, Watcher)
+     */
+    public void getChildren(final String path, Watcher watcher,
+            ChildrenCallback cb, Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new ChildWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getChildren);
+        GetChildrenRequest request = new GetChildrenRequest();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        GetChildrenResponse response = new GetChildrenResponse();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, wcb);
+    }
+
+    /**
+     * The asynchronous version of getChildren.
+     *
+     * @see #getChildren(String, boolean)
+     */
+    public void getChildren(String path, boolean watch, ChildrenCallback cb,
+            Object ctx)
+    {
+        getChildren(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
+    }
+
+    /**
+     * For the given znode path return the stat and children list.
+     * <p>
+     * If the watch is non-null and the call is successful (no exception is thrown),
+     * a watch will be left on the node with the given path. The watch willbe
+     * triggered by a successful operation that deletes the node of the given
+     * path or creates/delete a child under the node.
+     * <p>
+     * The list of children returned is not sorted and no guarantee is provided
+     * as to its natural or lexical order.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     *
+     * @since 3.3.0
+     * 
+     * @param path
+     * @param watcher explicit watcher
+     * @param stat stat of the znode designated by path
+     * @return an unordered array of children of the node with the given path
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws KeeperException If the server signals an error with a non-zero error code.
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public List<String> getChildren(final String path, Watcher watcher,
+            Stat stat)
+        throws KeeperException, InterruptedException
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new ChildWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getChildren2);
+        GetChildren2Request request = new GetChildren2Request();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        GetChildren2Response response = new GetChildren2Response();
+        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
+        if (r.getErr() != 0) {
+            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
+                    clientPath);
+        }
+        if (stat != null) {
+            DataTree.copyStat(response.getStat(), stat);
+        }
+        return response.getChildren();
+    }
+
+    /**
+     * For the given znode path return the stat and children list.
+     * <p>
+     * If the watch is true and the call is successful (no exception is thrown),
+     * a watch will be left on the node with the given path. The watch willbe
+     * triggered by a successful operation that deletes the node of the given
+     * path or creates/delete a child under the node.
+     * <p>
+     * The list of children returned is not sorted and no guarantee is provided
+     * as to its natural or lexical order.
+     * <p>
+     * A KeeperException with error code KeeperException.NoNode will be thrown
+     * if no node with the given path exists.
+     *
+     * @since 3.3.0
+     * 
+     * @param path
+     * @param watch
+     * @param stat stat of the znode designated by path
+     * @return an unordered array of children of the node with the given path
+     * @throws InterruptedException If the server transaction is interrupted.
+     * @throws KeeperException If the server signals an error with a non-zero
+     *  error code.
+     */
+    public List<String> getChildren(String path, boolean watch, Stat stat)
+            throws KeeperException, InterruptedException {
+        return getChildren(path, watch ? watchManager.defaultWatcher : null,
+                stat);
+    }
+
+    /**
+     * The asynchronous version of getChildren.
+     *
+     * @since 3.3.0
+     * 
+     * @see #getChildren(String, Watcher, Stat)
+     */
+    public void getChildren(final String path, Watcher watcher,
+            Children2Callback cb, Object ctx)
+    {
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        // the watch contains the un-chroot path
+        WatchRegistration wcb = null;
+        if (watcher != null) {
+            wcb = new ChildWatchRegistration(watcher, clientPath);
+        }
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.getChildren2);
+        GetChildren2Request request = new GetChildren2Request();
+        request.setPath(serverPath);
+        request.setWatch(watcher != null);
+        GetChildren2Response response = new GetChildren2Response();
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, wcb);
+    }
+
+    /**
+     * The asynchronous version of getChildren.
+     *
+     * @since 3.3.0
+     * 
+     * @see #getChildren(String, boolean, Stat)
+     */
+    public void getChildren(String path, boolean watch, Children2Callback cb,
+            Object ctx)
+    {
+        getChildren(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
+    }
+
+    /**
+     * Asynchronous sync. Flushes channel between process and leader.
+     * @param path
+     * @param cb a handler for the callback
+     * @param ctx context to be provided to the callback
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public void sync(final String path, VoidCallback cb, Object ctx){
+        final String clientPath = path;
+        PathUtils.validatePath(clientPath);
+
+        final String serverPath = prependChroot(clientPath);
+
+        RequestHeader h = new RequestHeader();
+        h.setType(ZooDefs.OpCode.sync);
+        SyncRequest request = new SyncRequest();
+        SyncResponse response = new SyncResponse();
+        request.setPath(serverPath);
+        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
+                clientPath, serverPath, ctx, null);
+    }
+
+    public States getState() {
+        return cnxn.getState();
+    }
+
+    /**
+     * String representation of this ZooKeeper client. Suitable for things
+     * like logging.
+     * 
+     * Do NOT count on the format of this string, it may change without
+     * warning.
+     * 
+     * @since 3.3.0
+     */
+    @Override
+    public String toString() {
+        States state = getState();
+        return ("State:" + state.toString()
+                + (state.isConnected() ?
+                        " Timeout:" + getSessionTimeout() + " " :
+                        " ")
+                + cnxn);
+    }
+
+    /*
+     * Methods to aid in testing follow.
+     * 
+     * THESE METHODS ARE EXPECTED TO BE USED FOR TESTING ONLY!!!
+     */
+
+    /**
+     * Wait up to wait milliseconds for the underlying threads to shutdown.
+     * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
+     * 
+     * @since 3.3.0
+     * 
+     * @param wait max wait in milliseconds
+     * @return true iff all threads are shutdown, otw false
+     */
+    protected boolean testableWaitForShutdown(int wait)
+        throws InterruptedException
+    {
+        cnxn.sendThread.join(wait);
+        if (cnxn.sendThread.isAlive()) return false;
+        cnxn.eventThread.join(wait);
+        if (cnxn.eventThread.isAlive()) return false;
+        return true;
+    }
+
+    /**
+     * Returns the address to which the socket is connected. Useful for testing
+     * against an ensemble - test client may need to know which server
+     * to shutdown if interested in verifying that the code handles
+     * disconnection/reconnection correctly.
+     * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
+     *
+     * @since 3.3.0
+     * 
+     * @return ip address of the remote side of the connection or null if
+     *         not connected
+     */
+    protected SocketAddress testableRemoteSocketAddress() {
+        return cnxn.sendThread.getClientCnxnSocket().getRemoteSocketAddress();
+    }
+
+    /** 
+     * Returns the local address to which the socket is bound.
+     * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
+     *
+     * @since 3.3.0
+     * 
+     * @return ip address of the remote side of the connection or null if
+     *         not connected
+     */
+    protected SocketAddress testableLocalSocketAddress() {
+        return cnxn.sendThread.getClientCnxnSocket().getLocalSocketAddress();
+    }
+
+    private static ClientCnxnSocket getClientCnxnSocket() throws IOException {
+        String clientCnxnSocketName = System
+                .getProperty(ZOOKEEPER_CLIENT_CNXN_SOCKET);
+        if (clientCnxnSocketName == null) {
+            clientCnxnSocketName = ClientCnxnSocketNIO.class.getName();
+        }
+        try {
+            return (ClientCnxnSocket) Class.forName(clientCnxnSocketName).getDeclaredConstructor()
+                    .newInstance();
+        } catch (Exception e) {
+            IOException ioe = new IOException("Couldn't instantiate "
+                    + clientCnxnSocketName);
+            ioe.initCause(e);
+            throw ioe;
+        }
+    }
+}


[14/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java
new file mode 100644
index 0000000..6ca538b
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java
@@ -0,0 +1,871 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.data.Stat;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The command line client to ZooKeeper.
+ *
+ */
+@InterfaceAudience.Public
+public class ZooKeeperMain {
+    private static final Logger LOG = LoggerFactory.getLogger(ZooKeeperMain.class);
+    static final Map<String,String> commandMap = new HashMap<String,String>( );
+
+    protected MyCommandOptions cl = new MyCommandOptions();
+    protected HashMap<Integer,String> history = new HashMap<Integer,String>( );
+    protected int commandCount = 0;
+    protected boolean printWatches = true;
+
+    protected ZooKeeper zk;
+    protected String host = "";
+
+    public boolean getPrintWatches( ) {
+        return printWatches;
+    }
+
+    static {
+        commandMap.put("connect", "host:port");
+        commandMap.put("close","");
+        commandMap.put("create", "[-s] [-e] path data acl");
+        commandMap.put("delete","path [version]");
+        commandMap.put("rmr","path");
+        commandMap.put("set","path data [version]");
+        commandMap.put("get","path [watch]");
+        commandMap.put("ls","path [watch]");
+        commandMap.put("ls2","path [watch]");
+        commandMap.put("getAcl","path");
+        commandMap.put("setAcl","path acl");
+        commandMap.put("stat","path [watch]");
+        commandMap.put("sync","path");
+        commandMap.put("setquota","-n|-b val path");
+        commandMap.put("listquota","path");
+        commandMap.put("delquota","[-n|-b] path");
+        commandMap.put("history","");
+        commandMap.put("redo","cmdno");
+        commandMap.put("printwatches", "on|off");
+        commandMap.put("quit","");
+        commandMap.put("addauth", "scheme auth");
+    }
+
+    static void usage() {
+        System.err.println("ZooKeeper -server host:port cmd args");
+        for (Map.Entry<String, String> entry : commandMap.entrySet()) {
+            System.err.println("\t" + entry.getKey() + " " + entry.getValue());
+        }
+    }
+
+    private class MyWatcher implements Watcher {
+        public void process(WatchedEvent event) {
+            if (getPrintWatches()) {
+                ZooKeeperMain.printMessage("WATCHER::");
+                ZooKeeperMain.printMessage(event.toString());
+            }
+        }
+    }
+
+    static private int getPermFromString(String permString) {
+        int perm = 0;
+        for (int i = 0; i < permString.length(); i++) {
+            switch (permString.charAt(i)) {
+            case 'r':
+                perm |= ZooDefs.Perms.READ;
+                break;
+            case 'w':
+                perm |= ZooDefs.Perms.WRITE;
+                break;
+            case 'c':
+                perm |= ZooDefs.Perms.CREATE;
+                break;
+            case 'd':
+                perm |= ZooDefs.Perms.DELETE;
+                break;
+            case 'a':
+                perm |= ZooDefs.Perms.ADMIN;
+                break;
+            default:
+                System.err
+                .println("Unknown perm type: " + permString.charAt(i));
+            }
+        }
+        return perm;
+    }
+
+    private static void printStat(Stat stat) {
+        System.err.println("cZxid = 0x" + Long.toHexString(stat.getCzxid()));
+        System.err.println("ctime = " + new Date(stat.getCtime()).toString());
+        System.err.println("mZxid = 0x" + Long.toHexString(stat.getMzxid()));
+        System.err.println("mtime = " + new Date(stat.getMtime()).toString());
+        System.err.println("pZxid = 0x" + Long.toHexString(stat.getPzxid()));
+        System.err.println("cversion = " + stat.getCversion());
+        System.err.println("dataVersion = " + stat.getVersion());
+        System.err.println("aclVersion = " + stat.getAversion());
+        System.err.println("ephemeralOwner = 0x"
+        		+ Long.toHexString(stat.getEphemeralOwner()));
+        System.err.println("dataLength = " + stat.getDataLength());
+        System.err.println("numChildren = " + stat.getNumChildren());
+    }
+
+    /**
+     * A storage class for both command line options and shell commands.
+     *
+     */
+    static class MyCommandOptions {
+
+        private Map<String,String> options = new HashMap<String,String>();
+        private List<String> cmdArgs = null;
+        private String command = null;
+        public static final Pattern ARGS_PATTERN = Pattern.compile("\\s*([^\"\']\\S*|\"[^\"]*\"|'[^']*')\\s*");
+        public static final Pattern QUOTED_PATTERN = Pattern.compile("^([\'\"])(.*)(\\1)$");
+
+        public MyCommandOptions() {
+          options.put("server", "localhost:2181");
+          options.put("timeout", "30000");
+        }
+
+        public String getOption(String opt) {
+            return options.get(opt);
+        }
+
+        public String getCommand( ) {
+            return command;
+        }
+
+        public String getCmdArgument( int index ) {
+            return cmdArgs.get(index);
+        }
+
+        public int getNumArguments( ) {
+            return cmdArgs.size();
+        }
+
+        public String[] getArgArray() {
+            return cmdArgs.toArray(new String[0]);
+        }
+
+        /**
+         * Parses a command line that may contain one or more flags
+         * before an optional command string
+         * @param args command line arguments
+         * @return true if parsing succeeded, false otherwise.
+         */
+        public boolean parseOptions(String[] args) {
+            List<String> argList = Arrays.asList(args);
+            Iterator<String> it = argList.iterator();
+
+            while (it.hasNext()) {
+                String opt = it.next();
+                try {
+                    if (opt.equals("-server")) {
+                        options.put("server", it.next());
+                    } else if (opt.equals("-timeout")) {
+                        options.put("timeout", it.next());
+                    } else if (opt.equals("-r")) {
+                        options.put("readonly", "true");
+                    }
+                } catch (NoSuchElementException e){
+                    System.err.println("Error: no argument found for option "
+                            + opt);
+                    return false;
+                }
+
+                if (!opt.startsWith("-")) {
+                    command = opt;
+                    cmdArgs = new ArrayList<String>( );
+                    cmdArgs.add( command );
+                    while (it.hasNext()) {
+                        cmdArgs.add(it.next());
+                    }
+                    return true;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Breaks a string into command + arguments.
+         * @param cmdstring string of form "cmd arg1 arg2..etc"
+         * @return true if parsing succeeded.
+         */
+        public boolean parseCommand( String cmdstring ) {
+            Matcher matcher = ARGS_PATTERN.matcher(cmdstring);
+
+            List<String> args = new LinkedList<String>();
+            while (matcher.find()) {
+                String value = matcher.group(1);
+                if (QUOTED_PATTERN.matcher(value).matches()) {
+                    // Strip off the surrounding quotes
+                    value = value.substring(1, value.length() - 1);
+                }
+                args.add(value);
+            }
+            if (args.isEmpty()){
+                return false;
+            }
+            command = args.get(0);
+            cmdArgs = args;
+            return true;
+        }
+    }
+
+
+    /**
+     * Makes a list of possible completions, either for commands
+     * or for zk nodes if the token to complete begins with /
+     *
+     */
+
+
+    protected void addToHistory(int i,String cmd) {
+        history.put(i, cmd);
+    }
+
+    public static List<String> getCommands() {
+        return new LinkedList<String>(commandMap.keySet());
+    }
+
+    protected String getPrompt() {       
+        return "[zk: " + host + "("+zk.getState()+")" + " " + commandCount + "] ";
+    }
+
+    public static void printMessage(String msg) {
+        System.out.println("\n"+msg);
+    }
+
+    protected void connectToZK(String newHost) throws InterruptedException, IOException {
+        if (zk != null && zk.getState().isAlive()) {
+            zk.close();
+        }
+        host = newHost;
+        boolean readOnly = cl.getOption("readonly") != null;
+        zk = new ZooKeeper(host,
+                 Integer.parseInt(cl.getOption("timeout")),
+                 new MyWatcher(), readOnly);
+    }
+    
+    public static void main(String args[])
+        throws KeeperException, IOException, InterruptedException
+    {
+        ZooKeeperMain main = new ZooKeeperMain(args);
+        main.run();
+    }
+
+    public ZooKeeperMain(String args[]) throws IOException, InterruptedException {
+        cl.parseOptions(args);
+        System.out.println("Connecting to " + cl.getOption("server"));
+        connectToZK(cl.getOption("server"));
+        //zk = new ZooKeeper(cl.getOption("server"),
+//                Integer.parseInt(cl.getOption("timeout")), new MyWatcher());
+    }
+
+    public ZooKeeperMain(ZooKeeper zk) {
+      this.zk = zk;
+    }
+
+    @SuppressWarnings("unchecked")
+    void run() throws KeeperException, IOException, InterruptedException {
+        if (cl.getCommand() == null) {
+            System.out.println("Welcome to ZooKeeper!");
+
+            boolean jlinemissing = false;
+            // only use jline if it's in the classpath
+            try {
+                Class<?> consoleC = Class.forName("jline.ConsoleReader");
+                Class<?> completorC =
+                    Class.forName("org.apache.zookeeper.JLineZNodeCompletor");
+
+                System.out.println("JLine support is enabled");
+
+                Object console =
+                    consoleC.getConstructor().newInstance();
+
+                Object completor =
+                    completorC.getConstructor(ZooKeeper.class).newInstance(zk);
+                Method addCompletor = consoleC.getMethod("addCompletor",
+                        Class.forName("jline.Completor"));
+                addCompletor.invoke(console, completor);
+
+                String line;
+                Method readLine = consoleC.getMethod("readLine", String.class);
+                while ((line = (String)readLine.invoke(console, getPrompt())) != null) {
+                    executeLine(line);
+                }
+            } catch (ClassNotFoundException e) {
+                LOG.debug("Unable to start jline", e);
+                jlinemissing = true;
+            } catch (NoSuchMethodException e) {
+                LOG.debug("Unable to start jline", e);
+                jlinemissing = true;
+            } catch (InvocationTargetException e) {
+                LOG.debug("Unable to start jline", e);
+                jlinemissing = true;
+            } catch (IllegalAccessException e) {
+                LOG.debug("Unable to start jline", e);
+                jlinemissing = true;
+            } catch (InstantiationException e) {
+                LOG.debug("Unable to start jline", e);
+                jlinemissing = true;
+            }
+
+            if (jlinemissing) {
+                System.out.println("JLine support is disabled");
+                BufferedReader br =
+                    new BufferedReader(new InputStreamReader(System.in));
+
+                String line;
+                while ((line = br.readLine()) != null) {
+                    executeLine(line);
+                }
+            }
+        } else {
+            // Command line args non-null.  Run what was passed.
+            processCmd(cl);
+        }
+    }
+
+    public void executeLine(String line)
+    throws InterruptedException, IOException, KeeperException {
+      if (!line.equals("")) {
+        cl.parseCommand(line);
+        addToHistory(commandCount,line);
+        processCmd(cl);
+        commandCount++;
+      }
+    }
+
+    private static DataCallback dataCallback = new DataCallback() {
+
+        public void processResult(int rc, String path, Object ctx, byte[] data,
+                Stat stat) {
+            System.out.println("rc = " + rc + " path = " + path + " data = "
+                    + (data == null ? "null" : new String(data)) + " stat = ");
+            printStat(stat);
+        }
+
+    };
+
+    /**
+     * trim the quota tree to recover unwanted tree elements
+     * in the quota's tree
+     * @param zk the zookeeper client
+     * @param path the path to start from and go up and see if their
+     * is any unwanted parent in the path.
+     * @return true if sucessful
+     * @throws KeeperException
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    private static boolean trimProcQuotas(ZooKeeper zk, String path)
+        throws KeeperException, IOException, InterruptedException
+    {
+        if (Quotas.quotaZookeeper.equals(path)) {
+            return true;
+        }
+        List<String> children = zk.getChildren(path, false);
+        if (children.size() == 0) {
+            zk.delete(path, -1);
+            String parent = path.substring(0, path.lastIndexOf('/'));
+            return trimProcQuotas(zk, parent);
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * this method deletes quota for a node.
+     * @param zk the zookeeper client
+     * @param path the path to delete quota for
+     * @param bytes true if number of bytes needs to
+     * be unset
+     * @param numNodes true if number of nodes needs
+     * to be unset
+     * @return true if quota deletion is successful
+     * @throws KeeperException
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    public static boolean delQuota(ZooKeeper zk, String path,
+            boolean bytes, boolean numNodes)
+        throws KeeperException, IOException, InterruptedException
+    {
+        String parentPath = Quotas.quotaZookeeper + path;
+        String quotaPath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
+        if (zk.exists(quotaPath, false) == null) {
+            System.out.println("Quota does not exist for " + path);
+            return true;
+        }
+        byte[] data = null;
+        try {
+            data = zk.getData(quotaPath, false, new Stat());
+        } catch(KeeperException.NoNodeException ne) {
+            System.err.println("quota does not exist for " + path);
+            return true;
+        }
+        StatsTrack strack = new StatsTrack(new String(data));
+        if (bytes && !numNodes) {
+            strack.setBytes(-1L);
+            zk.setData(quotaPath, strack.toString().getBytes(), -1);
+        } else if (!bytes && numNodes) {
+            strack.setCount(-1);
+            zk.setData(quotaPath, strack.toString().getBytes(), -1);
+        } else if (bytes && numNodes) {
+            // delete till you can find a node with more than
+            // one child
+            List<String> children = zk.getChildren(parentPath, false);
+            /// delete the direct children first
+            for (String child: children) {
+                zk.delete(parentPath + "/" + child, -1);
+            }
+            // cut the tree till their is more than one child
+            trimProcQuotas(zk, parentPath);
+        }
+        return true;
+    }
+
+    private static void checkIfParentQuota(ZooKeeper zk, String path)
+        throws InterruptedException, KeeperException
+    {
+        final String[] splits = path.split("/");
+        String quotaPath = Quotas.quotaZookeeper;
+        for (String str: splits) {
+            if (str.length() == 0) {
+                // this should only be for the beginning of the path
+                // i.e. "/..." - split(path)[0] is empty string before first '/'
+                continue;
+            }
+            quotaPath += "/" + str;
+            List<String> children =  null;
+            try {
+                children = zk.getChildren(quotaPath, false);
+            } catch(KeeperException.NoNodeException ne) {
+                LOG.debug("child removed during quota check", ne);
+                return;
+            }
+            if (children.size() == 0) {
+                return;
+            }
+            for (String child: children) {
+                if (Quotas.limitNode.equals(child)) {
+                    throw new IllegalArgumentException(path + " has a parent "
+                            + quotaPath + " which has a quota");
+                }
+            }
+        }
+    }
+
+    /**
+     * this method creates a quota node for the path
+     * @param zk the ZooKeeper client
+     * @param path the path for which quota needs to be created
+     * @param bytes the limit of bytes on this path
+     * @param numNodes the limit of number of nodes on this path
+     * @return true if its successful and false if not.
+     */
+    public static boolean createQuota(ZooKeeper zk, String path,
+            long bytes, int numNodes)
+        throws KeeperException, IOException, InterruptedException
+    {
+        // check if the path exists. We cannot create
+        // quota for a path that already exists in zookeeper
+        // for now.
+        Stat initStat = zk.exists(path, false);
+        if (initStat == null) {
+            throw new IllegalArgumentException(path + " does not exist.");
+        }
+        // now check if their is already existing
+        // parent or child that has quota
+
+        String quotaPath = Quotas.quotaZookeeper;
+        // check for more than 2 children --
+        // if zookeeper_stats and zookeeper_qutoas
+        // are not the children then this path
+        // is an ancestor of some path that
+        // already has quota
+        String realPath = Quotas.quotaZookeeper + path;
+        try {
+            List<String> children = zk.getChildren(realPath, false);
+            for (String child: children) {
+                if (!child.startsWith("zookeeper_")) {
+                    throw new IllegalArgumentException(path + " has child " +
+                            child + " which has a quota");
+                }
+            }
+        } catch(KeeperException.NoNodeException ne) {
+            // this is fine
+        }
+
+        //check for any parent that has been quota
+        checkIfParentQuota(zk, path);
+
+        // this is valid node for quota
+        // start creating all the parents
+        if (zk.exists(quotaPath, false) == null) {
+            try {
+                zk.create(Quotas.procZookeeper, null, Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+                zk.create(Quotas.quotaZookeeper, null, Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+            } catch(KeeperException.NodeExistsException ne) {
+                // do nothing
+            }
+        }
+
+        // now create the direct children
+        // and the stat and quota nodes
+        String[] splits = path.split("/");
+        StringBuilder sb = new StringBuilder();
+        sb.append(quotaPath);
+        for (int i=1; i<splits.length; i++) {
+            sb.append("/" + splits[i]);
+            quotaPath = sb.toString();
+            try {
+                zk.create(quotaPath, null, Ids.OPEN_ACL_UNSAFE ,
+                        CreateMode.PERSISTENT);
+            } catch(KeeperException.NodeExistsException ne) {
+                //do nothing
+            }
+        }
+        String statPath = quotaPath + "/" + Quotas.statNode;
+        quotaPath = quotaPath + "/" + Quotas.limitNode;
+        StatsTrack strack = new StatsTrack(null);
+        strack.setBytes(bytes);
+        strack.setCount(numNodes);
+        try {
+            zk.create(quotaPath, strack.toString().getBytes(),
+                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            StatsTrack stats = new StatsTrack(null);
+            stats.setBytes(0L);
+            stats.setCount(0);
+            zk.create(statPath, stats.toString().getBytes(),
+                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        } catch(KeeperException.NodeExistsException ne) {
+            byte[] data = zk.getData(quotaPath, false , new Stat());
+            StatsTrack strackC = new StatsTrack(new String(data));
+            if (bytes != -1L) {
+                strackC.setBytes(bytes);
+            }
+            if (numNodes != -1) {
+                strackC.setCount(numNodes);
+            }
+            zk.setData(quotaPath, strackC.toString().getBytes(), -1);
+        }
+        return true;
+    }
+
+    protected boolean processCmd(MyCommandOptions co)
+        throws KeeperException, IOException, InterruptedException
+    {
+        try {
+            return processZKCmd(co);
+        } catch (IllegalArgumentException e) {
+            System.err.println("Command failed: " + e);
+        } catch (KeeperException.NoNodeException e) {
+            System.err.println("Node does not exist: " + e.getPath());
+        } catch (KeeperException.NoChildrenForEphemeralsException e) {
+            System.err.println("Ephemerals cannot have children: "
+                    + e.getPath());
+        } catch (KeeperException.NodeExistsException e) {
+            System.err.println("Node already exists: " + e.getPath());
+        } catch (KeeperException.NotEmptyException e) {
+            System.err.println("Node not empty: " + e.getPath());
+        } catch (KeeperException.NotReadOnlyException e) {
+            System.err.println("Not a read-only call: " + e.getPath());
+        }catch (KeeperException.InvalidACLException  e) {
+            System.err.println("Acl is not valid : "+e.getPath());
+        }catch (KeeperException.NoAuthException  e) {
+            System.err.println("Authentication is not valid : "+e.getPath());
+        }catch (KeeperException.BadArgumentsException   e) {
+            System.err.println("Arguments are not valid : "+e.getPath());
+        }catch (KeeperException.BadVersionException e) {
+            System.err.println("version No is not valid : "+e.getPath());
+        }
+        return false;
+    }
+
+    protected boolean processZKCmd(MyCommandOptions co)
+        throws KeeperException, IOException, InterruptedException
+    {
+        Stat stat = new Stat();
+        String[] args = co.getArgArray();
+        String cmd = co.getCommand();
+        if (args.length < 1) {
+            usage();
+            return false;
+        }
+
+        if (!commandMap.containsKey(cmd)) {
+            usage();
+            return false;
+        }
+        
+        boolean watch = args.length > 2;
+        String path = null;
+        List<ACL> acl = Ids.OPEN_ACL_UNSAFE;
+        LOG.debug("Processing " + cmd);
+
+        if (cmd.equals("quit")) {
+            System.out.println("Quitting...");
+            zk.close();
+            System.exit(0);
+        } else if (cmd.equals("redo") && args.length >= 2) {
+            Integer i = Integer.decode(args[1]);
+            if (commandCount <= i || i < 0){ // don't allow redoing this redo
+                System.out.println("Command index out of range");
+                return false;
+            }
+            cl.parseCommand(history.get(i));
+            if (cl.getCommand().equals( "redo" )){
+                System.out.println("No redoing redos");
+                return false;
+            }
+            history.put(commandCount, history.get(i));
+            processCmd( cl);
+        } else if (cmd.equals("history")) {
+            for (int i=commandCount - 10;i<=commandCount;++i) {
+                if (i < 0) continue;
+                System.out.println(i + " - " + history.get(i));
+            }
+        } else if (cmd.equals("printwatches")) {
+            if (args.length == 1) {
+                System.out.println("printwatches is " + (printWatches ? "on" : "off"));
+            } else {
+                printWatches = args[1].equals("on");
+            }
+        } else if (cmd.equals("connect")) {
+            if (args.length >=2) {
+                connectToZK(args[1]);
+            } else {
+                connectToZK(host);
+            }
+        }
+        
+        // Below commands all need a live connection
+        if (zk == null || !zk.getState().isAlive()) {
+            System.out.println("Not connected");
+            return false;
+        }
+        
+        if (cmd.equals("create") && args.length >= 3) {
+            int first = 0;
+            CreateMode flags = CreateMode.PERSISTENT;
+            if ((args[1].equals("-e") && args[2].equals("-s"))
+                    || (args[1]).equals("-s") && (args[2].equals("-e"))) {
+                first+=2;
+                flags = CreateMode.EPHEMERAL_SEQUENTIAL;
+            } else if (args[1].equals("-e")) {
+                first++;
+                flags = CreateMode.EPHEMERAL;
+            } else if (args[1].equals("-s")) {
+                first++;
+                flags = CreateMode.PERSISTENT_SEQUENTIAL;
+            }
+            if (args.length == first + 4) {
+                acl = parseACLs(args[first+3]);
+            }
+            path = args[first + 1];
+            String newPath = zk.create(path, args[first+2].getBytes(), acl,
+                    flags);
+            System.err.println("Created " + newPath);
+        } else if (cmd.equals("delete") && args.length >= 2) {
+            path = args[1];
+            zk.delete(path, watch ? Integer.parseInt(args[2]) : -1);
+        } else if (cmd.equals("rmr") && args.length >= 2) {
+            path = args[1];
+            ZKUtil.deleteRecursive(zk, path);
+        } else if (cmd.equals("set") && args.length >= 3) {
+            path = args[1];
+            stat = zk.setData(path, args[2].getBytes(),
+                    args.length > 3 ? Integer.parseInt(args[3]) : -1);
+            printStat(stat);
+        } else if (cmd.equals("aget") && args.length >= 2) {
+            path = args[1];
+            zk.getData(path, watch, dataCallback, path);
+        } else if (cmd.equals("get") && args.length >= 2) {
+            path = args[1];
+            byte data[] = zk.getData(path, watch, stat);
+            data = (data == null)? "null".getBytes() : data;
+            System.out.println(new String(data));
+            printStat(stat);
+        } else if (cmd.equals("ls") && args.length >= 2) {
+            path = args[1];
+            List<String> children = zk.getChildren(path, watch);
+            System.out.println(children);
+        } else if (cmd.equals("ls2") && args.length >= 2) {
+            path = args[1];
+            List<String> children = zk.getChildren(path, watch, stat);
+            System.out.println(children);
+            printStat(stat);
+        } else if (cmd.equals("getAcl") && args.length >= 2) {
+            path = args[1];
+            acl = zk.getACL(path, stat);
+            for (ACL a : acl) {
+                System.out.println(a.getId() + ": "
+                        + getPermString(a.getPerms()));
+            }
+        } else if (cmd.equals("setAcl") && args.length >= 3) {
+            path = args[1];
+            stat = zk.setACL(path, parseACLs(args[2]),
+                    args.length > 4 ? Integer.parseInt(args[3]) : -1);
+            printStat(stat);
+        } else if (cmd.equals("stat") && args.length >= 2) {
+            path = args[1];
+            stat = zk.exists(path, watch);
+            if (stat == null) {
+              throw new KeeperException.NoNodeException(path);
+            }
+            printStat(stat);
+        } else if (cmd.equals("listquota") && args.length >= 2) {
+            path = args[1];
+            String absolutePath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
+            byte[] data =  null;
+            try {
+                System.err.println("absolute path is " + absolutePath);
+                data = zk.getData(absolutePath, false, stat);
+                StatsTrack st = new StatsTrack(new String(data));
+                System.out.println("Output quota for " + path + " "
+                        + st.toString());
+
+                data = zk.getData(Quotas.quotaZookeeper + path + "/" +
+                        Quotas.statNode, false, stat);
+                System.out.println("Output stat for " + path + " " +
+                        new StatsTrack(new String(data)).toString());
+            } catch(KeeperException.NoNodeException ne) {
+                System.err.println("quota for " + path + " does not exist.");
+            }
+        } else if (cmd.equals("setquota") && args.length >= 4) {
+            String option = args[1];
+            String val = args[2];
+            path = args[3];
+            System.err.println("Comment: the parts are " +
+                               "option " + option +
+                               " val " + val +
+                               " path " + path);
+            if ("-b".equals(option)) {
+                // we are setting the bytes quota
+                createQuota(zk, path, Long.parseLong(val), -1);
+            } else if ("-n".equals(option)) {
+                // we are setting the num quota
+                createQuota(zk, path, -1L, Integer.parseInt(val));
+            } else {
+                usage();
+            }
+
+        } else if (cmd.equals("delquota") && args.length >= 2) {
+            //if neither option -n or -b is specified, we delete
+            // the quota node for thsi node.
+            if (args.length == 3) {
+                //this time we have an option
+                String option = args[1];
+                path = args[2];
+                if ("-b".equals(option)) {
+                    delQuota(zk, path, true, false);
+                } else if ("-n".equals(option)) {
+                    delQuota(zk, path, false, true);
+                }
+            } else if (args.length == 2) {
+                path = args[1];
+                // we dont have an option specified.
+                // just delete whole quota node
+                delQuota(zk, path, true, true);
+            } else if (cmd.equals("help")) {
+                usage();
+            }
+        } else if (cmd.equals("close")) {
+                zk.close();
+        } else if (cmd.equals("sync") && args.length >= 2) {
+            path = args[1];
+            zk.sync(path, new AsyncCallback.VoidCallback() { public void processResult(int rc, String path, Object ctx) { System.out.println("Sync returned " + rc); } }, null );
+        } else if (cmd.equals("addauth") && args.length >=2 ) {
+            byte[] b = null;
+            if (args.length >= 3)
+                b = args[2].getBytes();
+
+            zk.addAuthInfo(args[1], b);
+        } else if (!commandMap.containsKey(cmd)) {
+            usage();
+        }
+        return watch;
+    }
+
+    private static String getPermString(int perms) {
+        StringBuilder p = new StringBuilder();
+        if ((perms & ZooDefs.Perms.CREATE) != 0) {
+            p.append('c');
+        }
+        if ((perms & ZooDefs.Perms.DELETE) != 0) {
+            p.append('d');
+        }
+        if ((perms & ZooDefs.Perms.READ) != 0) {
+            p.append('r');
+        }
+        if ((perms & ZooDefs.Perms.WRITE) != 0) {
+            p.append('w');
+        }
+        if ((perms & ZooDefs.Perms.ADMIN) != 0) {
+            p.append('a');
+        }
+        return p.toString();
+    }
+
+    private static List<ACL> parseACLs(String aclString) {
+        List<ACL> acl;
+        String acls[] = aclString.split(",");
+        acl = new ArrayList<ACL>();
+        for (String a : acls) {
+            int firstColon = a.indexOf(':');
+            int lastColon = a.lastIndexOf(':');
+            if (firstColon == -1 || lastColon == -1 || firstColon == lastColon) {
+                System.err
+                .println(a + " does not have the form scheme:id:perm");
+                continue;
+            }
+            ACL newAcl = new ACL();
+            newAcl.setId(new Id(a.substring(0, firstColon), a.substring(
+                    firstColon + 1, lastColon)));
+            newAcl.setPerms(getPermFromString(a.substring(lastColon + 1)));
+            acl.add(newAcl);
+        }
+        return acl;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java
new file mode 100644
index 0000000..775d1a2
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperTestable.java
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class ZooKeeperTestable implements Testable {
+    private static final Logger LOG = LoggerFactory
+            .getLogger(ZooKeeperTestable.class);
+
+    private final ZooKeeper zooKeeper;
+    private final ClientCnxn clientCnxn;
+
+    ZooKeeperTestable(ZooKeeper zooKeeper, ClientCnxn clientCnxn) {
+        this.zooKeeper = zooKeeper;
+        this.clientCnxn = clientCnxn;
+    }
+
+    @Override
+    public void injectSessionExpiration() {
+        LOG.info("injectSessionExpiration() called");
+
+        clientCnxn.eventThread.queueEvent(new WatchedEvent(
+                Watcher.Event.EventType.None,
+                Watcher.Event.KeeperState.Expired, null));
+        clientCnxn.eventThread.queueEventOfDeath();
+        clientCnxn.sendThread.getClientCnxnSocket().wakeupCnxn();
+        clientCnxn.state = ZooKeeper.States.CLOSED;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java b/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
new file mode 100644
index 0000000..ff0425a
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/client/ConnectStringParser.java
@@ -0,0 +1,87 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.client;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+
+import org.apache.zookeeper.common.PathUtils;
+
+/**
+ * A parser for ZooKeeper Client connect strings.
+ * 
+ * This class is not meant to be seen or used outside of ZooKeeper itself.
+ * 
+ * The chrootPath member should be replaced by a Path object in issue
+ * ZOOKEEPER-849.
+ * 
+ * @see org.apache.zookeeper.ZooKeeper
+ */
+public final class ConnectStringParser {
+    private static final int DEFAULT_PORT = 2181;
+
+    private final String chrootPath;
+
+    private final ArrayList<InetSocketAddress> serverAddresses = new ArrayList<InetSocketAddress>();
+
+    /**
+     * 
+     * @throws IllegalArgumentException
+     *             for an invalid chroot path.
+     */
+    public ConnectStringParser(String connectString) {
+        // parse out chroot, if any
+        int off = connectString.indexOf('/');
+        if (off >= 0) {
+            String chrootPath = connectString.substring(off);
+            // ignore "/" chroot spec, same as null
+            if (chrootPath.length() == 1) {
+                this.chrootPath = null;
+            } else {
+                PathUtils.validatePath(chrootPath);
+                this.chrootPath = chrootPath;
+            }
+            connectString = connectString.substring(0, off);
+        } else {
+            this.chrootPath = null;
+        }
+
+        String hostsList[] = connectString.split(",");
+        for (String host : hostsList) {
+            int port = DEFAULT_PORT;
+            int pidx = host.lastIndexOf(':');
+            if (pidx >= 0) {
+                // otherwise : is at the end of the string, ignore
+                if (pidx < host.length() - 1) {
+                    port = Integer.parseInt(host.substring(pidx + 1));
+                }
+                host = host.substring(0, pidx);
+            }
+            serverAddresses.add(InetSocketAddress.createUnresolved(host, port));
+        }
+    }
+
+    public String getChrootPath() {
+        return chrootPath;
+    }
+
+    public ArrayList<InetSocketAddress> getServerAddresses() {
+        return serverAddresses;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java b/zookeeper-server/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java
new file mode 100644
index 0000000..a4175e4
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/client/FourLetterWordMain.java
@@ -0,0 +1,107 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.client;
+
+import org.apache.log4j.Logger;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+
+import org.apache.yetus.audience.InterfaceAudience;
+
+@InterfaceAudience.Public
+public class FourLetterWordMain {
+    //in milliseconds, socket should connect/read within this period otherwise SocketTimeoutException
+    private static final int DEFAULT_SOCKET_TIMEOUT = 5000;
+    protected static final Logger LOG = Logger.getLogger(FourLetterWordMain.class);
+
+    /**
+     * Send the 4letterword
+     * @param host the destination host
+     * @param port the destination port
+     * @param cmd the 4letterword
+     * @return server response
+     * @throws java.io.IOException
+     */
+    public static String send4LetterWord(String host, int port, String cmd)
+            throws IOException
+    {
+        return send4LetterWord(host, port, cmd, DEFAULT_SOCKET_TIMEOUT);
+    }
+    /**
+     * Send the 4letterword
+     * @param host the destination host
+     * @param port the destination port
+     * @param cmd the 4letterword
+     * @param timeout in milliseconds, maximum time to wait while connecting/reading data
+     * @return server response
+     * @throws java.io.IOException
+     */
+    public static String send4LetterWord(String host, int port, String cmd, int timeout)
+            throws IOException
+    {
+        LOG.info("connecting to " + host + " " + port);
+        Socket sock = new Socket();
+        InetSocketAddress hostaddress= host != null ? new InetSocketAddress(host, port) :
+            new InetSocketAddress(InetAddress.getByName(null), port);
+        BufferedReader reader = null;
+        try {
+            sock.setSoTimeout(timeout);
+            sock.connect(hostaddress, timeout);
+            OutputStream outstream = sock.getOutputStream();
+            outstream.write(cmd.getBytes());
+            outstream.flush();
+            // this replicates NC - close the output stream before reading
+            sock.shutdownOutput();
+
+            reader =
+                    new BufferedReader(
+                            new InputStreamReader(sock.getInputStream()));
+            StringBuilder sb = new StringBuilder();
+            String line;
+            while((line = reader.readLine()) != null) {
+                sb.append(line + "\n");
+            }
+            return sb.toString();
+        } catch (SocketTimeoutException e) {
+            throw new IOException("Exception while executing four letter word: " + cmd, e);
+        } finally {
+            sock.close();
+            if (reader != null) {
+                reader.close();
+            }
+        }
+    }
+    
+    public static void main(String[] args)
+            throws IOException
+    {
+        if (args.length != 3) {
+            System.out.println("Usage: FourLetterWordMain <host> <port> <cmd>");
+        } else {
+            System.out.println(send4LetterWord(args[0], Integer.parseInt(args[1]), args[2]));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/client/HostProvider.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/client/HostProvider.java b/zookeeper-server/src/main/java/org/apache/zookeeper/client/HostProvider.java
new file mode 100644
index 0000000..61d9108
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/client/HostProvider.java
@@ -0,0 +1,66 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.client;
+
+import org.apache.yetus.audience.InterfaceAudience;
+
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+
+/**
+ * A set of hosts a ZooKeeper client should connect to.
+ * 
+ * Classes implementing this interface must guarantee the following:
+ * 
+ * * Every call to next() returns an InetSocketAddress. So the iterator never
+ * ends.
+ * 
+ * * The size() of a HostProvider may never be zero.
+ * 
+ * A HostProvider must return resolved InetSocketAddress instances on next(),
+ * but it's up to the HostProvider, when it wants to do the resolving.
+ * 
+ * Different HostProvider could be imagined:
+ * 
+ * * A HostProvider that loads the list of Hosts from an URL or from DNS 
+ * * A HostProvider that re-resolves the InetSocketAddress after a timeout. 
+ * * A HostProvider that prefers nearby hosts.
+ */
+@InterfaceAudience.Public
+public interface HostProvider {
+    public int size();
+
+    /**
+     * The next host to try to connect to.
+     *
+     * For a spinDelay of 0 there should be no wait.
+     *
+     * @param spinDelay Milliseconds to wait if all hosts have been tried once.
+     * @return The next host to try to connect to with resolved address. If the host is not resolvable, the unresolved
+     * address will be returned.
+     */
+    public InetSocketAddress next(long spinDelay);
+
+    /**
+     * Notify the HostProvider of a successful connection.
+     * 
+     * The HostProvider may use this notification to reset it's inner state.
+     */
+    public void onConnected();
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java b/zookeeper-server/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java
new file mode 100644
index 0000000..0005942
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/client/StaticHostProvider.java
@@ -0,0 +1,179 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.client;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Most simple HostProvider, resolves on every next() call.
+ *
+ * Please be aware that although this class doesn't do any DNS caching, there're multiple levels of caching already
+ * present across the stack like in JVM, OS level, hardware, etc. The best we could do here is to get the most recent
+ * address from the underlying system which is considered up-to-date.
+ *
+ */
+@InterfaceAudience.Public
+public final class StaticHostProvider implements HostProvider {
+    public interface Resolver {
+        InetAddress[] getAllByName(String name) throws UnknownHostException;
+    }
+
+    private static final Logger LOG = LoggerFactory
+            .getLogger(StaticHostProvider.class);
+
+    private final List<InetSocketAddress> serverAddresses = new ArrayList<InetSocketAddress>(5);
+
+    private int lastIndex = -1;
+
+    private int currentIndex = -1;
+
+    private Resolver resolver;
+
+    /**
+     * Constructs a SimpleHostSet.
+     *
+     * @param serverAddresses
+     *            possibly unresolved ZooKeeper server addresses
+     * @throws IllegalArgumentException
+     *             if serverAddresses is empty or resolves to an empty list
+     */
+    public StaticHostProvider(Collection<InetSocketAddress> serverAddresses) {
+        this.resolver = new Resolver() {
+            @Override
+            public InetAddress[] getAllByName(String name) throws UnknownHostException {
+                return InetAddress.getAllByName(name);
+            }
+        };
+        init(serverAddresses);
+    }
+
+    /**
+     * Introduced for testing purposes. getAllByName() is a static method of InetAddress, therefore cannot be easily mocked.
+     * By abstraction of Resolver interface we can easily inject a mocked implementation in tests.
+     *
+     * @param serverAddresses
+     *            possibly unresolved ZooKeeper server addresses
+     * @param resolver
+     *            custom resolver implementation
+     * @throws IllegalArgumentException
+     *             if serverAddresses is empty or resolves to an empty list
+     */
+    public StaticHostProvider(Collection<InetSocketAddress> serverAddresses, Resolver resolver) {
+        this.resolver = resolver;
+        init(serverAddresses);
+    }
+
+    /**
+     * Common init method for all constructors.
+     * Resolve all unresolved server addresses, put them in a list and shuffle.
+     */
+    private void init(Collection<InetSocketAddress> serverAddresses) {
+        if (serverAddresses.isEmpty()) {
+            throw new IllegalArgumentException(
+                    "A HostProvider may not be empty!");
+        }
+
+        this.serverAddresses.addAll(serverAddresses);
+        Collections.shuffle(this.serverAddresses);
+    }
+
+    /**
+     * Evaluate to a hostname if one is available and otherwise it returns the
+     * string representation of the IP address.
+     *
+     * In Java 7, we have a method getHostString, but earlier versions do not support it.
+     * This method is to provide a replacement for InetSocketAddress.getHostString().
+     *
+     * @param addr
+     * @return Hostname string of address parameter
+     */
+    private String getHostString(InetSocketAddress addr) {
+        String hostString = "";
+
+        if (addr == null) {
+            return hostString;
+        }
+        if (!addr.isUnresolved()) {
+            InetAddress ia = addr.getAddress();
+
+            // If the string starts with '/', then it has no hostname
+            // and we want to avoid the reverse lookup, so we return
+            // the string representation of the address.
+            if (ia.toString().startsWith("/")) {
+                hostString = ia.getHostAddress();
+            } else {
+                hostString = addr.getHostName();
+            }
+        } else {
+            // According to the Java 6 documentation, if the hostname is
+            // unresolved, then the string before the colon is the hostname.
+            String addrString = addr.toString();
+            hostString = addrString.substring(0, addrString.lastIndexOf(':'));
+        }
+
+        return hostString;
+    }
+
+    public int size() {
+        return serverAddresses.size();
+    }
+
+    public InetSocketAddress next(long spinDelay) {
+        currentIndex = ++currentIndex % serverAddresses.size();
+        if (currentIndex == lastIndex && spinDelay > 0) {
+            try {
+                Thread.sleep(spinDelay);
+            } catch (InterruptedException e) {
+                LOG.warn("Unexpected exception", e);
+            }
+        } else if (lastIndex == -1) {
+            // We don't want to sleep on the first ever connect attempt.
+            lastIndex = 0;
+        }
+
+        InetSocketAddress curAddr = serverAddresses.get(currentIndex);
+        try {
+            String curHostString = getHostString(curAddr);
+            List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>(Arrays.asList(this.resolver.getAllByName(curHostString)));
+            if (resolvedAddresses.isEmpty()) {
+                return curAddr;
+            }
+            Collections.shuffle(resolvedAddresses);
+            return new InetSocketAddress(resolvedAddresses.get(0), curAddr.getPort());
+        } catch (UnknownHostException e) {
+            return curAddr;
+        }
+    }
+
+    @Override
+    public void onConnected() {
+        lastIndex = currentIndex;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java b/zookeeper-server/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java
new file mode 100644
index 0000000..af3303c
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java
@@ -0,0 +1,439 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.client;
+
+import java.io.IOException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.ClientCnxn;
+import org.apache.zookeeper.Environment;
+import org.apache.zookeeper.Login;
+import org.apache.zookeeper.SaslClientCallbackHandler;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.proto.GetSASLRequest;
+import org.apache.zookeeper.proto.SetSASLResponse;
+import org.apache.zookeeper.util.SecurityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class manages SASL authentication for the client. It
+ * allows ClientCnxn to authenticate using SASL with a Zookeeper server.
+ */
+public class ZooKeeperSaslClient {
+    public static final String LOGIN_CONTEXT_NAME_KEY = "zookeeper.sasl.clientconfig";
+    public static final String ENABLE_CLIENT_SASL_KEY = "zookeeper.sasl.client";
+    public static final String ENABLE_CLIENT_SASL_DEFAULT = "true";
+    private static volatile boolean initializedLogin = false; 
+
+    /**
+     * Returns true if the SASL client is enabled. By default, the client
+     * is enabled but can be disabled by setting the system property
+     * <code>zookeeper.sasl.client</code> to <code>false</code>. See
+     * ZOOKEEPER-1657 for more information.
+     *
+     * @return If the SASL client is enabled.
+     */
+    public static boolean isEnabled() {
+        return Boolean.valueOf(System.getProperty(ENABLE_CLIENT_SASL_KEY, ENABLE_CLIENT_SASL_DEFAULT));
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ZooKeeperSaslClient.class);
+    private static Login login = null;
+    private SaslClient saslClient;
+    private boolean isSASLConfigured = true;
+
+    private byte[] saslToken = new byte[0];
+
+    public enum SaslState {
+        INITIAL,INTERMEDIATE,COMPLETE,FAILED
+    }
+
+    private SaslState saslState = SaslState.INITIAL;
+
+    private boolean gotLastPacket = false;
+    /** informational message indicating the current configuration status */
+    private final String configStatus;
+
+    public SaslState getSaslState() {
+        return saslState;
+    }
+
+    public String getLoginContext() {
+        if (login != null)
+            return login.getLoginContextName();
+        return null;
+    }
+
+    public ZooKeeperSaslClient(final String serverPrincipal)
+            throws LoginException {
+        /**
+         * ZOOKEEPER-1373: allow system property to specify the JAAS
+         * configuration section that the zookeeper client should use.
+         * Default to "Client".
+         */
+        String clientSection = System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client");
+        // Note that 'Configuration' here refers to javax.security.auth.login.Configuration.
+        AppConfigurationEntry entries[] = null;
+        RuntimeException runtimeException = null;
+        try {
+            entries = Configuration.getConfiguration().getAppConfigurationEntry(clientSection);
+        } catch (SecurityException e) {
+            // handle below: might be harmless if the user doesn't intend to use JAAS authentication.
+            runtimeException = e;
+        } catch (IllegalArgumentException e) {
+            // third party customized getAppConfigurationEntry could throw IllegalArgumentException when JAAS
+            // configuration isn't set. We can reevaluate whether to catch RuntimeException instead when more 
+            // different types of RuntimeException found
+            runtimeException = e;
+        }
+        if (entries != null) {
+            this.configStatus = "Will attempt to SASL-authenticate using Login Context section '" + clientSection + "'";
+            this.saslClient = createSaslClient(serverPrincipal, clientSection);
+        } else {
+            // Handle situation of clientSection's being null: it might simply because the client does not intend to 
+            // use SASL, so not necessarily an error.
+            saslState = SaslState.FAILED;
+            String explicitClientSection = System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY);
+            if (explicitClientSection != null) {
+                // If the user explicitly overrides the default Login Context, they probably expected SASL to
+                // succeed. But if we got here, SASL failed.
+                if (runtimeException != null) {
+                    throw new LoginException("Zookeeper client cannot authenticate using the " + explicitClientSection +
+                            " section of the supplied JAAS configuration: '" +
+                            System.getProperty(Environment.JAAS_CONF_KEY) + "' because of a " +
+                            "RuntimeException: " + runtimeException);
+                } else {
+                    throw new LoginException("Client cannot SASL-authenticate because the specified JAAS configuration " +
+                            "section '" + explicitClientSection + "' could not be found.");
+                }
+            } else {
+                // The user did not override the default context. It might be that they just don't intend to use SASL,
+                // so log at INFO, not WARN, since they don't expect any SASL-related information.
+                String msg = "Will not attempt to authenticate using SASL ";
+                if (runtimeException != null) {
+                    msg += "(" + runtimeException + ")";
+                } else {
+                    msg += "(unknown error)";
+                }
+                this.configStatus = msg;
+                this.isSASLConfigured = false;
+            }
+            if (System.getProperty(Environment.JAAS_CONF_KEY)  != null) {
+                // Again, the user explicitly set something SASL-related, so they probably expected SASL to succeed.
+                if (runtimeException != null) {
+                    throw new LoginException("Zookeeper client cannot authenticate using the '" +
+                            System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client") +
+                            "' section of the supplied JAAS configuration: '" +
+                            System.getProperty(Environment.JAAS_CONF_KEY) + "' because of a " +
+                            "RuntimeException: " + runtimeException);
+                } else {
+                    throw new LoginException("No JAAS configuration section named '" +
+                            System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client") +
+                            "' was found in specified JAAS configuration file: '" +
+                            System.getProperty(Environment.JAAS_CONF_KEY) + "'.");
+                }
+            }
+        }
+    }
+    
+    /**
+     * @return informational message indicating the current configuration status.
+     */
+    public String getConfigStatus() {
+        return configStatus;
+    }
+
+    public boolean isComplete() {
+        return (saslState == SaslState.COMPLETE);
+    }
+
+    public boolean isFailed() {
+        return (saslState == SaslState.FAILED);
+    }
+
+    public static class ServerSaslResponseCallback implements AsyncCallback.DataCallback {
+        public void processResult(int rc, String path, Object ctx, byte data[], Stat stat) {
+            // processResult() is used by ClientCnxn's sendThread to respond to
+            // data[] contains the Zookeeper Server's SASL token.
+            // ctx is the ZooKeeperSaslClient object. We use this object's respondToServer() method
+            // to reply to the Zookeeper Server's SASL token
+            ZooKeeperSaslClient client = ((ClientCnxn)ctx).zooKeeperSaslClient;
+            if (client == null) {
+                LOG.warn("sasl client was unexpectedly null: cannot respond to Zookeeper server.");
+                return;
+            }
+            byte[] usedata = data;
+            if (data != null) {
+                LOG.debug("ServerSaslResponseCallback(): saslToken server response: (length="+usedata.length+")");
+            }
+            else {
+                usedata = new byte[0];
+                LOG.debug("ServerSaslResponseCallback(): using empty data[] as server response (length="+usedata.length+")");
+            }
+            client.respondToServer(usedata, (ClientCnxn)ctx);
+        }
+    }
+
+    private SaslClient createSaslClient(final String servicePrincipal,
+                                                     final String loginContext) throws LoginException {
+        try {
+            if (!initializedLogin) {
+                synchronized (ZooKeeperSaslClient.class) {
+                    if (login == null) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("JAAS loginContext is: " + loginContext);
+                        }
+                        // note that the login object is static: it's shared amongst all zookeeper-related connections.
+                        // in order to ensure the login is initialized only once, it must be synchronized the code snippet.
+                        login = new Login(loginContext, new SaslClientCallbackHandler(null, "Client"));
+                        login.startThreadIfNeeded();
+                        initializedLogin = true;
+                    }
+                }
+            }
+            return SecurityUtils.createSaslClient(login.getSubject(),
+                    servicePrincipal, "zookeeper", "zk-sasl-md5", LOG, "Client");
+        } catch (LoginException e) {
+            // We throw LoginExceptions...
+            throw e;
+        } catch (Exception e) {
+            // ..but consume (with a log message) all other types of exceptions.
+            LOG.error("Exception while trying to create SASL client: " + e);
+            return null;
+        }
+    }
+
+    public void respondToServer(byte[] serverToken, ClientCnxn cnxn) {
+        if (saslClient == null) {
+            LOG.error("saslClient is unexpectedly null. Cannot respond to server's SASL message; ignoring.");
+            return;
+        }
+
+        if (!(saslClient.isComplete())) {
+            try {
+                saslToken = createSaslToken(serverToken);
+                if (saslToken != null) {
+                    sendSaslPacket(saslToken, cnxn);
+                }
+            } catch (SaslException e) {
+                LOG.error("SASL authentication failed using login context '" +
+                        this.getLoginContext() + "' with exception: {}", e);
+                saslState = SaslState.FAILED;
+                gotLastPacket = true;
+            }
+        }
+
+        if (saslClient.isComplete()) {
+            // GSSAPI: server sends a final packet after authentication succeeds
+            // or fails.
+            if ((serverToken == null) && (saslClient.getMechanismName().equals("GSSAPI")))
+                gotLastPacket = true;
+            // non-GSSAPI: no final packet from server.
+            if (!saslClient.getMechanismName().equals("GSSAPI")) {
+                gotLastPacket = true;
+            }
+            // SASL authentication is completed, successfully or not:
+            // enable the socket's writable flag so that any packets waiting for authentication to complete in
+            // the outgoing queue will be sent to the Zookeeper server.
+            cnxn.enableWrite();
+        }
+    }
+
+    private byte[] createSaslToken() throws SaslException {
+        saslState = SaslState.INTERMEDIATE;
+        return createSaslToken(saslToken);
+    }
+
+    private byte[] createSaslToken(final byte[] saslToken) throws SaslException {
+        if (saslToken == null) {
+            // TODO: introspect about runtime environment (such as jaas.conf)
+            saslState = SaslState.FAILED;
+            throw new SaslException("Error in authenticating with a Zookeeper Quorum member: the quorum member's saslToken is null.");
+        }
+
+        Subject subject = login.getSubject();
+        if (subject != null) {
+            synchronized(login) {
+                try {
+                    final byte[] retval =
+                        Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
+                                public byte[] run() throws SaslException {
+                                    LOG.debug("saslClient.evaluateChallenge(len="+saslToken.length+")");
+                                    return saslClient.evaluateChallenge(saslToken);
+                                }
+                            });
+                    return retval;
+                }
+                catch (PrivilegedActionException e) {
+                    String error = "An error: (" + e + ") occurred when evaluating Zookeeper Quorum Member's " +
+                      " received SASL token.";
+                    // Try to provide hints to use about what went wrong so they can fix their configuration.
+                    // TODO: introspect about e: look for GSS information.
+                    final String UNKNOWN_SERVER_ERROR_TEXT =
+                      "(Mechanism level: Server not found in Kerberos database (7) - UNKNOWN_SERVER)";
+                    if (e.toString().indexOf(UNKNOWN_SERVER_ERROR_TEXT) > -1) {
+                        error += " This may be caused by Java's being unable to resolve the Zookeeper Quorum Member's" +
+                          " hostname correctly. You may want to try to adding" +
+                          " '-Dsun.net.spi.nameservice.provider.1=dns,sun' to your client's JVMFLAGS environment.";
+                    }
+                    error += " Zookeeper Client will go to AUTH_FAILED state.";
+                    LOG.error(error);
+                    saslState = SaslState.FAILED;
+                    throw new SaslException(error);
+                }
+            }
+        }
+        else {
+            throw new SaslException("Cannot make SASL token without subject defined. " +
+              "For diagnosis, please look for WARNs and ERRORs in your log related to the Login class.");
+        }
+    }
+
+    private void sendSaslPacket(byte[] saslToken, ClientCnxn cnxn)
+      throws SaslException{
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("ClientCnxn:sendSaslPacket:length="+saslToken.length);
+        }
+
+        GetSASLRequest request = new GetSASLRequest();
+        request.setToken(saslToken);
+        SetSASLResponse response = new SetSASLResponse();
+        ServerSaslResponseCallback cb = new ServerSaslResponseCallback();
+
+        try {
+            cnxn.sendPacket(request,response,cb, ZooDefs.OpCode.sasl);
+        } catch (IOException e) {
+            throw new SaslException("Failed to send SASL packet to server.",
+                e);
+        }
+    }
+
+    private void sendSaslPacket(ClientCnxn cnxn) throws SaslException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("ClientCnxn:sendSaslPacket:length="+saslToken.length);
+        }
+        GetSASLRequest request = new GetSASLRequest();
+        request.setToken(createSaslToken());
+        SetSASLResponse response = new SetSASLResponse();
+        ServerSaslResponseCallback cb = new ServerSaslResponseCallback();
+        try {
+            cnxn.sendPacket(request,response,cb, ZooDefs.OpCode.sasl);
+        } catch (IOException e) {
+            throw new SaslException("Failed to send SASL packet to server due " +
+              "to IOException:", e);
+        }
+    }
+
+    // used by ClientCnxn to know whether to emit a SASL-related event: either AuthFailed or SaslAuthenticated,
+    // or none, if not ready yet. Sets saslState to COMPLETE as a side-effect.
+    public KeeperState getKeeperState() {
+        if (saslClient != null) {
+            if (saslState == SaslState.FAILED) {
+              return KeeperState.AuthFailed;
+            }
+            if (saslClient.isComplete()) {
+                if (saslState == SaslState.INTERMEDIATE) {
+                    saslState = SaslState.COMPLETE;
+                    return KeeperState.SaslAuthenticated;
+                }
+            }
+        }
+        // No event ready to emit yet.
+        return null;
+    }
+
+    // Initialize the client's communications with the Zookeeper server by sending the server the first
+    // authentication packet.
+    public void initialize(ClientCnxn cnxn) throws SaslException {
+        if (saslClient == null) {
+            saslState = SaslState.FAILED;
+            throw new SaslException("saslClient failed to initialize properly: it's null.");
+        }
+        if (saslState == SaslState.INITIAL) {
+            if (saslClient.hasInitialResponse()) {
+                sendSaslPacket(cnxn);
+            }
+            else {
+                byte[] emptyToken = new byte[0];
+                sendSaslPacket(emptyToken, cnxn);
+            }
+            saslState = SaslState.INTERMEDIATE;
+        }
+    }
+
+    public boolean clientTunneledAuthenticationInProgress() {
+    	if (!isSASLConfigured) {
+    	    return false;
+        } 
+        // TODO: Rather than checking a disjunction here, should be a single member
+        // variable or method in this class to determine whether the client is
+        // configured to use SASL. (see also ZOOKEEPER-1455).
+        try {
+  	    if ((System.getProperty(Environment.JAAS_CONF_KEY) != null) ||
+              ((javax.security.auth.login.Configuration.getConfiguration() != null) &&
+                  (javax.security.auth.login.Configuration.getConfiguration().
+                       getAppConfigurationEntry(System.
+                       getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY,"Client")) 
+                           != null))) {
+                // Client is configured to use a valid login Configuration, so
+                // authentication is either in progress, successful, or failed.
+
+                // 1. Authentication hasn't finished yet: we must wait for it to do so.
+                if ((isComplete() == false) &&
+                    (isFailed() == false)) {
+                    return true;
+                }
+
+                // 2. SASL authentication has succeeded or failed..
+                if (isComplete() || isFailed()) {
+                    if (gotLastPacket == false) {
+                        // ..but still in progress, because there is a final SASL
+                        // message from server which must be received.
+                    return true;
+                    }
+                }
+            }
+            // Either client is not configured to use a tunnelled authentication
+            // scheme, or tunnelled authentication has completed (successfully or
+            // not), and all server SASL messages have been received.
+            return false;
+        } catch (SecurityException e) {
+            // Thrown if the caller does not have permission to retrieve the Configuration.
+            // In this case, simply returning false is correct.
+            if (LOG.isDebugEnabled() == true) {
+                LOG.debug("Could not retrieve login configuration: " + e);
+            }
+            return false;
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java
new file mode 100644
index 0000000..2584d3f
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/AtomicFileOutputStream.java
@@ -0,0 +1,126 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.common;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/*
+ * This code is originally from HDFS, see the similarly named files there
+ * in case of bug fixing, history, etc...
+ */
+
+/**
+ * A FileOutputStream that has the property that it will only show up at its
+ * destination once it has been entirely written and flushed to disk. While
+ * being written, it will use a .tmp suffix.
+ *
+ * When the output stream is closed, it is flushed, fsynced, and will be moved
+ * into place, overwriting any file that already exists at that location.
+ *
+ * <b>NOTE</b>: on Windows platforms, it will not atomically replace the target
+ * file - instead the target file is deleted before this one is moved into
+ * place.
+ */
+public class AtomicFileOutputStream extends FilterOutputStream {
+    private static final String TMP_EXTENSION = ".tmp";
+
+    private final static Logger LOG = LoggerFactory
+            .getLogger(AtomicFileOutputStream.class);
+
+    private final File origFile;
+    private final File tmpFile;
+
+    public AtomicFileOutputStream(File f) throws FileNotFoundException {
+        // Code unfortunately must be duplicated below since we can't assign
+        // anything
+        // before calling super
+        super(new FileOutputStream(new File(f.getParentFile(), f.getName()
+                + TMP_EXTENSION)));
+        origFile = f.getAbsoluteFile();
+        tmpFile = new File(f.getParentFile(), f.getName() + TMP_EXTENSION)
+                .getAbsoluteFile();
+    }
+
+    /**
+     * The default write method in FilterOutputStream does not call the write
+     * method of its underlying input stream with the same arguments. Instead
+     * it writes the data byte by byte, override it here to make it more
+     * efficient.
+     */
+    @Override
+    public void write(byte b[], int off, int len) throws IOException {
+        out.write(b, off, len);
+    }
+
+    @Override
+    public void close() throws IOException {
+        boolean triedToClose = false, success = false;
+        try {
+            flush();
+            ((FileOutputStream) out).getChannel().force(true);
+
+            triedToClose = true;
+            super.close();
+            success = true;
+        } finally {
+            if (success) {
+                boolean renamed = tmpFile.renameTo(origFile);
+                if (!renamed) {
+                    // On windows, renameTo does not replace.
+                    if (!origFile.delete() || !tmpFile.renameTo(origFile)) {
+                        throw new IOException(
+                                "Could not rename temporary file " + tmpFile
+                                        + " to " + origFile);
+                    }
+                }
+            } else {
+                if (!triedToClose) {
+                    // If we failed when flushing, try to close it to not leak
+                    // an FD
+                    IOUtils.closeStream(out);
+                }
+                // close wasn't successful, try to delete the tmp file
+                if (!tmpFile.delete()) {
+                    LOG.warn("Unable to delete tmp file " + tmpFile);
+                }
+            }
+        }
+    }
+
+    /**
+     * Close the atomic file, but do not "commit" the temporary file on top of
+     * the destination. This should be used if there is a failure in writing.
+     */
+    public void abort() {
+        try {
+            super.close();
+        } catch (IOException ioe) {
+            LOG.warn("Unable to abort file " + tmpFile, ioe);
+        }
+        if (!tmpFile.delete()) {
+            LOG.warn("Unable to delete tmp file during abort " + tmpFile);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/common/IOUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/IOUtils.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/IOUtils.java
new file mode 100644
index 0000000..16aea4e
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/IOUtils.java
@@ -0,0 +1,123 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.common;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.slf4j.Logger;
+
+/*
+ * This code is originally from HDFS, see the similarly named files there
+ * in case of bug fixing, history, etc...
+ */
+
+public class IOUtils {
+    /**
+     * Closes the stream ignoring {@link IOException}. Must only be called in
+     * cleaning up from exception handlers.
+     * 
+     * @param stream
+     *            the Stream to close
+     */
+    public static void closeStream(Closeable stream) {
+        cleanup(null, stream);
+    }
+
+    /**
+     * Close the Closeable objects and <b>ignore</b> any {@link IOException} or
+     * null pointers. Must only be used for cleanup in exception handlers.
+     * 
+     * @param log
+     *            the log to record problems to at debug level. Can be null.
+     * @param closeables
+     *            the objects to close
+     */
+    public static void cleanup(Logger log, Closeable... closeables) {
+        for (Closeable c : closeables) {
+            if (c != null) {
+                try {
+                    c.close();
+                } catch (IOException e) {
+                    if (log != null) {
+                        log.warn("Exception in closing " + c, e);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Copies from one stream to another.
+     * 
+     * @param in
+     *            InputStrem to read from
+     * @param out
+     *            OutputStream to write to
+     * @param buffSize
+     *            the size of the buffer
+     * @param close
+     *            whether or not close the InputStream and OutputStream at the
+     *            end. The streams are closed in the finally clause.
+     */
+    public static void copyBytes(InputStream in, OutputStream out,
+            int buffSize, boolean close) throws IOException {
+        try {
+            copyBytes(in, out, buffSize);
+            if (close) {
+                out.close();
+                out = null;
+                in.close();
+                in = null;
+            }
+        } finally {
+            if (close) {
+                closeStream(out);
+                closeStream(in);
+            }
+        }
+    }
+
+    /**
+     * Copies from one stream to another.
+     * 
+     * @param in
+     *            InputStrem to read from
+     * @param out
+     *            OutputStream to write to
+     * @param buffSize
+     *            the size of the buffer
+     */
+    public static void copyBytes(InputStream in, OutputStream out, int buffSize)
+            throws IOException {
+        PrintStream ps = out instanceof PrintStream ? (PrintStream) out : null;
+        byte buf[] = new byte[buffSize];
+        int bytesRead = in.read(buf);
+        while (bytesRead >= 0) {
+            out.write(buf, 0, bytesRead);
+            if ((ps != null) && ps.checkError()) {
+                throw new IOException("Unable to write to output stream.");
+            }
+            bytesRead = in.read(buf);
+        }
+    }
+
+}


[18/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java
new file mode 100644
index 0000000..447a3ee
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java
@@ -0,0 +1,1481 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.security.auth.login.LoginException;
+import javax.security.sasl.SaslException;
+
+import org.apache.jute.BinaryInputArchive;
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.jute.Record;
+import org.apache.zookeeper.AsyncCallback.ACLCallback;
+import org.apache.zookeeper.AsyncCallback.Children2Callback;
+import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.MultiCallback;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.OpResult.ErrorResult;
+import org.apache.zookeeper.Watcher.Event;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.OpCode;
+import org.apache.zookeeper.ZooKeeper.States;
+import org.apache.zookeeper.ZooKeeper.WatchRegistration;
+import org.apache.zookeeper.client.HostProvider;
+import org.apache.zookeeper.client.ZooKeeperSaslClient;
+import org.apache.zookeeper.common.Time;
+import org.apache.zookeeper.proto.AuthPacket;
+import org.apache.zookeeper.proto.ConnectRequest;
+import org.apache.zookeeper.proto.CreateResponse;
+import org.apache.zookeeper.proto.ExistsResponse;
+import org.apache.zookeeper.proto.GetACLResponse;
+import org.apache.zookeeper.proto.GetChildren2Response;
+import org.apache.zookeeper.proto.GetChildrenResponse;
+import org.apache.zookeeper.proto.GetDataResponse;
+import org.apache.zookeeper.proto.GetSASLRequest;
+import org.apache.zookeeper.proto.ReplyHeader;
+import org.apache.zookeeper.proto.RequestHeader;
+import org.apache.zookeeper.proto.SetACLResponse;
+import org.apache.zookeeper.proto.SetDataResponse;
+import org.apache.zookeeper.proto.SetWatches;
+import org.apache.zookeeper.proto.WatcherEvent;
+import org.apache.zookeeper.server.ByteBufferInputStream;
+import org.apache.zookeeper.server.ZooKeeperThread;
+import org.apache.zookeeper.server.ZooTrace;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class manages the socket i/o for the client. ClientCnxn maintains a list
+ * of available servers to connect to and "transparently" switches servers it is
+ * connected to as needed.
+ *
+ */
+public class ClientCnxn {
+    private static final Logger LOG = LoggerFactory.getLogger(ClientCnxn.class);
+
+    private static final String ZK_SASL_CLIENT_USERNAME =
+        "zookeeper.sasl.client.username";
+
+    /* ZOOKEEPER-706: If a session has a large number of watches set then
+     * attempting to re-establish those watches after a connection loss may
+     * fail due to the SetWatches request exceeding the server's configured
+     * jute.maxBuffer value. To avoid this we instead split the watch
+     * re-establishement across multiple SetWatches calls. This constant
+     * controls the size of each call. It is set to 128kB to be conservative
+     * with respect to the server's 1MB default for jute.maxBuffer.
+     */
+    private static final int SET_WATCHES_MAX_LENGTH = 128 * 1024;
+
+    /** This controls whether automatic watch resetting is enabled.
+     * Clients automatically reset watches during session reconnect, this
+     * option allows the client to turn off this behavior by setting
+     * the environment variable "zookeeper.disableAutoWatchReset" to "true" */
+    private static boolean disableAutoWatchReset;
+    static {
+        // this var should not be public, but otw there is no easy way
+        // to test
+        disableAutoWatchReset =
+            Boolean.getBoolean("zookeeper.disableAutoWatchReset");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("zookeeper.disableAutoWatchReset is "
+                    + disableAutoWatchReset);
+        }
+    }
+
+    static class AuthData {
+        AuthData(String scheme, byte data[]) {
+            this.scheme = scheme;
+            this.data = data;
+        }
+
+        String scheme;
+
+        byte data[];
+    }
+
+    private final CopyOnWriteArraySet<AuthData> authInfo = new CopyOnWriteArraySet<AuthData>();
+
+    /**
+     * These are the packets that have been sent and are waiting for a response.
+     */
+    private final LinkedList<Packet> pendingQueue = new LinkedList<Packet>();
+
+    /**
+     * These are the packets that need to be sent.
+     */
+    private final LinkedList<Packet> outgoingQueue = new LinkedList<Packet>();
+
+    private int connectTimeout;
+
+    /**
+     * The timeout in ms the client negotiated with the server. This is the
+     * "real" timeout, not the timeout request by the client (which may have
+     * been increased/decreased by the server which applies bounds to this
+     * value.
+     */
+    private volatile int negotiatedSessionTimeout;
+
+    private int readTimeout;
+
+    private final int sessionTimeout;
+
+    private final ZooKeeper zooKeeper;
+
+    private final ClientWatchManager watcher;
+
+    private long sessionId;
+
+    private byte sessionPasswd[] = new byte[16];
+
+    /**
+     * If true, the connection is allowed to go to r-o mode. This field's value
+     * is sent, besides other data, during session creation handshake. If the
+     * server on the other side of the wire is partitioned it'll accept
+     * read-only clients only.
+     */
+    private boolean readOnly;
+
+    final String chrootPath;
+
+    final SendThread sendThread;
+
+    final EventThread eventThread;
+
+    /**
+     * Set to true when close is called. Latches the connection such that we
+     * don't attempt to re-connect to the server if in the middle of closing the
+     * connection (client sends session disconnect to server as part of close
+     * operation)
+     */
+    private volatile boolean closing = false;
+    
+    /**
+     * A set of ZooKeeper hosts this client could connect to.
+     */
+    private final HostProvider hostProvider;
+
+    /**
+     * Is set to true when a connection to a r/w server is established for the
+     * first time; never changed afterwards.
+     * <p>
+     * Is used to handle situations when client without sessionId connects to a
+     * read-only server. Such client receives "fake" sessionId from read-only
+     * server, but this sessionId is invalid for other servers. So when such
+     * client finds a r/w server, it sends 0 instead of fake sessionId during
+     * connection handshake and establishes new, valid session.
+     * <p>
+     * If this field is false (which implies we haven't seen r/w server before)
+     * then non-zero sessionId is fake, otherwise it is valid.
+     */
+    volatile boolean seenRwServerBefore = false;
+
+
+    public ZooKeeperSaslClient zooKeeperSaslClient;
+
+    public long getSessionId() {
+        return sessionId;
+    }
+
+    public byte[] getSessionPasswd() {
+        return sessionPasswd;
+    }
+
+    public int getSessionTimeout() {
+        return negotiatedSessionTimeout;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        SocketAddress local = sendThread.getClientCnxnSocket().getLocalSocketAddress();
+        SocketAddress remote = sendThread.getClientCnxnSocket().getRemoteSocketAddress();
+        sb
+            .append("sessionid:0x").append(Long.toHexString(getSessionId()))
+            .append(" local:").append(local)
+            .append(" remoteserver:").append(remote)
+            .append(" lastZxid:").append(lastZxid)
+            .append(" xid:").append(xid)
+            .append(" sent:").append(sendThread.getClientCnxnSocket().getSentCount())
+            .append(" recv:").append(sendThread.getClientCnxnSocket().getRecvCount())
+            .append(" queuedpkts:").append(outgoingQueue.size())
+            .append(" pendingresp:").append(pendingQueue.size())
+            .append(" queuedevents:").append(eventThread.waitingEvents.size());
+
+        return sb.toString();
+    }
+
+    /**
+     * This class allows us to pass the headers and the relevant records around.
+     */
+    static class Packet {
+        RequestHeader requestHeader;
+
+        ReplyHeader replyHeader;
+
+        Record request;
+
+        Record response;
+
+        ByteBuffer bb;
+
+        /** Client's view of the path (may differ due to chroot) **/
+        String clientPath;
+        /** Servers's view of the path (may differ due to chroot) **/
+        String serverPath;
+
+        boolean finished;
+
+        AsyncCallback cb;
+
+        Object ctx;
+
+        WatchRegistration watchRegistration;
+
+        public boolean readOnly;
+
+        /** Convenience ctor */
+        Packet(RequestHeader requestHeader, ReplyHeader replyHeader,
+               Record request, Record response,
+               WatchRegistration watchRegistration) {
+            this(requestHeader, replyHeader, request, response,
+                 watchRegistration, false);
+        }
+
+        Packet(RequestHeader requestHeader, ReplyHeader replyHeader,
+               Record request, Record response,
+               WatchRegistration watchRegistration, boolean readOnly) {
+
+            this.requestHeader = requestHeader;
+            this.replyHeader = replyHeader;
+            this.request = request;
+            this.response = response;
+            this.readOnly = readOnly;
+            this.watchRegistration = watchRegistration;
+        }
+
+        public void createBB() {
+            try {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+                boa.writeInt(-1, "len"); // We'll fill this in later
+                if (requestHeader != null) {
+                    requestHeader.serialize(boa, "header");
+                }
+                if (request instanceof ConnectRequest) {
+                    request.serialize(boa, "connect");
+                    // append "am-I-allowed-to-be-readonly" flag
+                    boa.writeBool(readOnly, "readOnly");
+                } else if (request != null) {
+                    request.serialize(boa, "request");
+                }
+                baos.close();
+                this.bb = ByteBuffer.wrap(baos.toByteArray());
+                this.bb.putInt(this.bb.capacity() - 4);
+                this.bb.rewind();
+            } catch (IOException e) {
+                LOG.warn("Ignoring unexpected exception", e);
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+
+            sb.append("clientPath:" + clientPath);
+            sb.append(" serverPath:" + serverPath);
+            sb.append(" finished:" + finished);
+
+            sb.append(" header:: " + requestHeader);
+            sb.append(" replyHeader:: " + replyHeader);
+            sb.append(" request:: " + request);
+            sb.append(" response:: " + response);
+
+            // jute toString is horrible, remove unnecessary newlines
+            return sb.toString().replaceAll("\r*\n+", " ");
+        }
+    }
+
+    /**
+     * Creates a connection object. The actual network connect doesn't get
+     * established until needed. The start() instance method must be called
+     * subsequent to construction.
+     *
+     * @param chrootPath - the chroot of this client. Should be removed from this Class in ZOOKEEPER-838
+     * @param hostProvider
+     *                the list of ZooKeeper servers to connect to
+     * @param sessionTimeout
+     *                the timeout for connections.
+     * @param zooKeeper
+     *                the zookeeper object that this connection is related to.
+     * @param watcher watcher for this connection
+     * @param clientCnxnSocket
+     *                the socket implementation used (e.g. NIO/Netty)
+     * @param canBeReadOnly
+     *                whether the connection is allowed to go to read-only
+     *                mode in case of partitioning
+     * @throws IOException
+     */
+    public ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,
+            ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket, boolean canBeReadOnly)
+            throws IOException {
+        this(chrootPath, hostProvider, sessionTimeout, zooKeeper, watcher,
+             clientCnxnSocket, 0, new byte[16], canBeReadOnly);
+    }
+
+    /**
+     * Creates a connection object. The actual network connect doesn't get
+     * established until needed. The start() instance method must be called
+     * subsequent to construction.
+     *
+     * @param chrootPath - the chroot of this client. Should be removed from this Class in ZOOKEEPER-838
+     * @param hostProvider
+     *                the list of ZooKeeper servers to connect to
+     * @param sessionTimeout
+     *                the timeout for connections.
+     * @param zooKeeper
+     *                the zookeeper object that this connection is related to.
+     * @param watcher watcher for this connection
+     * @param clientCnxnSocket
+     *                the socket implementation used (e.g. NIO/Netty)
+     * @param sessionId session id if re-establishing session
+     * @param sessionPasswd session passwd if re-establishing session
+     * @param canBeReadOnly
+     *                whether the connection is allowed to go to read-only
+     *                mode in case of partitioning
+     * @throws IOException
+     */
+    public ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,
+            ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket,
+            long sessionId, byte[] sessionPasswd, boolean canBeReadOnly) {
+        this.zooKeeper = zooKeeper;
+        this.watcher = watcher;
+        this.sessionId = sessionId;
+        this.sessionPasswd = sessionPasswd;
+        this.sessionTimeout = sessionTimeout;
+        this.hostProvider = hostProvider;
+        this.chrootPath = chrootPath;
+
+        connectTimeout = sessionTimeout / hostProvider.size();
+        readTimeout = sessionTimeout * 2 / 3;
+        readOnly = canBeReadOnly;
+
+        sendThread = new SendThread(clientCnxnSocket);
+        eventThread = new EventThread();
+
+    }
+
+    /**
+     * tests use this to check on reset of watches
+     * @return if the auto reset of watches are disabled
+     */
+    public static boolean getDisableAutoResetWatch() {
+        return disableAutoWatchReset;
+    }
+    /**
+     * tests use this to set the auto reset
+     * @param b the value to set disable watches to
+     */
+    public static void setDisableAutoResetWatch(boolean b) {
+        disableAutoWatchReset = b;
+    }
+    public void start() {
+        sendThread.start();
+        eventThread.start();
+    }
+
+    private Object eventOfDeath = new Object();
+
+    private static class WatcherSetEventPair {
+        private final Set<Watcher> watchers;
+        private final WatchedEvent event;
+
+        public WatcherSetEventPair(Set<Watcher> watchers, WatchedEvent event) {
+            this.watchers = watchers;
+            this.event = event;
+        }
+    }
+
+    /**
+     * Guard against creating "-EventThread-EventThread-EventThread-..." thread
+     * names when ZooKeeper object is being created from within a watcher.
+     * See ZOOKEEPER-795 for details.
+     */
+    private static String makeThreadName(String suffix) {
+        String name = Thread.currentThread().getName().
+            replaceAll("-EventThread", "");
+        return name + suffix;
+    }
+
+    class EventThread extends ZooKeeperThread {
+        private final LinkedBlockingQueue<Object> waitingEvents =
+            new LinkedBlockingQueue<Object>();
+
+        /** This is really the queued session state until the event
+         * thread actually processes the event and hands it to the watcher.
+         * But for all intents and purposes this is the state.
+         */
+        private volatile KeeperState sessionState = KeeperState.Disconnected;
+
+       private volatile boolean wasKilled = false;
+       private volatile boolean isRunning = false;
+
+        EventThread() {
+            super(makeThreadName("-EventThread"));
+            setDaemon(true);
+        }
+
+        public void queueEvent(WatchedEvent event) {
+            if (event.getType() == EventType.None
+                    && sessionState == event.getState()) {
+                return;
+            }
+            sessionState = event.getState();
+
+            // materialize the watchers based on the event
+            WatcherSetEventPair pair = new WatcherSetEventPair(
+                    watcher.materialize(event.getState(), event.getType(),
+                            event.getPath()),
+                            event);
+            // queue the pair (watch set & event) for later processing
+            waitingEvents.add(pair);
+        }
+
+       public void queuePacket(Packet packet) {
+          if (wasKilled) {
+             synchronized (waitingEvents) {
+                if (isRunning) waitingEvents.add(packet);
+                else processEvent(packet);
+             }
+          } else {
+             waitingEvents.add(packet);
+          }
+       }
+
+        public void queueEventOfDeath() {
+            waitingEvents.add(eventOfDeath);
+        }
+
+        @Override
+        public void run() {
+           try {
+              isRunning = true;
+              while (true) {
+                 Object event = waitingEvents.take();
+                 if (event == eventOfDeath) {
+                    wasKilled = true;
+                 } else {
+                    processEvent(event);
+                 }
+                 if (wasKilled)
+                    synchronized (waitingEvents) {
+                       if (waitingEvents.isEmpty()) {
+                          isRunning = false;
+                          break;
+                       }
+                    }
+              }
+           } catch (InterruptedException e) {
+              LOG.error("Event thread exiting due to interruption", e);
+           }
+
+            LOG.info("EventThread shut down for session: 0x{}",
+                     Long.toHexString(getSessionId()));
+        }
+
+       private void processEvent(Object event) {
+          try {
+              if (event instanceof WatcherSetEventPair) {
+                  // each watcher will process the event
+                  WatcherSetEventPair pair = (WatcherSetEventPair) event;
+                  for (Watcher watcher : pair.watchers) {
+                      try {
+                          watcher.process(pair.event);
+                      } catch (Throwable t) {
+                          LOG.error("Error while calling watcher ", t);
+                      }
+                  }
+              } else {
+                  Packet p = (Packet) event;
+                  int rc = 0;
+                  String clientPath = p.clientPath;
+                  if (p.replyHeader.getErr() != 0) {
+                      rc = p.replyHeader.getErr();
+                  }
+                  if (p.cb == null) {
+                      LOG.warn("Somehow a null cb got to EventThread!");
+                  } else if (p.response instanceof ExistsResponse
+                          || p.response instanceof SetDataResponse
+                          || p.response instanceof SetACLResponse) {
+                      StatCallback cb = (StatCallback) p.cb;
+                      if (rc == 0) {
+                          if (p.response instanceof ExistsResponse) {
+                              cb.processResult(rc, clientPath, p.ctx,
+                                      ((ExistsResponse) p.response)
+                                              .getStat());
+                          } else if (p.response instanceof SetDataResponse) {
+                              cb.processResult(rc, clientPath, p.ctx,
+                                      ((SetDataResponse) p.response)
+                                              .getStat());
+                          } else if (p.response instanceof SetACLResponse) {
+                              cb.processResult(rc, clientPath, p.ctx,
+                                      ((SetACLResponse) p.response)
+                                              .getStat());
+                          }
+                      } else {
+                          cb.processResult(rc, clientPath, p.ctx, null);
+                      }
+                  } else if (p.response instanceof GetDataResponse) {
+                      DataCallback cb = (DataCallback) p.cb;
+                      GetDataResponse rsp = (GetDataResponse) p.response;
+                      if (rc == 0) {
+                          cb.processResult(rc, clientPath, p.ctx, rsp
+                                  .getData(), rsp.getStat());
+                      } else {
+                          cb.processResult(rc, clientPath, p.ctx, null,
+                                  null);
+                      }
+                  } else if (p.response instanceof GetACLResponse) {
+                      ACLCallback cb = (ACLCallback) p.cb;
+                      GetACLResponse rsp = (GetACLResponse) p.response;
+                      if (rc == 0) {
+                          cb.processResult(rc, clientPath, p.ctx, rsp
+                                  .getAcl(), rsp.getStat());
+                      } else {
+                          cb.processResult(rc, clientPath, p.ctx, null,
+                                  null);
+                      }
+                  } else if (p.response instanceof GetChildrenResponse) {
+                      ChildrenCallback cb = (ChildrenCallback) p.cb;
+                      GetChildrenResponse rsp = (GetChildrenResponse) p.response;
+                      if (rc == 0) {
+                          cb.processResult(rc, clientPath, p.ctx, rsp
+                                  .getChildren());
+                      } else {
+                          cb.processResult(rc, clientPath, p.ctx, null);
+                      }
+                  } else if (p.response instanceof GetChildren2Response) {
+                      Children2Callback cb = (Children2Callback) p.cb;
+                      GetChildren2Response rsp = (GetChildren2Response) p.response;
+                      if (rc == 0) {
+                          cb.processResult(rc, clientPath, p.ctx, rsp
+                                  .getChildren(), rsp.getStat());
+                      } else {
+                          cb.processResult(rc, clientPath, p.ctx, null, null);
+                      }
+                  } else if (p.response instanceof CreateResponse) {
+                      StringCallback cb = (StringCallback) p.cb;
+                      CreateResponse rsp = (CreateResponse) p.response;
+                      if (rc == 0) {
+                          cb.processResult(rc, clientPath, p.ctx,
+                                  (chrootPath == null
+                                          ? rsp.getPath()
+                                          : rsp.getPath()
+                                    .substring(chrootPath.length())));
+                      } else {
+                          cb.processResult(rc, clientPath, p.ctx, null);
+                      }
+                  } else if (p.response instanceof MultiResponse) {
+                          MultiCallback cb = (MultiCallback) p.cb;
+                          MultiResponse rsp = (MultiResponse) p.response;
+                          if (rc == 0) {
+                                  List<OpResult> results = rsp.getResultList();
+                                  int newRc = rc;
+                                  for (OpResult result : results) {
+                                          if (result instanceof ErrorResult
+                                              && KeeperException.Code.OK.intValue()
+                                                  != (newRc = ((ErrorResult) result).getErr())) {
+                                                  break;
+                                          }
+                                  }
+                                  cb.processResult(newRc, clientPath, p.ctx, results);
+                          } else {
+                                  cb.processResult(rc, clientPath, p.ctx, null);
+                          }
+                  }  else if (p.cb instanceof VoidCallback) {
+                      VoidCallback cb = (VoidCallback) p.cb;
+                      cb.processResult(rc, clientPath, p.ctx);
+                  }
+              }
+          } catch (Throwable t) {
+              LOG.error("Caught unexpected throwable", t);
+          }
+       }
+    }
+
+    private void finishPacket(Packet p) {
+        if (p.watchRegistration != null) {
+            p.watchRegistration.register(p.replyHeader.getErr());
+        }
+
+        if (p.cb == null) {
+            synchronized (p) {
+                p.finished = true;
+                p.notifyAll();
+            }
+        } else {
+            p.finished = true;
+            eventThread.queuePacket(p);
+        }
+    }
+
+    private void conLossPacket(Packet p) {
+        if (p.replyHeader == null) {
+            return;
+        }
+        switch (state) {
+        case AUTH_FAILED:
+            p.replyHeader.setErr(KeeperException.Code.AUTHFAILED.intValue());
+            break;
+        case CLOSED:
+            p.replyHeader.setErr(KeeperException.Code.SESSIONEXPIRED.intValue());
+            break;
+        default:
+            p.replyHeader.setErr(KeeperException.Code.CONNECTIONLOSS.intValue());
+        }
+        finishPacket(p);
+    }
+
+    private volatile long lastZxid;
+
+    public long getLastZxid() {
+        return lastZxid;
+    }
+
+    static class EndOfStreamException extends IOException {
+        private static final long serialVersionUID = -5438877188796231422L;
+
+        public EndOfStreamException(String msg) {
+            super(msg);
+        }
+        
+        @Override
+        public String toString() {
+            return "EndOfStreamException: " + getMessage();
+        }
+    }
+
+    private static class SessionTimeoutException extends IOException {
+        private static final long serialVersionUID = 824482094072071178L;
+
+        public SessionTimeoutException(String msg) {
+            super(msg);
+        }
+    }
+    
+    private static class SessionExpiredException extends IOException {
+        private static final long serialVersionUID = -1388816932076193249L;
+
+        public SessionExpiredException(String msg) {
+            super(msg);
+        }
+    }
+
+    private static class RWServerFoundException extends IOException {
+        private static final long serialVersionUID = 90431199887158758L;
+
+        public RWServerFoundException(String msg) {
+            super(msg);
+        }
+    }
+    
+    public static final int packetLen = Integer.getInteger("jute.maxbuffer",
+            4096 * 1024);
+
+    /**
+     * This class services the outgoing request queue and generates the heart
+     * beats. It also spawns the ReadThread.
+     */
+    class SendThread extends ZooKeeperThread {
+        private long lastPingSentNs;
+        private final ClientCnxnSocket clientCnxnSocket;
+        private Random r = new Random(System.nanoTime());        
+        private boolean isFirstConnect = true;
+
+        void readResponse(ByteBuffer incomingBuffer) throws IOException {
+            ByteBufferInputStream bbis = new ByteBufferInputStream(
+                    incomingBuffer);
+            BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis);
+            ReplyHeader replyHdr = new ReplyHeader();
+
+            replyHdr.deserialize(bbia, "header");
+            if (replyHdr.getXid() == -2) {
+                // -2 is the xid for pings
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Got ping response for sessionid: 0x"
+                            + Long.toHexString(sessionId)
+                            + " after "
+                            + ((System.nanoTime() - lastPingSentNs) / 1000000)
+                            + "ms");
+                }
+                return;
+            }
+            if (replyHdr.getXid() == -4) {
+                // -4 is the xid for AuthPacket               
+                if(replyHdr.getErr() == KeeperException.Code.AUTHFAILED.intValue()) {
+                    state = States.AUTH_FAILED;                    
+                    eventThread.queueEvent( new WatchedEvent(Watcher.Event.EventType.None, 
+                            Watcher.Event.KeeperState.AuthFailed, null) );            		            		
+                }
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Got auth sessionid:0x"
+                            + Long.toHexString(sessionId));
+                }
+                return;
+            }
+            if (replyHdr.getXid() == -1) {
+                // -1 means notification
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Got notification sessionid:0x"
+                        + Long.toHexString(sessionId));
+                }
+                WatcherEvent event = new WatcherEvent();
+                event.deserialize(bbia, "response");
+
+                // convert from a server path to a client path
+                if (chrootPath != null) {
+                    String serverPath = event.getPath();
+                    if(serverPath.compareTo(chrootPath)==0)
+                        event.setPath("/");
+                    else if (serverPath.length() > chrootPath.length())
+                        event.setPath(serverPath.substring(chrootPath.length()));
+                    else {
+                    	LOG.warn("Got server path " + event.getPath()
+                    			+ " which is too short for chroot path "
+                    			+ chrootPath);
+                    }
+                }
+
+                WatchedEvent we = new WatchedEvent(event);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Got " + we + " for sessionid 0x"
+                            + Long.toHexString(sessionId));
+                }
+
+                eventThread.queueEvent( we );
+                return;
+            }
+
+            // If SASL authentication is currently in progress, construct and
+            // send a response packet immediately, rather than queuing a
+            // response as with other packets.
+            if (clientTunneledAuthenticationInProgress()) {
+                GetSASLRequest request = new GetSASLRequest();
+                request.deserialize(bbia,"token");
+                zooKeeperSaslClient.respondToServer(request.getToken(),
+                  ClientCnxn.this);
+                return;
+            }
+
+            Packet packet;
+            synchronized (pendingQueue) {
+                if (pendingQueue.size() == 0) {
+                    throw new IOException("Nothing in the queue, but got "
+                            + replyHdr.getXid());
+                }
+                packet = pendingQueue.remove();
+            }
+            /*
+             * Since requests are processed in order, we better get a response
+             * to the first request!
+             */
+            try {
+                if (packet.requestHeader.getXid() != replyHdr.getXid()) {
+                    packet.replyHeader.setErr(
+                            KeeperException.Code.CONNECTIONLOSS.intValue());
+                    throw new IOException("Xid out of order. Got Xid "
+                            + replyHdr.getXid() + " with err " +
+                            + replyHdr.getErr() +
+                            " expected Xid "
+                            + packet.requestHeader.getXid()
+                            + " for a packet with details: "
+                            + packet );
+                }
+
+                packet.replyHeader.setXid(replyHdr.getXid());
+                packet.replyHeader.setErr(replyHdr.getErr());
+                packet.replyHeader.setZxid(replyHdr.getZxid());
+                if (replyHdr.getZxid() > 0) {
+                    lastZxid = replyHdr.getZxid();
+                }
+                if (packet.response != null && replyHdr.getErr() == 0) {
+                    packet.response.deserialize(bbia, "response");
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Reading reply sessionid:0x"
+                            + Long.toHexString(sessionId) + ", packet:: " + packet);
+                }
+            } finally {
+                finishPacket(packet);
+            }
+        }
+
+        SendThread(ClientCnxnSocket clientCnxnSocket) {
+            super(makeThreadName("-SendThread()"));
+            state = States.CONNECTING;
+            this.clientCnxnSocket = clientCnxnSocket;
+            setDaemon(true);
+        }
+
+        // TODO: can not name this method getState since Thread.getState()
+        // already exists
+        // It would be cleaner to make class SendThread an implementation of
+        // Runnable
+        /**
+         * Used by ClientCnxnSocket
+         * 
+         * @return
+         */
+        ZooKeeper.States getZkState() {
+            return state;
+        }
+
+        ClientCnxnSocket getClientCnxnSocket() {
+            return clientCnxnSocket;
+        }
+
+        void primeConnection() throws IOException {
+            LOG.info("Socket connection established to "
+                     + clientCnxnSocket.getRemoteSocketAddress()
+                     + ", initiating session");
+            isFirstConnect = false;
+            long sessId = (seenRwServerBefore) ? sessionId : 0;
+            ConnectRequest conReq = new ConnectRequest(0, lastZxid,
+                    sessionTimeout, sessId, sessionPasswd);
+            synchronized (outgoingQueue) {
+                // We add backwards since we are pushing into the front
+                // Only send if there's a pending watch
+                // TODO: here we have the only remaining use of zooKeeper in
+                // this class. It's to be eliminated!
+                if (!disableAutoWatchReset) {
+                    List<String> dataWatches = zooKeeper.getDataWatches();
+                    List<String> existWatches = zooKeeper.getExistWatches();
+                    List<String> childWatches = zooKeeper.getChildWatches();
+                    if (!dataWatches.isEmpty()
+                                || !existWatches.isEmpty() || !childWatches.isEmpty()) {
+
+                        Iterator<String> dataWatchesIter = prependChroot(dataWatches).iterator();
+                        Iterator<String> existWatchesIter = prependChroot(existWatches).iterator();
+                        Iterator<String> childWatchesIter = prependChroot(childWatches).iterator();
+                        long setWatchesLastZxid = lastZxid;
+
+                        while (dataWatchesIter.hasNext()
+                                       || existWatchesIter.hasNext() || childWatchesIter.hasNext()) {
+                            List<String> dataWatchesBatch = new ArrayList<String>();
+                            List<String> existWatchesBatch = new ArrayList<String>();
+                            List<String> childWatchesBatch = new ArrayList<String>();
+                            int batchLength = 0;
+
+                            // Note, we may exceed our max length by a bit when we add the last
+                            // watch in the batch. This isn't ideal, but it makes the code simpler.
+                            while (batchLength < SET_WATCHES_MAX_LENGTH) {
+                                final String watch;
+                                if (dataWatchesIter.hasNext()) {
+                                    watch = dataWatchesIter.next();
+                                    dataWatchesBatch.add(watch);
+                                } else if (existWatchesIter.hasNext()) {
+                                    watch = existWatchesIter.next();
+                                    existWatchesBatch.add(watch);
+                                } else if (childWatchesIter.hasNext()) {
+                                    watch = childWatchesIter.next();
+                                    childWatchesBatch.add(watch);
+                                } else {
+                                    break;
+                                }
+                                batchLength += watch.length();
+                            }
+
+                            SetWatches sw = new SetWatches(setWatchesLastZxid,
+                                    dataWatchesBatch,
+                                    existWatchesBatch,
+                                    childWatchesBatch);
+                            RequestHeader h = new RequestHeader();
+                            h.setType(ZooDefs.OpCode.setWatches);
+                            h.setXid(-8);
+                            Packet packet = new Packet(h, new ReplyHeader(), sw, null, null);
+                            outgoingQueue.addFirst(packet);
+                        }
+                    }
+                }
+
+                for (AuthData id : authInfo) {
+                    outgoingQueue.addFirst(new Packet(new RequestHeader(-4,
+                            OpCode.auth), null, new AuthPacket(0, id.scheme,
+                            id.data), null, null));
+                }
+                outgoingQueue.addFirst(new Packet(null, null, conReq,
+                            null, null, readOnly));
+            }
+            clientCnxnSocket.enableReadWriteOnly();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Session establishment request sent on "
+                        + clientCnxnSocket.getRemoteSocketAddress());
+            }
+        }
+
+        private List<String> prependChroot(List<String> paths) {
+            if (chrootPath != null && !paths.isEmpty()) {
+                for (int i = 0; i < paths.size(); ++i) {
+                    String clientPath = paths.get(i);
+                    String serverPath;
+                    // handle clientPath = "/"
+                    if (clientPath.length() == 1) {
+                        serverPath = chrootPath;
+                    } else {
+                        serverPath = chrootPath + clientPath;
+                    }
+                    paths.set(i, serverPath);
+                }
+            }
+            return paths;
+        }
+
+        private void sendPing() {
+            lastPingSentNs = System.nanoTime();
+            RequestHeader h = new RequestHeader(-2, OpCode.ping);
+            queuePacket(h, null, null, null, null, null, null, null, null);
+        }
+
+        private InetSocketAddress rwServerAddress = null;
+
+        private final static int minPingRwTimeout = 100;
+
+        private final static int maxPingRwTimeout = 60000;
+
+        private int pingRwTimeout = minPingRwTimeout;
+
+        // Set to true if and only if constructor of ZooKeeperSaslClient
+        // throws a LoginException: see startConnect() below.
+        private boolean saslLoginFailed = false;
+
+        private void startConnect(InetSocketAddress addr) throws IOException {
+            // initializing it for new connection
+            saslLoginFailed = false;
+            state = States.CONNECTING;
+
+            setName(getName().replaceAll("\\(.*\\)",
+                    "(" + addr.getHostName() + ":" + addr.getPort() + ")"));
+            if (ZooKeeperSaslClient.isEnabled()) {
+                try {
+                    String principalUserName = System.getProperty(
+                            ZK_SASL_CLIENT_USERNAME, "zookeeper");
+                    zooKeeperSaslClient =
+                        new ZooKeeperSaslClient(
+                                principalUserName+"/"+addr.getHostName());
+                } catch (LoginException e) {
+                    // An authentication error occurred when the SASL client tried to initialize:
+                    // for Kerberos this means that the client failed to authenticate with the KDC.
+                    // This is different from an authentication error that occurs during communication
+                    // with the Zookeeper server, which is handled below.
+                    LOG.warn("SASL configuration failed: " + e + " Will continue connection to Zookeeper server without "
+                      + "SASL authentication, if Zookeeper server allows it.");
+                    eventThread.queueEvent(new WatchedEvent(
+                      Watcher.Event.EventType.None,
+                      Watcher.Event.KeeperState.AuthFailed, null));
+                    saslLoginFailed = true;
+                }
+            }
+            logStartConnect(addr);
+
+            clientCnxnSocket.connect(addr);
+        }
+
+        private void logStartConnect(InetSocketAddress addr) {
+            String msg = "Opening socket connection to server " + addr;
+            if (zooKeeperSaslClient != null) {
+              msg += ". " + zooKeeperSaslClient.getConfigStatus();
+            }
+            LOG.info(msg);
+        }
+
+        private static final String RETRY_CONN_MSG =
+            ", closing socket connection and attempting reconnect";
+        
+        @Override
+        public void run() {
+            clientCnxnSocket.introduce(this,sessionId);
+            clientCnxnSocket.updateNow();
+            clientCnxnSocket.updateLastSendAndHeard();
+            int to;
+            long lastPingRwServer = Time.currentElapsedTime();
+            final int MAX_SEND_PING_INTERVAL = 10000; //10 seconds
+            InetSocketAddress serverAddress = null;
+            while (state.isAlive()) {
+                try {
+                    if (!clientCnxnSocket.isConnected()) {
+                        if(!isFirstConnect){
+                            try {
+                                Thread.sleep(r.nextInt(1000));
+                            } catch (InterruptedException e) {
+                                LOG.warn("Unexpected exception", e);
+                            }
+                        }
+                        // don't re-establish connection if we are closing
+                        if (closing || !state.isAlive()) {
+                            break;
+                        }
+                        if (rwServerAddress != null) {
+                            serverAddress = rwServerAddress;
+                            rwServerAddress = null;
+                        } else {
+                            serverAddress = hostProvider.next(1000);
+                        }
+                        startConnect(serverAddress);
+                        clientCnxnSocket.updateLastSendAndHeard();
+                    }
+
+                    if (state.isConnected()) {
+                        // determine whether we need to send an AuthFailed event.
+                        if (zooKeeperSaslClient != null) {
+                            boolean sendAuthEvent = false;
+                            if (zooKeeperSaslClient.getSaslState() == ZooKeeperSaslClient.SaslState.INITIAL) {
+                                try {
+                                    zooKeeperSaslClient.initialize(ClientCnxn.this);
+                                } catch (SaslException e) {
+                                   LOG.error("SASL authentication with Zookeeper Quorum member failed: " + e);
+                                    state = States.AUTH_FAILED;
+                                    sendAuthEvent = true;
+                                }
+                            }
+                            KeeperState authState = zooKeeperSaslClient.getKeeperState();
+                            if (authState != null) {
+                                if (authState == KeeperState.AuthFailed) {
+                                    // An authentication error occurred during authentication with the Zookeeper Server.
+                                    state = States.AUTH_FAILED;
+                                    sendAuthEvent = true;
+                                } else {
+                                    if (authState == KeeperState.SaslAuthenticated) {
+                                        sendAuthEvent = true;
+                                    }
+                                }
+                            }
+
+                            if (sendAuthEvent == true) {
+                                eventThread.queueEvent(new WatchedEvent(
+                                      Watcher.Event.EventType.None,
+                                      authState,null));
+                            }
+                        }
+                        to = readTimeout - clientCnxnSocket.getIdleRecv();
+                    } else {
+                        to = connectTimeout - clientCnxnSocket.getIdleRecv();
+                    }
+                    
+                    if (to <= 0) {
+                        String warnInfo;
+                        warnInfo = "Client session timed out, have not heard from server in "
+                            + clientCnxnSocket.getIdleRecv()
+                            + "ms"
+                            + " for sessionid 0x"
+                            + Long.toHexString(sessionId);
+                        LOG.warn(warnInfo);
+                        throw new SessionTimeoutException(warnInfo);
+                    }
+                    if (state.isConnected()) {
+                    	//1000(1 second) is to prevent race condition missing to send the second ping
+                    	//also make sure not to send too many pings when readTimeout is small 
+                        int timeToNextPing = readTimeout / 2 - clientCnxnSocket.getIdleSend() - 
+                        		((clientCnxnSocket.getIdleSend() > 1000) ? 1000 : 0);
+                        //send a ping request either time is due or no packet sent out within MAX_SEND_PING_INTERVAL
+                        if (timeToNextPing <= 0 || clientCnxnSocket.getIdleSend() > MAX_SEND_PING_INTERVAL) {
+                            sendPing();
+                            clientCnxnSocket.updateLastSend();
+                        } else {
+                            if (timeToNextPing < to) {
+                                to = timeToNextPing;
+                            }
+                        }
+                    }
+
+                    // If we are in read-only mode, seek for read/write server
+                    if (state == States.CONNECTEDREADONLY) {
+                        long now = Time.currentElapsedTime();
+                        int idlePingRwServer = (int) (now - lastPingRwServer);
+                        if (idlePingRwServer >= pingRwTimeout) {
+                            lastPingRwServer = now;
+                            idlePingRwServer = 0;
+                            pingRwTimeout =
+                                Math.min(2*pingRwTimeout, maxPingRwTimeout);
+                            pingRwServer();
+                        }
+                        to = Math.min(to, pingRwTimeout - idlePingRwServer);
+                    }
+
+                    clientCnxnSocket.doTransport(to, pendingQueue, outgoingQueue, ClientCnxn.this);
+                } catch (Throwable e) {
+                    if (closing) {
+                        if (LOG.isDebugEnabled()) {
+                            // closing so this is expected
+                            LOG.debug("An exception was thrown while closing send thread for session 0x"
+                                    + Long.toHexString(getSessionId())
+                                    + " : " + e.getMessage());
+                        }
+                        break;
+                    } else {
+                        // this is ugly, you have a better way speak up
+                        if (e instanceof SessionExpiredException) {
+                            LOG.info(e.getMessage() + ", closing socket connection");
+                        } else if (e instanceof SessionTimeoutException) {
+                            LOG.info(e.getMessage() + RETRY_CONN_MSG);
+                        } else if (e instanceof EndOfStreamException) {
+                            LOG.info(e.getMessage() + RETRY_CONN_MSG);
+                        } else if (e instanceof RWServerFoundException) {
+                            LOG.info(e.getMessage());
+                        } else if (e instanceof SocketException) {
+                            LOG.info("Socket error occurred: {}: {}", serverAddress, e.getMessage());
+                        } else {
+                            LOG.warn("Session 0x{} for server {}, unexpected error{}",
+                                            Long.toHexString(getSessionId()),
+                                            serverAddress,
+                                            RETRY_CONN_MSG,
+                                            e);
+                        }
+                        cleanup();
+                        if (state.isAlive()) {
+                            eventThread.queueEvent(new WatchedEvent(
+                                    Event.EventType.None,
+                                    Event.KeeperState.Disconnected,
+                                    null));
+                        }
+                        clientCnxnSocket.updateNow();
+                        clientCnxnSocket.updateLastSendAndHeard();
+                    }
+                }
+            }
+            cleanup();
+            clientCnxnSocket.close();
+            if (state.isAlive()) {
+                eventThread.queueEvent(new WatchedEvent(Event.EventType.None,
+                        Event.KeeperState.Disconnected, null));
+            }
+            ZooTrace.logTraceMessage(LOG, ZooTrace.getTextTraceLevel(),
+                    "SendThread exited loop for session: 0x"
+                           + Long.toHexString(getSessionId()));
+        }
+
+        private void pingRwServer() throws RWServerFoundException, UnknownHostException {
+            String result = null;
+            InetSocketAddress addr = hostProvider.next(0);
+            LOG.info("Checking server " + addr + " for being r/w." +
+                    " Timeout " + pingRwTimeout);
+
+            Socket sock = null;
+            BufferedReader br = null;
+            try {
+                sock = new Socket(addr.getHostName(), addr.getPort());
+                sock.setSoLinger(false, -1);
+                sock.setSoTimeout(1000);
+                sock.setTcpNoDelay(true);
+                sock.getOutputStream().write("isro".getBytes());
+                sock.getOutputStream().flush();
+                sock.shutdownOutput();
+                br = new BufferedReader(
+                        new InputStreamReader(sock.getInputStream()));
+                result = br.readLine();
+            } catch (ConnectException e) {
+                // ignore, this just means server is not up
+            } catch (IOException e) {
+                // some unexpected error, warn about it
+                LOG.warn("Exception while seeking for r/w server " +
+                        e.getMessage(), e);
+            } finally {
+                if (sock != null) {
+                    try {
+                        sock.close();
+                    } catch (IOException e) {
+                        LOG.warn("Unexpected exception", e);
+                    }
+                }
+                if (br != null) {
+                    try {
+                        br.close();
+                    } catch (IOException e) {
+                        LOG.warn("Unexpected exception", e);
+                    }
+                }
+            }
+
+            if ("rw".equals(result)) {
+                pingRwTimeout = minPingRwTimeout;
+                // save the found address so that it's used during the next
+                // connection attempt
+                rwServerAddress = addr;
+                throw new RWServerFoundException("Majority server found at "
+                        + addr.getHostName() + ":" + addr.getPort());
+            }
+        }
+
+        private void cleanup() {
+            clientCnxnSocket.cleanup();
+            synchronized (pendingQueue) {
+                for (Packet p : pendingQueue) {
+                    conLossPacket(p);
+                }
+                pendingQueue.clear();
+            }
+            synchronized (outgoingQueue) {
+                for (Packet p : outgoingQueue) {
+                    conLossPacket(p);
+                }
+                outgoingQueue.clear();
+            }
+        }
+
+        /**
+         * Callback invoked by the ClientCnxnSocket once a connection has been
+         * established.
+         * 
+         * @param _negotiatedSessionTimeout
+         * @param _sessionId
+         * @param _sessionPasswd
+         * @param isRO
+         * @throws IOException
+         */
+        void onConnected(int _negotiatedSessionTimeout, long _sessionId,
+                byte[] _sessionPasswd, boolean isRO) throws IOException {
+            negotiatedSessionTimeout = _negotiatedSessionTimeout;
+            if (negotiatedSessionTimeout <= 0) {
+                state = States.CLOSED;
+
+                eventThread.queueEvent(new WatchedEvent(
+                        Watcher.Event.EventType.None,
+                        Watcher.Event.KeeperState.Expired, null));
+                eventThread.queueEventOfDeath();
+
+                String warnInfo;
+                warnInfo = "Unable to reconnect to ZooKeeper service, session 0x"
+                    + Long.toHexString(sessionId) + " has expired";
+                LOG.warn(warnInfo);
+                throw new SessionExpiredException(warnInfo);
+            }
+            if (!readOnly && isRO) {
+                LOG.error("Read/write client got connected to read-only server");
+            }
+            readTimeout = negotiatedSessionTimeout * 2 / 3;
+            connectTimeout = negotiatedSessionTimeout / hostProvider.size();
+            hostProvider.onConnected();
+            sessionId = _sessionId;
+            sessionPasswd = _sessionPasswd;
+            state = (isRO) ?
+                    States.CONNECTEDREADONLY : States.CONNECTED;
+            seenRwServerBefore |= !isRO;
+            LOG.info("Session establishment complete on server "
+                    + clientCnxnSocket.getRemoteSocketAddress()
+                    + ", sessionid = 0x" + Long.toHexString(sessionId)
+                    + ", negotiated timeout = " + negotiatedSessionTimeout
+                    + (isRO ? " (READ-ONLY mode)" : ""));
+            KeeperState eventState = (isRO) ?
+                    KeeperState.ConnectedReadOnly : KeeperState.SyncConnected;
+            eventThread.queueEvent(new WatchedEvent(
+                    Watcher.Event.EventType.None,
+                    eventState, null));
+        }
+
+        void close() {
+            state = States.CLOSED;
+            clientCnxnSocket.wakeupCnxn();
+        }
+
+        void testableCloseSocket() throws IOException {
+            clientCnxnSocket.testableCloseSocket();
+        }
+
+        public boolean clientTunneledAuthenticationInProgress() {
+            // 1. SASL client is disabled.
+            if (!ZooKeeperSaslClient.isEnabled()) {
+                return false;
+            }
+
+            // 2. SASL login failed.
+            if (saslLoginFailed == true) {
+                return false;
+            }
+
+            // 3. SendThread has not created the authenticating object yet,
+            // therefore authentication is (at the earliest stage of being) in progress.
+            if (zooKeeperSaslClient == null) {
+                return true;
+            }
+
+            // 4. authenticating object exists, so ask it for its progress.
+            return zooKeeperSaslClient.clientTunneledAuthenticationInProgress();
+        }
+
+        public void sendPacket(Packet p) throws IOException {
+            clientCnxnSocket.sendPacket(p);
+        }
+    }
+
+    /**
+     * Shutdown the send/event threads. This method should not be called
+     * directly - rather it should be called as part of close operation. This
+     * method is primarily here to allow the tests to verify disconnection
+     * behavior.
+     */
+    public void disconnect() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Disconnecting client for session: 0x"
+                      + Long.toHexString(getSessionId()));
+        }
+
+        sendThread.close();
+        eventThread.queueEventOfDeath();
+    }
+
+    /**
+     * Close the connection, which includes; send session disconnect to the
+     * server, shutdown the send/event threads.
+     *
+     * @throws IOException
+     */
+    public void close() throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Closing client for session: 0x"
+                      + Long.toHexString(getSessionId()));
+        }
+
+        try {
+            RequestHeader h = new RequestHeader();
+            h.setType(ZooDefs.OpCode.closeSession);
+
+            submitRequest(h, null, null, null);
+        } catch (InterruptedException e) {
+            // ignore, close the send/event threads
+        } finally {
+            disconnect();
+        }
+    }
+
+    private int xid = 1;
+
+    // @VisibleForTesting
+    volatile States state = States.NOT_CONNECTED;
+
+    /*
+     * getXid() is called externally by ClientCnxnNIO::doIO() when packets are sent from the outgoingQueue to
+     * the server. Thus, getXid() must be public.
+     */
+    synchronized public int getXid() {
+        return xid++;
+    }
+
+    public ReplyHeader submitRequest(RequestHeader h, Record request,
+            Record response, WatchRegistration watchRegistration)
+            throws InterruptedException {
+        ReplyHeader r = new ReplyHeader();
+        Packet packet = queuePacket(h, r, request, response, null, null, null,
+                    null, watchRegistration);
+        synchronized (packet) {
+            while (!packet.finished) {
+                packet.wait();
+            }
+        }
+        return r;
+    }
+
+    public void enableWrite() {
+        sendThread.getClientCnxnSocket().enableWrite();
+    }
+
+    public void sendPacket(Record request, Record response, AsyncCallback cb, int opCode)
+    throws IOException {
+        // Generate Xid now because it will be sent immediately,
+        // by call to sendThread.sendPacket() below.
+        int xid = getXid();
+        RequestHeader h = new RequestHeader();
+        h.setXid(xid);
+        h.setType(opCode);
+
+        ReplyHeader r = new ReplyHeader();
+        r.setXid(xid);
+
+        Packet p = new Packet(h, r, request, response, null, false);
+        p.cb = cb;
+        sendThread.sendPacket(p);
+    }
+
+    Packet queuePacket(RequestHeader h, ReplyHeader r, Record request,
+            Record response, AsyncCallback cb, String clientPath,
+            String serverPath, Object ctx, WatchRegistration watchRegistration)
+    {
+        Packet packet = null;
+
+        // Note that we do not generate the Xid for the packet yet. It is
+        // generated later at send-time, by an implementation of ClientCnxnSocket::doIO(),
+        // where the packet is actually sent.
+        synchronized (outgoingQueue) {
+            packet = new Packet(h, r, request, response, watchRegistration);
+            packet.cb = cb;
+            packet.ctx = ctx;
+            packet.clientPath = clientPath;
+            packet.serverPath = serverPath;
+            if (!state.isAlive() || closing) {
+                conLossPacket(packet);
+            } else {
+                // If the client is asking to close the session then
+                // mark as closing
+                if (h.getType() == OpCode.closeSession) {
+                    closing = true;
+                }
+                outgoingQueue.add(packet);
+            }
+        }
+        sendThread.getClientCnxnSocket().wakeupCnxn();
+        return packet;
+    }
+
+    public void addAuthInfo(String scheme, byte auth[]) {
+        if (!state.isAlive()) {
+            return;
+        }
+        authInfo.add(new AuthData(scheme, auth));
+        queuePacket(new RequestHeader(-4, OpCode.auth), null,
+                new AuthPacket(0, scheme, auth), null, null, null, null,
+                null, null);
+    }
+
+    States getState() {
+        return state;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java
new file mode 100644
index 0000000..b676531
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocket.java
@@ -0,0 +1,175 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.jute.BinaryInputArchive;
+import org.apache.zookeeper.ClientCnxn.Packet;
+import org.apache.zookeeper.common.Time;
+import org.apache.zookeeper.proto.ConnectResponse;
+import org.apache.zookeeper.server.ByteBufferInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A ClientCnxnSocket does the lower level communication with a socket
+ * implementation.
+ * 
+ * This code has been moved out of ClientCnxn so that a Netty implementation can
+ * be provided as an alternative to the NIO socket code.
+ * 
+ */
+abstract class ClientCnxnSocket {
+    private static final Logger LOG = LoggerFactory.getLogger(ClientCnxnSocket.class);
+
+    protected boolean initialized;
+
+    /**
+     * This buffer is only used to read the length of the incoming message.
+     */
+    protected final ByteBuffer lenBuffer = ByteBuffer.allocateDirect(4);
+
+    /**
+     * After the length is read, a new incomingBuffer is allocated in
+     * readLength() to receive the full message.
+     */
+    protected ByteBuffer incomingBuffer = lenBuffer;
+    protected long sentCount = 0;
+    protected long recvCount = 0;
+    protected long lastHeard;
+    protected long lastSend;
+    protected long now;
+    protected ClientCnxn.SendThread sendThread;
+
+    /**
+     * The sessionId is only available here for Log and Exception messages.
+     * Otherwise the socket doesn't need to know it.
+     */
+    protected long sessionId;
+
+    void introduce(ClientCnxn.SendThread sendThread, long sessionId) {
+        this.sendThread = sendThread;
+        this.sessionId = sessionId;
+    }
+
+    void updateNow() {
+        now = Time.currentElapsedTime();
+    }
+
+    int getIdleRecv() {
+        return (int) (now - lastHeard);
+    }
+
+    int getIdleSend() {
+        return (int) (now - lastSend);
+    }
+
+    long getSentCount() {
+        return sentCount;
+    }
+
+    long getRecvCount() {
+        return recvCount;
+    }
+
+    void updateLastHeard() {
+        this.lastHeard = now;
+    }
+
+    void updateLastSend() {
+        this.lastSend = now;
+    }
+
+    void updateLastSendAndHeard() {
+        this.lastSend = now;
+        this.lastHeard = now;
+    }
+
+    protected void readLength() throws IOException {
+        int len = incomingBuffer.getInt();
+        if (len < 0 || len >= ClientCnxn.packetLen) {
+            throw new IOException("Packet len" + len + " is out of range!");
+        }
+        incomingBuffer = ByteBuffer.allocate(len);
+    }
+
+    void readConnectResult() throws IOException {
+        if (LOG.isTraceEnabled()) {
+            StringBuilder buf = new StringBuilder("0x[");
+            for (byte b : incomingBuffer.array()) {
+                buf.append(Integer.toHexString(b) + ",");
+            }
+            buf.append("]");
+            LOG.trace("readConnectResult " + incomingBuffer.remaining() + " "
+                    + buf.toString());
+        }
+        ByteBufferInputStream bbis = new ByteBufferInputStream(incomingBuffer);
+        BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis);
+        ConnectResponse conRsp = new ConnectResponse();
+        conRsp.deserialize(bbia, "connect");
+
+        // read "is read-only" flag
+        boolean isRO = false;
+        try {
+            isRO = bbia.readBool("readOnly");
+        } catch (IOException e) {
+            // this is ok -- just a packet from an old server which
+            // doesn't contain readOnly field
+            LOG.warn("Connected to an old server; r-o mode will be unavailable");
+        }
+
+        this.sessionId = conRsp.getSessionId();
+        sendThread.onConnected(conRsp.getTimeOut(), this.sessionId,
+                conRsp.getPasswd(), isRO);
+    }
+
+    abstract boolean isConnected();
+
+    abstract void connect(InetSocketAddress addr) throws IOException;
+
+    abstract SocketAddress getRemoteSocketAddress();
+
+    abstract SocketAddress getLocalSocketAddress();
+
+    abstract void cleanup();
+
+    abstract void close();
+
+    abstract void wakeupCnxn();
+
+    abstract void enableWrite();
+
+    abstract void disableWrite();
+
+    abstract void enableReadWriteOnly();
+
+    abstract void doTransport(int waitTimeOut, List<Packet> pendingQueue,
+            LinkedList<Packet> outgoingQueue, ClientCnxn cnxn)
+            throws IOException, InterruptedException;
+
+    abstract void testableCloseSocket() throws IOException;
+
+    abstract void sendPacket(Packet p) throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java
new file mode 100644
index 0000000..720619d
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java
@@ -0,0 +1,431 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+import org.apache.zookeeper.ClientCnxn.EndOfStreamException;
+import org.apache.zookeeper.ClientCnxn.Packet;
+import org.apache.zookeeper.ZooDefs.OpCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClientCnxnSocketNIO extends ClientCnxnSocket {
+    private static final Logger LOG = LoggerFactory
+            .getLogger(ClientCnxnSocketNIO.class);
+
+    private final Selector selector = Selector.open();
+
+    private SelectionKey sockKey;
+
+    ClientCnxnSocketNIO() throws IOException {
+        super();
+    }
+
+    @Override
+    boolean isConnected() {
+        return sockKey != null;
+    }
+    
+    /**
+     * @return true if a packet was received
+     * @throws InterruptedException
+     * @throws IOException
+     */
+    void doIO(List<Packet> pendingQueue, LinkedList<Packet> outgoingQueue, ClientCnxn cnxn)
+      throws InterruptedException, IOException {
+        SocketChannel sock = (SocketChannel) sockKey.channel();
+        if (sock == null) {
+            throw new IOException("Socket is null!");
+        }
+        if (sockKey.isReadable()) {
+            int rc = sock.read(incomingBuffer);
+            if (rc < 0) {
+                throw new EndOfStreamException(
+                        "Unable to read additional data from server sessionid 0x"
+                                + Long.toHexString(sessionId)
+                                + ", likely server has closed socket");
+            }
+            if (!incomingBuffer.hasRemaining()) {
+                incomingBuffer.flip();
+                if (incomingBuffer == lenBuffer) {
+                    recvCount++;
+                    readLength();
+                } else if (!initialized) {
+                    readConnectResult();
+                    enableRead();
+                    if (findSendablePacket(outgoingQueue,
+                            cnxn.sendThread.clientTunneledAuthenticationInProgress()) != null) {
+                        // Since SASL authentication has completed (if client is configured to do so),
+                        // outgoing packets waiting in the outgoingQueue can now be sent.
+                        enableWrite();
+                    }
+                    lenBuffer.clear();
+                    incomingBuffer = lenBuffer;
+                    updateLastHeard();
+                    initialized = true;
+                } else {
+                    sendThread.readResponse(incomingBuffer);
+                    lenBuffer.clear();
+                    incomingBuffer = lenBuffer;
+                    updateLastHeard();
+                }
+            }
+        }
+        if (sockKey.isWritable()) {
+            synchronized(outgoingQueue) {
+                Packet p = findSendablePacket(outgoingQueue,
+                        cnxn.sendThread.clientTunneledAuthenticationInProgress());
+
+                if (p != null) {
+                    updateLastSend();
+                    // If we already started writing p, p.bb will already exist
+                    if (p.bb == null) {
+                        if ((p.requestHeader != null) &&
+                                (p.requestHeader.getType() != OpCode.ping) &&
+                                (p.requestHeader.getType() != OpCode.auth)) {
+                            p.requestHeader.setXid(cnxn.getXid());
+                        }
+                        p.createBB();
+                    }
+                    sock.write(p.bb);
+                    if (!p.bb.hasRemaining()) {
+                        sentCount++;
+                        outgoingQueue.removeFirstOccurrence(p);
+                        if (p.requestHeader != null
+                                && p.requestHeader.getType() != OpCode.ping
+                                && p.requestHeader.getType() != OpCode.auth) {
+                            synchronized (pendingQueue) {
+                                pendingQueue.add(p);
+                            }
+                        }
+                    }
+                }
+                if (outgoingQueue.isEmpty()) {
+                    // No more packets to send: turn off write interest flag.
+                    // Will be turned on later by a later call to enableWrite(),
+                    // from within ZooKeeperSaslClient (if client is configured
+                    // to attempt SASL authentication), or in either doIO() or
+                    // in doTransport() if not.
+                    disableWrite();
+                } else if (!initialized && p != null && !p.bb.hasRemaining()) {
+                    // On initial connection, write the complete connect request
+                    // packet, but then disable further writes until after
+                    // receiving a successful connection response.  If the
+                    // session is expired, then the server sends the expiration
+                    // response and immediately closes its end of the socket.  If
+                    // the client is simultaneously writing on its end, then the
+                    // TCP stack may choose to abort with RST, in which case the
+                    // client would never receive the session expired event.  See
+                    // http://docs.oracle.com/javase/6/docs/technotes/guides/net/articles/connection_release.html
+                    disableWrite();
+                } else {
+                    // Just in case
+                    enableWrite();
+                }
+            }
+        }
+    }
+
+    private Packet findSendablePacket(LinkedList<Packet> outgoingQueue,
+                                      boolean clientTunneledAuthenticationInProgress) {
+        synchronized (outgoingQueue) {
+            if (outgoingQueue.isEmpty()) {
+                return null;
+            }
+            if (outgoingQueue.getFirst().bb != null // If we've already starting sending the first packet, we better finish
+                || !clientTunneledAuthenticationInProgress) {
+                return outgoingQueue.getFirst();
+            }
+
+            // Since client's authentication with server is in progress,
+            // send only the null-header packet queued by primeConnection().
+            // This packet must be sent so that the SASL authentication process
+            // can proceed, but all other packets should wait until
+            // SASL authentication completes.
+            ListIterator<Packet> iter = outgoingQueue.listIterator();
+            while (iter.hasNext()) {
+                Packet p = iter.next();
+                if (p.requestHeader == null) {
+                    // We've found the priming-packet. Move it to the beginning of the queue.
+                    iter.remove();
+                    outgoingQueue.add(0, p);
+                    return p;
+                } else {
+                    // Non-priming packet: defer it until later, leaving it in the queue
+                    // until authentication completes.
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("deferring non-priming packet: " + p +
+                                "until SASL authentication completes.");
+                    }
+                }
+            }
+            // no sendable packet found.
+            return null;
+        }
+    }
+
+    @Override
+    void cleanup() {
+        if (sockKey != null) {
+            SocketChannel sock = (SocketChannel) sockKey.channel();
+            sockKey.cancel();
+            try {
+                sock.socket().shutdownInput();
+            } catch (IOException e) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Ignoring exception during shutdown input", e);
+                }
+            }
+            try {
+                sock.socket().shutdownOutput();
+            } catch (IOException e) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Ignoring exception during shutdown output",
+                            e);
+                }
+            }
+            try {
+                sock.socket().close();
+            } catch (IOException e) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Ignoring exception during socket close", e);
+                }
+            }
+            try {
+                sock.close();
+            } catch (IOException e) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Ignoring exception during channel close", e);
+                }
+            }
+        }
+        try {
+            Thread.sleep(100);
+        } catch (InterruptedException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("SendThread interrupted during sleep, ignoring");
+            }
+        }
+        sockKey = null;
+    }
+ 
+    @Override
+    void close() {
+        try {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Doing client selector close");
+            }
+            selector.close();
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Closed client selector");
+            }
+        } catch (IOException e) {
+            LOG.warn("Ignoring exception during selector close", e);
+        }
+    }
+    
+    /**
+     * create a socket channel.
+     * @return the created socket channel
+     * @throws IOException
+     */
+    SocketChannel createSock() throws IOException {
+        SocketChannel sock;
+        sock = SocketChannel.open();
+        sock.configureBlocking(false);
+        sock.socket().setSoLinger(false, -1);
+        sock.socket().setTcpNoDelay(true);
+        return sock;
+    }
+
+    /**
+     * register with the selection and connect
+     * @param sock the {@link SocketChannel} 
+     * @param addr the address of remote host
+     * @throws IOException
+     */
+    void registerAndConnect(SocketChannel sock, InetSocketAddress addr) 
+    throws IOException {
+        sockKey = sock.register(selector, SelectionKey.OP_CONNECT);
+        boolean immediateConnect = sock.connect(addr);
+        if (immediateConnect) {
+            sendThread.primeConnection();
+        }
+    }
+    
+    @Override
+    void connect(InetSocketAddress addr) throws IOException {
+        SocketChannel sock = createSock();
+        try {
+           registerAndConnect(sock, addr);
+        } catch (IOException e) {
+            LOG.error("Unable to open socket to " + addr);
+            sock.close();
+            throw e;
+        }
+        initialized = false;
+
+        /*
+         * Reset incomingBuffer
+         */
+        lenBuffer.clear();
+        incomingBuffer = lenBuffer;
+    }
+
+    /**
+     * Returns the address to which the socket is connected.
+     * 
+     * @return ip address of the remote side of the connection or null if not
+     *         connected
+     */
+    @Override
+    SocketAddress getRemoteSocketAddress() {
+        // a lot could go wrong here, so rather than put in a bunch of code
+        // to check for nulls all down the chain let's do it the simple
+        // yet bulletproof way
+        try {
+            return ((SocketChannel) sockKey.channel()).socket()
+                    .getRemoteSocketAddress();
+        } catch (NullPointerException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the local address to which the socket is bound.
+     * 
+     * @return ip address of the remote side of the connection or null if not
+     *         connected
+     */
+    @Override
+    SocketAddress getLocalSocketAddress() {
+        // a lot could go wrong here, so rather than put in a bunch of code
+        // to check for nulls all down the chain let's do it the simple
+        // yet bulletproof way
+        try {
+            return ((SocketChannel) sockKey.channel()).socket()
+                    .getLocalSocketAddress();
+        } catch (NullPointerException e) {
+            return null;
+        }
+    }
+
+    @Override
+    synchronized void wakeupCnxn() {
+        selector.wakeup();
+    }
+    
+    @Override
+    void doTransport(int waitTimeOut, List<Packet> pendingQueue, LinkedList<Packet> outgoingQueue,
+                     ClientCnxn cnxn)
+            throws IOException, InterruptedException {
+        selector.select(waitTimeOut);
+        Set<SelectionKey> selected;
+        synchronized (this) {
+            selected = selector.selectedKeys();
+        }
+        // Everything below and until we get back to the select is
+        // non blocking, so time is effectively a constant. That is
+        // Why we just have to do this once, here
+        updateNow();
+        for (SelectionKey k : selected) {
+            SocketChannel sc = ((SocketChannel) k.channel());
+            if ((k.readyOps() & SelectionKey.OP_CONNECT) != 0) {
+                if (sc.finishConnect()) {
+                    updateLastSendAndHeard();
+                    sendThread.primeConnection();
+                }
+            } else if ((k.readyOps() & (SelectionKey.OP_READ | SelectionKey.OP_WRITE)) != 0) {
+                doIO(pendingQueue, outgoingQueue, cnxn);
+            }
+        }
+        if (sendThread.getZkState().isConnected()) {
+            synchronized(outgoingQueue) {
+                if (findSendablePacket(outgoingQueue,
+                        cnxn.sendThread.clientTunneledAuthenticationInProgress()) != null) {
+                    enableWrite();
+                }
+            }
+        }
+        selected.clear();
+    }
+
+    //TODO should this be synchronized?
+    @Override
+    void testableCloseSocket() throws IOException {
+        LOG.info("testableCloseSocket() called");
+        ((SocketChannel) sockKey.channel()).socket().close();
+    }
+
+    @Override
+    synchronized void enableWrite() {
+        int i = sockKey.interestOps();
+        if ((i & SelectionKey.OP_WRITE) == 0) {
+            sockKey.interestOps(i | SelectionKey.OP_WRITE);
+        }
+    }
+
+    @Override
+    public synchronized void disableWrite() {
+        int i = sockKey.interestOps();
+        if ((i & SelectionKey.OP_WRITE) != 0) {
+            sockKey.interestOps(i & (~SelectionKey.OP_WRITE));
+        }
+    }
+
+    synchronized private void enableRead() {
+        int i = sockKey.interestOps();
+        if ((i & SelectionKey.OP_READ) == 0) {
+            sockKey.interestOps(i | SelectionKey.OP_READ);
+        }
+    }
+
+    @Override
+    synchronized void enableReadWriteOnly() {
+        sockKey.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
+    }
+
+    Selector getSelector() {
+        return selector;
+    }
+
+    @Override
+    void sendPacket(Packet p) throws IOException {
+        SocketChannel sock = (SocketChannel) sockKey.channel();
+        if (sock == null) {
+            throw new IOException("Socket is null!");
+        }
+        p.createBB();
+        ByteBuffer pbb = p.bb;
+        sock.write(pbb);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ClientWatchManager.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientWatchManager.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientWatchManager.java
new file mode 100644
index 0000000..d56374d
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientWatchManager.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper;
+
+import java.util.Set;
+
+/**
+ */
+public interface ClientWatchManager {
+    /**
+     * Return a set of watchers that should be notified of the event. The 
+     * manager must not notify the watcher(s), however it will update it's 
+     * internal structure as if the watches had triggered. The intent being 
+     * that the callee is now responsible for notifying the watchers of the 
+     * event, possibly at some later time.
+     * 
+     * @param state event state
+     * @param type event type
+     * @param path event path
+     * @return may be empty set but must not be null
+     */
+    public Set<Watcher> materialize(Watcher.Event.KeeperState state,
+        Watcher.Event.EventType type, String path);
+}


[02/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherTest.java
new file mode 100644
index 0000000..1c06690
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/WatcherTest.java
@@ -0,0 +1,408 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.ClientCnxn;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.Watcher.Event;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class WatcherTest extends ClientBase {
+    protected static final Logger LOG = LoggerFactory.getLogger(WatcherTest.class);
+
+    private long timeOfLastWatcherInvocation;
+
+    private final class MyStatCallback implements StatCallback {
+        int rc;
+        public void processResult(int rc, String path, Object ctx, Stat stat) {
+            ((int[])ctx)[0]++;
+            this.rc = rc;
+        }
+    }
+
+    private class MyWatcher extends CountdownWatcher {
+        LinkedBlockingQueue<WatchedEvent> events =
+            new LinkedBlockingQueue<WatchedEvent>();
+
+        public void process(WatchedEvent event) {
+            super.process(event);
+            if (event.getType() != Event.EventType.None) {
+                timeOfLastWatcherInvocation = System.currentTimeMillis();
+                try {
+                    events.put(event);
+                } catch (InterruptedException e) {
+                    LOG.warn("ignoring interrupt during event.put");
+                }
+            }
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        // Reset to default value since some test cases set this to true.
+        // Needed for JDK7 since unit test can run is random order
+        ClientCnxn.setDisableAutoResetWatch(false);
+    }
+
+    /**
+     * Verify that we get all of the events we expect to get. This particular
+     * case verifies that we see all of the data events on a particular node.
+     * There was a bug (ZOOKEEPER-137) that resulted in events being dropped
+     * in some cases (timing).
+     *
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws KeeperException
+     */
+    @Test
+    public void testWatcherCorrectness()
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk = null;
+        try {
+            MyWatcher watcher = new MyWatcher();
+            zk = createClient(watcher, hostPort);
+
+            StatCallback scb = new StatCallback() {
+                public void processResult(int rc, String path, Object ctx,
+                        Stat stat) {
+                    // don't do anything
+                }
+            };
+            VoidCallback vcb = new VoidCallback() {
+                public void processResult(int rc, String path, Object ctx) {
+                    // don't do anything
+                }
+            };
+
+            String names[] = new String[10];
+            for (int i = 0; i < names.length; i++) {
+                String name = zk.create("/tc-", "initialvalue".getBytes(),
+                        Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+                names[i] = name;
+
+                Stat stat = new Stat();
+                zk.getData(name, watcher, stat);
+                zk.setData(name, "new".getBytes(), stat.getVersion(), scb, null);
+                stat = zk.exists(name, watcher);
+                zk.delete(name, stat.getVersion(), vcb, null);
+            }
+
+            for (int i = 0; i < names.length; i++) {
+                String name = names[i];
+                WatchedEvent event = watcher.events.poll(10, TimeUnit.SECONDS);
+                Assert.assertEquals(name, event.getPath());
+                Assert.assertEquals(Event.EventType.NodeDataChanged, event.getType());
+                Assert.assertEquals(Event.KeeperState.SyncConnected, event.getState());
+                event = watcher.events.poll(10, TimeUnit.SECONDS);
+                Assert.assertEquals(name, event.getPath());
+                Assert.assertEquals(Event.EventType.NodeDeleted, event.getType());
+                Assert.assertEquals(Event.KeeperState.SyncConnected, event.getState());
+            }
+        } finally {
+            if (zk != null) {
+                zk.close();
+            }
+        }
+    }
+
+    @Test
+    public void testWatcherCount() 
+    throws IOException, InterruptedException, KeeperException {
+        ZooKeeper zk1 = null, zk2 = null;
+        try {
+            MyWatcher w1 = new MyWatcher();
+            zk1 = createClient(w1, hostPort);
+
+            MyWatcher w2 = new MyWatcher();
+            zk2 = createClient(w2, hostPort);
+
+            Stat stat = new Stat();
+            zk1.create("/watch-count-test", "value".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+            zk1.create("/watch-count-test-2", "value".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+
+            zk1.getData("/watch-count-test", w1, stat);
+            zk1.getData("/watch-count-test-2", w1, stat);
+            zk2.getData("/watch-count-test", w2, stat);
+
+            Assert.assertEquals(ClientBase.getServer(serverFactory)
+                    .getZKDatabase().getDataTree().getWatchCount(), 3);
+
+        } finally {
+            if(zk1 != null) {
+                zk1.close();
+            }
+            if(zk2 != null) {
+                zk2.close();
+            }
+        }
+
+    }
+
+    final static int COUNT = 100;
+    /**
+     * This test checks that watches for pending requests do not get triggered,
+     * but watches set by previous requests do.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testWatchAutoResetWithPending() throws Exception {
+       MyWatcher watches[] = new MyWatcher[COUNT];
+       MyStatCallback cbs[] = new MyStatCallback[COUNT];
+       MyWatcher watcher = new MyWatcher();
+       int count[] = new int[1];
+       TestableZooKeeper zk = createClient(watcher, hostPort, 6000);
+       ZooKeeper zk2 = createClient(watcher, hostPort, 5000);
+       zk2.create("/test", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+       for(int i = 0; i < COUNT/2; i++) {
+           watches[i] = new MyWatcher();
+           cbs[i] = new MyStatCallback();
+           zk.exists("/test", watches[i], cbs[i], count);
+       }
+       zk.exists("/test", false);
+       Assert.assertTrue("Failed to pause the connection!", zk.pauseCnxn(3000));
+       zk2.close();
+       stopServer();
+       watches[0].waitForDisconnected(60000);
+       for(int i = COUNT/2; i < COUNT; i++) {
+           watches[i] = new MyWatcher();
+           cbs[i] = new MyStatCallback();
+           zk.exists("/test", watches[i], cbs[i], count);
+       }
+       startServer();
+       watches[COUNT/2-1].waitForConnected(60000);
+       Assert.assertEquals(null, zk.exists("/test", false));
+       waitForAllWatchers();
+       for(int i = 0; i < COUNT/2; i++) {
+           Assert.assertEquals("For " + i, 1, watches[i].events.size());
+       }
+       for(int i = COUNT/2; i < COUNT; i++) {
+           if (cbs[i].rc == 0) {
+               Assert.assertEquals("For " +i, 1, watches[i].events.size());
+           } else {
+               Assert.assertEquals("For " +i, 0, watches[i].events.size());
+           }
+       }
+       Assert.assertEquals(COUNT, count[0]);
+       zk.close();
+    }
+
+    /**
+     * Wait until no watcher has been fired in the last second to ensure that all watches
+     * that are waiting to be fired have been fired
+     * @throws Exception
+     */
+    private void waitForAllWatchers() throws Exception {
+        timeOfLastWatcherInvocation = System.currentTimeMillis();
+        while (System.currentTimeMillis() - timeOfLastWatcherInvocation < 1000) {
+            Thread.sleep(1000);
+        }
+    }
+    
+    final int TIMEOUT = 5000;
+
+    @Test
+    public void testWatcherAutoResetWithGlobal() throws Exception {
+        ZooKeeper zk = null;
+        MyWatcher watcher = new MyWatcher();
+        zk = createClient(watcher, hostPort, TIMEOUT);
+        testWatcherAutoReset(zk, watcher, watcher);
+        zk.close();
+    }
+
+    @Test
+    public void testWatcherAutoResetWithLocal() throws Exception {
+        ZooKeeper zk = null;
+        MyWatcher watcher = new MyWatcher();
+        zk = createClient(watcher, hostPort, TIMEOUT);
+        testWatcherAutoReset(zk, watcher, new MyWatcher());
+        zk.close();
+    }
+
+    @Test
+    public void testWatcherAutoResetDisabledWithGlobal() throws Exception {
+        ClientCnxn.setDisableAutoResetWatch(true);
+        testWatcherAutoResetWithGlobal();
+    }
+
+    @Test
+    public void testWatcherAutoResetDisabledWithLocal() throws Exception {
+        ClientCnxn.setDisableAutoResetWatch(true);
+        testWatcherAutoResetWithLocal();
+    }
+
+    private void testWatcherAutoReset(ZooKeeper zk, MyWatcher globalWatcher,
+            MyWatcher localWatcher) throws Exception {
+        boolean isGlobal = (localWatcher == globalWatcher);
+        // First test to see if the watch survives across reconnects
+        zk.create("/watchtest", new byte[0], Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        zk.create("/watchtest/child", new byte[0], Ids.OPEN_ACL_UNSAFE,
+                CreateMode.EPHEMERAL);
+        if (isGlobal) {
+            zk.getChildren("/watchtest", true);
+            zk.getData("/watchtest/child", true, new Stat());
+            zk.exists("/watchtest/child2", true);
+        } else {
+            zk.getChildren("/watchtest", localWatcher);
+            zk.getData("/watchtest/child", localWatcher, new Stat());
+            zk.exists("/watchtest/child2", localWatcher);
+        }
+
+        Assert.assertTrue(localWatcher.events.isEmpty());
+
+        stopServer();
+        globalWatcher.waitForDisconnected(3000);
+        localWatcher.waitForDisconnected(500);
+        startServer();
+        globalWatcher.waitForConnected(3000);
+        if (!isGlobal && !ClientCnxn.getDisableAutoResetWatch()) {
+            localWatcher.waitForConnected(500);
+        }
+
+        Assert.assertTrue(localWatcher.events.isEmpty());
+        zk.setData("/watchtest/child", new byte[1], -1);
+        zk.create("/watchtest/child2", new byte[0], Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        WatchedEvent e;
+        if (!ClientCnxn.getDisableAutoResetWatch()) {
+            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+            Assert.assertEquals(e.getPath(), EventType.NodeDataChanged, e.getType());
+            Assert.assertEquals("/watchtest/child", e.getPath());
+        } else {
+            // we'll catch this later if it does happen after timeout, so
+            // why waste the time on poll
+        }
+
+        if (!ClientCnxn.getDisableAutoResetWatch()) {
+            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+            // The create will trigger the get children and the exist
+            // watches
+            Assert.assertEquals(EventType.NodeCreated, e.getType());
+            Assert.assertEquals("/watchtest/child2", e.getPath());
+        } else {
+            // we'll catch this later if it does happen after timeout, so
+            // why waste the time on poll
+        }
+
+        if (!ClientCnxn.getDisableAutoResetWatch()) {
+            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+            Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+            Assert.assertEquals("/watchtest", e.getPath());
+        } else {
+            // we'll catch this later if it does happen after timeout, so
+            // why waste the time on poll
+        }
+
+        Assert.assertTrue(localWatcher.events.isEmpty()); // ensure no late arrivals
+        stopServer();
+        globalWatcher.waitForDisconnected(TIMEOUT);
+        try {
+            try {
+                localWatcher.waitForDisconnected(500);
+                if (!isGlobal && !ClientCnxn.getDisableAutoResetWatch()) {
+                    Assert.fail("Got an event when I shouldn't have");
+                }
+            } catch(TimeoutException toe) {
+                if (ClientCnxn.getDisableAutoResetWatch()) {
+                    Assert.fail("Didn't get an event when I should have");
+                }
+                // Else what we are expecting since there are no outstanding watches
+            }
+        } catch (Exception e1) {
+            LOG.error("bad", e1);
+            throw new RuntimeException(e1);
+        }
+        startServer();
+        globalWatcher.waitForConnected(TIMEOUT);
+
+        if (isGlobal) {
+            zk.getChildren("/watchtest", true);
+            zk.getData("/watchtest/child", true, new Stat());
+            zk.exists("/watchtest/child2", true);
+        } else {
+            zk.getChildren("/watchtest", localWatcher);
+            zk.getData("/watchtest/child", localWatcher, new Stat());
+            zk.exists("/watchtest/child2", localWatcher);
+        }
+
+        // Do trigger an event to make sure that we do not get
+        // it later
+        zk.delete("/watchtest/child2", -1);
+
+        e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertEquals(EventType.NodeDeleted, e.getType());
+        Assert.assertEquals("/watchtest/child2", e.getPath());
+
+        e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
+        Assert.assertEquals("/watchtest", e.getPath());
+
+        Assert.assertTrue(localWatcher.events.isEmpty());
+
+        stopServer();
+        globalWatcher.waitForDisconnected(TIMEOUT);
+        localWatcher.waitForDisconnected(500);
+        startServer();
+        globalWatcher.waitForConnected(TIMEOUT);
+        if (!isGlobal && !ClientCnxn.getDisableAutoResetWatch()) {
+            localWatcher.waitForConnected(500);
+        }
+
+        zk.delete("/watchtest/child", -1);
+        zk.delete("/watchtest", -1);
+
+        if (!ClientCnxn.getDisableAutoResetWatch()) {
+            e = localWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+            Assert.assertEquals(EventType.NodeDeleted, e.getType());
+            Assert.assertEquals("/watchtest/child", e.getPath());
+        } else {
+            // we'll catch this later if it does happen after timeout, so
+            // why waste the time on poll
+        }
+
+        // Make sure nothing is straggling!
+        Thread.sleep(1000);
+        Assert.assertTrue(localWatcher.events.isEmpty());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java
new file mode 100644
index 0000000..c213b2a
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZkDatabaseCorruptionTest.java
@@ -0,0 +1,161 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ZkDatabaseCorruptionTest extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(ZkDatabaseCorruptionTest.class);
+    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
+
+    private final QuorumBase qb = new QuorumBase();
+
+    @Before
+    public void setUp() throws Exception {
+        LOG.info("STARTING quorum " + getClass().getName());
+        qb.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        LOG.info("STOPPING quorum " + getClass().getName());
+    }
+
+    private void corruptFile(File f) throws IOException {
+        RandomAccessFile outFile = new RandomAccessFile(f, "rw");
+        outFile.write("fail servers".getBytes());
+        outFile.close();
+    }
+
+    private void corruptAllSnapshots(File snapDir) throws IOException {
+        File[] listFiles = snapDir.listFiles();
+        for (File f: listFiles) {
+            if (f.getName().startsWith("snapshot")) {
+                corruptFile(f);
+            }
+        }
+    }
+
+    private class NoopStringCallback implements AsyncCallback.StringCallback {
+        @Override
+        public void processResult(int rc, String path, Object ctx,
+                                  String name) {
+        }
+    }
+
+    @Test
+    public void testCorruption() throws Exception {
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        ZooKeeper zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        SyncRequestProcessor.setSnapCount(100);
+        for (int i = 0; i < 2000; i++) {
+            zk.create("/0-" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                      CreateMode.PERSISTENT, new NoopStringCallback(), null);
+        }
+        zk.close();
+
+        long leaderSid = 1;
+        QuorumPeer leader = null;
+        //find out who is the leader and kill it
+        for (QuorumPeer quorumPeer : Arrays.asList(qb.s1, qb.s2, qb.s3, qb.s4, qb.s5)) {
+            if (quorumPeer.getPeerState() == ServerState.LEADING) {
+                leader = quorumPeer;
+                break;
+            }
+            ++leaderSid;
+        }
+
+        Assert.assertNotNull("Cannot find the leader.", leader);
+        leader.shutdown();
+
+        // now corrupt the leader's database
+        FileTxnSnapLog snapLog = leader.getTxnFactory();
+        File snapDir= snapLog.getSnapDir();
+        //corrupt all the snapshot in the snapshot directory
+        corruptAllSnapshots(snapDir);
+        qb.shutdownServers();
+        qb.setupServers();
+
+        if (leaderSid != 1)qb.s1.start(); else leader = qb.s1;
+        if (leaderSid != 2)qb.s2.start(); else leader = qb.s2;
+        if (leaderSid != 3)qb.s3.start(); else leader = qb.s3;
+        if (leaderSid != 4)qb.s4.start(); else leader = qb.s4;
+        if (leaderSid != 5)qb.s5.start(); else leader = qb.s5;
+
+        try {
+            leader.start();
+            Assert.assertTrue(false);
+        } catch(RuntimeException re) {
+            LOG.info("Got an error: expected", re);
+        }
+        //wait for servers to be up
+        String[] list = qb.hostPort.split(",");
+        for (int i = 0; i < 5; i++) {
+            if(leaderSid != (i + 1)) {
+                String hp = list[i];
+                Assert.assertTrue("waiting for server up",
+                        ClientBase.waitForServerUp(hp,
+                                CONNECTION_TIMEOUT));
+                LOG.info("{} is accepting client connections", hp);
+            } else {
+                LOG.info("Skipping the leader");
+            }
+        }
+
+        zk = qb.createClient();
+        SyncRequestProcessor.setSnapCount(100);
+        for (int i = 2000; i < 4000; i++) {
+            zk.create("/0-" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
+                      CreateMode.PERSISTENT, new NoopStringCallback(), null);
+        }
+        zk.close();
+
+        if (leaderSid != 1)QuorumBase.shutdown(qb.s1);
+        if (leaderSid != 2)QuorumBase.shutdown(qb.s2);
+        if (leaderSid != 3)QuorumBase.shutdown(qb.s3);
+        if (leaderSid != 4)QuorumBase.shutdown(qb.s4);
+        if (leaderSid != 5)QuorumBase.shutdown(qb.s5);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
new file mode 100644
index 0000000..fbf09b3
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Quotas;
+import org.apache.zookeeper.StatsTrack;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooKeeperMain;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ZooKeeperQuotaTest extends ClientBase {
+
+
+    private static final Logger LOG = LoggerFactory.getLogger(
+            ZooKeeperQuotaTest.class);
+
+    @Test
+    public void testQuota() throws IOException,
+        InterruptedException, KeeperException, Exception {
+        final ZooKeeper zk = createClient();
+        final String path = "/a/b/v";
+        // making sure setdata works on /
+        zk.setData("/", "some".getBytes(), -1);
+        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        zk.create("/a/b/v/d", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        ZooKeeperMain.createQuota(zk, path, 5L, 10);
+
+        // see if its set
+        String absolutePath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
+        byte[] data = zk.getData(absolutePath, false, new Stat());
+        StatsTrack st = new StatsTrack(new String(data));
+        Assert.assertTrue("bytes are set", st.getBytes() == 5L);
+        Assert.assertTrue("num count is set", st.getCount() == 10);
+
+        String statPath = Quotas.quotaZookeeper + path + "/" + Quotas.statNode;
+        byte[] qdata = zk.getData(statPath, false, new Stat());
+        StatsTrack qst = new StatsTrack(new String(qdata));
+        Assert.assertTrue("bytes are set", qst.getBytes() == 8L);
+        Assert.assertTrue("count is set", qst.getCount() == 2);
+
+        //force server to restart and load from snapshot, not txn log
+        stopServer();
+        startServer();
+        stopServer();
+        startServer();
+        ZooKeeperServer server = getServer(serverFactory);
+        Assert.assertNotNull("Quota is still set",
+            server.getZKDatabase().getDataTree().getMaxPrefixWithQuota(path) != null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java
new file mode 100644
index 0000000..0bbba61
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperTestClient.java
@@ -0,0 +1,422 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.common.Time;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+
+public class ZooKeeperTestClient extends ZKTestCase implements Watcher {
+  protected String hostPort = "127.0.0.1:22801";
+
+  protected static final String dirOnZK = "/test_dir";
+
+  protected String testDirOnZK = dirOnZK + "/" + Time.currentElapsedTime();
+
+  LinkedBlockingQueue<WatchedEvent> events = new LinkedBlockingQueue<WatchedEvent>();
+
+  private WatchedEvent getEvent(int numTries) throws InterruptedException {
+    WatchedEvent event = null;
+    for (int i = 0; i < numTries; i++) {
+      System.out.println("i = " + i);
+      event = events.poll(10, TimeUnit.SECONDS);
+      if (event != null) {
+        break;
+      }
+      Thread.sleep(5000);
+    }
+    return event;
+
+  }
+
+  private void deleteZKDir(ZooKeeper zk, String nodeName)
+          throws IOException, InterruptedException, KeeperException {
+
+    Stat stat = zk.exists(nodeName, false);
+    if (stat == null) {
+      return;
+    }
+
+    List<String> children1 = zk.getChildren(nodeName, false);
+    List<String> c2 = zk.getChildren(nodeName, false, stat);
+
+    if (!children1.equals(c2)) {
+        Assert.fail("children lists from getChildren()/getChildren2() do not match");
+    }
+
+    if (!stat.equals(stat)) {
+        Assert.fail("stats from exists()/getChildren2() do not match");
+    }
+
+    if (children1.size() == 0) {
+      zk.delete(nodeName, -1);
+      return;
+    }
+    for (String n : children1) {
+      deleteZKDir(zk, n);
+    }
+  }
+
+  private void checkRoot() throws IOException,
+      InterruptedException {
+    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
+
+    try {
+      zk.create(dirOnZK, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+    } catch (KeeperException.NodeExistsException ke) {
+        // expected, sort of
+    } catch (KeeperException ke) {
+        Assert.fail("Unexpected exception code for create " + dirOnZK + ": "
+            + ke.getMessage());
+    }
+
+    try {
+      zk.create(testDirOnZK, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+    } catch (KeeperException.NodeExistsException ke) {
+        // expected, sort of
+    } catch (KeeperException ke) {
+        Assert.fail("Unexpected exception code for create " + testDirOnZK + ": "
+            + ke.getMessage());
+    }
+
+    zk.close();
+  }
+
+  private void enode_test_1() throws IOException,
+          InterruptedException, KeeperException {
+    checkRoot();
+    String parentName = testDirOnZK;
+    String nodeName = parentName + "/enode_abc";
+    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
+
+    Stat stat = zk.exists(parentName, false);
+    if (stat == null) {
+      try {
+        zk.create(parentName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+      } catch (KeeperException ke) {
+        Assert.fail("Creating node " + parentName + ke.getMessage());
+      }
+    }
+
+    try {
+      zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NODEEXISTS;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for createin: " + ke.getMessage());
+      }
+    }
+
+    stat = zk.exists(nodeName, false);
+    if (stat == null) {
+      Assert.fail("node " + nodeName + " should exist");
+    }
+    System.out.println("Closing client with sessionid: 0x"
+            + Long.toHexString(zk.getSessionId()));
+    zk.close();
+    zk = new ZooKeeper(hostPort, 10000, this);
+
+    for (int i = 0; i < 10; i++) {
+      System.out.println("i = " + i);
+      stat = zk.exists(nodeName, false);
+      if (stat != null) {
+        System.out.println("node " + nodeName
+            + " should not exist after reconnection close");
+      } else {
+        System.out.println("node " + nodeName
+            + " is gone after reconnection close!");
+        break;
+      }
+      Thread.sleep(5000);
+    }
+    deleteZKDir(zk, nodeName);
+    zk.close();
+
+  }
+
+  private void enode_test_2() throws IOException,
+          InterruptedException, KeeperException {
+    checkRoot();
+    String parentName = testDirOnZK;
+    String nodeName = parentName + "/enode_abc";
+    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
+    ZooKeeper zk_1 = new ZooKeeper(hostPort, 10000, this);
+
+    Stat stat_parent = zk_1.exists(parentName, false);
+    if (stat_parent == null) {
+      try {
+        zk.create(parentName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+      } catch (KeeperException ke) {
+        Assert.fail("Creating node " + parentName + ke.getMessage());
+      }
+    }
+
+    Stat stat_node = zk_1.exists(nodeName, false);
+    if (stat_node != null) {
+
+      try {
+        zk.delete(nodeName, -1);
+      } catch (KeeperException ke) {
+        Code code = ke.code();
+        boolean valid = code == KeeperException.Code.NONODE
+            || code == KeeperException.Code.NOTEMPTY;
+        if (!valid) {
+          Assert.fail("Unexpected exception code for delete: " + ke.getMessage());
+        }
+      }
+    }
+
+    List<String> firstGen1 = zk_1.getChildren(parentName, true);
+    Stat stat = new Stat();
+    List<String> firstGen2 = zk_1.getChildren(parentName, true, stat);
+
+    if (!firstGen1.equals(firstGen2)) {
+        Assert.fail("children lists from getChildren()/getChildren2() do not match");
+    }
+
+    if (!stat_parent.equals(stat)) {
+        Assert.fail("stat from exists()/getChildren() do not match");
+    }
+
+    try {
+      zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NODEEXISTS;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for createin: " + ke.getMessage());
+      }
+    }
+
+    Thread.sleep(5000);
+    WatchedEvent event = events.poll(10, TimeUnit.SECONDS);
+    if (event == null) {
+      throw new IOException("No event was delivered promptly");
+    }
+    if (event.getType() != EventType.NodeChildrenChanged
+        || !event.getPath().equalsIgnoreCase(parentName)) {
+      Assert.fail("Unexpected event was delivered: " + event.toString());
+    }
+
+    stat_node = zk_1.exists(nodeName, false);
+    if (stat_node == null) {
+      Assert.fail("node " + nodeName + " should exist");
+    }
+
+    try {
+      zk.delete(parentName, -1);
+      Assert.fail("Should be impossible to delete a non-empty node " + parentName);
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NOTEMPTY;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for delete: " + code);
+      }
+    }
+
+    try {
+      zk.create(nodeName + "/def", null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+      Assert.fail("Should be impossible to create child off Ephemeral node " + nodeName);
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NOCHILDRENFOREPHEMERALS;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for createin: " + code);
+      }
+    }
+
+    try {
+      List<String> children1 = zk.getChildren(nodeName, false);
+      List<String> children2 = zk.getChildren(nodeName, false, null);
+
+      if (!children1.equals(children2)) {
+          Assert.fail("children lists from getChildren()/getChildren2() does not match");
+      }
+
+      if (children1.size() > 0) {
+        Assert.fail("ephemeral node " + nodeName + " should not have children");
+      }
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NONODE;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for createin: " + code);
+      }
+    }
+    firstGen1 = zk_1.getChildren(parentName, true);
+    firstGen2 = zk_1.getChildren(parentName, true, null);
+
+    if (!firstGen1.equals(firstGen2)) {
+        Assert.fail("children list from getChildren()/getChildren2() does not match");
+    }
+
+    stat_node = zk_1.exists(nodeName, true);
+    if (stat_node == null) {
+      Assert.fail("node " + nodeName + " should exist");
+    }
+    System.out.println("session id of zk: " + zk.getSessionId());
+    System.out.println("session id of zk_1: " + zk_1.getSessionId());
+    zk.close();
+
+    Stat no_stat = zk_1.exists("nosuchnode", false);
+
+    event = this.getEvent(10);
+    if (event == null) {
+      throw new Error("First event was not delivered promptly");
+    }
+    if (!((event.getType() == EventType.NodeChildrenChanged &&
+           event.getPath().equalsIgnoreCase(parentName)) ||
+         (event.getType() == EventType.NodeDeleted &&
+           event.getPath().equalsIgnoreCase(nodeName)))) {
+      System.out.print(parentName + " "
+          + EventType.NodeChildrenChanged + " " + nodeName + " " + EventType.NodeDeleted);
+      Assert.fail("Unexpected first event was delivered: " + event.toString());
+    }
+
+    event = this.getEvent(10);
+
+    if (event == null) {
+      throw new Error("Second event was not delivered promptly");
+    }
+    if (!((event.getType() == EventType.NodeChildrenChanged &&
+        event.getPath().equalsIgnoreCase(parentName)) ||
+      (event.getType() == EventType.NodeDeleted &&
+        event.getPath().equalsIgnoreCase(nodeName)))) {
+      System.out.print(parentName + " "
+          + EventType.NodeChildrenChanged + " " + nodeName + " " + EventType.NodeDeleted);
+      Assert.fail("Unexpected second event was delivered: " + event.toString());
+    }
+
+    firstGen1 = zk_1.getChildren(parentName, false);
+    stat_node = zk_1.exists(nodeName, false);
+    if (stat_node != null) {
+      Assert.fail("node " + nodeName + " should have been deleted");
+    }
+    if (firstGen1.contains(nodeName)) {
+      Assert.fail("node " + nodeName + " should not be a children");
+    }
+    deleteZKDir(zk_1, nodeName);
+    zk_1.close();
+  }
+
+  private void delete_create_get_set_test_1() throws
+          IOException, InterruptedException, KeeperException {
+    checkRoot();
+    ZooKeeper zk = new ZooKeeper(hostPort, 10000, this);
+    String parentName = testDirOnZK;
+    String nodeName = parentName + "/benwashere";
+    try {
+      zk.delete(nodeName, -1);
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NONODE
+          || code == KeeperException.Code.NOTEMPTY;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for delete: " + ke.getMessage());
+      }
+    }
+    try {
+      zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NODEEXISTS;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for create: " + ke.getMessage());
+      }
+    }
+    try {
+      zk.setData(nodeName, "hi".getBytes(), 5700);
+      Assert.fail("Should have gotten BadVersion exception");
+    } catch (KeeperException ke) {
+      if (ke.code() != Code.BADVERSION) {
+        Assert.fail("Should have gotten BadVersion exception");
+      }
+    }
+    zk.setData(nodeName, "hi".getBytes(), -1);
+    Stat st = new Stat();
+    byte[] bytes = zk.getData(nodeName, false, st);
+    String retrieved = new String(bytes);
+    if (!"hi".equals(retrieved)) {
+      Assert.fail("The retrieved data [" + retrieved
+          + "] is differented than the expected [hi]");
+    }
+    try {
+      zk.delete(nodeName, 6800);
+      Assert.fail("Should have gotten BadVersion exception");
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NOTEMPTY
+          || code == KeeperException.Code.BADVERSION;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for delete: " + ke.getMessage());
+      }
+    }
+    try {
+      zk.delete(nodeName, -1);
+    } catch (KeeperException ke) {
+      Code code = ke.code();
+      boolean valid = code == KeeperException.Code.NOTEMPTY;
+      if (!valid) {
+        Assert.fail("Unexpected exception code for delete: " + code);
+      }
+    }
+    deleteZKDir(zk, nodeName);
+    zk.close();
+  }
+
+  public void my_test_1() throws IOException,
+          InterruptedException, KeeperException {
+    enode_test_1();
+    enode_test_2();
+    delete_create_get_set_test_1();
+  }
+
+  synchronized public void process(WatchedEvent event) {
+    try {
+      System.out.println("Got an event " + event.toString());
+      events.put(event);
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+  }
+
+  public static void main(String[] args) {
+    ZooKeeperTestClient zktc = new ZooKeeperTestClient();
+    try {
+      zktc.my_test_1();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/check_compatibility.py
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/check_compatibility.py b/zookeeper-server/src/test/resources/check_compatibility.py
new file mode 100644
index 0000000..cad8195
--- /dev/null
+++ b/zookeeper-server/src/test/resources/check_compatibility.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+#
+# 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.
+
+# Script which checks Java API compatibility between two revisions of the
+# Java client.
+#
+# Based on the compatibility checker from the HBase project, but ported to
+# Python for better readability.
+
+# Lifted from Kudu: https://github.com/apache/kudu/blob/master/build-support/check_compatibility.py
+
+import logging
+import optparse
+import os
+import shutil
+import subprocess
+import sys
+
+JAVA_ACC_GIT_URL = "https://github.com/lvc/japi-compliance-checker.git"
+
+# The annotations for what we consider our public API.
+PUBLIC_ANNOTATIONS = ["org.apache.yetus.audience.InterfaceAudience.LimitedPrivate",
+                      "org.apache.yetus.audience.InterfaceAudience.Public"]
+
+# Various relative paths
+PATH_TO_REPO_DIR = "../../../../"
+PATH_TO_BUILD_DIR = PATH_TO_REPO_DIR + "build/compat-check"
+PATH_TO_JACC_DIR = PATH_TO_REPO_DIR + "build/jacc"
+
+def check_output(*popenargs, **kwargs):
+    # r"""Run command with arguments and return its output as a byte string.
+    # Backported from Python 2.7 as it's implemented as pure python on stdlib.
+    # >>> check_output(['/usr/bin/python', '--version'])
+    # Python 2.6.2
+    # """
+    process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
+    output, unused_err = process.communicate()
+    retcode = process.poll()
+    if retcode:
+        cmd = kwargs.get("args")
+        if cmd is None:
+            cmd = popenargs[0]
+        error = subprocess.CalledProcessError(retcode, cmd)
+        error.output = output
+        raise error
+    return output
+
+def get_repo_dir():
+    """ Return the path to the top of the repo. """
+    dirname, _ = os.path.split(os.path.abspath(__file__))
+    return os.path.abspath(os.path.join(dirname, PATH_TO_REPO_DIR))
+
+
+def get_scratch_dir():
+    """ Return the path to the scratch dir that we build within. """
+    dirname, _ = os.path.split(os.path.abspath(__file__))
+    return os.path.abspath(os.path.join(dirname, PATH_TO_BUILD_DIR))
+
+
+def get_java_acc_dir():
+    dirname, _ = os.path.split(os.path.abspath(__file__))
+    return os.path.abspath(os.path.join(dirname, PATH_TO_JACC_DIR))
+
+
+def clean_scratch_dir(scratch_dir):
+    """ Clean up and re-create the scratch directory. """
+    if os.path.exists(scratch_dir):
+        logging.info("Removing scratch dir %s...", scratch_dir)
+        shutil.rmtree(scratch_dir)
+    logging.info("Creating empty scratch dir %s...", scratch_dir)
+    os.makedirs(scratch_dir)
+
+
+def checkout_tree(rev, path):
+    """ Check out the Java source tree for the given revision into the given path. """
+    logging.info("Checking out %s in %s", rev, path)
+    os.makedirs(path)
+    # Extract java source
+    subprocess.check_call(["bash", '-o', 'pipefail', "-c",
+                           ("git archive --format=tar %s | " +
+                            "tar -C \"%s\" -xf -") % (rev, path)],
+                          cwd=get_repo_dir())
+
+
+def get_git_hash(revname):
+    """ Convert 'revname' to its SHA-1 hash. """
+    return check_output(["git", "rev-parse", revname],
+                        cwd=get_repo_dir()).strip()
+
+
+def build_tree(path):
+    """ Run the Java build within 'path'. """
+    logging.info("Building in %s...", path)
+    subprocess.check_call(["ant", "jar"], cwd=path)
+
+
+def checkout_java_acc(force):
+    """
+    Check out the Java API Compliance Checker. If 'force' is true, will re-download even if the
+    directory exists.
+    """
+    acc_dir = get_java_acc_dir()
+    if os.path.exists(acc_dir):
+        logging.info("Java JAVA_ACC is already downloaded.")
+        if not force:
+            return
+        logging.info("Forcing re-download.")
+        shutil.rmtree(acc_dir)
+    logging.info("Checking out Java JAVA_ACC...")
+    subprocess.check_call(["git", "clone", "-b", "2.1", "--single-branch", "--depth=1", JAVA_ACC_GIT_URL, acc_dir])
+
+
+def find_client_jars(path):
+    """ Return a list of jars within 'path' to be checked for compatibility. """
+    return check_output(["find", path, "-name", "zookeeper*.jar"]).rstrip('\n')
+
+
+def run_java_acc(src_name, src, dst_name, dst):
+    """ Run the compliance checker to compare 'src' and 'dst'. """
+    src_jar = find_client_jars(src)
+    dst_jar = find_client_jars(dst)
+    logging.info("Will check compatibility between original jars:\n%s\n" +
+                 "and new jars:\n%s",
+                 src_jar, dst_jar)
+
+    annotations_path = os.path.join(get_scratch_dir(), "annotations.txt")
+    with file(annotations_path, "w") as f:
+        for ann in PUBLIC_ANNOTATIONS:
+            print >>f,  ann
+
+    java_acc_path = os.path.join(get_java_acc_dir(), "japi-compliance-checker.pl")
+
+    out_path = os.path.join(get_scratch_dir(), "report.html")
+    subprocess.check_call(["perl", java_acc_path,
+                           "-lib", "ZooKeeper",
+                           "-v1", src_name,
+                           "-v2", dst_name,
+                           "-d1", src_jar,
+                           "-d2", dst_jar,
+                           "-annotations-list", annotations_path,
+                           "-report-path", out_path])
+
+
+def main(argv):
+    logging.basicConfig(level=logging.INFO)
+    parser = optparse.OptionParser(
+        usage="usage: %prog SRC..[DST]")
+    parser.add_option("-f", "--force-download", dest="force_download_deps",
+                      help=("Download dependencies (i.e. Java JAVA_ACC) even if they are " +
+                            "already present"))
+    opts, args = parser.parse_args()
+
+    if len(args) != 1:
+        parser.error("no src/dst revision specified")
+        sys.exit(1)
+
+    src_rev, dst_rev = args[0].split("..", 1)
+    if dst_rev == "":
+        dst_rev = "HEAD"
+    src_rev = get_git_hash(src_rev)
+    dst_rev = get_git_hash(dst_rev)
+
+    logging.info("Source revision: %s", src_rev)
+    logging.info("Destination revision: %s", dst_rev)
+
+    # Download deps.
+    checkout_java_acc(opts.force_download_deps)
+
+    # Set up the build.
+    scratch_dir = get_scratch_dir()
+    clean_scratch_dir(scratch_dir)
+
+    # Check out the src and dst source trees.
+    src_dir = os.path.join(scratch_dir, "src")
+    dst_dir = os.path.join(scratch_dir, "dst")
+    checkout_tree(src_rev, src_dir)
+    checkout_tree(dst_rev, dst_dir)
+
+    # Run the build in each.
+    build_tree(src_dir)
+    build_tree(dst_dir)
+
+    run_java_acc(src_rev, src_dir + "/build",
+                 dst_rev, dst_dir + "/build")
+
+
+if __name__ == "__main__":
+    main(sys.argv)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/checkstyle-noframes-sorted.xsl
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/checkstyle-noframes-sorted.xsl b/zookeeper-server/src/test/resources/checkstyle-noframes-sorted.xsl
new file mode 100644
index 0000000..5f9e93b
--- /dev/null
+++ b/zookeeper-server/src/test/resources/checkstyle-noframes-sorted.xsl
@@ -0,0 +1,178 @@
+<xsl:stylesheet	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="html" indent="yes"/>
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+<xsl:key name="files" match="file" use="@name" />
+
+<!-- Checkstyle XML Style Sheet by Stephane Bailliez <sb...@apache.org>         -->
+<!-- Part of the Checkstyle distribution found at http://checkstyle.sourceforge.net -->
+<!-- Usage (generates checkstyle_report.html):                                      -->
+<!--    <checkstyle failonviolation="false" config="${check.config}">               -->
+<!--      <fileset dir="${src.dir}" includes="**/*.java"/>                          -->
+<!--      <formatter type="xml" toFile="${doc.dir}/checkstyle_report.xml"/>         -->
+<!--    </checkstyle>                                                               -->
+<!--    <style basedir="${doc.dir}" destdir="${doc.dir}"                            -->
+<!--            includes="checkstyle_report.xml"                                    -->
+<!--            style="${doc.dir}/checkstyle-noframes-sorted.xsl"/>                 -->
+
+<xsl:template match="checkstyle">
+	<html>
+		<head>
+		<style type="text/css">
+    .bannercell {
+      border: 0px;
+      padding: 0px;
+    }
+    body {
+      margin-left: 10;
+      margin-right: 10;
+      font:normal 80% arial,helvetica,sanserif;
+      background-color:#FFFFFF;
+      color:#000000;
+    }
+    .a td {
+      background: #efefef;
+    }
+    .b td {
+      background: #fff;
+    }
+    th, td {
+      text-align: left;
+      vertical-align: top;
+    }
+    th {
+      font-weight:bold;
+      background: #ccc;
+      color: black;
+    }
+    table, th, td {
+      font-size:100%;
+      border: none
+    }
+    table.log tr td, tr th {
+
+    }
+    h2 {
+      font-weight:bold;
+      font-size:140%;
+      margin-bottom: 5;
+    }
+    h3 {
+      font-size:100%;
+      font-weight:bold;
+      background: #525D76;
+      color: white;
+      text-decoration: none;
+      padding: 5px;
+      margin-right: 2px;
+      margin-left: 2px;
+      margin-bottom: 0;
+    }
+		</style>
+		</head>
+		<body>
+			<a name="top"></a>
+      <!-- jakarta logo -->
+      <table border="0" cellpadding="0" cellspacing="0" width="100%">
+      <tr>
+        <td class="bannercell" rowspan="2">
+          <!--a href="http://jakarta.apache.org/">
+          <img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
+          </a-->
+        </td>
+    		<td class="text-align:right"><h2>CheckStyle Audit</h2></td>
+    		</tr>
+    		<tr>
+    		<td class="text-align:right">Designed for use with <a href='http://checkstyle.sourceforge.net/'>CheckStyle</a> and <a href='http://jakarta.apache.org'>Ant</a>.</td>
+    		</tr>
+      </table>
+    	<hr size="1"/>
+
+			<!-- Summary part -->
+			<xsl:apply-templates select="." mode="summary"/>
+			<hr size="1" width="100%" align="left"/>
+
+			<!-- Package List part -->
+			<xsl:apply-templates select="." mode="filelist"/>
+			<hr size="1" width="100%" align="left"/>
+
+			<!-- For each package create its part -->
+            <xsl:apply-templates select="file[@name and generate-id(.) = generate-id(key('files', @name))]" />
+
+			<hr size="1" width="100%" align="left"/>
+
+
+		</body>
+	</html>
+</xsl:template>
+
+
+
+	<xsl:template match="checkstyle" mode="filelist">
+		<h3>Files</h3>
+		<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+      <tr>
+        <th>Name</th>
+        <th>Errors</th>
+      </tr>
+          <xsl:for-each select="file[@name and generate-id(.) = generate-id(key('files', @name))]">
+                <xsl:sort data-type="number" order="descending" select="count(key('files', @name)/error)"/>
+				<xsl:variable name="errorCount" select="count(error)"/>
+				<tr>
+          <xsl:call-template name="alternated-row"/>
+					<td><a href="#f-{@name}"><xsl:value-of select="@name"/></a></td>
+					<td><xsl:value-of select="$errorCount"/></td>
+				</tr>
+			</xsl:for-each>
+		</table>
+	</xsl:template>
+
+
+	<xsl:template match="file">
+    <a name="f-{@name}"></a>
+    <h3>File <xsl:value-of select="@name"/></h3>
+
+    <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+    	<tr>
+    	  <th>Error Description</th>
+    	  <th>Line</th>
+      </tr>
+        <xsl:for-each select="key('files', @name)/error">
+          <xsl:sort data-type="number" order="ascending" select="@line"/>
+    	<tr>
+        <xsl:call-template name="alternated-row"/>
+    	  <td><xsl:value-of select="@message"/></td>
+    	  <td><xsl:value-of select="@line"/></td>
+    	</tr>
+    	</xsl:for-each>
+    </table>
+    <a href="#top">Back to top</a>
+	</xsl:template>
+
+
+	<xsl:template match="checkstyle" mode="summary">
+		<h3>Summary</h3>
+        <xsl:variable name="fileCount" select="count(file[@name and generate-id(.) = generate-id(key('files', @name))])"/>
+		<xsl:variable name="errorCount" select="count(file/error)"/>
+		<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+		<tr>
+			<th>Files</th>
+			<th>Errors</th>
+		</tr>
+		<tr>
+		  <xsl:call-template name="alternated-row"/>
+			<td><xsl:value-of select="$fileCount"/></td>
+			<td><xsl:value-of select="$errorCount"/></td>
+		</tr>
+		</table>
+	</xsl:template>
+
+  <xsl:template name="alternated-row">
+    <xsl:attribute name="class">
+      <xsl:if test="position() mod 2 = 1">a</xsl:if>
+      <xsl:if test="position() mod 2 = 0">b</xsl:if>
+    </xsl:attribute>
+  </xsl:template>
+</xsl:stylesheet>
+
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/checkstyle.xml
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/checkstyle.xml b/zookeeper-server/src/test/resources/checkstyle.xml
new file mode 100644
index 0000000..a5d5182
--- /dev/null
+++ b/zookeeper-server/src/test/resources/checkstyle.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
+    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
+
+<!--
+   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.
+-->
+<!--
+  [Forked from Hadoop@2d7363b27360e36fdd62546c0f9d0b1d78133f29]
+
+  Checkstyle configuration for Zookeeper that is based on the sun_checks.xml file
+  that is bundled with Checkstyle and includes checks for:
+
+    - the Java Language Specification at
+      http://java.sun.com/docs/books/jls/second_edition/html/index.html
+
+    - the Sun Code Conventions at http://java.sun.com/docs/codeconv/
+
+    - the Javadoc guidelines at
+      http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
+
+    - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
+
+    - some best practices
+
+  Checkstyle is very configurable. Be sure to read the documentation at
+  http://checkstyle.sf.net (or in your downloaded distribution).
+
+  Most Checks are configurable, be sure to consult the documentation.
+
+  To completely disable a check, just comment it out or delete it from the file.
+
+  Finally, it is worth reading the documentation.
+
+-->
+
+<module name="Checker">
+
+    <!-- Checks that a package.html file exists for each package.     -->
+    <!-- See http://checkstyle.sf.net/config_javadoc.html#PackageHtml -->
+    <module name="JavadocPackage"/>
+
+    <!-- Checks whether files end with a new line.                        -->
+    <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
+    <!-- module name="NewlineAtEndOfFile"/-->
+
+    <!-- Checks that property files contain the same keys.         -->
+    <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
+    <module name="Translation"/>
+
+    <module name="FileLength"/>
+    <module name="FileTabCharacter"/>
+
+    <module name="TreeWalker">
+
+        <!-- Checks for Javadoc comments.                     -->
+        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+        <module name="JavadocType">
+          <property name="scope" value="public"/>
+          <property name="allowMissingParamTags" value="true"/>
+        </module>
+        <module name="JavadocStyle"/>
+
+        <!-- Checks for Naming Conventions.                  -->
+        <!-- See http://checkstyle.sf.net/config_naming.html -->
+        <module name="ConstantName"/>
+        <module name="LocalFinalVariableName"/>
+        <module name="LocalVariableName"/>
+        <module name="MemberName"/>
+        <module name="MethodName"/>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+
+
+        <!-- Checks for Headers                                -->
+        <!-- See http://checkstyle.sf.net/config_header.html   -->
+        <!-- <module name="Header">                            -->
+            <!-- The follow property value demonstrates the ability     -->
+            <!-- to have access to ANT properties. In this case it uses -->
+            <!-- the ${basedir} property to allow Checkstyle to be run  -->
+            <!-- from any directory within a project. See property      -->
+            <!-- expansion,                                             -->
+            <!-- http://checkstyle.sf.net/config.html#properties        -->
+            <!-- <property                                              -->
+            <!--     name="headerFile"                                  -->
+            <!--     value="${basedir}/java.header"/>                   -->
+        <!-- </module> -->
+
+        <!-- Following interprets the header file as regular expressions. -->
+        <!-- <module name="RegexpHeader"/>                                -->
+
+
+        <!-- Checks for imports                              -->
+        <!-- See http://checkstyle.sf.net/config_import.html -->
+        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+        <module name="RedundantImport"/>
+        <module name="UnusedImports"/>
+
+
+        <!-- Checks for Size Violations.                    -->
+        <!-- See http://checkstyle.sf.net/config_sizes.html -->
+        <module name="LineLength">
+          <property name="ignorePattern" value="^import"/>
+        </module>
+        <module name="MethodLength"/>
+        <module name="ParameterNumber"/>
+
+
+        <!-- Checks for whitespace                               -->
+        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+        <module name="EmptyForIteratorPad"/>
+        <module name="MethodParamPad"/>
+        <module name="NoWhitespaceAfter"/>
+        <module name="NoWhitespaceBefore"/>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+        <module name="WhitespaceAfter">
+	    	<property name="tokens" value="COMMA, SEMI"/>
+		</module>
+
+
+        <!-- Modifier Checks                                    -->
+        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+        <module name="ModifierOrder"/>
+        <module name="RedundantModifier"/>
+
+
+        <!-- Checks for blocks. You know, those {}'s         -->
+        <!-- See http://checkstyle.sf.net/config_blocks.html -->
+        <module name="AvoidNestedBlocks"/>
+        <module name="EmptyBlock"/>
+        <module name="LeftCurly"/>
+        <module name="NeedBraces"/>
+        <module name="RightCurly"/>
+
+
+        <!-- Checks for common coding problems               -->
+        <!-- See http://checkstyle.sf.net/config_coding.html -->
+        <!-- module name="AvoidInlineConditionals"/-->
+        <module name="EmptyStatement"/>
+        <module name="EqualsHashCode"/>
+        <module name="HiddenField">
+          <property name="ignoreConstructorParameter" value="true"/>
+        </module>
+        <module name="IllegalInstantiation"/>
+        <module name="InnerAssignment"/>
+        <module name="MissingSwitchDefault"/>
+        <module name="SimplifyBooleanExpression"/>
+        <module name="SimplifyBooleanReturn"/>
+
+        <!-- Checks for class design                         -->
+        <!-- See http://checkstyle.sf.net/config_design.html -->
+        <module name="FinalClass"/>
+        <module name="HideUtilityClassConstructor"/>
+        <module name="InterfaceIsType"/>
+        <module name="VisibilityModifier"/>
+
+
+        <!-- Miscellaneous other checks.                   -->
+        <!-- See http://checkstyle.sf.net/config_misc.html -->
+        <module name="ArrayTypeStyle"/>
+        <module name="Indentation">
+            <property name="basicOffset" value="4" />
+            <property name="caseIndent" value="0" />
+        </module> 
+        <module name="TodoComment"/>
+        <module name="UpperEll"/>
+
+    </module>
+
+</module>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/buffersize/create/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/buffersize/create/version-2/log.1 b/zookeeper-server/src/test/resources/data/buffersize/create/version-2/log.1
new file mode 100644
index 0000000..4f05bc1
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/buffersize/create/version-2/log.1 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/buffersize/create/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/buffersize/create/version-2/snapshot.0 b/zookeeper-server/src/test/resources/data/buffersize/create/version-2/snapshot.0
new file mode 100644
index 0000000..49b512e
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/buffersize/create/version-2/snapshot.0 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/buffersize/set/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/buffersize/set/version-2/log.1 b/zookeeper-server/src/test/resources/data/buffersize/set/version-2/log.1
new file mode 100644
index 0000000..8586f16
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/buffersize/set/version-2/log.1 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/buffersize/set/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/buffersize/set/version-2/snapshot.0 b/zookeeper-server/src/test/resources/data/buffersize/set/version-2/snapshot.0
new file mode 100644
index 0000000..49b512e
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/buffersize/set/version-2/snapshot.0 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/log.1 b/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/log.1
new file mode 100644
index 0000000..2f145a6
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/log.1 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0 b/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0
new file mode 100644
index 0000000..49b512e
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.0 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2 b/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2
new file mode 100644
index 0000000..59dfa70
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/buffersize/snapshot/version-2/snapshot.2 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.1
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.1 b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.1
new file mode 100644
index 0000000..9dc15ae
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.1 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.274
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.274 b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.274
new file mode 100644
index 0000000..3bb868e
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.274 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.42
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.42 b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.42
new file mode 100644
index 0000000..5385be5
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.42 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.63b
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.63b b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.63b
new file mode 100644
index 0000000..4ee0a98
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/log.63b differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.0
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.0 b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.0
new file mode 100644
index 0000000..49b512e
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.0 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.272
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.272 b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.272
new file mode 100644
index 0000000..71f32a5
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.272 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.273
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.273 b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.273
new file mode 100644
index 0000000..3146f56
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.273 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.639
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.639 b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.639
new file mode 100644
index 0000000..cf9e389
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.639 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.83f
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.83f b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.83f
new file mode 100644
index 0000000..26dc5f6
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/invalidsnap/version-2/snapshot.83f differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/kerberos/minikdc-krb5.conf
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/kerberos/minikdc-krb5.conf b/zookeeper-server/src/test/resources/data/kerberos/minikdc-krb5.conf
new file mode 100644
index 0000000..43ec7c4
--- /dev/null
+++ b/zookeeper-server/src/test/resources/data/kerberos/minikdc-krb5.conf
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+# This resource is originally from HDFS, see the similarly named files there
+# in case of bug fixing, history, etc.
+# Branch : trunk
+# Github Revision: 1d1ab587e4e92ce3aea4cb144811f69145cb3b33
+#
+[libdefaults]
+    default_realm = {0}
+    udp_preference_limit = 1
+
+[realms]
+    {0} = '{'
+        kdc = {1}:{2}
+    '}'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/kerberos/minikdc.ldiff
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/kerberos/minikdc.ldiff b/zookeeper-server/src/test/resources/data/kerberos/minikdc.ldiff
new file mode 100644
index 0000000..20c8d77
--- /dev/null
+++ b/zookeeper-server/src/test/resources/data/kerberos/minikdc.ldiff
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+# This resource is originally from HDFS, see the similarly named files there
+# in case of bug fixing, history, etc.
+# Branch : trunk
+# Github Revision: 1d1ab587e4e92ce3aea4cb144811f69145cb3b33
+#
+dn: ou=users,dc=${0},dc=${1}
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: uid=krbtgt,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3}
+krb5KeyVersionNumber: 0
+
+dn: uid=ldap,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: LDAP
+sn: Service
+uid: ldap
+userPassword: secret
+krb5PrincipalName: ldap/${4}@${2}.${3}
+krb5KeyVersionNumber: 0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/upgrade/log.100000001
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/upgrade/log.100000001 b/zookeeper-server/src/test/resources/data/upgrade/log.100000001
new file mode 100644
index 0000000..00655f1
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/upgrade/log.100000001 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/upgrade/log.100001bf0
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/upgrade/log.100001bf0 b/zookeeper-server/src/test/resources/data/upgrade/log.100001bf0
new file mode 100644
index 0000000..83fa697
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/upgrade/log.100001bf0 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/upgrade/snapshot.100000000
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/upgrade/snapshot.100000000 b/zookeeper-server/src/test/resources/data/upgrade/snapshot.100000000
new file mode 100644
index 0000000..56f9015
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/upgrade/snapshot.100000000 differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/data/upgrade/snapshot.100001bec
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/data/upgrade/snapshot.100001bec b/zookeeper-server/src/test/resources/data/upgrade/snapshot.100001bec
new file mode 100644
index 0000000..0010d1e
Binary files /dev/null and b/zookeeper-server/src/test/resources/data/upgrade/snapshot.100001bec differ

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/resources/findbugsExcludeFile.xml
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/resources/findbugsExcludeFile.xml b/zookeeper-server/src/test/resources/findbugsExcludeFile.xml
new file mode 100644
index 0000000..c023f4f
--- /dev/null
+++ b/zookeeper-server/src/test/resources/findbugsExcludeFile.xml
@@ -0,0 +1,166 @@
+<FindBugsFilter>
+  <!-- Allow command line utilities, which follow pattern *Main.java, to call
+       system exit -->
+  <Match>
+    <Class name="~org\.apache\.zookeeper\..*Main" />
+    <Bug pattern="DM_EXIT" />
+  </Match>
+
+  <!-- This is too complicated to resolve/ingrained into the architecture
+       In particular we want to make sure we exit if this occurs
+       Also notice logged as fatal error -->
+  <Match>
+    <Class name="org.apache.zookeeper.server.ZooKeeperCriticalThread" />
+    <Method name="handleException" />
+    <Bug pattern="DM_EXIT" />
+  </Match>
+
+  <!-- In particular we want to make sure we exit if this occurs, unrecoverable.
+       Also notice logged as fatal error -->
+  <Match>
+    <Class name="org.apache.zookeeper.server.ZooKeeperServer" />
+    <Method name="takeSnapshot" />
+    <Bug pattern="DM_EXIT" />
+  </Match>
+
+
+  <!-- We want to catch all exceptions and cleanup, regardless of source
+       (incl runtime) -->
+  <Match>
+    <Class name="org.apache.zookeeper.ClientCnxn$SendThread" />
+    <Method name="run" />
+    <Bug pattern="REC_CATCH_EXCEPTION" />
+  </Match>
+
+   <!-- If we cannot open a socket to elect a leader, then we should
+            simply exit -->
+   <Match>
+     <Class name="org.apache.zookeeper.server.quorum.LeaderElection" />
+       <Method name="lookForLeader" />
+       <Bug pattern="DM_EXIT" />
+   </Match>
+
+   <!-- Committing out of order is an unrecoverable error, so we should
+              really exit  -->
+   <Match>
+     <Class name="org.apache.zookeeper.server.quorum.FollowerZooKeeperServer" />
+       <Method name="commit" />
+       <Bug pattern="DM_EXIT" />
+     </Match>
+
+   <!-- Two unrecoverable errors while following the leader  -->
+   <Match>
+     <Class name="org.apache.zookeeper.server.quorum.Learner" />
+       <Method name="syncWithLeader" />
+       <Bug pattern="DM_EXIT" />
+   </Match>
+
+  <Match>
+    <Package name="org.apache.jute.compiler.generated" />
+  </Match>
+
+  <Match>
+    <Package name="~org\.apache\.zookeeper\.(proto|data|txn)" />
+    <Bug code="EI, EI2" />
+  </Match>
+
+  <Match>
+    <Class name="org.apache.zookeeper.server.DataNode" />
+      <Bug code="EI2"/>
+  </Match>
+
+  <Match>
+    <Class name="org.apache.zookeeper.server.quorum.QuorumPacket" />
+       <Bug code="EI2, EI" />
+  </Match>
+
+  <Match>
+    <Class name="org.apache.zookeeper.server.quorum.QuorumAuthPacket" />
+      <Bug code="EI2, EI" />
+  </Match>
+
+  <Match>
+    <Class name="org.apache.zookeeper.ClientCnxn"/>
+      <Bug code="EI, EI2" />
+  </Match>
+
+  <Match>
+    <Class name="org.apache.zookeeper.server.DataNode"/>
+      <Field name="children"/> 
+      <Bug code="IS"/>
+  </Match>
+ <Match>
+   <Class name="org.apache.zookeeper.server.quorum.Leader"/>
+     <Field name="lastProposed"/>
+     <Bug code="IS"/>
+  </Match>
+  <Match>
+    <Class name="org.apache.zookeeper.server.persistence.FileTxnLog"/>
+    <Field name="serverStats"/>
+    <Bug code="IS"/>
+  </Match>
+  <Match>
+     <Class name="org.apache.zookeeper.server.quorum.LearnerSessionTracker"/>
+       <Bug code="UrF"/>
+  </Match>
+  <Match>
+    <Class name="org.apache.zookeeper.server.quorum.AuthFastLeaderElection$Messenger$WorkerSender"/>
+    <Method name="process"/>
+    <Bug code="RV,SF"/>
+  </Match>
+  <Match>
+    <Class name="org.apache.zookeeper.server.quorum.AuthFastLeaderElection$Messenger$WorkerReceiver"/>
+    <Method name="run"/>
+    <Bug code="SF"/>
+  </Match>
+
+  <!-- these are old classes just for upgrading and should go away -->
+  <Match>
+    <Class name="org.apache.zookeeper.server.quorum.AuthFastLeaderElection"/>
+  </Match>
+  <Match>
+    <Class name="org.apache.zookeeper.server.upgrade.DataNodeV1"/>
+  </Match> 
+
+  <Match>
+    <Class name="org.apache.zookeeper.server.upgrade.DataTreeV1"/>
+  </Match>
+
+  <!-- References code in a generated file that may or maynot be null -->
+  <Match>
+    <Class name="org.apache.zookeeper.Version" />
+    <Method name="getVersion" />
+    <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE" />
+  </Match>
+
+  <!-- sync'd object is also being used to protect the isrunning flag, this is ok -->
+  <Match>
+    <Class name="org.apache.zookeeper.ClientCnxn$EventThread"/>
+    <Bug code="JLM"/>
+    <Or>
+      <Method name="queuePacket" />
+      <Method name="run" />
+    </Or>
+  </Match>
+
+  <Match>
+    <Class name="org.apache.zookeeper.server.quorum.QuorumPeer"/>
+    <Bug pattern="OS_OPEN_STREAM" />
+    <Method name="writeLongToFile" />
+  </Match>
+
+  <!-- Disable 'Malicious code vulnerability warnings' due to mutable collection types in interface.
+       Undo this when ZOOKEEPER-1362 is done. -->
+  <Match>
+    <Class name="org.apache.zookeeper.ZooDefs$Ids"/>
+      <Bug pattern="MS_MUTABLE_COLLECTION" />
+  </Match>
+
+  <!-- Disable 'Found reliance on default encoding in' warnings. Ideally this should be fixed
+       by fixing the underlying cause - reliance on 'default' encoding in IO operations.
+       Please see ZOOKEEPER-1976 for detailed discussion. -->
+  <Match>
+    <Bug pattern="DM_DEFAULT_ENCODING" />
+  </Match>
+
+</FindBugsFilter>


[30/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml b/zookeeper-common/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml
deleted file mode 100644
index c28b238..0000000
--- a/zookeeper-common/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml
+++ /dev/null
@@ -1,2717 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
-<!-- Generated by the JDiff Javadoc doclet -->
-<!-- (http://www.jdiff.org) -->
-<!-- on Wed Apr 22 05:04:00 UTC 2009 -->
-
-<!--
-   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.
--->
-
-<api
-  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
-  xsi:noNamespaceSchemaLocation='api.xsd'
-  name="zookeeper 3.1.1"
-  jdversion="1.0.9">
-
-<!--  Command line arguments =  -doclet jdiff.JDiff -docletpath /home/gkesavan/zk-3.1/src/java/lib/jdiff-1.0.9.jar:/home/gkesavan/zk-3.1/src/java/lib/xerces-1.4.4.jar -classpath /home/gkesavan/zk-3.1/src/java/lib/jdiff-1.0.9.jar:/home/gkesavan/zk-3.1/src/java/lib/junit-4.4.jar:/home/gkesavan/zk-3.1/src/java/lib/log4j-1.2.15.jar:/home/gkesavan/zk-3.1/src/java/lib/xerces-1.4.4.jar:/home/gkesavan/zk-3.1/build/classes -sourcepath /home/gkesavan/zk-3.1/src/java/main -apidir /home/gkesavan/zk-3.1/src/java/lib/jdiff -apiname zookeeper 3.1.1 -->
-<package name="org.apache.zookeeper">
-  <!-- start interface org.apache.zookeeper.AsyncCallback -->
-  <interface name="AsyncCallback"    abstract="true"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-  </interface>
-  <!-- end interface org.apache.zookeeper.AsyncCallback -->
-  <!-- start interface org.apache.zookeeper.AsyncCallback.ACLCallback -->
-  <interface name="AsyncCallback.ACLCallback"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.AsyncCallback"/>
-    <method name="processResult"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="rc" type="int"/>
-      <param name="path" type="java.lang.String"/>
-      <param name="ctx" type="java.lang.Object"/>
-      <param name="acl" type="java.util.List"/>
-      <param name="stat" type="org.apache.zookeeper.data.Stat"/>
-    </method>
-  </interface>
-  <!-- end interface org.apache.zookeeper.AsyncCallback.ACLCallback -->
-  <!-- start interface org.apache.zookeeper.AsyncCallback.ChildrenCallback -->
-  <interface name="AsyncCallback.ChildrenCallback"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.AsyncCallback"/>
-    <method name="processResult"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="rc" type="int"/>
-      <param name="path" type="java.lang.String"/>
-      <param name="ctx" type="java.lang.Object"/>
-      <param name="children" type="java.util.List"/>
-    </method>
-  </interface>
-  <!-- end interface org.apache.zookeeper.AsyncCallback.ChildrenCallback -->
-  <!-- start interface org.apache.zookeeper.AsyncCallback.DataCallback -->
-  <interface name="AsyncCallback.DataCallback"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.AsyncCallback"/>
-    <method name="processResult"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="rc" type="int"/>
-      <param name="path" type="java.lang.String"/>
-      <param name="ctx" type="java.lang.Object"/>
-      <param name="data" type="byte[]"/>
-      <param name="stat" type="org.apache.zookeeper.data.Stat"/>
-    </method>
-  </interface>
-  <!-- end interface org.apache.zookeeper.AsyncCallback.DataCallback -->
-  <!-- start interface org.apache.zookeeper.AsyncCallback.StatCallback -->
-  <interface name="AsyncCallback.StatCallback"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.AsyncCallback"/>
-    <method name="processResult"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="rc" type="int"/>
-      <param name="path" type="java.lang.String"/>
-      <param name="ctx" type="java.lang.Object"/>
-      <param name="stat" type="org.apache.zookeeper.data.Stat"/>
-    </method>
-  </interface>
-  <!-- end interface org.apache.zookeeper.AsyncCallback.StatCallback -->
-  <!-- start interface org.apache.zookeeper.AsyncCallback.StringCallback -->
-  <interface name="AsyncCallback.StringCallback"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.AsyncCallback"/>
-    <method name="processResult"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="rc" type="int"/>
-      <param name="path" type="java.lang.String"/>
-      <param name="ctx" type="java.lang.Object"/>
-      <param name="name" type="java.lang.String"/>
-    </method>
-  </interface>
-  <!-- end interface org.apache.zookeeper.AsyncCallback.StringCallback -->
-  <!-- start interface org.apache.zookeeper.AsyncCallback.VoidCallback -->
-  <interface name="AsyncCallback.VoidCallback"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.AsyncCallback"/>
-    <method name="processResult"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="rc" type="int"/>
-      <param name="path" type="java.lang.String"/>
-      <param name="ctx" type="java.lang.Object"/>
-    </method>
-  </interface>
-  <!-- end interface org.apache.zookeeper.AsyncCallback.VoidCallback -->
-  <!-- start class org.apache.zookeeper.ClientCnxn -->
-  <class name="ClientCnxn" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="ClientCnxn" type="java.lang.String, int, org.apache.zookeeper.ZooKeeper, org.apache.zookeeper.ClientWatchManager"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <exception name="IOException" type="java.io.IOException"/>
-    </constructor>
-    <constructor name="ClientCnxn" type="java.lang.String, int, org.apache.zookeeper.ZooKeeper, org.apache.zookeeper.ClientWatchManager, long, byte[]"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <exception name="IOException" type="java.io.IOException"/>
-      <doc>
-      <![CDATA[Creates a connection object. The actual network connect doesn't get
- established until needed.
-
- @param hosts
-                a comma separated list of hosts that can be connected to.
- @param sessionTimeout
-                the timeout for connections.
- @param zooKeeper
-                the zookeeper object that this connection is related to.
- @throws KeeperException
- @throws IOException]]>
-      </doc>
-    </constructor>
-    <method name="getSessionId" return="long"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getSessionPasswd" return="byte[]"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="toString" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="disconnect"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Shutdown the send/event threads. This method should not be called
- directly - rather it should be called as part of close operation. This
- method is primarily here to allow the tests to verify disconnection
- behavior.]]>
-      </doc>
-    </method>
-    <method name="close"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <exception name="IOException" type="java.io.IOException"/>
-      <doc>
-      <![CDATA[Close the connection, which includes; send session disconnect to the
- server, shutdown the send/event threads.
- 
- @throws IOException]]>
-      </doc>
-    </method>
-    <method name="submitRequest" return="org.apache.zookeeper.proto.ReplyHeader"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="h" type="org.apache.zookeeper.proto.RequestHeader"/>
-      <param name="request" type="org.apache.jute.Record"/>
-      <param name="response" type="org.apache.jute.Record"/>
-      <param name="watchRegistration" type="org.apache.zookeeper.ZooKeeper.WatchRegistration"/>
-      <exception name="InterruptedException" type="java.lang.InterruptedException"/>
-    </method>
-    <method name="addAuthInfo"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="scheme" type="java.lang.String"/>
-      <param name="auth" type="byte[]"/>
-    </method>
-    <field name="disableAutoWatchReset" type="boolean"
-      transient="false" volatile="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[This controls whether automatic watch resetting is enabled.
- Clients automatically reset watches during session reconnect, this
- option allows the client to turn off this behavior by setting
- the environment variable "zookeeper.disableAutoWatchReset" to "true"]]>
-      </doc>
-    </field>
-    <field name="packetLen" type="int"
-      transient="false" volatile="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <doc>
-    <![CDATA[This class manages the socket i/o for the client. ClientCnxn maintains a list
- of available servers to connect to and "transparently" switches servers it is
- connected to as needed.]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.ClientCnxn -->
-  <!-- start interface org.apache.zookeeper.ClientWatchManager -->
-  <interface name="ClientWatchManager"    abstract="true"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <method name="materialize" return="java.util.Set"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="state" type="org.apache.zookeeper.Watcher.Event.KeeperState"/>
-      <param name="type" type="org.apache.zookeeper.Watcher.Event.EventType"/>
-      <param name="path" type="java.lang.String"/>
-      <doc>
-      <![CDATA[Return a set of watchers that should be notified of the event. The 
- manager must not notify the watcher(s), however it will update it's 
- internal structure as if the watches had triggered. The intent being 
- that the callee is now responsible for notifying the watchers of the 
- event, possibly at some later time.
- 
- @param state event state
- @param type event type
- @param path event path
- @return]]>
-      </doc>
-    </method>
-  </interface>
-  <!-- end interface org.apache.zookeeper.ClientWatchManager -->
-  <!-- start class org.apache.zookeeper.CreateMode -->
-  <class name="CreateMode" extends="java.lang.Enum"
-    abstract="false"
-    static="false" final="true" visibility="public"
-    deprecated="not deprecated">
-    <method name="values" return="org.apache.zookeeper.CreateMode[]"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="valueOf" return="org.apache.zookeeper.CreateMode"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="name" type="java.lang.String"/>
-    </method>
-    <method name="isEphemeral" return="boolean"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="isSequential" return="boolean"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="toFlag" return="int"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="fromFlag" return="org.apache.zookeeper.CreateMode"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="flag" type="int"/>
-      <exception name="KeeperException" type="org.apache.zookeeper.KeeperException"/>
-      <doc>
-      <![CDATA[Map an integer value to a CreateMode value]]>
-      </doc>
-    </method>
-    <field name="PERSISTENT" type="org.apache.zookeeper.CreateMode"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The znode will not be automatically deleted upon client's disconnect.]]>
-      </doc>
-    </field>
-    <field name="PERSISTENT_SEQUENTIAL" type="org.apache.zookeeper.CreateMode"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The znode will not be automatically deleted upon client's disconnect,
- and its name will be appended with a monotonically increasing number.]]>
-      </doc>
-    </field>
-    <field name="EPHEMERAL" type="org.apache.zookeeper.CreateMode"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The znode will be deleted upon the client's disconnect.]]>
-      </doc>
-    </field>
-    <field name="EPHEMERAL_SEQUENTIAL" type="org.apache.zookeeper.CreateMode"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The znode will be deleted upon the client's disconnect, and its name
- will be appended with a monotonically increasing number.]]>
-      </doc>
-    </field>
-    <doc>
-    <![CDATA[CreateMode value determines how the znode is created on ZooKeeper.]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.CreateMode -->
-  <!-- start class org.apache.zookeeper.Environment -->
-  <class name="Environment" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="Environment"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <method name="list" return="java.util.List"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="logEnv"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="msg" type="java.lang.String"/>
-      <param name="log" type="org.apache.log4j.Logger"/>
-    </method>
-    <doc>
-    <![CDATA[Provide insight into the runtime environment.]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.Environment -->
-  <!-- start class org.apache.zookeeper.Environment.Entry -->
-  <class name="Environment.Entry" extends="java.lang.Object"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="Environment.Entry" type="java.lang.String, java.lang.String"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <method name="getKey" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getValue" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="toString" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-  </class>
-  <!-- end class org.apache.zookeeper.Environment.Entry -->
-  <!-- start class org.apache.zookeeper.KeeperException -->
-  <class name="KeeperException" extends="java.lang.Exception"
-    abstract="true"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException" type="org.apache.zookeeper.KeeperException.Code"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <method name="create" return="org.apache.zookeeper.KeeperException"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="code" type="org.apache.zookeeper.KeeperException.Code"/>
-      <param name="path" type="java.lang.String"/>
-      <doc>
-      <![CDATA[All non-specific keeper exceptions should be constructed via
- this factory method in order to guarantee consistency in error
- codes and such.  If you know the error code, then you should
- construct the special purpose exception directly.  That will
- allow you to have the most specific possible declarations of
- what exceptions might actually be thrown.
-
- @param code The error code.
- @param path The ZooKeeper path being operated on.
- @return The specialized exception, presumably to be thrown by
-  the caller.]]>
-      </doc>
-    </method>
-    <method name="create" return="org.apache.zookeeper.KeeperException"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link #create(Code, String)}
- instead">
-      <param name="code" type="int"/>
-      <param name="path" type="java.lang.String"/>
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link #create(Code, String)}
- instead]]>
-      </doc>
-    </method>
-    <method name="create" return="org.apache.zookeeper.KeeperException"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link #create(Code)}
- instead">
-      <param name="code" type="int"/>
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link #create(Code)}
- instead]]>
-      </doc>
-    </method>
-    <method name="create" return="org.apache.zookeeper.KeeperException"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="code" type="org.apache.zookeeper.KeeperException.Code"/>
-      <doc>
-      <![CDATA[All non-specific keeper exceptions should be constructed via
- this factory method in order to guarantee consistency in error
- codes and such.  If you know the error code, then you should
- construct the special purpose exception directly.  That will
- allow you to have the most specific possible declarations of
- what exceptions might actually be thrown.
-
- @param code The error code of your new exception.  This will
- also determine the specific type of the exception that is
- returned.
- @return The specialized exception, presumably to be thrown by
- the caller.]]>
-      </doc>
-    </method>
-    <method name="setCode"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="deprecated in 3.1.0, exceptions should be immutable, this
- method should not be used">
-      <param name="code" type="int"/>
-      <doc>
-      <![CDATA[Set the code for this exception
- @param code error code
- @deprecated deprecated in 3.1.0, exceptions should be immutable, this
- method should not be used]]>
-      </doc>
-    </method>
-    <method name="getCode" return="int"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link #code()} instead">
-      <doc>
-      <![CDATA[Read the error code for this exception
- @return the error code for this exception
- @deprecated deprecated in 3.1.0, use {@link #code()} instead]]>
-      </doc>
-    </method>
-    <method name="code" return="org.apache.zookeeper.KeeperException.Code"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Read the error Code for this exception
- @return the error Code for this exception]]>
-      </doc>
-    </method>
-    <method name="getPath" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Read the path for this exception
- @return the path associated with this error, null if none]]>
-      </doc>
-    </method>
-    <method name="getMessage" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException -->
-  <!-- start class org.apache.zookeeper.KeeperException.APIErrorException -->
-  <class name="KeeperException.APIErrorException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.APIErrorException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.APIERROR]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.APIErrorException -->
-  <!-- start class org.apache.zookeeper.KeeperException.AuthFailedException -->
-  <class name="KeeperException.AuthFailedException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.AuthFailedException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.AUTHFAILED]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.AuthFailedException -->
-  <!-- start class org.apache.zookeeper.KeeperException.BadArgumentsException -->
-  <class name="KeeperException.BadArgumentsException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.BadArgumentsException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.BADARGUMENTS]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.BadArgumentsException -->
-  <!-- start class org.apache.zookeeper.KeeperException.BadVersionException -->
-  <class name="KeeperException.BadVersionException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.BadVersionException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.BADVERSION]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.BadVersionException -->
-  <!-- start class org.apache.zookeeper.KeeperException.Code -->
-  <class name="KeeperException.Code" extends="java.lang.Enum"
-    abstract="false"
-    static="true" final="true" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.KeeperException.CodeDeprecated"/>
-    <method name="values" return="org.apache.zookeeper.KeeperException.Code[]"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="valueOf" return="org.apache.zookeeper.KeeperException.Code"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="name" type="java.lang.String"/>
-    </method>
-    <method name="intValue" return="int"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Get the int value for a particular Code.
- @return error code as integer]]>
-      </doc>
-    </method>
-    <method name="get" return="org.apache.zookeeper.KeeperException.Code"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="code" type="int"/>
-      <doc>
-      <![CDATA[Get the Code value for a particular integer error code
- @param code int error code
- @return Code value corresponding to specified int code, or null]]>
-      </doc>
-    </method>
-    <field name="OK" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Everything is OK]]>
-      </doc>
-    </field>
-    <field name="SYSTEMERROR" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[System and server-side errors.
- This is never thrown by the server, it shouldn't be used other than
- to indicate a range. Specifically error codes greater than this
- value, but lesser than {@link #APIERROR}, are system errors.]]>
-      </doc>
-    </field>
-    <field name="RUNTIMEINCONSISTENCY" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[A runtime inconsistency was found]]>
-      </doc>
-    </field>
-    <field name="DATAINCONSISTENCY" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[A data inconsistency was found]]>
-      </doc>
-    </field>
-    <field name="CONNECTIONLOSS" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Connection to the server has been lost]]>
-      </doc>
-    </field>
-    <field name="MARSHALLINGERROR" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Error while marshalling or unmarshalling data]]>
-      </doc>
-    </field>
-    <field name="UNIMPLEMENTED" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Operation is unimplemented]]>
-      </doc>
-    </field>
-    <field name="OPERATIONTIMEOUT" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Operation timeout]]>
-      </doc>
-    </field>
-    <field name="BADARGUMENTS" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Invalid arguments]]>
-      </doc>
-    </field>
-    <field name="APIERROR" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[API errors.
- This is never thrown by the server, it shouldn't be used other than
- to indicate a range. Specifically error codes greater than this
- value are API errors (while values less than this indicate a
- {@link #SYSTEMERROR}).]]>
-      </doc>
-    </field>
-    <field name="NONODE" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Node does not exist]]>
-      </doc>
-    </field>
-    <field name="NOAUTH" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Not authenticated]]>
-      </doc>
-    </field>
-    <field name="BADVERSION" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Version conflict]]>
-      </doc>
-    </field>
-    <field name="NOCHILDRENFOREPHEMERALS" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Ephemeral nodes may not have children]]>
-      </doc>
-    </field>
-    <field name="NODEEXISTS" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The node already exists]]>
-      </doc>
-    </field>
-    <field name="NOTEMPTY" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The node has children]]>
-      </doc>
-    </field>
-    <field name="SESSIONEXPIRED" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The session has been expired by the server]]>
-      </doc>
-    </field>
-    <field name="INVALIDCALLBACK" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Invalid callback specified]]>
-      </doc>
-    </field>
-    <field name="INVALIDACL" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Invalid ACL specified]]>
-      </doc>
-    </field>
-    <field name="AUTHFAILED" type="org.apache.zookeeper.KeeperException.Code"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Client authentication failed]]>
-      </doc>
-    </field>
-    <doc>
-    <![CDATA[Codes which represent the various KeeperException
- types. This enum replaces the deprecated earlier static final int
- constants. The old, deprecated, values are in "camel case" while the new
- enum values are in all CAPS.]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.Code -->
-  <!-- start interface org.apache.zookeeper.KeeperException.CodeDeprecated -->
-  <interface name="KeeperException.CodeDeprecated"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <field name="Ok" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#OK} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#OK} instead]]>
-      </doc>
-    </field>
-    <field name="SystemError" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead]]>
-      </doc>
-    </field>
-    <field name="RuntimeInconsistency" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use
- {@link Code#RUNTIMEINCONSISTENCY} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use
- {@link Code#RUNTIMEINCONSISTENCY} instead]]>
-      </doc>
-    </field>
-    <field name="DataInconsistency" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY}
- instead]]>
-      </doc>
-    </field>
-    <field name="ConnectionLoss" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS}
- instead]]>
-      </doc>
-    </field>
-    <field name="MarshallingError" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR}
- instead]]>
-      </doc>
-    </field>
-    <field name="Unimplemented" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED}
- instead]]>
-      </doc>
-    </field>
-    <field name="OperationTimeout" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT}
- instead]]>
-      </doc>
-    </field>
-    <field name="BadArguments" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#BADARGUMENTS}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#BADARGUMENTS}
- instead]]>
-      </doc>
-    </field>
-    <field name="APIError" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#APIERROR} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#APIERROR} instead]]>
-      </doc>
-    </field>
-    <field name="NoNode" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#NONODE} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NONODE} instead]]>
-      </doc>
-    </field>
-    <field name="NoAuth" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#NOAUTH} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NOAUTH} instead]]>
-      </doc>
-    </field>
-    <field name="BadVersion" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#BADVERSION} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#BADVERSION} instead]]>
-      </doc>
-    </field>
-    <field name="NoChildrenForEphemerals" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use
- {@link Code#NOCHILDRENFOREPHEMERALS}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use
- {@link Code#NOCHILDRENFOREPHEMERALS}
- instead]]>
-      </doc>
-    </field>
-    <field name="NodeExists" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead]]>
-      </doc>
-    </field>
-    <field name="NotEmpty" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead]]>
-      </doc>
-    </field>
-    <field name="SessionExpired" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead]]>
-      </doc>
-    </field>
-    <field name="InvalidCallback" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK}
- instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK}
- instead]]>
-      </doc>
-    </field>
-    <field name="InvalidACL" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#INVALIDACL} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#INVALIDACL} instead]]>
-      </doc>
-    </field>
-    <field name="AuthFailed" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead">
-      <doc>
-      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead]]>
-      </doc>
-    </field>
-    <doc>
-    <![CDATA[This interface contains the original static final int constants
- which have now been replaced with an enumeration in Code. Do not
- reference this class directly, if necessary (legacy code) continue
- to access the constants through Code.
- Note: an interface is used here due to the fact that enums cannot
- reference constants defined within the same enum as said constants
- are considered initialized _after_ the enum itself. By using an
- interface as a super type this allows the deprecated constants to
- be initialized first and referenced when constructing the enums. I
- didn't want to have constants declared twice. This
- interface should be private, but it's declared public to enable
- javadoc to include in the user API spec.]]>
-    </doc>
-  </interface>
-  <!-- end interface org.apache.zookeeper.KeeperException.CodeDeprecated -->
-  <!-- start class org.apache.zookeeper.KeeperException.ConnectionLossException -->
-  <class name="KeeperException.ConnectionLossException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.ConnectionLossException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.CONNECTIONLOSS]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.ConnectionLossException -->
-  <!-- start class org.apache.zookeeper.KeeperException.DataInconsistencyException -->
-  <class name="KeeperException.DataInconsistencyException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.DataInconsistencyException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.DATAINCONSISTENCY]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.DataInconsistencyException -->
-  <!-- start class org.apache.zookeeper.KeeperException.InvalidACLException -->
-  <class name="KeeperException.InvalidACLException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.InvalidACLException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.INVALIDACL]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.InvalidACLException -->
-  <!-- start class org.apache.zookeeper.KeeperException.InvalidCallbackException -->
-  <class name="KeeperException.InvalidCallbackException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.InvalidCallbackException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.INVALIDCALLBACK]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.InvalidCallbackException -->
-  <!-- start class org.apache.zookeeper.KeeperException.MarshallingErrorException -->
-  <class name="KeeperException.MarshallingErrorException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.MarshallingErrorException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.MARSHALLINGERROR]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.MarshallingErrorException -->
-  <!-- start class org.apache.zookeeper.KeeperException.NoAuthException -->
-  <class name="KeeperException.NoAuthException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.NoAuthException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.NOAUTH]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.NoAuthException -->
-  <!-- start class org.apache.zookeeper.KeeperException.NoChildrenForEphemeralsException -->
-  <class name="KeeperException.NoChildrenForEphemeralsException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.NoChildrenForEphemeralsException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.NOCHILDRENFOREPHEMERALS]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.NoChildrenForEphemeralsException -->
-  <!-- start class org.apache.zookeeper.KeeperException.NodeExistsException -->
-  <class name="KeeperException.NodeExistsException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.NodeExistsException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.NODEEXISTS]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.NodeExistsException -->
-  <!-- start class org.apache.zookeeper.KeeperException.NoNodeException -->
-  <class name="KeeperException.NoNodeException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.NoNodeException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.NONODE]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.NoNodeException -->
-  <!-- start class org.apache.zookeeper.KeeperException.NotEmptyException -->
-  <class name="KeeperException.NotEmptyException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.NotEmptyException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.NOTEMPTY]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.NotEmptyException -->
-  <!-- start class org.apache.zookeeper.KeeperException.OperationTimeoutException -->
-  <class name="KeeperException.OperationTimeoutException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.OperationTimeoutException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.OPERATIONTIMEOUT]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.OperationTimeoutException -->
-  <!-- start class org.apache.zookeeper.KeeperException.RuntimeInconsistencyException -->
-  <class name="KeeperException.RuntimeInconsistencyException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.RuntimeInconsistencyException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.RUNTIMEINCONSISTENCY]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.RuntimeInconsistencyException -->
-  <!-- start class org.apache.zookeeper.KeeperException.SessionExpiredException -->
-  <class name="KeeperException.SessionExpiredException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.SessionExpiredException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.SESSIONEXPIRED]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.SessionExpiredException -->
-  <!-- start class org.apache.zookeeper.KeeperException.SystemErrorException -->
-  <class name="KeeperException.SystemErrorException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.SystemErrorException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.SYSTEMERROR]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.SystemErrorException -->
-  <!-- start class org.apache.zookeeper.KeeperException.UnimplementedException -->
-  <class name="KeeperException.UnimplementedException" extends="org.apache.zookeeper.KeeperException"
-    abstract="false"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="KeeperException.UnimplementedException"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <doc>
-    <![CDATA[@see Code.UNIMPLEMENTED]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.KeeperException.UnimplementedException -->
-  <!-- start class org.apache.zookeeper.Quotas -->
-  <class name="Quotas" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="Quotas"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <method name="quotaPath" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="path" type="java.lang.String"/>
-      <doc>
-      <![CDATA[return the quota path associated with this
- prefix
- @param path the actual path in zookeeper.
- @return the limit quota path]]>
-      </doc>
-    </method>
-    <method name="statPath" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="path" type="java.lang.String"/>
-      <doc>
-      <![CDATA[return the stat quota path associated with this
- prefix.
- @param path the actual path in zookeeper
- @return the stat quota path]]>
-      </doc>
-    </method>
-    <field name="procZookeeper" type="java.lang.String"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[the zookeeper nodes that acts as the management and status node]]>
-      </doc>
-    </field>
-    <field name="quotaZookeeper" type="java.lang.String"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[the zookeeper quota node that acts as the quota
- management node for zookeeper]]>
-      </doc>
-    </field>
-    <field name="limitNode" type="java.lang.String"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[the limit node that has the limit of
- a subtree]]>
-      </doc>
-    </field>
-    <field name="statNode" type="java.lang.String"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[the stat node that monitors the limit of
- a subtree.]]>
-      </doc>
-    </field>
-    <doc>
-    <![CDATA[this class manages quotas
- and has many other utils
- for quota]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.Quotas -->
-  <!-- start class org.apache.zookeeper.ServerAdminClient -->
-  <class name="ServerAdminClient" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="ServerAdminClient"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <method name="ruok"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="host" type="java.lang.String"/>
-      <param name="port" type="int"/>
-    </method>
-    <method name="dump"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="host" type="java.lang.String"/>
-      <param name="port" type="int"/>
-    </method>
-    <method name="stat"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="host" type="java.lang.String"/>
-      <param name="port" type="int"/>
-    </method>
-    <method name="kill"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="host" type="java.lang.String"/>
-      <param name="port" type="int"/>
-    </method>
-    <method name="setTraceMask"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="host" type="java.lang.String"/>
-      <param name="port" type="int"/>
-      <param name="traceMaskStr" type="java.lang.String"/>
-    </method>
-    <method name="getTraceMask"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="host" type="java.lang.String"/>
-      <param name="port" type="int"/>
-    </method>
-    <method name="main"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="args" type="java.lang.String[]"/>
-    </method>
-  </class>
-  <!-- end class org.apache.zookeeper.ServerAdminClient -->
-  <!-- start class org.apache.zookeeper.StatsTrack -->
-  <class name="StatsTrack" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="StatsTrack"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[a default constructor for
- stats]]>
-      </doc>
-    </constructor>
-    <constructor name="StatsTrack" type="java.lang.String"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[the stat string should be of the form count=int,bytes=long
- if stats is called with null the count and bytes are initialized
- to -1.
- @param stats the stat string to be intialized with]]>
-      </doc>
-    </constructor>
-    <method name="getCount" return="int"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[get the count of nodes allowed as part of quota
-
- @return the count as part of this string]]>
-      </doc>
-    </method>
-    <method name="setCount"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="count" type="int"/>
-      <doc>
-      <![CDATA[set the count for this stat tracker.
-
- @param count
-            the count to set with]]>
-      </doc>
-    </method>
-    <method name="getBytes" return="long"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[get the count of bytes allowed as part of quota
-
- @return the bytes as part of this string]]>
-      </doc>
-    </method>
-    <method name="setBytes"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="bytes" type="long"/>
-      <doc>
-      <![CDATA[set teh bytes for this stat tracker.
-
- @param bytes
-            the bytes to set with]]>
-      </doc>
-    </method>
-    <method name="toString" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <doc>
-    <![CDATA[a class that represents the stats associated with quotas]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.StatsTrack -->
-  <!-- start class org.apache.zookeeper.Version -->
-  <class name="Version" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <implements name="org.apache.zookeeper.version.Info"/>
-    <constructor name="Version"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <method name="getRevision" return="int"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getBuildDate" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getVersion" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getVersionRevision" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getFullVersion" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="printUsage"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="main"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="args" type="java.lang.String[]"/>
-      <doc>
-      <![CDATA[Prints the current version, revision and build date to the standard out.
- 
- @param args
-            <ul>
-            <li> --short - prints a short version string "1.2.3"
-            <li> --revision - prints a short version string with the SVN
-            repository revision "1.2.3-94"
-            <li> --full - prints the revision and the build date
-            </ul>]]>
-      </doc>
-    </method>
-  </class>
-  <!-- end class org.apache.zookeeper.Version -->
-  <!-- start class org.apache.zookeeper.WatchedEvent -->
-  <class name="WatchedEvent" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="WatchedEvent" type="org.apache.zookeeper.Watcher.Event.EventType, org.apache.zookeeper.Watcher.Event.KeeperState, java.lang.String"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Create a WatchedEvent with specified type, state and path]]>
-      </doc>
-    </constructor>
-    <constructor name="WatchedEvent" type="org.apache.zookeeper.proto.WatcherEvent"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Convert a WatcherEvent sent over the wire into a full-fledged WatcherEvent]]>
-      </doc>
-    </constructor>
-    <method name="getState" return="org.apache.zookeeper.Watcher.Event.KeeperState"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getType" return="org.apache.zookeeper.Watcher.Event.EventType"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getPath" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="toString" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="getWrapper" return="org.apache.zookeeper.proto.WatcherEvent"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Convert WatchedEvent to type that can be sent over network]]>
-      </doc>
-    </method>
-    <doc>
-    <![CDATA[A WatchedEvent represents a change on the ZooKeeper that a Watcher
-  is able to respond to.  The WatchedEvent includes exactly what happened,
-  the current state of the ZooKeeper, and the path of the znode that
-  was involved in the event.]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.WatchedEvent -->
-  <!-- start interface org.apache.zookeeper.Watcher -->
-  <interface name="Watcher"    abstract="true"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <method name="process"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="event" type="org.apache.zookeeper.WatchedEvent"/>
-    </method>
-    <doc>
-    <![CDATA[This interface specifies the public interface an event handler class must
- implement. A ZooKeeper client will get various events from the ZooKeepr
- server it connects to. An application using such a client handles these
- events by registering a callback object with the client. The callback object
- is expected to be an instance of a class that implements Watcher interface.]]>
-    </doc>
-  </interface>
-  <!-- end interface org.apache.zookeeper.Watcher -->
-  <!-- start interface org.apache.zookeeper.Watcher.Event -->
-  <interface name="Watcher.Event"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <doc>
-    <![CDATA[This interface defines the possible states an Event may represent]]>
-    </doc>
-  </interface>
-  <!-- end interface org.apache.zookeeper.Watcher.Event -->
-  <!-- start class org.apache.zookeeper.Watcher.Event.EventType -->
-  <class name="Watcher.Event.EventType" extends="java.lang.Enum"
-    abstract="false"
-    static="true" final="true" visibility="public"
-    deprecated="not deprecated">
-    <method name="values" return="org.apache.zookeeper.Watcher.Event.EventType[]"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="valueOf" return="org.apache.zookeeper.Watcher.Event.EventType"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="name" type="java.lang.String"/>
-    </method>
-    <method name="getIntValue" return="int"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="fromInt" return="org.apache.zookeeper.Watcher.Event.EventType"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="intValue" type="int"/>
-    </method>
-    <field name="None" type="org.apache.zookeeper.Watcher.Event.EventType"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="NodeCreated" type="org.apache.zookeeper.Watcher.Event.EventType"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="NodeDeleted" type="org.apache.zookeeper.Watcher.Event.EventType"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="NodeDataChanged" type="org.apache.zookeeper.Watcher.Event.EventType"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="NodeChildrenChanged" type="org.apache.zookeeper.Watcher.Event.EventType"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <doc>
-    <![CDATA[Enumeration of types of events that may occur on the ZooKeeper]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.Watcher.Event.EventType -->
-  <!-- start class org.apache.zookeeper.Watcher.Event.KeeperState -->
-  <class name="Watcher.Event.KeeperState" extends="java.lang.Enum"
-    abstract="false"
-    static="true" final="true" visibility="public"
-    deprecated="not deprecated">
-    <method name="values" return="org.apache.zookeeper.Watcher.Event.KeeperState[]"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="valueOf" return="org.apache.zookeeper.Watcher.Event.KeeperState"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="name" type="java.lang.String"/>
-    </method>
-    <method name="getIntValue" return="int"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </method>
-    <method name="fromInt" return="org.apache.zookeeper.Watcher.Event.KeeperState"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="intValue" type="int"/>
-    </method>
-    <field name="Unknown" type="org.apache.zookeeper.Watcher.Event.KeeperState"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Unused, this state is never generated by the server]]>
-      </doc>
-    </field>
-    <field name="Disconnected" type="org.apache.zookeeper.Watcher.Event.KeeperState"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The client is in the disconnected state - it is not connected
- to any server in the ensemble.]]>
-      </doc>
-    </field>
-    <field name="NoSyncConnected" type="org.apache.zookeeper.Watcher.Event.KeeperState"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[Unused, this state is never generated by the server]]>
-      </doc>
-    </field>
-    <field name="SyncConnected" type="org.apache.zookeeper.Watcher.Event.KeeperState"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The client is in the connected state - it is connected
- to a server in the ensemble (one of the servers specified
- in the host connection parameter during ZooKeeper client
- creation).]]>
-      </doc>
-    </field>
-    <field name="Expired" type="org.apache.zookeeper.Watcher.Event.KeeperState"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The serving cluster has expired this session. The ZooKeeper
- client connection (the session) is no longer valid. You must
- create a new client connection (instantiate a new ZooKeeper
- instance) if you with to access the ensemble.]]>
-      </doc>
-    </field>
-    <doc>
-    <![CDATA[Enumeration of states the ZooKeeper may be at the event]]>
-    </doc>
-  </class>
-  <!-- end class org.apache.zookeeper.Watcher.Event.KeeperState -->
-  <!-- start class org.apache.zookeeper.ZooDefs -->
-  <class name="ZooDefs" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="ZooDefs"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-    </constructor>
-    <field name="opNames" type="java.lang.String[]"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-  </class>
-  <!-- end class org.apache.zookeeper.ZooDefs -->
-  <!-- start interface org.apache.zookeeper.ZooDefs.Ids -->
-  <interface name="ZooDefs.Ids"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <field name="ANYONE_ID_UNSAFE" type="org.apache.zookeeper.data.Id"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[This Id represents anyone.]]>
-      </doc>
-    </field>
-    <field name="AUTH_IDS" type="org.apache.zookeeper.data.Id"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[This Id is only usable to set ACLs. It will get substituted with the
- Id's the client authenticated with.]]>
-      </doc>
-    </field>
-    <field name="OPEN_ACL_UNSAFE" type="java.util.ArrayList"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[This is a completely open ACL with the exception of ADMIN permission.]]>
-      </doc>
-    </field>
-    <field name="CREATOR_ALL_ACL" type="java.util.ArrayList"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[This ACL gives the creators authentication id's all permissions.]]>
-      </doc>
-    </field>
-    <field name="READ_ACL_UNSAFE" type="java.util.ArrayList"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[This ACL gives the world the ability to read.]]>
-      </doc>
-    </field>
-  </interface>
-  <!-- end interface org.apache.zookeeper.ZooDefs.Ids -->
-  <!-- start interface org.apache.zookeeper.ZooDefs.OpCode -->
-  <interface name="ZooDefs.OpCode"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <field name="notification" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="create" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="delete" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="exists" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="getData" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="setData" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="getACL" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="setACL" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="getChildren" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="sync" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="ping" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="auth" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="setWatches" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="createSession" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="closeSession" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="error" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-  </interface>
-  <!-- end interface org.apache.zookeeper.ZooDefs.OpCode -->
-  <!-- start interface org.apache.zookeeper.ZooDefs.Perms -->
-  <interface name="ZooDefs.Perms"    abstract="true"
-    static="true" final="false" visibility="public"
-    deprecated="not deprecated">
-    <field name="READ" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="WRITE" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="CREATE" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="DELETE" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="ADMIN" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-    <field name="ALL" type="int"
-      transient="false" volatile="false"
-      static="true" final="true" visibility="public"
-      deprecated="not deprecated">
-    </field>
-  </interface>
-  <!-- end interface org.apache.zookeeper.ZooDefs.Perms -->
-  <!-- start class org.apache.zookeeper.ZooKeeper -->
-  <class name="ZooKeeper" extends="java.lang.Object"
-    abstract="false"
-    static="false" final="false" visibility="public"
-    deprecated="not deprecated">
-    <constructor name="ZooKeeper" type="java.lang.String, int, org.apache.zookeeper.Watcher"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <exception name="IOException" type="java.io.IOException"/>
-      <doc>
-      <![CDATA[To create a client(ZooKeeper) object, the application needs to pass a
- string containing a comma separated list of host:port pairs, each 
- corresponding to a ZooKeeper server.
- <p>
- The client object will pick an arbitrary server and try to connect to it.
- If failed, it will try the next one in the list, until a connection is
- established, or all the servers have been tried.
-
- @param host
-            comma separated host:port pairs, each corresponding to a zk
-            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
- @param sessionTimeout
-            session timeout in milliseconds
- @param watcher
-            a watcher object which will be notified of state changes, may
-            also be notified for node events
-
- @throws IOException in cases of network failure]]>
-      </doc>
-    </constructor>
-    <constructor name="ZooKeeper" type="java.lang.String, int, org.apache.zookeeper.Watcher, long, byte[]"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <exception name="IOException" type="java.io.IOException"/>
-      <doc>
-      <![CDATA[To create a client(ZooKeeper) object, the application needs to pass a
- string containing a comma separated list of host:port pairs, each
- corresponding to a ZooKeeper server.
- <p>
- The client object will pick an arbitrary server and try to connect to it.
- If failed, it will try the next one in the list, until a connection is
- established, or all the servers have been tried.
- <p>
- Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
- client connection, these values must be passed as sessionId and
- sessionPasswd respectively if reconnecting. Otherwise, if not
- reconnecting, use the other constructor which does not require these
- parameters.
-
- @param host
-            comma separated host:port pairs, each corresponding to a zk
-            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
- @param sessionTimeout
-            session timeout in milliseconds
- @param watcher
-            a watcher object which will be notified of state changes, may
-            also be notified for node events
- @param sessionId
-            specific session id to use if reconnecting
- @param sessionPasswd
-            password for this session
-
- @throws IOException in cases of network failure]]>
-      </doc>
-    </constructor>
-    <method name="getSessionId" return="long"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The session id for this ZooKeeper client instance. The value returned is
- not valid until the client connects to a server and may change after a
- re-connect.
-
- @return current session id]]>
-      </doc>
-    </method>
-    <method name="getSessionPasswd" return="byte[]"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <doc>
-      <![CDATA[The session password for this ZooKeeper client instance. The value
- returned is not valid until the client connects to a server and may
- change after a re-connect.
-
- @return current session password]]>
-      </doc>
-    </method>
-    <method name="addAuthInfo"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="scheme" type="java.lang.String"/>
-      <param name="auth" type="byte[]"/>
-    </method>
-    <method name="register"
-      abstract="false" native="false" synchronized="true"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="watcher" type="org.apache.zookeeper.Watcher"/>
-    </method>
-    <method name="close"
-      abstract="false" native="false" synchronized="true"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <exception name="InterruptedException" type="java.lang.InterruptedException"/>
-      <doc>
-      <![CDATA[Close this client object. Once the client is closed, its session becomes
- invalid. All the ephemeral nodes in the ZooKeeper server associated with
- the session will be removed. The watches left on those nodes (and on
- their parents) will be triggered.
-
- @throws InterruptedException
-
- @throws IOException
- @throws InterruptedException]]>
-      </doc>
-    </method>
-    <method name="create" return="java.lang.String"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="path" type="java.lang.String"/>
-      <param name="data" type="byte[]"/>
-      <param name="acl" type="java.util.List"/>
-      <param name="createMode" type="org.apache.zookeeper.CreateMode"/>
-      <exception name="KeeperException" type="org.apache.zookeeper.KeeperException"/>
-      <exception name="InterruptedException" type="java.lang.InterruptedException"/>
-      <doc>
-      <![CDATA[Create a node with the given path. The node data will be the given data,
- and node acl will be the given acl.
- <p>
- The flags argument specifies whether the created node will be ephemeral
- or not.
- <p>
- An ephemeral node will be removed by the ZooKeeper automatically when the
- session associated with the creation of the node expires.
- <p>
- The flags argument can also specify to create a sequential node. The
- actual path name of a sequential node will be the given path plus a
- suffix "_i" where i is the current sequential number of the node. Once
- such a node is created, the sequential number will be incremented by one.
- <p>
- If a node with the same actual path already exists in the ZooKeeper, a
- KeeperException with error code KeeperException.NodeExists will be
- thrown. Note that since a different actual path is used for each
- invocation of creating sequential node with the same path argument, the
- call will never throw "file exists" KeeperException.
- <p>
- If the parent node does not exist in the ZooKeeper, a KeeperException
- with error code KeeperException.NoNode will be thrown.
- <p>
- An ephemeral node cannot have children. If the parent node of the given
- path is ephemeral, a KeeperException with error code
- KeeperException.NoChildrenForEphemerals will be thrown.
- <p>
- This operation, if successful, will trigger all the watches left on the
- node of the given path by exists and getData API calls, and the watches
- left on the parent node by getChildren API calls.
- <p>
- If a node is created successfully, the ZooKeeper server will trigger the
- watches on the path left by exists calls, and the watches on the parent
- of the node by getChildren calls.
- <p>
- The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
- Arrays larger than this will cause a KeeperExecption to be thrown.
-
- @param path
-                the path for the node
- @param data
-                the initial data for the node
- @param acl
-                the acl for the node
- @param flags
-                specifying whether the node to be created is ephemeral
-                and/or sequential
- @return the actual path of the created node
- @throws KeeperException if the server returns a non-zero error code
- @throws org.apache.zookeeper.KeeperException.InvalidACLException if the ACL is invalid
- @throws InterruptedException if the transaction is interrupted
- @throws IllegalArgumentException if an invalid path is specified]]>
-      </doc>
-    </method>
-    <method name="validatePath"
-      abstract="false" native="false" synchronized="false"
-      static="true" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="path" type="java.lang.String"/>
-      <exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"/>
-      <doc>
-      <![CDATA[Validate the provided znode path string
- @param path znode path string
- @throws IllegalArgumentException if the path is invalid]]>
-      </doc>
-    </method>
-    <method name="create"
-      abstract="false" native="false" synchronized="false"
-      static="false" final="false" visibility="public"
-      deprecated="not deprecated">
-      <param name="path" type="java.lang.String"/>
-      <param name="data" type="byte[]"/>
-      <param name="acl" type="java.util.List"/>
-      <param name="createMode" type="org.apache.zookeeper.CreateMode"/>
-      <param name="cb" type="org.apache.zookeeper.AsyncCallback.StringCallback"/>
-      <param name="ctx" type="java.lang.Object"/>
-      <doc>
-      <![CDATA[The Asynchronous version of create. The request doesn't actually until
- the asynchronous callback is called.
-
- @see #create(String, byte[], List<ACL>, CreateMode)]]>
-      </doc>
-  

<TRUNCATED>

[32/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeper.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeper.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeper.java
deleted file mode 100644
index 3e46ee7..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ZooKeeper.java
+++ /dev/null
@@ -1,1857 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.apache.zookeeper.AsyncCallback.*;
-import org.apache.zookeeper.OpResult.ErrorResult;
-import org.apache.zookeeper.client.ConnectStringParser;
-import org.apache.zookeeper.client.HostProvider;
-import org.apache.zookeeper.client.StaticHostProvider;
-import org.apache.zookeeper.client.ZooKeeperSaslClient;
-import org.apache.zookeeper.common.PathUtils;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.proto.*;
-import org.apache.zookeeper.server.DataTree;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.util.*;
-
-/**
- * This is the main class of ZooKeeper client library. To use a ZooKeeper
- * service, an application must first instantiate an object of ZooKeeper class.
- * All the iterations will be done by calling the methods of ZooKeeper class.
- * The methods of this class are thread-safe unless otherwise noted.
- * <p>
- * Once a connection to a server is established, a session ID is assigned to the
- * client. The client will send heart beats to the server periodically to keep
- * the session valid.
- * <p>
- * The application can call ZooKeeper APIs through a client as long as the
- * session ID of the client remains valid.
- * <p>
- * If for some reason, the client fails to send heart beats to the server for a
- * prolonged period of time (exceeding the sessionTimeout value, for instance),
- * the server will expire the session, and the session ID will become invalid.
- * The client object will no longer be usable. To make ZooKeeper API calls, the
- * application must create a new client object.
- * <p>
- * If the ZooKeeper server the client currently connects to fails or otherwise
- * does not respond, the client will automatically try to connect to another
- * server before its session ID expires. If successful, the application can
- * continue to use the client.
- * <p>
- * The ZooKeeper API methods are either synchronous or asynchronous. Synchronous
- * methods blocks until the server has responded. Asynchronous methods just queue
- * the request for sending and return immediately. They take a callback object that
- * will be executed either on successful execution of the request or on error with
- * an appropriate return code (rc) indicating the error.
- * <p>
- * Some successful ZooKeeper API calls can leave watches on the "data nodes" in
- * the ZooKeeper server. Other successful ZooKeeper API calls can trigger those
- * watches. Once a watch is triggered, an event will be delivered to the client
- * which left the watch at the first place. Each watch can be triggered only
- * once. Thus, up to one event will be delivered to a client for every watch it
- * leaves.
- * <p>
- * A client needs an object of a class implementing Watcher interface for
- * processing the events delivered to the client.
- *
- * When a client drops the current connection and re-connects to a server, all the
- * existing watches are considered as being triggered but the undelivered events
- * are lost. To emulate this, the client will generate a special event to tell
- * the event handler a connection has been dropped. This special event has
- * EventType None and KeeperState Disconnected.
- *
- */
-@InterfaceAudience.Public
-public class ZooKeeper {
-
-    public static final String ZOOKEEPER_CLIENT_CNXN_SOCKET = "zookeeper.clientCnxnSocket";
-
-    protected final ClientCnxn cnxn;
-    private static final Logger LOG;
-    static {
-        //Keep these two lines together to keep the initialization order explicit
-        LOG = LoggerFactory.getLogger(ZooKeeper.class);
-        Environment.logEnv("Client environment:", LOG);
-    }
-
-
-    public ZooKeeperSaslClient getSaslClient() {
-        return cnxn.zooKeeperSaslClient;
-    }
-
-    private final ZKWatchManager watchManager = new ZKWatchManager();
-
-    List<String> getDataWatches() {
-        synchronized(watchManager.dataWatches) {
-            List<String> rc = new ArrayList<String>(watchManager.dataWatches.keySet());
-            return rc;
-        }
-    }
-    List<String> getExistWatches() {
-        synchronized(watchManager.existWatches) {
-            List<String> rc =  new ArrayList<String>(watchManager.existWatches.keySet());
-            return rc;
-        }
-    }
-    List<String> getChildWatches() {
-        synchronized(watchManager.childWatches) {
-            List<String> rc = new ArrayList<String>(watchManager.childWatches.keySet());
-            return rc;
-        }
-    }
-
-    /**
-     * Manage watchers & handle events generated by the ClientCnxn object.
-     *
-     * We are implementing this as a nested class of ZooKeeper so that
-     * the public methods will not be exposed as part of the ZooKeeper client
-     * API.
-     */
-    private static class ZKWatchManager implements ClientWatchManager {
-        private final Map<String, Set<Watcher>> dataWatches =
-            new HashMap<String, Set<Watcher>>();
-        private final Map<String, Set<Watcher>> existWatches =
-            new HashMap<String, Set<Watcher>>();
-        private final Map<String, Set<Watcher>> childWatches =
-            new HashMap<String, Set<Watcher>>();
-
-        private volatile Watcher defaultWatcher;
-
-        final private void addTo(Set<Watcher> from, Set<Watcher> to) {
-            if (from != null) {
-                to.addAll(from);
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see org.apache.zookeeper.ClientWatchManager#materialize(Event.KeeperState, 
-         *                                                        Event.EventType, java.lang.String)
-         */
-        @Override
-        public Set<Watcher> materialize(Watcher.Event.KeeperState state,
-                                        Watcher.Event.EventType type,
-                                        String clientPath)
-        {
-            Set<Watcher> result = new HashSet<Watcher>();
-
-            switch (type) {
-            case None:
-                result.add(defaultWatcher);
-                boolean clear = ClientCnxn.getDisableAutoResetWatch() &&
-                        state != Watcher.Event.KeeperState.SyncConnected;
-
-                synchronized(dataWatches) {
-                    for(Set<Watcher> ws: dataWatches.values()) {
-                        result.addAll(ws);
-                    }
-                    if (clear) {
-                        dataWatches.clear();
-                    }
-                }
-
-                synchronized(existWatches) {
-                    for(Set<Watcher> ws: existWatches.values()) {
-                        result.addAll(ws);
-                    }
-                    if (clear) {
-                        existWatches.clear();
-                    }
-                }
-
-                synchronized(childWatches) {
-                    for(Set<Watcher> ws: childWatches.values()) {
-                        result.addAll(ws);
-                    }
-                    if (clear) {
-                        childWatches.clear();
-                    }
-                }
-
-                return result;
-            case NodeDataChanged:
-            case NodeCreated:
-                synchronized (dataWatches) {
-                    addTo(dataWatches.remove(clientPath), result);
-                }
-                synchronized (existWatches) {
-                    addTo(existWatches.remove(clientPath), result);
-                }
-                break;
-            case NodeChildrenChanged:
-                synchronized (childWatches) {
-                    addTo(childWatches.remove(clientPath), result);
-                }
-                break;
-            case NodeDeleted:
-                synchronized (dataWatches) {
-                    addTo(dataWatches.remove(clientPath), result);
-                }
-                // XXX This shouldn't be needed, but just in case
-                synchronized (existWatches) {
-                    Set<Watcher> list = existWatches.remove(clientPath);
-                    if (list != null) {
-                        addTo(list, result);
-                        LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!");
-                    }
-                }
-                synchronized (childWatches) {
-                    addTo(childWatches.remove(clientPath), result);
-                }
-                break;
-            default:
-                String msg = "Unhandled watch event type " + type
-                    + " with state " + state + " on path " + clientPath;
-                LOG.error(msg);
-                throw new RuntimeException(msg);
-            }
-
-            return result;
-        }
-    }
-
-    /**
-     * Register a watcher for a particular path.
-     */
-    abstract class WatchRegistration {
-        private Watcher watcher;
-        private String clientPath;
-        public WatchRegistration(Watcher watcher, String clientPath)
-        {
-            this.watcher = watcher;
-            this.clientPath = clientPath;
-        }
-
-        abstract protected Map<String, Set<Watcher>> getWatches(int rc);
-
-        /**
-         * Register the watcher with the set of watches on path.
-         * @param rc the result code of the operation that attempted to
-         * add the watch on the path.
-         */
-        public void register(int rc) {
-            if (shouldAddWatch(rc)) {
-                Map<String, Set<Watcher>> watches = getWatches(rc);
-                synchronized(watches) {
-                    Set<Watcher> watchers = watches.get(clientPath);
-                    if (watchers == null) {
-                        watchers = new HashSet<Watcher>();
-                        watches.put(clientPath, watchers);
-                    }
-                    watchers.add(watcher);
-                }
-            }
-        }
-        /**
-         * Determine whether the watch should be added based on return code.
-         * @param rc the result code of the operation that attempted to add the
-         * watch on the node
-         * @return true if the watch should be added, otw false
-         */
-        protected boolean shouldAddWatch(int rc) {
-            return rc == 0;
-        }
-    }
-
-    /** Handle the special case of exists watches - they add a watcher
-     * even in the case where NONODE result code is returned.
-     */
-    class ExistsWatchRegistration extends WatchRegistration {
-        public ExistsWatchRegistration(Watcher watcher, String clientPath) {
-            super(watcher, clientPath);
-        }
-
-        @Override
-        protected Map<String, Set<Watcher>> getWatches(int rc) {
-            return rc == 0 ?  watchManager.dataWatches : watchManager.existWatches;
-        }
-
-        @Override
-        protected boolean shouldAddWatch(int rc) {
-            return rc == 0 || rc == KeeperException.Code.NONODE.intValue();
-        }
-    }
-
-    class DataWatchRegistration extends WatchRegistration {
-        public DataWatchRegistration(Watcher watcher, String clientPath) {
-            super(watcher, clientPath);
-        }
-
-        @Override
-        protected Map<String, Set<Watcher>> getWatches(int rc) {
-            return watchManager.dataWatches;
-        }
-    }
-
-    class ChildWatchRegistration extends WatchRegistration {
-        public ChildWatchRegistration(Watcher watcher, String clientPath) {
-            super(watcher, clientPath);
-        }
-
-        @Override
-        protected Map<String, Set<Watcher>> getWatches(int rc) {
-            return watchManager.childWatches;
-        }
-    }
-
-    @InterfaceAudience.Public
-    public enum States {
-        CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY,
-        CLOSED, AUTH_FAILED, NOT_CONNECTED;
-
-        public boolean isAlive() {
-            return this != CLOSED && this != AUTH_FAILED;
-        }
-
-        /**
-         * Returns whether we are connected to a server (which
-         * could possibly be read-only, if this client is allowed
-         * to go to read-only mode)
-         * */
-        public boolean isConnected() {
-            return this == CONNECTED || this == CONNECTEDREADONLY;
-        }
-    }
-
-    /**
-     * To create a ZooKeeper client object, the application needs to pass a
-     * connection string containing a comma separated list of host:port pairs,
-     * each corresponding to a ZooKeeper server.
-     * <p>
-     * Session establishment is asynchronous. This constructor will initiate
-     * connection to the server and return immediately - potentially (usually)
-     * before the session is fully established. The watcher argument specifies
-     * the watcher that will be notified of any changes in state. This
-     * notification can come at any point before or after the constructor call
-     * has returned.
-     * <p>
-     * The instantiated ZooKeeper client object will pick an arbitrary server
-     * from the connectString and attempt to connect to it. If establishment of
-     * the connection fails, another server in the connect string will be tried
-     * (the order is non-deterministic, as we random shuffle the list), until a
-     * connection is established. The client will continue attempts until the
-     * session is explicitly closed.
-     * <p>
-     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
-     * connection string. This will run the client commands while interpreting
-     * all paths relative to this root (similar to the unix chroot command).
-     *
-     * @param connectString
-     *            comma separated host:port pairs, each corresponding to a zk
-     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If
-     *            the optional chroot suffix is used the example would look
-     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
-     *            where the client would be rooted at "/app/a" and all paths
-     *            would be relative to this root - ie getting/setting/etc...
-     *            "/foo/bar" would result in operations being run on
-     *            "/app/a/foo/bar" (from the server perspective).
-     * @param sessionTimeout
-     *            session timeout in milliseconds
-     * @param watcher
-     *            a watcher object which will be notified of state changes, may
-     *            also be notified for node events
-     *
-     * @throws IOException
-     *             in cases of network failure
-     * @throws IllegalArgumentException
-     *             if an invalid chroot path is specified
-     */
-    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
-        throws IOException
-    {
-        this(connectString, sessionTimeout, watcher, false);
-    }
-
-    /**
-     * To create a ZooKeeper client object, the application needs to pass a
-     * connection string containing a comma separated list of host:port pairs,
-     * each corresponding to a ZooKeeper server.
-     * <p>
-     * Session establishment is asynchronous. This constructor will initiate
-     * connection to the server and return immediately - potentially (usually)
-     * before the session is fully established. The watcher argument specifies
-     * the watcher that will be notified of any changes in state. This
-     * notification can come at any point before or after the constructor call
-     * has returned.
-     * <p>
-     * The instantiated ZooKeeper client object will pick an arbitrary server
-     * from the connectString and attempt to connect to it. If establishment of
-     * the connection fails, another server in the connect string will be tried
-     * (the order is non-deterministic, as we random shuffle the list), until a
-     * connection is established. The client will continue attempts until the
-     * session is explicitly closed.
-     * <p>
-     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
-     * connection string. This will run the client commands while interpreting
-     * all paths relative to this root (similar to the unix chroot command).
-     *
-     * @param connectString
-     *            comma separated host:port pairs, each corresponding to a zk
-     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If
-     *            the optional chroot suffix is used the example would look
-     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
-     *            where the client would be rooted at "/app/a" and all paths
-     *            would be relative to this root - ie getting/setting/etc...
-     *            "/foo/bar" would result in operations being run on
-     *            "/app/a/foo/bar" (from the server perspective).
-     * @param sessionTimeout
-     *            session timeout in milliseconds
-     * @param watcher
-     *            a watcher object which will be notified of state changes, may
-     *            also be notified for node events
-     * @param canBeReadOnly
-     *            (added in 3.4) whether the created client is allowed to go to
-     *            read-only mode in case of partitioning. Read-only mode
-     *            basically means that if the client can't find any majority
-     *            servers but there's partitioned server it could reach, it
-     *            connects to one in read-only mode, i.e. read requests are
-     *            allowed while write requests are not. It continues seeking for
-     *            majority in the background.
-     *
-     * @throws IOException
-     *             in cases of network failure
-     * @throws IllegalArgumentException
-     *             if an invalid chroot path is specified
-     */
-    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
-            boolean canBeReadOnly)
-        throws IOException
-    {
-        LOG.info("Initiating client connection, connectString=" + connectString
-                + " sessionTimeout=" + sessionTimeout + " watcher=" + watcher);
-
-        watchManager.defaultWatcher = watcher;
-
-        ConnectStringParser connectStringParser = new ConnectStringParser(
-                connectString);
-        HostProvider hostProvider = new StaticHostProvider(
-                connectStringParser.getServerAddresses());
-        cnxn = new ClientCnxn(connectStringParser.getChrootPath(),
-                hostProvider, sessionTimeout, this, watchManager,
-                getClientCnxnSocket(), canBeReadOnly);
-        cnxn.start();
-    }
-
-    /**
-     * To create a ZooKeeper client object, the application needs to pass a
-     * connection string containing a comma separated list of host:port pairs,
-     * each corresponding to a ZooKeeper server.
-     * <p>
-     * Session establishment is asynchronous. This constructor will initiate
-     * connection to the server and return immediately - potentially (usually)
-     * before the session is fully established. The watcher argument specifies
-     * the watcher that will be notified of any changes in state. This
-     * notification can come at any point before or after the constructor call
-     * has returned.
-     * <p>
-     * The instantiated ZooKeeper client object will pick an arbitrary server
-     * from the connectString and attempt to connect to it. If establishment of
-     * the connection fails, another server in the connect string will be tried
-     * (the order is non-deterministic, as we random shuffle the list), until a
-     * connection is established. The client will continue attempts until the
-     * session is explicitly closed (or the session is expired by the server).
-     * <p>
-     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
-     * connection string. This will run the client commands while interpreting
-     * all paths relative to this root (similar to the unix chroot command).
-     * <p>
-     * Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
-     * client connection, these values must be passed as sessionId and
-     * sessionPasswd respectively if reconnecting. Otherwise, if not
-     * reconnecting, use the other constructor which does not require these
-     * parameters.
-     *
-     * @param connectString
-     *            comma separated host:port pairs, each corresponding to a zk
-     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
-     *            If the optional chroot suffix is used the example would look
-     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
-     *            where the client would be rooted at "/app/a" and all paths
-     *            would be relative to this root - ie getting/setting/etc...
-     *            "/foo/bar" would result in operations being run on
-     *            "/app/a/foo/bar" (from the server perspective).
-     * @param sessionTimeout
-     *            session timeout in milliseconds
-     * @param watcher
-     *            a watcher object which will be notified of state changes, may
-     *            also be notified for node events
-     * @param sessionId
-     *            specific session id to use if reconnecting
-     * @param sessionPasswd
-     *            password for this session
-     *
-     * @throws IOException in cases of network failure
-     * @throws IllegalArgumentException if an invalid chroot path is specified
-     * @throws IllegalArgumentException for an invalid list of ZooKeeper hosts
-     */
-    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
-            long sessionId, byte[] sessionPasswd)
-        throws IOException
-    {
-        this(connectString, sessionTimeout, watcher, sessionId, sessionPasswd, false);
-    }
-
-    /**
-     * To create a ZooKeeper client object, the application needs to pass a
-     * connection string containing a comma separated list of host:port pairs,
-     * each corresponding to a ZooKeeper server.
-     * <p>
-     * Session establishment is asynchronous. This constructor will initiate
-     * connection to the server and return immediately - potentially (usually)
-     * before the session is fully established. The watcher argument specifies
-     * the watcher that will be notified of any changes in state. This
-     * notification can come at any point before or after the constructor call
-     * has returned.
-     * <p>
-     * The instantiated ZooKeeper client object will pick an arbitrary server
-     * from the connectString and attempt to connect to it. If establishment of
-     * the connection fails, another server in the connect string will be tried
-     * (the order is non-deterministic, as we random shuffle the list), until a
-     * connection is established. The client will continue attempts until the
-     * session is explicitly closed (or the session is expired by the server).
-     * <p>
-     * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
-     * connection string. This will run the client commands while interpreting
-     * all paths relative to this root (similar to the unix chroot command).
-     * <p>
-     * Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
-     * client connection, these values must be passed as sessionId and
-     * sessionPasswd respectively if reconnecting. Otherwise, if not
-     * reconnecting, use the other constructor which does not require these
-     * parameters.
-     *
-     * @param connectString
-     *            comma separated host:port pairs, each corresponding to a zk
-     *            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
-     *            If the optional chroot suffix is used the example would look
-     *            like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
-     *            where the client would be rooted at "/app/a" and all paths
-     *            would be relative to this root - ie getting/setting/etc...
-     *            "/foo/bar" would result in operations being run on
-     *            "/app/a/foo/bar" (from the server perspective).
-     * @param sessionTimeout
-     *            session timeout in milliseconds
-     * @param watcher
-     *            a watcher object which will be notified of state changes, may
-     *            also be notified for node events
-     * @param sessionId
-     *            specific session id to use if reconnecting
-     * @param sessionPasswd
-     *            password for this session
-     * @param canBeReadOnly
-     *            (added in 3.4) whether the created client is allowed to go to
-     *            read-only mode in case of partitioning. Read-only mode
-     *            basically means that if the client can't find any majority
-     *            servers but there's partitioned server it could reach, it
-     *            connects to one in read-only mode, i.e. read requests are
-     *            allowed while write requests are not. It continues seeking for
-     *            majority in the background.
-     *
-     * @throws IOException in cases of network failure
-     * @throws IllegalArgumentException if an invalid chroot path is specified
-     */
-    public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
-            long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
-        throws IOException
-    {
-        LOG.info("Initiating client connection, connectString=" + connectString
-                + " sessionTimeout=" + sessionTimeout
-                + " watcher=" + watcher
-                + " sessionId=" + Long.toHexString(sessionId)
-                + " sessionPasswd="
-                + (sessionPasswd == null ? "<null>" : "<hidden>"));
-
-        watchManager.defaultWatcher = watcher;
-
-        ConnectStringParser connectStringParser = new ConnectStringParser(
-                connectString);
-        HostProvider hostProvider = new StaticHostProvider(
-                connectStringParser.getServerAddresses());
-        cnxn = new ClientCnxn(connectStringParser.getChrootPath(),
-                hostProvider, sessionTimeout, this, watchManager,
-                getClientCnxnSocket(), sessionId, sessionPasswd, canBeReadOnly);
-        cnxn.seenRwServerBefore = true; // since user has provided sessionId
-        cnxn.start();
-    }
-
-    // VisibleForTesting
-    public Testable getTestable() {
-        return new ZooKeeperTestable(this, cnxn);
-    }
-
-    /**
-     * The session id for this ZooKeeper client instance. The value returned is
-     * not valid until the client connects to a server and may change after a
-     * re-connect.
-     *
-     * This method is NOT thread safe
-     *
-     * @return current session id
-     */
-    public long getSessionId() {
-        return cnxn.getSessionId();
-    }
-
-    /**
-     * The session password for this ZooKeeper client instance. The value
-     * returned is not valid until the client connects to a server and may
-     * change after a re-connect.
-     *
-     * This method is NOT thread safe
-     *
-     * @return current session password
-     */
-    public byte[] getSessionPasswd() {
-        return cnxn.getSessionPasswd();
-    }
-
-    /**
-     * The negotiated session timeout for this ZooKeeper client instance. The
-     * value returned is not valid until the client connects to a server and
-     * may change after a re-connect.
-     *
-     * This method is NOT thread safe
-     *
-     * @return current session timeout
-     */
-    public int getSessionTimeout() {
-        return cnxn.getSessionTimeout();
-    }
-
-    /**
-     * Add the specified scheme:auth information to this connection.
-     *
-     * This method is NOT thread safe
-     *
-     * @param scheme
-     * @param auth
-     */
-    public void addAuthInfo(String scheme, byte auth[]) {
-        cnxn.addAuthInfo(scheme, auth);
-    }
-
-    /**
-     * Specify the default watcher for the connection (overrides the one
-     * specified during construction).
-     *
-     * @param watcher
-     */
-    public synchronized void register(Watcher watcher) {
-        watchManager.defaultWatcher = watcher;
-    }
-
-    /**
-     * Close this client object. Once the client is closed, its session becomes
-     * invalid. All the ephemeral nodes in the ZooKeeper server associated with
-     * the session will be removed. The watches left on those nodes (and on
-     * their parents) will be triggered.
-     *
-     * @throws InterruptedException
-     */
-    public synchronized void close() throws InterruptedException {
-        if (!cnxn.getState().isAlive()) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Close called on already closed client");
-            }
-            return;
-        }
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Closing session: 0x" + Long.toHexString(getSessionId()));
-        }
-
-        try {
-            cnxn.close();
-        } catch (IOException e) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Ignoring unexpected exception during close", e);
-            }
-        }
-
-        LOG.info("Session: 0x" + Long.toHexString(getSessionId()) + " closed");
-    }
-
-    /**
-     * Prepend the chroot to the client path (if present). The expectation of
-     * this function is that the client path has been validated before this
-     * function is called
-     * @param clientPath path to the node
-     * @return server view of the path (chroot prepended to client path)
-     */
-    private String prependChroot(String clientPath) {
-        if (cnxn.chrootPath != null) {
-            // handle clientPath = "/"
-            if (clientPath.length() == 1) {
-                return cnxn.chrootPath;
-            }
-            return cnxn.chrootPath + clientPath;
-        } else {
-            return clientPath;
-        }
-    }
-
-    /**
-     * Create a node with the given path. The node data will be the given data,
-     * and node acl will be the given acl.
-     * <p>
-     * The flags argument specifies whether the created node will be ephemeral
-     * or not.
-     * <p>
-     * An ephemeral node will be removed by the ZooKeeper automatically when the
-     * session associated with the creation of the node expires.
-     * <p>
-     * The flags argument can also specify to create a sequential node. The
-     * actual path name of a sequential node will be the given path plus a
-     * suffix "i" where i is the current sequential number of the node. The sequence
-     * number is always fixed length of 10 digits, 0 padded. Once
-     * such a node is created, the sequential number will be incremented by one.
-     * <p>
-     * If a node with the same actual path already exists in the ZooKeeper, a
-     * KeeperException with error code KeeperException.NodeExists will be
-     * thrown. Note that since a different actual path is used for each
-     * invocation of creating sequential node with the same path argument, the
-     * call will never throw "file exists" KeeperException.
-     * <p>
-     * If the parent node does not exist in the ZooKeeper, a KeeperException
-     * with error code KeeperException.NoNode will be thrown.
-     * <p>
-     * An ephemeral node cannot have children. If the parent node of the given
-     * path is ephemeral, a KeeperException with error code
-     * KeeperException.NoChildrenForEphemerals will be thrown.
-     * <p>
-     * This operation, if successful, will trigger all the watches left on the
-     * node of the given path by exists and getData API calls, and the watches
-     * left on the parent node by getChildren API calls.
-     * <p>
-     * If a node is created successfully, the ZooKeeper server will trigger the
-     * watches on the path left by exists calls, and the watches on the parent
-     * of the node by getChildren calls.
-     * <p>
-     * The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
-     * Arrays larger than this will cause a KeeperExecption to be thrown.
-     *
-     * @param path
-     *                the path for the node
-     * @param data
-     *                the initial data for the node
-     * @param acl
-     *                the acl for the node
-     * @param createMode
-     *                specifying whether the node to be created is ephemeral
-     *                and/or sequential
-     * @return the actual path of the created node
-     * @throws KeeperException if the server returns a non-zero error code
-     * @throws KeeperException.InvalidACLException if the ACL is invalid, null, or empty
-     * @throws InterruptedException if the transaction is interrupted
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public String create(final String path, byte data[], List<ACL> acl,
-            CreateMode createMode)
-        throws KeeperException, InterruptedException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath, createMode.isSequential());
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.create);
-        CreateRequest request = new CreateRequest();
-        CreateResponse response = new CreateResponse();
-        request.setData(data);
-        request.setFlags(createMode.toFlag());
-        request.setPath(serverPath);
-        if (acl != null && acl.size() == 0) {
-            throw new KeeperException.InvalidACLException();
-        }
-        request.setAcl(acl);
-        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-        if (cnxn.chrootPath == null) {
-            return response.getPath();
-        } else {
-            return response.getPath().substring(cnxn.chrootPath.length());
-        }
-    }
-
-    /**
-     * The asynchronous version of create.
-     *
-     * @see #create(String, byte[], List, CreateMode)
-     */
-
-    public void create(final String path, byte data[], List<ACL> acl,
-            CreateMode createMode,  StringCallback cb, Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath, createMode.isSequential());
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.create);
-        CreateRequest request = new CreateRequest();
-        CreateResponse response = new CreateResponse();
-        ReplyHeader r = new ReplyHeader();
-        request.setData(data);
-        request.setFlags(createMode.toFlag());
-        request.setPath(serverPath);
-        request.setAcl(acl);
-        cnxn.queuePacket(h, r, request, response, cb, clientPath,
-                serverPath, ctx, null);
-    }
-
-    /**
-     * Delete the node with the given path. The call will succeed if such a node
-     * exists, and the given version matches the node's version (if the given
-     * version is -1, it matches any node's versions).
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if the nodes does not exist.
-     * <p>
-     * A KeeperException with error code KeeperException.BadVersion will be
-     * thrown if the given version does not match the node's version.
-     * <p>
-     * A KeeperException with error code KeeperException.NotEmpty will be thrown
-     * if the node has children.
-     * <p>
-     * This operation, if successful, will trigger all the watches on the node
-     * of the given path left by exists API calls, and the watches on the parent
-     * node left by getChildren API calls.
-     *
-     * @param path
-     *                the path of the node to be deleted.
-     * @param version
-     *                the expected node version.
-     * @throws InterruptedException IF the server transaction is interrupted
-     * @throws KeeperException If the server signals an error with a non-zero
-     *   return code.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public void delete(final String path, int version)
-        throws InterruptedException, KeeperException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath;
-
-        // maintain semantics even in chroot case
-        // specifically - root cannot be deleted
-        // I think this makes sense even in chroot case.
-        if (clientPath.equals("/")) {
-            // a bit of a hack, but delete(/) will never succeed and ensures
-            // that the same semantics are maintained
-            serverPath = clientPath;
-        } else {
-            serverPath = prependChroot(clientPath);
-        }
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.delete);
-        DeleteRequest request = new DeleteRequest();
-        request.setPath(serverPath);
-        request.setVersion(version);
-        ReplyHeader r = cnxn.submitRequest(h, request, null, null);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-    }
-
-    /**
-     * Executes multiple ZooKeeper operations or none of them.
-     * <p>
-     * On success, a list of results is returned.
-     * On failure, an exception is raised which contains partial results and
-     * error details, see {@link KeeperException#getResults}
-     * <p>
-     * Note: The maximum allowable size of all of the data arrays in all of
-     * the setData operations in this single request is typically 1 MB
-     * (1,048,576 bytes). This limit is specified on the server via
-     * <a href="http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#Unsafe+Options">jute.maxbuffer</a>.
-     * Requests larger than this will cause a KeeperException to be
-     * thrown.
-     *
-     * @param ops An iterable that contains the operations to be done.
-     * These should be created using the factory methods on {@link Op}.
-     * @return A list of results, one for each input Op, the order of
-     * which exactly matches the order of the <code>ops</code> input
-     * operations.
-     * @throws InterruptedException If the operation was interrupted.
-     * The operation may or may not have succeeded, but will not have
-     * partially succeeded if this exception is thrown.
-     * @throws KeeperException If the operation could not be completed
-     * due to some error in doing one of the specified ops.
-     * @throws IllegalArgumentException if an invalid path is specified
-     *
-     * @since 3.4.0
-     */
-    public List<OpResult> multi(Iterable<Op> ops) throws InterruptedException, KeeperException {
-        for (Op op : ops) {
-            op.validate();
-        }
-        return multiInternal(generateMultiTransaction(ops));
-    }
-
-    /**
-     * The asynchronous version of multi.
-     *
-     * @see #multi(Iterable)
-     * @since 3.4.7
-     */
-    public void multi(Iterable<Op> ops, MultiCallback cb, Object ctx) {
-        List<OpResult> results = validatePath(ops);
-        if (results.size() > 0) {
-            cb.processResult(KeeperException.Code.BADARGUMENTS.intValue(),
-                             null, ctx, results);
-            return;
-        }
-        multiInternal(generateMultiTransaction(ops), cb, ctx);
-    }
-
-    private List<OpResult> validatePath(Iterable<Op> ops) {
-        List<OpResult> results = new ArrayList<OpResult>();
-        boolean error = false;
-        for (Op op : ops) {
-            try {
-                op.validate();
-            } catch (IllegalArgumentException iae) {
-                LOG.error("IllegalArgumentException: " + iae.getMessage());
-                ErrorResult err = new ErrorResult(
-                        KeeperException.Code.BADARGUMENTS.intValue());
-                results.add(err);
-                error = true;
-                continue;
-            } catch (KeeperException ke) {
-                LOG.error("KeeperException: " + ke.getMessage());
-                ErrorResult err = new ErrorResult(ke.code().intValue());
-                results.add(err);
-                error = true;
-                continue;
-            }
-            ErrorResult err = new ErrorResult(
-                    KeeperException.Code.RUNTIMEINCONSISTENCY.intValue());
-            results.add(err);
-        }
-        if (false == error) {
-            results.clear();
-        }
-        return results;
-    }
-
-    private MultiTransactionRecord generateMultiTransaction(Iterable<Op> ops) {
-        List<Op> transaction = new ArrayList<Op>();
-
-        for (Op op : ops) {
-            transaction.add(withRootPrefix(op));
-        }
-        return new MultiTransactionRecord(transaction);
-    }
-
-    private Op withRootPrefix(Op op) {
-        if (null != op.getPath()) {
-            final String serverPath = prependChroot(op.getPath());
-            if (!op.getPath().equals(serverPath)) {
-                return op.withChroot(serverPath);
-            }
-        }
-        return op;
-    }
-
-    protected void multiInternal(MultiTransactionRecord request, MultiCallback cb, Object ctx) {
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.multi);
-        MultiResponse response = new MultiResponse();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, null, null, ctx, null);
-    }
-
-    protected List<OpResult> multiInternal(MultiTransactionRecord request)
-        throws InterruptedException, KeeperException {
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.multi);
-        MultiResponse response = new MultiResponse();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()));
-        }
-
-        List<OpResult> results = response.getResultList();
-        
-        ErrorResult fatalError = null;
-        for (OpResult result : results) {
-            if (result instanceof ErrorResult && ((ErrorResult)result).getErr() != KeeperException.Code.OK.intValue()) {
-                fatalError = (ErrorResult) result;
-                break;
-            }
-        }
-
-        if (fatalError != null) {
-            KeeperException ex = KeeperException.create(KeeperException.Code.get(fatalError.getErr()));
-            ex.setMultiResults(results);
-            throw ex;
-        }
-
-        return results;
-    }
-
-    /**
-     * A Transaction is a thin wrapper on the {@link #multi} method
-     * which provides a builder object that can be used to construct
-     * and commit an atomic set of operations.
-     *
-     * @since 3.4.0
-     *
-     * @return a Transaction builder object
-     */
-    public Transaction transaction() {
-        return new Transaction(this);
-    }
-
-    /**
-     * The asynchronous version of delete.
-     *
-     * @see #delete(String, int)
-     */
-    public void delete(final String path, int version, VoidCallback cb,
-            Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath;
-
-        // maintain semantics even in chroot case
-        // specifically - root cannot be deleted
-        // I think this makes sense even in chroot case.
-        if (clientPath.equals("/")) {
-            // a bit of a hack, but delete(/) will never succeed and ensures
-            // that the same semantics are maintained
-            serverPath = clientPath;
-        } else {
-            serverPath = prependChroot(clientPath);
-        }
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.delete);
-        DeleteRequest request = new DeleteRequest();
-        request.setPath(serverPath);
-        request.setVersion(version);
-        cnxn.queuePacket(h, new ReplyHeader(), request, null, cb, clientPath,
-                serverPath, ctx, null);
-    }
-
-    /**
-     * Return the stat of the node of the given path. Return null if no such a
-     * node exists.
-     * <p>
-     * If the watch is non-null and the call is successful (no exception is thrown),
-     * a watch will be left on the node with the given path. The watch will be
-     * triggered by a successful operation that creates/delete the node or sets
-     * the data on the node.
-     *
-     * @param path the node path
-     * @param watcher explicit watcher
-     * @return the stat of the node of the given path; return null if no such a
-     *         node exists.
-     * @throws KeeperException If the server signals an error
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public Stat exists(final String path, Watcher watcher)
-        throws KeeperException, InterruptedException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new ExistsWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.exists);
-        ExistsRequest request = new ExistsRequest();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        SetDataResponse response = new SetDataResponse();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
-        if (r.getErr() != 0) {
-            if (r.getErr() == KeeperException.Code.NONODE.intValue()) {
-                return null;
-            }
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-
-        return response.getStat().getCzxid() == -1 ? null : response.getStat();
-    }
-
-    /**
-     * Return the stat of the node of the given path. Return null if no such a
-     * node exists.
-     * <p>
-     * If the watch is true and the call is successful (no exception is thrown),
-     * a watch will be left on the node with the given path. The watch will be
-     * triggered by a successful operation that creates/delete the node or sets
-     * the data on the node.
-     *
-     * @param path
-     *                the node path
-     * @param watch
-     *                whether need to watch this node
-     * @return the stat of the node of the given path; return null if no such a
-     *         node exists.
-     * @throws KeeperException If the server signals an error
-     * @throws InterruptedException If the server transaction is interrupted.
-     */
-    public Stat exists(String path, boolean watch) throws KeeperException,
-        InterruptedException
-    {
-        return exists(path, watch ? watchManager.defaultWatcher : null);
-    }
-
-    /**
-     * The asynchronous version of exists.
-     *
-     * @see #exists(String, Watcher)
-     */
-    public void exists(final String path, Watcher watcher,
-            StatCallback cb, Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new ExistsWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.exists);
-        ExistsRequest request = new ExistsRequest();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        SetDataResponse response = new SetDataResponse();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, wcb);
-    }
-
-    /**
-     * The asynchronous version of exists.
-     *
-     * @see #exists(String, boolean)
-     */
-    public void exists(String path, boolean watch, StatCallback cb, Object ctx) {
-        exists(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
-    }
-
-    /**
-     * Return the data and the stat of the node of the given path.
-     * <p>
-     * If the watch is non-null and the call is successful (no exception is
-     * thrown), a watch will be left on the node with the given path. The watch
-     * will be triggered by a successful operation that sets data on the node, or
-     * deletes the node.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     *
-     * @param path the given path
-     * @param watcher explicit watcher
-     * @param stat the stat of the node
-     * @return the data of the node
-     * @throws KeeperException If the server signals an error with a non-zero error code
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public byte[] getData(final String path, Watcher watcher, Stat stat)
-        throws KeeperException, InterruptedException
-     {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new DataWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getData);
-        GetDataRequest request = new GetDataRequest();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        GetDataResponse response = new GetDataResponse();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-        if (stat != null) {
-            DataTree.copyStat(response.getStat(), stat);
-        }
-        return response.getData();
-    }
-
-    /**
-     * Return the data and the stat of the node of the given path.
-     * <p>
-     * If the watch is true and the call is successful (no exception is
-     * thrown), a watch will be left on the node with the given path. The watch
-     * will be triggered by a successful operation that sets data on the node, or
-     * deletes the node.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     *
-     * @param path the given path
-     * @param watch whether need to watch this node
-     * @param stat the stat of the node
-     * @return the data of the node
-     * @throws KeeperException If the server signals an error with a non-zero error code
-     * @throws InterruptedException If the server transaction is interrupted.
-     */
-    public byte[] getData(String path, boolean watch, Stat stat)
-            throws KeeperException, InterruptedException {
-        return getData(path, watch ? watchManager.defaultWatcher : null, stat);
-    }
-
-    /**
-     * The asynchronous version of getData.
-     *
-     * @see #getData(String, Watcher, Stat)
-     */
-    public void getData(final String path, Watcher watcher,
-            DataCallback cb, Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new DataWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getData);
-        GetDataRequest request = new GetDataRequest();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        GetDataResponse response = new GetDataResponse();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, wcb);
-    }
-
-    /**
-     * The asynchronous version of getData.
-     *
-     * @see #getData(String, boolean, Stat)
-     */
-    public void getData(String path, boolean watch, DataCallback cb, Object ctx) {
-        getData(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
-    }
-
-    /**
-     * Set the data for the node of the given path if such a node exists and the
-     * given version matches the version of the node (if the given version is
-     * -1, it matches any node's versions). Return the stat of the node.
-     * <p>
-     * This operation, if successful, will trigger all the watches on the node
-     * of the given path left by getData calls.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     * <p>
-     * A KeeperException with error code KeeperException.BadVersion will be
-     * thrown if the given version does not match the node's version.
-     * <p>
-     * The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
-     * Arrays larger than this will cause a KeeperException to be thrown.
-     *
-     * @param path
-     *                the path of the node
-     * @param data
-     *                the data to set
-     * @param version
-     *                the expected matching version
-     * @return the state of the node
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws KeeperException If the server signals an error with a non-zero error code.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public Stat setData(final String path, byte data[], int version)
-        throws KeeperException, InterruptedException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.setData);
-        SetDataRequest request = new SetDataRequest();
-        request.setPath(serverPath);
-        request.setData(data);
-        request.setVersion(version);
-        SetDataResponse response = new SetDataResponse();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-        return response.getStat();
-    }
-
-    /**
-     * The asynchronous version of setData.
-     *
-     * @see #setData(String, byte[], int)
-     */
-    public void setData(final String path, byte data[], int version,
-            StatCallback cb, Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.setData);
-        SetDataRequest request = new SetDataRequest();
-        request.setPath(serverPath);
-        request.setData(data);
-        request.setVersion(version);
-        SetDataResponse response = new SetDataResponse();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, null);
-    }
-
-    /**
-     * Return the ACL and stat of the node of the given path.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     *
-     * @param path
-     *                the given path for the node
-     * @param stat
-     *                the stat of the node will be copied to this parameter if
-     *                not null.
-     * @return the ACL array of the given node.
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws KeeperException If the server signals an error with a non-zero error code.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public List<ACL> getACL(final String path, Stat stat)
-        throws KeeperException, InterruptedException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getACL);
-        GetACLRequest request = new GetACLRequest();
-        request.setPath(serverPath);
-        GetACLResponse response = new GetACLResponse();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-        if (stat != null) {
-            DataTree.copyStat(response.getStat(), stat);
-        }
-        return response.getAcl();
-    }
-
-    /**
-     * The asynchronous version of getACL.
-     *
-     * @see #getACL(String, Stat)
-     */
-    public void getACL(final String path, Stat stat, ACLCallback cb,
-            Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getACL);
-        GetACLRequest request = new GetACLRequest();
-        request.setPath(serverPath);
-        GetACLResponse response = new GetACLResponse();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, null);
-    }
-
-    /**
-     * Set the ACL for the node of the given path if such a node exists and the
-     * given aclVersion matches the acl version of the node. Return the stat of the
-     * node.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     * <p>
-     * A KeeperException with error code KeeperException.BadVersion will be
-     * thrown if the given aclVersion does not match the node's aclVersion.
-     *
-     * @param path the given path for the node
-     * @param acl the given acl for the node
-     * @param aclVersion the given acl version of the node
-     * @return the stat of the node.
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws KeeperException If the server signals an error with a non-zero error code.
-     * @throws org.apache.zookeeper.KeeperException.InvalidACLException If the acl is invalide.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public Stat setACL(final String path, List<ACL> acl, int aclVersion)
-        throws KeeperException, InterruptedException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.setACL);
-        SetACLRequest request = new SetACLRequest();
-        request.setPath(serverPath);
-        if (acl != null && acl.size() == 0) {
-            throw new KeeperException.InvalidACLException(clientPath);
-        }
-        request.setAcl(acl);
-        request.setVersion(aclVersion);
-        SetACLResponse response = new SetACLResponse();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, null);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-        return response.getStat();
-    }
-
-    /**
-     * The asynchronous version of setACL.
-     *
-     * @see #setACL(String, List, int)
-     */
-    public void setACL(final String path, List<ACL> acl, int version,
-            StatCallback cb, Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.setACL);
-        SetACLRequest request = new SetACLRequest();
-        request.setPath(serverPath);
-        request.setAcl(acl);
-        request.setVersion(version);
-        SetACLResponse response = new SetACLResponse();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, null);
-    }
-
-    /**
-     * Return the list of the children of the node of the given path.
-     * <p>
-     * If the watch is non-null and the call is successful (no exception is thrown),
-     * a watch will be left on the node with the given path. The watch willbe
-     * triggered by a successful operation that deletes the node of the given
-     * path or creates/delete a child under the node.
-     * <p>
-     * The list of children returned is not sorted and no guarantee is provided
-     * as to its natural or lexical order.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     *
-     * @param path
-     * @param watcher explicit watcher
-     * @return an unordered array of children of the node with the given path
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws KeeperException If the server signals an error with a non-zero error code.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public List<String> getChildren(final String path, Watcher watcher)
-        throws KeeperException, InterruptedException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new ChildWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getChildren);
-        GetChildrenRequest request = new GetChildrenRequest();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        GetChildrenResponse response = new GetChildrenResponse();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-        return response.getChildren();
-    }
-
-    /**
-     * Return the list of the children of the node of the given path.
-     * <p>
-     * If the watch is true and the call is successful (no exception is thrown),
-     * a watch will be left on the node with the given path. The watch willbe
-     * triggered by a successful operation that deletes the node of the given
-     * path or creates/delete a child under the node.
-     * <p>
-     * The list of children returned is not sorted and no guarantee is provided
-     * as to its natural or lexical order.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     *
-     * @param path
-     * @param watch
-     * @return an unordered array of children of the node with the given path
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws KeeperException If the server signals an error with a non-zero error code.
-     */
-    public List<String> getChildren(String path, boolean watch)
-            throws KeeperException, InterruptedException {
-        return getChildren(path, watch ? watchManager.defaultWatcher : null);
-    }
-
-    /**
-     * The asynchronous version of getChildren.
-     *
-     * @see #getChildren(String, Watcher)
-     */
-    public void getChildren(final String path, Watcher watcher,
-            ChildrenCallback cb, Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new ChildWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getChildren);
-        GetChildrenRequest request = new GetChildrenRequest();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        GetChildrenResponse response = new GetChildrenResponse();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, wcb);
-    }
-
-    /**
-     * The asynchronous version of getChildren.
-     *
-     * @see #getChildren(String, boolean)
-     */
-    public void getChildren(String path, boolean watch, ChildrenCallback cb,
-            Object ctx)
-    {
-        getChildren(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
-    }
-
-    /**
-     * For the given znode path return the stat and children list.
-     * <p>
-     * If the watch is non-null and the call is successful (no exception is thrown),
-     * a watch will be left on the node with the given path. The watch willbe
-     * triggered by a successful operation that deletes the node of the given
-     * path or creates/delete a child under the node.
-     * <p>
-     * The list of children returned is not sorted and no guarantee is provided
-     * as to its natural or lexical order.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     *
-     * @since 3.3.0
-     * 
-     * @param path
-     * @param watcher explicit watcher
-     * @param stat stat of the znode designated by path
-     * @return an unordered array of children of the node with the given path
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws KeeperException If the server signals an error with a non-zero error code.
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public List<String> getChildren(final String path, Watcher watcher,
-            Stat stat)
-        throws KeeperException, InterruptedException
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new ChildWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getChildren2);
-        GetChildren2Request request = new GetChildren2Request();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        GetChildren2Response response = new GetChildren2Response();
-        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
-        if (r.getErr() != 0) {
-            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
-                    clientPath);
-        }
-        if (stat != null) {
-            DataTree.copyStat(response.getStat(), stat);
-        }
-        return response.getChildren();
-    }
-
-    /**
-     * For the given znode path return the stat and children list.
-     * <p>
-     * If the watch is true and the call is successful (no exception is thrown),
-     * a watch will be left on the node with the given path. The watch willbe
-     * triggered by a successful operation that deletes the node of the given
-     * path or creates/delete a child under the node.
-     * <p>
-     * The list of children returned is not sorted and no guarantee is provided
-     * as to its natural or lexical order.
-     * <p>
-     * A KeeperException with error code KeeperException.NoNode will be thrown
-     * if no node with the given path exists.
-     *
-     * @since 3.3.0
-     * 
-     * @param path
-     * @param watch
-     * @param stat stat of the znode designated by path
-     * @return an unordered array of children of the node with the given path
-     * @throws InterruptedException If the server transaction is interrupted.
-     * @throws KeeperException If the server signals an error with a non-zero
-     *  error code.
-     */
-    public List<String> getChildren(String path, boolean watch, Stat stat)
-            throws KeeperException, InterruptedException {
-        return getChildren(path, watch ? watchManager.defaultWatcher : null,
-                stat);
-    }
-
-    /**
-     * The asynchronous version of getChildren.
-     *
-     * @since 3.3.0
-     * 
-     * @see #getChildren(String, Watcher, Stat)
-     */
-    public void getChildren(final String path, Watcher watcher,
-            Children2Callback cb, Object ctx)
-    {
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        // the watch contains the un-chroot path
-        WatchRegistration wcb = null;
-        if (watcher != null) {
-            wcb = new ChildWatchRegistration(watcher, clientPath);
-        }
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.getChildren2);
-        GetChildren2Request request = new GetChildren2Request();
-        request.setPath(serverPath);
-        request.setWatch(watcher != null);
-        GetChildren2Response response = new GetChildren2Response();
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, wcb);
-    }
-
-    /**
-     * The asynchronous version of getChildren.
-     *
-     * @since 3.3.0
-     * 
-     * @see #getChildren(String, boolean, Stat)
-     */
-    public void getChildren(String path, boolean watch, Children2Callback cb,
-            Object ctx)
-    {
-        getChildren(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
-    }
-
-    /**
-     * Asynchronous sync. Flushes channel between process and leader.
-     * @param path
-     * @param cb a handler for the callback
-     * @param ctx context to be provided to the callback
-     * @throws IllegalArgumentException if an invalid path is specified
-     */
-    public void sync(final String path, VoidCallback cb, Object ctx){
-        final String clientPath = path;
-        PathUtils.validatePath(clientPath);
-
-        final String serverPath = prependChroot(clientPath);
-
-        RequestHeader h = new RequestHeader();
-        h.setType(ZooDefs.OpCode.sync);
-        SyncRequest request = new SyncRequest();
-        SyncResponse response = new SyncResponse();
-        request.setPath(serverPath);
-        cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
-                clientPath, serverPath, ctx, null);
-    }
-
-    public States getState() {
-        return cnxn.getState();
-    }
-
-    /**
-     * String representation of this ZooKeeper client. Suitable for things
-     * like logging.
-     * 
-     * Do NOT count on the format of this string, it may change without
-     * warning.
-     * 
-     * @since 3.3.0
-     */
-    @Override
-    public String toString() {
-        States state = getState();
-        return ("State:" + state.toString()
-                + (state.isConnected() ?
-                        " Timeout:" + getSessionTimeout() + " " :
-                        " ")
-                + cnxn);
-    }
-
-    /*
-     * Methods to aid in testing follow.
-     * 
-     * THESE METHODS ARE EXPECTED TO BE USED FOR TESTING ONLY!!!
-     */
-
-    /**
-     * Wait up to wait milliseconds for the underlying threads to shutdown.
-     * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
-     * 
-     * @since 3.3.0
-     * 
-     * @param wait max wait in milliseconds
-     * @return true iff all threads are shutdown, otw false
-     */
-    protected boolean testableWaitForShutdown(int wait)
-        throws InterruptedException
-    {
-        cnxn.sendThread.join(wait);
-        if (cnxn.sendThread.isAlive()) return false;
-        cnxn.eventThread.join(wait);
-        if (cnxn.eventThread.isAlive()) return false;
-        return true;
-    }
-
-    /**
-     * Returns the address to which the socket is connected. Useful for testing
-     * against an ensemble - test client may need to know which server
-     * to shutdown if interested in verifying that the code handles
-     * disconnection/reconnection correctly.
-     * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
-     *
-     * @since 3.3.0
-     * 
-     * @return ip address of the remote side of the connection or null if
-     *         not connected
-     */
-    protected SocketAddress testableRemoteSocketAddress() {
-        return cnxn.sendThread.getClientCnxnSocket().getRemoteSocketAddress();
-    }
-
-    /** 
-     * Returns the local address to which the socket is bound.
-     * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
-     *
-     * @since 3.3.0
-     * 
-     * @return ip address of the remote side of the connection or null if
-     *         not connected
-     */
-    protected SocketAddress testableLocalSocketAddress() {
-        return cnxn.sendThread.getClientCnxnSocket().getLocalSocketAddress();
-    }
-
-    private static ClientCnxnSocket getClientCnxnSocket() throws IOException {
-        String clientCnxnSocketName = System
-                .getProperty(ZOOKEEPER_CLIENT_CNXN_SOCKET);
-        if (clientCnxnSocketName == null) {
-            clientCnxnSocketName = ClientCnxnSocketNIO.class.getName();
-        }
-        try {
-            return (ClientCnxnSocket) Class.forName(clientCnxnSocketName).getDeclaredConstructor()
-                    .newInstance();
-        } catch (Exception e) {
-            IOException ioe = new IOException("Couldn't instantiate "
-                    + clientCnxnSocketName);
-            ioe.initCause(e);
-            throw ioe;
-        }
-    }
-}


[24/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java
deleted file mode 100644
index de26698..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LENonTerminateTest.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.quorum.Election;
-import org.apache.zookeeper.server.quorum.FLELostMessageTest;
-import org.apache.zookeeper.server.quorum.LeaderElection;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.Vote;
-import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class LENonTerminateTest extends ZKTestCase {
-    public class MockLeaderElection extends LeaderElection {
-        public MockLeaderElection(QuorumPeer self) {
-            super(self);            
-        }
-
-        /**
-         * Temporary for 3.3.0 - we want to ensure that a round of voting happens
-         * before any of the peers update their votes. The easiest way to do that
-         * is to add a latch that all wait on after counting their votes. 
-         * 
-         * In 3.4.0 we intend to make this class more testable, and therefore
-         * there should be much less duplicated code.
-         * 
-         * JMX bean method calls are removed to reduce noise.
-         */
-        public Vote lookForLeader() throws InterruptedException {            
-            self.setCurrentVote(new Vote(self.getId(),
-                    self.getLastLoggedZxid()));
-            // We are going to look for a leader by casting a vote for ourself
-            byte requestBytes[] = new byte[4];
-            ByteBuffer requestBuffer = ByteBuffer.wrap(requestBytes);
-            byte responseBytes[] = new byte[28];
-            ByteBuffer responseBuffer = ByteBuffer.wrap(responseBytes);
-            /* The current vote for the leader. Initially me! */
-            DatagramSocket s = null;
-            try {
-                s = new DatagramSocket();
-                s.setSoTimeout(200);
-            } catch (SocketException e1) {
-                LOG.error("Socket exception when creating socket for leader election", e1);
-                System.exit(4);
-            }
-            DatagramPacket requestPacket = new DatagramPacket(requestBytes,
-                    requestBytes.length);
-            DatagramPacket responsePacket = new DatagramPacket(responseBytes,
-                    responseBytes.length);
-            int xid = epochGen.nextInt();
-            while (self.isRunning()) {
-                HashMap<InetSocketAddress, Vote> votes =
-                    new HashMap<InetSocketAddress, Vote>(self.getVotingView().size());
-
-                requestBuffer.clear();
-                requestBuffer.putInt(xid);
-                requestPacket.setLength(4);
-                HashSet<Long> heardFrom = new HashSet<Long>();
-                for (QuorumServer server :
-                    self.getVotingView().values())
-                {
-                    LOG.info("Server address: " + server.addr);
-                    try {
-                        requestPacket.setSocketAddress(server.addr);
-                    } catch (IllegalArgumentException e) {
-                        // Sun doesn't include the address that causes this
-                        // exception to be thrown, so we wrap the exception
-                        // in order to capture this critical detail.
-                        throw new IllegalArgumentException(
-                                "Unable to set socket address on packet, msg:"
-                                + e.getMessage() + " with addr:" + server.addr,
-                                e);
-                    }
-
-                    try {
-                        s.send(requestPacket);
-                        responsePacket.setLength(responseBytes.length);
-                        s.receive(responsePacket);
-                        if (responsePacket.getLength() != responseBytes.length) {
-                            LOG.error("Got a short response: "
-                                    + responsePacket.getLength());
-                            continue;
-                        }
-                        responseBuffer.clear();
-                        int recvedXid = responseBuffer.getInt();
-                        if (recvedXid != xid) {
-                            LOG.error("Got bad xid: expected " + xid
-                                    + " got " + recvedXid);
-                            continue;
-                        }
-                        long peerId = responseBuffer.getLong();
-                        heardFrom.add(peerId);
-                        //if(server.id != peerId){
-                        Vote vote = new Vote(responseBuffer.getLong(),
-                                responseBuffer.getLong());
-                        InetSocketAddress addr =
-                            (InetSocketAddress) responsePacket
-                            .getSocketAddress();
-                        votes.put(addr, vote);
-                        //}
-                    } catch (IOException e) {
-                        LOG.warn("Ignoring exception while looking for leader",
-                                e);
-                        // Errors are okay, since hosts may be
-                        // down
-                    }
-                }
-
-                ElectionResult result = countVotes(votes, heardFrom);
-                
-                /**
-                 * This is the only difference from LeaderElection - wait for
-                 * this latch on the first time through this method. This ensures
-                 * that the first round of voting happens before setCurrentVote
-                 * is called below.
-                 */
-                LOG.info("Waiting for first round of voting to complete");
-                latch.countDown();
-                Assert.assertTrue("Thread timed out waiting for latch",
-                        latch.await(10000, TimeUnit.MILLISECONDS));
-                
-                // ZOOKEEPER-569:
-                // If no votes are received for live peers, reset to voting 
-                // for ourselves as otherwise we may hang on to a vote 
-                // for a dead peer                 
-                if (result.numValidVotes == 0) {
-                    self.setCurrentVote(new Vote(self.getId(),
-                            self.getLastLoggedZxid()));
-                } else {
-                    if (result.winner.getId() >= 0) {
-                        self.setCurrentVote(result.vote);
-                        // To do: this doesn't use a quorum verifier
-                        if (result.winningCount > (self.getVotingView().size() / 2)) {
-                            self.setCurrentVote(result.winner);
-                            s.close();
-                            Vote current = self.getCurrentVote();
-                            LOG.info("Found leader: my type is: " + self.getLearnerType());
-                            /*
-                             * We want to make sure we implement the state machine
-                             * correctly. If we are a PARTICIPANT, once a leader
-                             * is elected we can move either to LEADING or 
-                             * FOLLOWING. However if we are an OBSERVER, it is an
-                             * error to be elected as a Leader.
-                             */
-                            if (self.getLearnerType() == LearnerType.OBSERVER) {
-                                if (current.getId() == self.getId()) {
-                                    // This should never happen!
-                                    LOG.error("OBSERVER elected as leader!");
-                                    Thread.sleep(100);
-                                }
-                                else {
-                                    self.setPeerState(ServerState.OBSERVING);
-                                    Thread.sleep(100);
-                                    return current;
-                                }
-                            } else {
-                                self.setPeerState((current.getId() == self.getId())
-                                        ? ServerState.LEADING: ServerState.FOLLOWING);
-                                if (self.getPeerState() == ServerState.FOLLOWING) {
-                                    Thread.sleep(100);
-                                }                            
-                                return current;
-                            }
-                        }
-                    }
-                }
-                Thread.sleep(1000);
-            }
-            return null;
-        }         
-    }
-    
-    public class MockQuorumPeer extends QuorumPeer {
-        public MockQuorumPeer(Map<Long,QuorumServer> quorumPeers, File snapDir,
-                File logDir, int clientPort, int electionAlg,
-                long myid, int tickTime, int initLimit, int syncLimit)
-        throws IOException
-        {
-            super(quorumPeers, snapDir, logDir, electionAlg,
-                    myid,tickTime, initLimit,syncLimit, false,
-                    ServerCnxnFactory.createFactory(clientPort, -1),
-                    new QuorumMaj(countParticipants(quorumPeers)));
-        }
-        
-        protected  Election createElectionAlgorithm(int electionAlgorithm){
-            LOG.info("Returning mocked leader election");
-            return new MockLeaderElection(this);
-        }
-    }
-    
-    
-    protected static final Logger LOG = LoggerFactory.getLogger(FLELostMessageTest.class);
-    
-    int count;
-    HashMap<Long,QuorumServer> peers;
-    File tmpdir[];
-    int port[];   
-   
-    @Before
-    public void setUp() throws Exception {
-        count = 3;
-
-        peers = new HashMap<Long,QuorumServer>(count);
-        tmpdir = new File[count];
-        port = new int[count];
-    }
-
-    static final CountDownLatch latch = new CountDownLatch(2);
-    static final CountDownLatch mockLatch = new CountDownLatch(1);
-
-    class LEThread extends Thread {
-        int i;
-        QuorumPeer peer;
-        
-
-        LEThread(QuorumPeer peer, int i) {
-            this.i = i;
-            this.peer = peer;
-            LOG.info("Constructor: " + getName());
-
-        }
-
-        public void run(){            
-            try{
-                Vote v = null;
-                peer.setPeerState(ServerState.LOOKING);
-                LOG.info("Going to call leader election: " + i);
-                v = peer.getElectionAlg().lookForLeader();
-
-                if (v == null){
-                    Assert.fail("Thread " + i + " got a null vote");
-                }                                
-
-                /*
-                 * A real zookeeper would take care of setting the current vote. Here
-                 * we do it manually.
-                 */
-                peer.setCurrentVote(v);
-
-                LOG.info("Finished election: " + i + ", " + v.getId());
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            LOG.info("Joining");
-        }
-    }
-    
-    /**
-     * This tests ZK-569.
-     * With three peers A, B and C, the following could happen:
-     * 1. Round 1, A,B and C all vote for themselves
-     * 2. Round 2, C dies, A and B vote for C
-     * 3. Because C has died, votes for it are ignored, but A and B never
-     * reset their votes. Hence LE never terminates. ZK-569 fixes this by
-     * resetting votes to themselves if the set of votes for live peers is null.
-     */
-    @Test
-    public void testNonTermination() throws Exception {                
-        LOG.info("TestNonTermination: " + getTestName()+ ", " + count);
-        for(int i = 0; i < count; i++) {
-            int clientport = PortAssignment.unique();
-            peers.put(Long.valueOf(i),
-                      new QuorumServer(i, "127.0.0.1", clientport,
-                                       PortAssignment.unique(), null));
-            tmpdir[i] = ClientBase.createTmpDir();
-            port[i] = clientport;
-        }
-        
-        /*
-         * peer1 and peer2 are A and B in the above example. 
-         */
-        QuorumPeer peer1 = new MockQuorumPeer(peers, tmpdir[0], tmpdir[0], port[0], 0, 0, 2, 2, 2);
-        peer1.startLeaderElection();
-        LEThread thread1 = new LEThread(peer1, 0);
-        
-        QuorumPeer peer2 = new MockQuorumPeer(peers, tmpdir[1], tmpdir[1], port[1], 0, 1, 2, 2, 2);
-        peer2.startLeaderElection();        
-        LEThread thread2 = new LEThread(peer2, 1);
-                            
-        /*
-         * Start mock server.
-         */
-        Thread thread3 = new Thread() { 
-            public void run() {
-                try {
-                    mockServer();
-                } catch (Exception e) {
-                    LOG.error("exception", e);
-                    Assert.fail("Exception when running mocked server " + e);
-                }
-            }
-        };        
-        
-        thread3.start();
-        Assert.assertTrue("mockServer did not start in 5s",
-                mockLatch.await(5000, TimeUnit.MILLISECONDS));
-        thread1.start();
-        thread2.start();
-        /*
-         * Occasionally seen false negatives with a 5s timeout.
-         */
-        thread1.join(15000);
-        thread2.join(15000);
-        thread3.join(15000);
-        if (thread1.isAlive() || thread2.isAlive() || thread3.isAlive()) {
-            Assert.fail("Threads didn't join");
-        }
-    }
-     
-    /**
-     * MockServer plays the role of peer C. Respond to two requests for votes
-     * with vote for self and then Assert.fail. 
-     */
-    void mockServer() throws InterruptedException, IOException {          
-        byte b[] = new byte[36];
-        ByteBuffer responseBuffer = ByteBuffer.wrap(b);
-        DatagramPacket packet = new DatagramPacket(b, b.length);
-        QuorumServer server = peers.get(Long.valueOf(2));
-        DatagramSocket udpSocket = new DatagramSocket(server.addr.getPort());
-        LOG.info("In MockServer");
-        mockLatch.countDown();
-        Vote current = new Vote(2, 1);
-        for (int i=0;i<2;++i) {
-            udpSocket.receive(packet);
-            responseBuffer.rewind();
-            LOG.info("Received " + responseBuffer.getInt() + " " + responseBuffer.getLong() + " " + responseBuffer.getLong());
-            LOG.info("From " + packet.getSocketAddress());
-            responseBuffer.clear();
-            responseBuffer.getInt(); // Skip the xid
-            responseBuffer.putLong(2);
-            
-            responseBuffer.putLong(current.getId());
-            responseBuffer.putLong(current.getZxid());
-            packet.setData(b);
-            udpSocket.send(packet);
-        }
-    }    
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/LETest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LETest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/LETest.java
deleted file mode 100644
index 0fd3430..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LETest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Random;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.server.quorum.LeaderElection;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.Vote;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class LETest extends ZKTestCase {
-    private static final Logger LOG = LoggerFactory.getLogger(LETest.class);
-    volatile Vote votes[];
-    volatile boolean leaderDies;
-    volatile long leader = -1;
-    Random rand = new Random();
-    class LEThread extends Thread {
-        LeaderElection le;
-        int i;
-        QuorumPeer peer;
-        LEThread(LeaderElection le, QuorumPeer peer, int i) {
-            this.le = le;
-            this.i = i;
-            this.peer = peer;
-        }
-        public void run() {
-            try {
-                Vote v = null;
-                while(true) {
-                    v = le.lookForLeader();
-                    votes[i] = v;
-                    if (v.getId() == i) {
-                        synchronized(LETest.this) {
-                            if (leaderDies) {
-                                leaderDies = false;
-                                peer.stopLeaderElection();
-                                LOG.info("Leader " + i + " dying");
-                                leader = -2;
-                            } else {
-                                leader = i;
-                            }
-                            LETest.this.notifyAll();
-                        }
-                        break;
-                    }
-                    synchronized(LETest.this) {
-                        if (leader == -1) {
-                            LETest.this.wait();
-                        }
-                        if (leader == v.getId()) {
-                            break;
-                        }
-                    }
-                    Thread.sleep(rand.nextInt(1000));
-                    peer.setCurrentVote(new Vote(peer.getId(), 0));
-                }
-                LOG.info("Thread " + i + " votes " + v);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    @Test
-    public void testLE() throws Exception {
-        int count = 30;
-        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>(count);
-        ArrayList<LEThread> threads = new ArrayList<LEThread>(count);
-        File tmpdir[] = new File[count];
-        int port[] = new int[count];
-        votes = new Vote[count];
-        for(int i = 0; i < count; i++) {
-            peers.put(Long.valueOf(i),
-                      new QuorumServer(i, "127.0.0.1", PortAssignment.unique(), 0, null));
-            tmpdir[i] = ClientBase.createTmpDir();
-            port[i] = PortAssignment.unique();
-        }
-        LeaderElection le[] = new LeaderElection[count];
-        leaderDies = true;
-        boolean allowOneBadLeader = leaderDies;
-        for(int i = 0; i < le.length; i++) {
-            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i],
-                    port[i], 0, i, 1000, 2, 2);
-            peer.startLeaderElection();
-            le[i] = new LeaderElection(peer);
-            LEThread thread = new LEThread(le[i], peer, i);
-            thread.start();
-            threads.add(thread);
-        }
-        for(int i = 0; i < threads.size(); i++) {
-            threads.get(i).join(15000);
-            if (threads.get(i).isAlive()) {
-                Assert.fail("Threads didn't join");
-            }
-        }
-        long id = votes[0].getId();
-        for(int i = 1; i < votes.length; i++) {
-            if (votes[i] == null) {
-                Assert.fail("Thread " + i + " had a null vote");
-            }
-            if (votes[i].getId() != id) {
-                if (allowOneBadLeader && votes[i].getId() == i) {
-                    allowOneBadLeader = false;
-                } else {
-                    Assert.fail("Thread " + i + " got " + votes[i].getId() + " expected " + id);
-                }
-            }
-        }
-    }    
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java
deleted file mode 100644
index 9135307..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogNoServerTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.jute.BinaryInputArchive;
-import org.apache.jute.BinaryOutputArchive;
-import org.apache.jute.Record;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.common.Time;
-import org.apache.zookeeper.server.DataNode;
-import org.apache.zookeeper.server.DataTree;
-import org.apache.zookeeper.server.persistence.FileHeader;
-import org.apache.zookeeper.server.persistence.FileTxnLog;
-import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
-import org.apache.zookeeper.txn.CreateTxn;
-import org.apache.zookeeper.txn.DeleteTxn;
-import org.apache.zookeeper.txn.MultiTxn;
-import org.apache.zookeeper.txn.Txn;
-import org.apache.zookeeper.txn.TxnHeader;
-import org.junit.Assert;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-public class LoadFromLogNoServerTest extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(LoadFromLogNoServerTest.class);
-
-    /**
-     * For ZOOKEEPER-1046. Verify if cversion and pzxid if incremented
-     * after create/delete failure during restore.
-     */
-    @Test
-    public void testTxnFailure() throws Exception {
-        long count = 1;
-        File tmpDir = ClientBase.createTmpDir();
-        FileTxnSnapLog logFile = new FileTxnSnapLog(tmpDir, tmpDir);
-        DataTree dt = new DataTree();
-        dt.createNode("/test", new byte[0], null, 0, -1, 1, 1);
-        for (count = 1; count <= 3; count++) {
-            dt.createNode("/test/" + count, new byte[0], null, 0, -1, count,
-                    Time.currentElapsedTime());
-        }
-        DataNode zk = dt.getNode("/test");
-
-        // Make create to fail, then verify cversion.
-        LOG.info("Attempting to create " + "/test/" + (count - 1));
-        doOp(logFile, ZooDefs.OpCode.create, "/test/" + (count - 1), dt, zk, -1);
-
-        LOG.info("Attempting to create " + "/test/" + (count - 1));
-        doOp(logFile, ZooDefs.OpCode.create, "/test/" + (count - 1), dt, zk,
-                zk.stat.getCversion() + 1);
-
-        LOG.info("Attempting to create " + "/test/" + (count - 1));
-        doOp(logFile, ZooDefs.OpCode.multi, "/test/" + (count - 1), dt, zk,
-                zk.stat.getCversion() + 1);
-
-        LOG.info("Attempting to create " + "/test/" + (count - 1));
-        doOp(logFile, ZooDefs.OpCode.multi, "/test/" + (count - 1), dt, zk,
-                -1);
-
-        // Make delete fo fail, then verify cversion.
-        // this doesn't happen anymore, we only set the cversion on create
-        // LOG.info("Attempting to delete " + "/test/" + (count + 1));
-        // doOp(logFile, OpCode.delete, "/test/" + (count + 1), dt, zk);
-    }
-
-    /*
-     * Does create/delete depending on the type and verifies
-     * if cversion before the operation is 1 less than cversion afer.
-     */
-    private void doOp(FileTxnSnapLog logFile, int type, String path,
-                      DataTree dt, DataNode parent, int cversion) throws Exception {
-        int lastSlash = path.lastIndexOf('/');
-        String parentName = path.substring(0, lastSlash);
-
-        int prevCversion = parent.stat.getCversion();
-        long prevPzxid = parent.stat.getPzxid();
-        List<String> child = dt.getChildren(parentName, null, null);
-        String childStr = "";
-        for (String s : child) {
-            childStr += s + " ";
-        }
-        LOG.info("Children: " + childStr + " for " + parentName);
-        LOG.info("(cverions, pzxid): " + prevCversion + ", " + prevPzxid);
-
-        Record txn = null;
-        TxnHeader txnHeader = null;
-        if (type == ZooDefs.OpCode.delete) {
-            txn = new DeleteTxn(path);
-            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
-                    Time.currentElapsedTime(), ZooDefs.OpCode.delete);
-        } else if (type == ZooDefs.OpCode.create) {
-            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
-                    Time.currentElapsedTime(), ZooDefs.OpCode.create);
-            txn = new CreateTxn(path, new byte[0], null, false, cversion);
-        }
-        else if (type == ZooDefs.OpCode.multi) {
-            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
-                    Time.currentElapsedTime(), ZooDefs.OpCode.create);
-            txn = new CreateTxn(path, new byte[0], null, false, cversion);
-            ArrayList txnList = new ArrayList();
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-            txn.serialize(boa, "request") ;
-            ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
-            Txn txact = new Txn(ZooDefs.OpCode.create,  bb.array());
-            txnList.add(txact);
-            txn = new MultiTxn(txnList);
-            txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1,
-                    Time.currentElapsedTime(), ZooDefs.OpCode.multi);
-        }
-        logFile.processTransaction(txnHeader, dt, null, txn);
-
-        int newCversion = parent.stat.getCversion();
-        long newPzxid = parent.stat.getPzxid();
-        child = dt.getChildren(parentName, null, null);
-        childStr = "";
-        for (String s : child) {
-            childStr += s + " ";
-        }
-        LOG.info("Children: " + childStr + " for " + parentName);
-        LOG.info("(cverions, pzxid): " +newCversion + ", " + newPzxid);
-        Assert.assertTrue(type + " <cversion, pzxid> verification failed. Expected: <" +
-                        (prevCversion + 1) + ", " + (prevPzxid + 1) + ">, found: <" +
-                        newCversion + ", " + newPzxid + ">",
-                (newCversion == prevCversion + 1 && newPzxid == prevPzxid + 1));
-    }
-
-    /**
-     * Simulates ZOOKEEPER-1069 and verifies that flush() before padLogFile
-     * fixes it.
-     */
-    @Test
-    public void testPad() throws Exception {
-        File tmpDir = ClientBase.createTmpDir();
-        FileTxnLog txnLog = new FileTxnLog(tmpDir);
-        TxnHeader txnHeader = new TxnHeader(0xabcd, 0x123, 0x123,
-                Time.currentElapsedTime(), ZooDefs.OpCode.create);
-        Record txn = new CreateTxn("/Test", new byte[0], null, false, 1);
-        txnLog.append(txnHeader, txn);
-        FileInputStream in = new FileInputStream(tmpDir.getPath() + "/log." +
-                Long.toHexString(txnHeader.getZxid()));
-        BinaryInputArchive ia  = BinaryInputArchive.getArchive(in);
-        FileHeader header = new FileHeader();
-        header.deserialize(ia, "fileheader");
-        LOG.info("Received magic : " + header.getMagic() +
-                " Expected : " + FileTxnLog.TXNLOG_MAGIC);
-        Assert.assertTrue("Missing magic number ",
-                header.getMagic() == FileTxnLog.TXNLOG_MAGIC);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java
deleted file mode 100644
index dac3910..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/LoadFromLogTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException.NoNodeException;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.apache.zookeeper.server.persistence.FileTxnLog;
-import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
-import org.apache.zookeeper.server.persistence.TxnLog.TxnIterator;
-import org.apache.zookeeper.txn.TxnHeader;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-
-public class LoadFromLogTest extends ClientBase {
-    private static final int NUM_MESSAGES = 300;
-    protected static final Logger LOG = LoggerFactory.getLogger(LoadFromLogTest.class);
-
-    // setting up the quorum has a transaction overhead for creating and closing the session
-    private static final int TRANSACTION_OVERHEAD = 2;	
-    private static final int TOTAL_TRANSACTIONS = NUM_MESSAGES + TRANSACTION_OVERHEAD;
-
-    @Before
-     public void setUp() throws Exception {
-                SyncRequestProcessor.setSnapCount(50);
-                super.setUp();
-            }
-
-    /**
-     * test that all transactions from the Log are loaded, and only once
-     * @throws Exception an exception might be thrown here
-     */
-    @Test
-    public void testLoad() throws Exception {
-        ZooKeeper zk = createZKClient(hostPort);
-
-        // generate some transactions that will get logged
-        try {
-            for (int i = 0; i< NUM_MESSAGES; i++) {
-                zk.create("/invalidsnap-" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-            }
-        } finally {
-            zk.close();
-        }
-        stopServer();
-
-        // now verify that the FileTxnLog reads every transaction only once
-        File logDir = new File(tmpDir, FileTxnSnapLog.version + FileTxnSnapLog.VERSION);
-        FileTxnLog txnLog = new FileTxnLog(logDir);
-
-        TxnIterator itr = txnLog.read(0);
-        long expectedZxid = 0;
-        long lastZxid = 0;
-        TxnHeader hdr;
-        do {
-            hdr = itr.getHeader();
-            expectedZxid++;
-            Assert.assertTrue("not the same transaction. lastZxid=" + lastZxid + ", zxid=" + hdr.getZxid(), lastZxid != hdr.getZxid());
-            Assert.assertTrue("excepting next transaction. expected=" + expectedZxid + ", retreived=" + hdr.getZxid(), (hdr.getZxid() == expectedZxid));
-            lastZxid = hdr.getZxid();
-        }while(itr.next());
-	
-        Assert.assertTrue("processed all transactions. " + expectedZxid + " == " + TOTAL_TRANSACTIONS, (expectedZxid == TOTAL_TRANSACTIONS));
-    }
-
-    /**
-     * Test we can restore the snapshot that has data ahead of the zxid
-     * of the snapshot file. 
-     */
-    @Test
-    public void testRestore() throws Exception {
-        ZooKeeper zk = createZKClient(hostPort);
-
-		// generate some transactions
-		String lastPath = null;
-		try {
-			zk.create("/invalidsnap", new byte[0], Ids.OPEN_ACL_UNSAFE,
-					CreateMode.PERSISTENT);
-			for (int i = 0; i < NUM_MESSAGES; i++) {
-				lastPath = zk.create("/invalidsnap/test-", new byte[0],
-						Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-			}
-		} finally {
-			zk.close();
-		}
-		String[] tokens = lastPath.split("-");
-		String expectedPath = "/invalidsnap/test-"
-				+ String.format("%010d",
-                Integer.parseInt(tokens[1]) + 1);
-        ZooKeeperServer zks = getServer(serverFactory);
-		long eZxid = zks.getZKDatabase().getDataTreeLastProcessedZxid();
-		// force the zxid to be behind the content
-		zks.getZKDatabase().setlastProcessedZxid(
-				zks.getZKDatabase().getDataTreeLastProcessedZxid() - 10);
-		LOG.info("Set lastProcessedZxid to "
-				+ zks.getZKDatabase().getDataTreeLastProcessedZxid());
-		// Force snapshot and restore
-		zks.takeSnapshot();
-		zks.shutdown();
-		stopServer();
-
-		startServer();
-		zks = getServer(serverFactory);
-		long fZxid = zks.getZKDatabase().getDataTreeLastProcessedZxid();
-
-		// Verify lastProcessedZxid is set correctly
-		Assert.assertTrue("Restore failed expected zxid=" + eZxid + " found="
-				+ fZxid, fZxid == eZxid);
-        zk = createZKClient(hostPort);
-
-		// Verify correctness of data and whether sequential znode creation 
-		// proceeds correctly after this point
-		String[] children;
-		String path;
-		try {
-			children = zk.getChildren("/invalidsnap", false).toArray(
-					new String[0]);
-			path = zk.create("/invalidsnap/test-", new byte[0],
-					Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-		} finally {
-			zk.close();
-		}
-		LOG.info("Expected " + expectedPath + " found " + path);
-		Assert.assertTrue("Error in sequential znode creation expected "
-				+ expectedPath + " found " + path, path.equals(expectedPath));
-		Assert.assertTrue("Unexpected number of children " + children.length
-				+ " expected " + NUM_MESSAGES,
-				(children.length == NUM_MESSAGES));
-	}
-    
-    /**
-     * Test we can restore a snapshot that has errors and data ahead of the zxid
-     * of the snapshot file. 
-     */
-    @Test
-    public void testRestoreWithTransactionErrors() throws Exception {
-        ZooKeeper zk = createZKClient(hostPort);
-
-        // generate some transactions
-        try {
-            for (int i = 0; i < NUM_MESSAGES; i++) {
-                try {
-                    zk.create("/invaliddir/test-", new byte[0],
-                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-                } catch(NoNodeException e) {
-                    //Expected
-                }
-            }
-        } finally {
-            zk.close();
-        }
-
-        // force the zxid to be behind the content
-        ZooKeeperServer zks = getServer(serverFactory);
-        zks.getZKDatabase().setlastProcessedZxid(
-                zks.getZKDatabase().getDataTreeLastProcessedZxid() - 10);
-        LOG.info("Set lastProcessedZxid to "
-                + zks.getZKDatabase().getDataTreeLastProcessedZxid());
-        
-        // Force snapshot and restore
-        zks.takeSnapshot();
-        zks.shutdown();
-        stopServer();
-
-        zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-        startServer();
-   }
-
-    /**
-     * ZOOKEEPER-1573: test restoring a snapshot with deleted txns ahead of the
-     * snapshot file's zxid.
-     */
-    @Test
-    public void testReloadSnapshotWithMissingParent() throws Exception {
-        ZooKeeper zk = createZKClient(hostPort);
-
-        // create transactions to create the snapshot with create/delete pattern
-        zk.create("/a", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        Stat stat = zk.exists("/a", false);
-        long createZxId = stat.getMzxid();
-        zk.create("/a/b", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk.delete("/a/b", -1);
-        zk.delete("/a", -1);
-        // force the zxid to be behind the content
-        ZooKeeperServer zks = getServer(serverFactory);
-        zks.getZKDatabase().setlastProcessedZxid(createZxId);
-        LOG.info("Set lastProcessedZxid to {}", zks.getZKDatabase()
-                .getDataTreeLastProcessedZxid());
-        // Force snapshot and restore
-        zks.takeSnapshot();
-        zks.shutdown();
-        stopServer();
-        startServer();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java
deleted file mode 100644
index 0a31ac9..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/MaxCnxnsTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.jute.BinaryOutputArchive;
-import org.apache.zookeeper.proto.ConnectRequest;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class MaxCnxnsTest extends ClientBase {
-    final private int numCnxns = 30;
-    AtomicInteger numConnected = new AtomicInteger(0);
-    String host;
-    int port;
-
-    @Override
-    public void setUp() throws Exception {
-        maxCnxns = numCnxns;
-        super.setUp();
-    }
-
-    class CnxnThread extends Thread {
-        int i;
-        SocketChannel socket;
-        public CnxnThread(int i) {
-            super("CnxnThread-"+i);
-            this.i = i;
-        }
-
-        public void run() {
-            SocketChannel sChannel = null;
-            try {
-                /*
-                 * For future unwary socket programmers: although connect 'blocks' it
-                 * does not require an accept on the server side to return. Therefore
-                 * you can not assume that all the sockets are connected at the end of
-                 * this for loop.
-                 */
-                sChannel = SocketChannel.open();
-                sChannel.connect(new InetSocketAddress(host,port));
-                // Construct a connection request
-                ConnectRequest conReq = new ConnectRequest(0, 0,
-                        10000, 0, "password".getBytes());
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-                boa.writeInt(-1, "len");
-                conReq.serialize(boa, "connect");
-                baos.close();
-                ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
-                bb.putInt(bb.capacity() - 4);
-                bb.rewind();
-
-                /* Send a connect request. Any socket that has been closed (or at least
-                 * not added to the cnxn list on the server) will not have any bytes to
-                 * read and get an eof.
-                 *
-                 *  The trick here was finding a call that caused the server to put
-                 *  bytes in the input stream without closing the cnxn. None of
-                 *  the four letter commands do that, so we actually try to create
-                 *  a session which should send us something back, while maintaining
-                 *  the connection.
-                 */
-
-                int eof = sChannel.write(bb);
-                // If the socket times out, we count that as Assert.failed -
-                // the server should respond within 10s
-                sChannel.socket().setSoTimeout(10000);
-                if (!sChannel.socket().isClosed()){
-                    eof = sChannel.socket().getInputStream().read();
-                    if (eof != -1) {
-                        numConnected.incrementAndGet();
-                    }
-                }
-            }
-            catch (IOException io) {
-                // "Connection reset by peer"
-            }
-            finally {
-                if (sChannel != null) {
-                    try {
-                        sChannel.close();
-                    }
-                    catch (Exception e) {
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Verify the ability to limit the number of concurrent connections.
-     * @throws IOException
-     * @throws InterruptedException
-     */
-    @Test
-    public void testMaxCnxns() throws IOException, InterruptedException{
-        String split[] = hostPort.split(":");
-        host = split[0];
-        port = Integer.parseInt(split[1]);
-        int numThreads = numCnxns + 5;
-        CnxnThread[] threads = new CnxnThread[numThreads];
-
-        for (int i=0;i<numCnxns;++i) {
-          threads[i] = new CnxnThread(i);
-        }
-
-        for (int i=0;i<numCnxns;++i) {
-            threads[i].start();
-        }
-
-        for (int i=0;i<numCnxns;++i) {
-            threads[i].join();
-        }
-        Assert.assertSame(numCnxns,numConnected.get());
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java
deleted file mode 100644
index 0277c23..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/MultiTransactionTest.java
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.AsyncCallback.MultiCallback;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.Transaction;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.OpResult.CheckResult;
-import org.apache.zookeeper.OpResult.CreateResult;
-import org.apache.zookeeper.OpResult.DeleteResult;
-import org.apache.zookeeper.OpResult.ErrorResult;
-import org.apache.zookeeper.OpResult.SetDataResult;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MultiTransactionTest extends ClientBase {
-    private static final Logger LOG = Logger.getLogger(MultiTransactionTest.class);
-
-    private ZooKeeper zk;
-    private ZooKeeper zk_chroot;
-
-    private final boolean useAsync;
-
-    public MultiTransactionTest(boolean useAsync) {
-        this.useAsync = useAsync;
-    }
-
-    @Parameters
-    public static Collection<Object[]> configs() {
-        return Arrays.asList(new Object[][] {
-            { false }, { true },
-        });
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        SyncRequestProcessor.setSnapCount(150);
-        super.setUp();
-        zk = createClient();
-    }
-
-    static class MultiResult {
-        int rc;
-        List<OpResult> results;
-        boolean finished = false;
-    }
-
-    private List<OpResult> multi(ZooKeeper zk, Iterable<Op> ops)
-    throws KeeperException, InterruptedException {
-        if (useAsync) {
-            final MultiResult res = new MultiResult();
-            zk.multi(ops, new MultiCallback() {
-                @Override
-                public void processResult(int rc, String path, Object ctx,
-                                          List<OpResult> opResults) {
-                    synchronized (res) {
-                        res.rc = rc;
-                        res.results = opResults;
-                        res.finished = true;
-                        res.notifyAll();
-                    }
-                }
-            }, null);
-            synchronized (res) {
-                while (!res.finished) {
-                    res.wait();
-                }
-            }
-            if (KeeperException.Code.OK.intValue() != res.rc) {
-                KeeperException ke = KeeperException.create(KeeperException.Code.get(res.rc));
-                throw ke;
-            }
-            return res.results;
-        } else {
-            return zk.multi(ops);
-        }
-    }
-
-    private void multiHavingErrors(ZooKeeper zk, Iterable<Op> ops,
-            List<Integer> expectedResultCodes, String expectedErr)
-            throws KeeperException, InterruptedException {
-        if (useAsync) {
-            final MultiResult res = new MultiResult();
-            zk.multi(ops, new MultiCallback() {
-                    @Override
-                    public void processResult(int rc, String path, Object ctx,
-                                              List<OpResult> opResults) {
-                        synchronized (res) {
-                            res.rc = rc;
-                            res.results = opResults;
-                            res.finished = true;
-                            res.notifyAll();
-                        }
-                    }
-                }, null);
-            synchronized (res) {
-                while (!res.finished) {
-                    res.wait();
-                }
-            }
-            for (int i = 0; i < res.results.size(); i++) {
-                OpResult opResult = res.results.get(i);
-                Assert.assertTrue("Did't recieve proper error response",
-                                  opResult instanceof ErrorResult);
-                ErrorResult errRes = (ErrorResult) opResult;
-                Assert.assertEquals("Did't recieve proper error code",
-                                    expectedResultCodes.get(i).intValue(), errRes.getErr());
-            }
-        } else {
-            try {
-                zk.multi(ops);
-                Assert.fail("Shouldn't have validated in ZooKeeper client!");
-            } catch (KeeperException e) {
-                Assert.assertEquals("Wrong exception", expectedErr, e.code()
-                                    .name());
-            } catch (IllegalArgumentException e) {
-                Assert.assertEquals("Wrong exception", expectedErr,
-                                    e.getMessage());
-            }
-        }
-    }
-
-    private List<OpResult> commit(Transaction txn)
-    throws KeeperException, InterruptedException {
-        if (useAsync) {
-            final MultiResult res = new MultiResult();
-            txn.commit(new MultiCallback() {
-                @Override
-                public void processResult(int rc, String path, Object ctx,
-                                          List<OpResult> opResults) {
-                    synchronized (res) {
-                        res.rc = rc;
-                        res.results = opResults;
-                        res.finished = true;
-                        res.notifyAll();
-                    }
-                }
-            }, null);
-            synchronized (res) {
-                while (!res.finished) {
-                    res.wait();
-                }
-            }
-            if (KeeperException.Code.OK.intValue() != res.rc) {
-                KeeperException ke = KeeperException.create(KeeperException.Code.get(res.rc));
-                throw ke;
-            }
-            return res.results;
-        } else {
-            return txn.commit();
-        }
-    }
-
-    /**
-     * Test verifies the multi calls with invalid znode path
-     */
-    @Test(timeout = 90000)
-    public void testInvalidPath() throws Exception {
-        List<Integer> expectedResultCodes = new ArrayList<Integer>();
-        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
-                                .intValue());
-        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
-        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
-                                .intValue());
-        // create with CreateMode
-        List<Op> opList = Arrays.asList(Op.create("/multi0", new byte[0],
-                                                  Ids.OPEN_ACL_UNSAFE,
-                                                  CreateMode.PERSISTENT),
-                                        Op.create(
-                                                  "/multi1/", new byte[0],
-                                                  Ids.OPEN_ACL_UNSAFE,
-                                                  CreateMode.PERSISTENT),
-                                        Op.create("/multi2", new byte[0],
-                                                  Ids.OPEN_ACL_UNSAFE,
-                                                  CreateMode.PERSISTENT));
-        String expectedErr = "Path must not end with / character";
-        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
-
-        // create with valid sequential flag
-        opList = Arrays.asList(Op.create("/multi0", new byte[0],
-                                         Ids.OPEN_ACL_UNSAFE,
-                                         CreateMode.PERSISTENT),
-                               Op.create("multi1/", new byte[0],
-                                         Ids.OPEN_ACL_UNSAFE,
-                                         CreateMode.EPHEMERAL_SEQUENTIAL.toFlag()),
-                               Op.create("/multi2",
-                                         new byte[0], Ids.OPEN_ACL_UNSAFE,
-                                         CreateMode.PERSISTENT));
-        expectedErr = "Path must start with / character";
-        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
-
-        // check
-        opList = Arrays.asList(Op.check("/multi0", -1),
-                               Op.check("/multi1/", 100),
-                               Op.check("/multi2", 5));
-        expectedErr = "Path must not end with / character";
-        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
-
-        // delete
-        opList = Arrays.asList(Op.delete("/multi0", -1),
-                               Op.delete("/multi1/", 100),
-                               Op.delete("/multi2", 5));
-        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
-
-        // Multiple bad arguments
-        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
-
-        // setdata
-        opList = Arrays.asList(Op.setData("/multi0", new byte[0], -1),
-                               Op.setData("/multi1/", new byte[0], -1),
-                               Op.setData("/multi2", new byte[0], -1),
-                               Op.setData("multi3", new byte[0], -1));
-        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
-    }
-
-    /**
-     * Test verifies the multi calls with blank znode path
-     */
-    @Test(timeout = 90000)
-    public void testBlankPath() throws Exception {
-        List<Integer> expectedResultCodes = new ArrayList<Integer>();
-        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
-                                .intValue());
-        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
-        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
-                                .intValue());
-        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
-
-        // delete
-        String expectedErr = "Path cannot be null";
-        List<Op> opList = Arrays.asList(Op.delete("/multi0", -1),
-                                        Op.delete(null, 100),
-                                        Op.delete("/multi2", 5),
-                                        Op.delete("", -1));
-        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
-    }
-
-    /**
-     * Test verifies the multi.create with invalid createModeFlag
-     */
-    @Test(timeout = 90000)
-    public void testInvalidCreateModeFlag() throws Exception {
-        List<Integer> expectedResultCodes = new ArrayList<Integer>();
-        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
-                                .intValue());
-        expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue());
-        expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY
-                                .intValue());
-
-        int createModeFlag = 6789;
-        List<Op> opList = Arrays.asList(Op.create("/multi0", new byte[0],
-                                                  Ids.OPEN_ACL_UNSAFE,
-                                                  CreateMode.PERSISTENT),
-                                        Op.create("/multi1", new byte[0],
-                                                  Ids.OPEN_ACL_UNSAFE,
-                                                  createModeFlag),
-                                        Op.create("/multi2", new byte[0],
-                                                  Ids.OPEN_ACL_UNSAFE,
-                                                  CreateMode.PERSISTENT));
-        String expectedErr = KeeperException.Code.BADARGUMENTS.name();
-        multiHavingErrors(zk, opList, expectedResultCodes, expectedErr);
-    }
-
-    /**
-     * ZOOKEEPER-2052:
-     * Multi abort shouldn't have any side effect.
-     * We fix a bug in rollback and the following scenario should work:
-     * 1. multi delete abort because of not empty directory
-     * 2. ephemeral nodes under that directory are deleted
-     * 3. multi delete should succeed.
-     */
-    @Test
-    public void testMultiRollback() throws Exception {
-        zk.create("/foo", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-
-        ZooKeeper epheZk = createClient();
-        epheZk.create("/foo/bar", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-
-        List<Op> opList = Arrays.asList(Op.delete("/foo", -1));
-        try {
-            multi(zk, opList);
-            Assert.fail("multi delete should failed for not empty directory");
-        } catch (KeeperException.NotEmptyException e) {
-        }
-
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        zk.exists("/foo/bar", new Watcher() {
-                @Override
-                public void process(WatchedEvent event) {
-                    if (event.getType() == Event.EventType.NodeDeleted){
-                        latch.countDown();
-                    }
-                }
-            });
-
-        epheZk.close();
-
-        latch.await();
-
-        try {
-            zk.getData("/foo/bar", false, null);
-            Assert.fail("ephemeral node should have been deleted");
-        } catch (KeeperException.NoNodeException e) {
-        }
-
-        multi(zk, opList);
-
-        try {
-            zk.getData("/foo", false, null);
-            Assert.fail("persistent node should have been deleted after multi");
-        } catch (KeeperException.NoNodeException e) {
-        }
-    }
-
-    @Test
-    public void testChRootCreateDelete() throws Exception {
-        // creating the subtree for chRoot clients.
-        String chRoot = createNameSpace();
-        // Creating child using chRoot client.
-        zk_chroot = createClient(this.hostPort + chRoot);
-        Op createChild = Op.create("/myid", new byte[0],
-                Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        multi(zk_chroot, Arrays.asList(createChild));
-        
-        Assert.assertNotNull("zNode is not created under chroot:" + chRoot, zk
-                .exists(chRoot + "/myid", false));
-        Assert.assertNotNull("zNode is not created under chroot:" + chRoot,
-                zk_chroot.exists("/myid", false));
-        Assert.assertNull("zNode is created directly under '/', ignored configured chroot",
-                zk.exists("/myid", false));
-        
-        // Deleting child using chRoot client.
-        Op deleteChild = Op.delete("/myid", 0);
-        multi(zk_chroot, Arrays.asList(deleteChild));
-        Assert.assertNull("zNode exists under chroot:" + chRoot, zk.exists(
-                chRoot + "/myid", false));
-        Assert.assertNull("zNode exists under chroot:" + chRoot, zk_chroot
-                .exists("/myid", false));
-    }
-
-    @Test
-    public void testChRootSetData() throws Exception {
-        // creating the subtree for chRoot clients.
-        String chRoot = createNameSpace();
-        // setData using chRoot client.
-        zk_chroot = createClient(this.hostPort + chRoot);
-        String[] names = {"/multi0", "/multi1", "/multi2"};
-        List<Op> ops = new ArrayList<Op>();
-
-        for (int i = 0; i < names.length; i++) {
-            ops.add(Op.create(names[i], new byte[0], Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT));
-            ops.add(Op.setData(names[i], names[i].getBytes(), 0));
-        }
-
-        multi(zk_chroot, ops) ;
-
-        for (int i = 0; i < names.length; i++) {
-            Assert.assertArrayEquals("zNode data not matching", names[i]
-                    .getBytes(), zk_chroot.getData(names[i], false, null));
-        }
-    }
-
-    @Test
-    public void testChRootCheck() throws Exception {
-        // creating the subtree for chRoot clients.
-        String chRoot = createNameSpace();
-        // checking the child version using chRoot client.
-        zk_chroot = createClient(this.hostPort + chRoot);
-        String[] names = {"/multi0", "/multi1", "/multi2"};
-        List<Op> ops = new ArrayList<Op>();
-        for (int i = 0; i < names.length; i++) {
-            zk.create(chRoot + names[i], new byte[0], Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        }
-        for (int i = 0; i < names.length; i++) {
-            ops.add(Op.check(names[i], 0));
-        }
-        multi(zk_chroot, ops) ;
-    }
-
-    @Test
-    public void testChRootTransaction() throws Exception {
-        // creating the subtree for chRoot clients.
-        String chRoot = createNameSpace();
-        // checking the child version using chRoot client.
-        zk_chroot = createClient(this.hostPort + chRoot);
-        String childPath = "/myid";
-        Transaction transaction = zk_chroot.transaction();
-        transaction.create(childPath, new byte[0], Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        transaction.check(childPath, 0);
-        transaction.setData(childPath, childPath.getBytes(), 0);
-        commit(transaction);
-
-        Assert.assertNotNull("zNode is not created under chroot:" + chRoot, zk
-                .exists(chRoot + childPath, false));
-        Assert.assertNotNull("zNode is not created under chroot:" + chRoot,
-                zk_chroot.exists(childPath, false));
-        Assert.assertNull("zNode is created directly under '/', ignored configured chroot",
-                        zk.exists(childPath, false));
-        Assert.assertArrayEquals("zNode data not matching", childPath
-                .getBytes(), zk_chroot.getData(childPath, false, null));
-
-        transaction = zk_chroot.transaction();
-        // Deleting child using chRoot client.
-        transaction.delete(childPath, 1);
-        commit(transaction);
-
-        Assert.assertNull("chroot:" + chRoot + " exists after delete", zk
-                .exists(chRoot + "/myid", false));
-        Assert.assertNull("chroot:" + chRoot + " exists after delete",
-                zk_chroot.exists("/myid", false));
-    }
-
-    private String createNameSpace() throws InterruptedException,
-            KeeperException {
-        // creating the subtree for chRoot clients.
-        String chRoot = "/appsX";
-        Op createChRoot = Op.create(chRoot, new byte[0], Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        multi(zk, Arrays.asList(createChRoot));
-        return chRoot;
-    }
-
-    @Test
-    public void testCreate() throws Exception {
-        multi(zk, Arrays.asList(
-                Op.create("/multi0", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.create("/multi1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.create("/multi2", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
-                ));
-        zk.getData("/multi0", false, null);
-        zk.getData("/multi1", false, null);
-        zk.getData("/multi2", false, null);
-    }
-    
-    @Test
-    public void testCreateDelete() throws Exception {
-
-        multi(zk, Arrays.asList(
-                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.delete("/multi", 0)
-                ));
-
-        // '/multi' should have been deleted
-        Assert.assertNull(zk.exists("/multi", null));
-    }
-
-    @Test
-    public void testInvalidVersion() throws Exception {
-
-        try {
-            multi(zk, Arrays.asList(
-                    Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                    Op.delete("/multi", 1)
-            ));
-            Assert.fail("delete /multi should have failed");
-        } catch (KeeperException e) {
-            /* PASS */
-        }
-    }
-
-    @Test
-    public void testNestedCreate() throws Exception {
-
-        multi(zk, Arrays.asList(
-                /* Create */
-                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.create("/multi/a", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.create("/multi/a/1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-
-                /* Delete */
-                Op.delete("/multi/a/1", 0),
-                Op.delete("/multi/a", 0),
-                Op.delete("/multi", 0)
-                ));
-
-        //Verify tree deleted
-        Assert.assertNull(zk.exists("/multi/a/1", null));
-        Assert.assertNull(zk.exists("/multi/a", null));
-        Assert.assertNull(zk.exists("/multi", null));
-    }
-
-    @Test
-    public void testSetData() throws Exception {
-
-        String[] names = {"/multi0", "/multi1", "/multi2"};
-        List<Op> ops = new ArrayList<Op>();
-
-        for (int i = 0; i < names.length; i++) {
-            ops.add(Op.create(names[i], new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT));
-            ops.add(Op.setData(names[i], names[i].getBytes(), 0));
-        }
-
-        multi(zk, ops) ;
-
-        for (int i = 0; i < names.length; i++) {
-            Assert.assertArrayEquals(names[i].getBytes(), zk.getData(names[i], false, null));
-        }
-    }
-
-    @Test
-    public void testUpdateConflict() throws Exception {
-    
-        Assert.assertNull(zk.exists("/multi", null));
-        
-        try {
-            multi(zk, Arrays.asList(
-                    Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                    Op.setData("/multi", "X".getBytes(), 0),
-                    Op.setData("/multi", "Y".getBytes(), 0)
-                    ));
-            Assert.fail("Should have thrown a KeeperException for invalid version");
-        } catch (KeeperException e) {
-            //PASS
-            LOG.error("STACKTRACE: " + e);
-        }
-
-        Assert.assertNull(zk.exists("/multi", null));
-
-        //Updating version solves conflict -- order matters
-        multi(zk, Arrays.asList(
-                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.setData("/multi", "X".getBytes(), 0),
-                Op.setData("/multi", "Y".getBytes(), 1)
-                ));
-
-        Assert.assertArrayEquals(zk.getData("/multi", false, null), "Y".getBytes());
-    }
-
-    @Test
-    public void TestDeleteUpdateConflict() throws Exception {
-
-        /* Delete of a node folowed by an update of the (now) deleted node */
-        try {
-            multi(zk, Arrays.asList(
-                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.delete("/multi", 0),
-                Op.setData("/multi", "Y".getBytes(), 0)
-                ));
-            Assert.fail("/multi should have been deleted so setData should have failed");
-        } catch (KeeperException e) {
-            /* PASS */
-        }
-
-        // '/multi' should never have been created as entire op should fail
-        Assert.assertNull(zk.exists("/multi", null)) ;
-    }
-
-    @Test
-    public void TestGetResults() throws Exception {
-        /* Delete of a node folowed by an update of the (now) deleted node */
-        Iterable<Op> ops = Arrays.asList(
-                Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.delete("/multi", 0),
-                Op.setData("/multi", "Y".getBytes(), 0),
-                Op.create("/foo", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
-        );
-        List<OpResult> results = null;
-        if (useAsync) {
-            final MultiResult res = new MultiResult();
-            zk.multi(ops, new MultiCallback() {
-                @Override
-                public void processResult(int rc, String path, Object ctx,
-                                          List<OpResult> opResults) {
-                    synchronized (res) {
-                        res.rc = rc;
-                        res.results = opResults;
-                        res.finished = true;
-                        res.notifyAll();
-                    }
-                }
-            }, null);
-            synchronized (res) {
-                while (!res.finished) {
-                    res.wait();
-                }
-            }
-            Assert.assertFalse("/multi should have been deleted so setData should have failed",
-                               KeeperException.Code.OK.intValue() == res.rc);
-            Assert.assertNull(zk.exists("/multi", null));
-            results = res.results;
-        } else {
-            try {
-                zk.multi(ops);
-                Assert.fail("/multi should have been deleted so setData should have failed");
-            } catch (KeeperException e) {
-                // '/multi' should never have been created as entire op should fail
-                Assert.assertNull(zk.exists("/multi", null));
-                results = e.getResults();
-            }
-        }
-
-        Assert.assertNotNull(results);
-        for (OpResult r : results) {
-            LOG.info("RESULT==> " + r);
-            if (r instanceof ErrorResult) {
-                ErrorResult er = (ErrorResult) r;
-                LOG.info("ERROR RESULT: " + er + " ERR=>" + KeeperException.Code.get(er.getErr()));
-            }
-        }
-    }
-
-    /**
-     * Exercise the equals methods of OpResult classes.
-     */
-    @Test
-    public void testOpResultEquals() {
-        opEquals(new CreateResult("/foo"),
-                new CreateResult("/foo"),
-                new CreateResult("nope"));
-
-        opEquals(new CheckResult(),
-                new CheckResult(),
-                null);
-        
-        opEquals(new SetDataResult(new Stat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)),
-                new SetDataResult(new Stat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)),
-                new SetDataResult(new Stat(11, 12, 13, 14, 15, 16, 17, 18, 19, 110, 111)));
-        
-        opEquals(new ErrorResult(1),
-                new ErrorResult(1),
-                new ErrorResult(2));
-        
-        opEquals(new DeleteResult(),
-                new DeleteResult(),
-                null);
-
-        opEquals(new ErrorResult(1),
-                new ErrorResult(1),
-                new ErrorResult(2));
-    }
-
-    private void opEquals(OpResult expected, OpResult value, OpResult near) {
-        assertEquals(value, value);
-        assertFalse(value.equals(new Object()));
-        assertFalse(value.equals(near));
-        assertFalse(value.equals(value instanceof CreateResult ?
-                new ErrorResult(1) : new CreateResult("nope2")));
-        assertTrue(value.equals(expected));
-    }
-
-    @Test
-    public void testWatchesTriggered() throws KeeperException, InterruptedException {
-        HasTriggeredWatcher watcher = new HasTriggeredWatcher();
-        zk.getChildren("/", watcher);
-        multi(zk, Arrays.asList(
-                Op.create("/t", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                Op.delete("/t", -1)
-        ));
-        assertTrue(watcher.triggered.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testNoWatchesTriggeredForFailedMultiRequest() throws InterruptedException, KeeperException {
-        HasTriggeredWatcher watcher = new HasTriggeredWatcher();
-        zk.getChildren("/", watcher);
-        try {
-            multi(zk, Arrays.asList(
-                    Op.create("/t", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
-                    Op.delete("/nonexisting", -1)
-            ));
-            fail("expected previous multi op to fail!");
-        } catch (KeeperException.NoNodeException e) {
-            // expected
-        }
-        SyncCallback cb = new SyncCallback();
-        zk.sync("/", cb, null);
-
-        // by waiting for the callback we're assured that the event queue is flushed
-        cb.done.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
-        assertEquals(1, watcher.triggered.getCount());
-    }
-    
-    @Test
-    public void testTransactionBuilder() throws Exception {
-        List<OpResult> results = commit(zk.transaction()
-                .create("/t1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
-                .create("/t1/child", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
-                .create("/t2", null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL));
-        assertEquals(3, results.size());
-        for (OpResult r : results) {
-            CreateResult c = (CreateResult)r;
-            assertTrue(c.getPath().startsWith("/t"));
-            assertNotNull(c.toString());
-        }
-        assertNotNull(zk.exists("/t1", false));
-        assertNotNull(zk.exists("/t1/child", false));
-        assertNotNull(zk.exists("/t2", false));
-        
-        results = commit(zk.transaction()
-                .check("/t1", 0)
-                .check("/t1/child", 0)
-                .check("/t2", 0));
-        assertEquals(3, results.size());
-        for (OpResult r : results) {
-            CheckResult c = (CheckResult)r;
-            assertNotNull(c.toString());
-        }
-        
-        try {
-            results = commit(zk.transaction()
-                    .check("/t1", 0)
-                    .check("/t1/child", 0)
-                    .check("/t2", 1));
-            fail();
-        } catch (KeeperException.BadVersionException e) {
-            // expected
-        }
-        
-        results = commit(zk.transaction()
-                .check("/t1", 0)
-                .setData("/t1", new byte[0], 0));
-        assertEquals(2, results.size());
-        for (OpResult r : results) {
-            assertNotNull(r.toString());
-        }
-
-        try {
-            results = commit(zk.transaction()
-                    .check("/t1", 1)
-                    .setData("/t1", new byte[0], 2));
-            fail();
-        } catch (KeeperException.BadVersionException e) {
-            // expected
-        }
-        
-        results = commit(zk.transaction()
-                .check("/t1", 1)
-                .check("/t1/child", 0)
-                .check("/t2", 0));
-        assertEquals(3, results.size());
-
-        results = commit(zk.transaction()
-                .delete("/t2", -1)
-                .delete("/t1/child", -1));
-        assertEquals(2, results.size());
-        for (OpResult r : results) {
-            DeleteResult d = (DeleteResult)r;
-            assertNotNull(d.toString());
-        }
-        assertNotNull(zk.exists("/t1", false));
-        assertNull(zk.exists("/t1/child", false));
-        assertNull(zk.exists("/t2", false));
-    }
-
-    private static class HasTriggeredWatcher implements Watcher {
-        private final CountDownLatch triggered = new CountDownLatch(1);
-
-        @Override
-        public void process(WatchedEvent event) {
-            triggered.countDown();
-        }
-    }
-    private static class SyncCallback implements AsyncCallback.VoidCallback {
-        private final CountDownLatch done = new CountDownLatch(1);
-
-        @Override
-        public void processResult(int rc, String path, Object ctx) {
-            done.countDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java
deleted file mode 100644
index d61a3e2..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteBase.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.zookeeper.server.NettyServerCnxnFactory;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Run tests with: Nio Client against Netty server
- */
-@RunWith(Suite.class)
-public class NioNettySuiteBase {
-    @BeforeClass
-    public static void setUp() {
-        System.setProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY,
-                NettyServerCnxnFactory.class.getName());
-    }
-
-    @AfterClass
-    public static void tearDown() {
-        System.clearProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java
deleted file mode 100644
index 96e7b0c..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteHammerTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.junit.runners.Suite;
-
-/**
- * Run tests with: Nio Client against Netty server
- */
-@Suite.SuiteClasses({
-        AsyncHammerTest.class
-        })
-public class NioNettySuiteHammerTest extends NioNettySuiteBase {
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java
deleted file mode 100644
index eaf17b9..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NioNettySuiteTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.junit.runners.Suite;
-
-/**
- * Run tests with: Nio Client against Netty server
- */
-@Suite.SuiteClasses({
-        ACLTest.class,
-        AsyncOpsTest.class,
-        ChrootClientTest.class,
-        ClientTest.class,
-        FourLetterWordsTest.class,
-        NullDataTest.class,
-        SessionTest.class,
-        WatcherTest.class
-        })
-public class NioNettySuiteTest extends NioNettySuiteBase {
-}


[05/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java
new file mode 100644
index 0000000..133d920
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java
@@ -0,0 +1,183 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.server.ZKDatabase;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
+import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * This class tests the non-recoverable error behavior of quorum server.
+ */
+public class NonRecoverableErrorTest extends QuorumPeerTestBase {
+    private static final String NODE_PATH = "/noLeaderIssue";
+
+    /**
+     * Test case for https://issues.apache.org/jira/browse/ZOOKEEPER-2247.
+     * Test to verify that even after non recoverable error (error while
+     * writing transaction log), ZooKeeper is still available.
+     */
+    @Test(timeout = 30000)
+    public void testZooKeeperServiceAvailableOnLeader() throws Exception {
+        int SERVER_COUNT = 3;
+        final int clientPorts[] = new int[SERVER_COUNT];
+        StringBuilder sb = new StringBuilder();
+        String server;
+
+        for (int i = 0; i < SERVER_COUNT; i++) {
+            clientPorts[i] = PortAssignment.unique();
+            server = "server." + i + "=127.0.0.1:" + PortAssignment.unique()
+                    + ":" + PortAssignment.unique();
+            sb.append(server + "\n");
+        }
+        String currentQuorumCfgSection = sb.toString();
+        MainThread mt[] = new MainThread[SERVER_COUNT];
+
+        for (int i = 0; i < SERVER_COUNT; i++) {
+            mt[i] = new MainThread(i, clientPorts[i], currentQuorumCfgSection);
+            mt[i].start();
+        }
+
+        // ensure server started
+        for (int i = 0; i < SERVER_COUNT; i++) {
+            Assert.assertTrue("waiting for server " + i + " being up",
+                    ClientBase.waitForServerUp("127.0.0.1:" + clientPorts[i],
+                            CONNECTION_TIMEOUT));
+        }
+
+        CountdownWatcher watcher = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper("127.0.0.1:" + clientPorts[0],
+                ClientBase.CONNECTION_TIMEOUT, watcher);
+        watcher.waitForConnected(ClientBase.CONNECTION_TIMEOUT);
+
+        String data = "originalData";
+        zk.create(NODE_PATH, data.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+
+        // get information of current leader
+        QuorumPeer leader = getLeaderQuorumPeer(mt);
+        assertNotNull("Leader must have been elected by now", leader);
+
+        // inject problem in leader
+        FileTxnSnapLog snapLog = leader.getActiveServer().getTxnLogFactory();
+        FileTxnSnapLog fileTxnSnapLogWithError = new FileTxnSnapLog(
+                snapLog.getDataDir(), snapLog.getSnapDir()) {
+            @Override
+            public void commit() throws IOException {
+                throw new IOException("Input/output error");
+            }
+        };
+        ZKDatabase originalZKDatabase = leader.getActiveServer()
+                .getZKDatabase();
+        long leaderCurrentEpoch = leader.getCurrentEpoch();
+
+        ZKDatabase newDB = new ZKDatabase(fileTxnSnapLogWithError);
+        leader.getActiveServer().setZKDatabase(newDB);
+
+        try {
+            // do create operation, so that injected IOException is thrown
+            zk.create(uniqueZnode(), data.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            fail("IOException is expected due to error injected to transaction log commit");
+        } catch (Exception e) {
+            // do nothing
+        }
+
+        // resetting watcher so that this watcher can be again used to ensure
+        // that the zkClient is able to re-establish connection with the
+        // newly elected zookeeper quorum.
+        watcher.reset();
+        waitForNewLeaderElection(leader, leaderCurrentEpoch);
+
+        // ensure server started, give enough time, so that new leader election
+        // takes place
+        for (int i = 0; i < SERVER_COUNT; i++) {
+            Assert.assertTrue("waiting for server " + i + " being up",
+                    ClientBase.waitForServerUp("127.0.0.1:" + clientPorts[i],
+                            CONNECTION_TIMEOUT));
+        }
+
+        // revert back the error
+        leader.getActiveServer().setZKDatabase(originalZKDatabase);
+
+        // verify that now ZooKeeper service is up and running
+        leader = getLeaderQuorumPeer(mt);
+        assertNotNull("New leader must have been elected by now", leader);
+
+        String uniqueNode = uniqueZnode();
+        watcher.waitForConnected(ClientBase.CONNECTION_TIMEOUT);
+        String createNode = zk.create(uniqueNode, data.getBytes(),
+                Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        // if node is created successfully then it means that ZooKeeper service
+        // is available
+        assertEquals("Failed to create znode", uniqueNode, createNode);
+        zk.close();
+        // stop all severs
+        for (int i = 0; i < SERVER_COUNT; i++) {
+            mt[i].shutdown();
+        }
+    }
+
+    private void waitForNewLeaderElection(QuorumPeer peer,
+            long leaderCurrentEpoch) throws IOException, InterruptedException {
+        LOG.info("Waiting for new LE cycle..");
+        int count = 100; // giving a grace period of 10seconds
+        while (count > 0) {
+            if (leaderCurrentEpoch == peer.getCurrentEpoch()) {
+                Thread.sleep(100);
+            }
+            count--;
+        }
+        Assert.assertTrue("New LE cycle must have triggered",
+                leaderCurrentEpoch != peer.getCurrentEpoch());
+    }
+
+    private QuorumPeer getLeaderQuorumPeer(MainThread[] mt) {
+        for (int i = mt.length - 1; i >= 0; i--) {
+            QuorumPeer quorumPeer = mt[i].getQuorumPeer();
+            if (null != quorumPeer
+                    && ServerState.LEADING == quorumPeer.getPeerState()) {
+                return quorumPeer;
+            }
+        }
+        return null;
+    }
+
+    private String uniqueZnode() {
+        UUID randomUUID = UUID.randomUUID();
+        String node = NODE_PATH + "/" + randomUUID.toString();
+        return node;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/NullDataTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/NullDataTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NullDataTest.java
new file mode 100644
index 0000000..8f1a1bb
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/NullDataTest.java
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class NullDataTest extends ClientBase implements StatCallback {
+    String snapCount;
+    CountDownLatch cn = new CountDownLatch(1);
+    
+    @Override
+    public void setUp() throws Exception {
+        // Change the snapcount to happen more often
+        snapCount = System.getProperty("zookeeper.snapCount", "1024");
+        System.setProperty("zookeeper.snapCount", "10");
+        super.setUp();
+    }
+    
+    @Override
+    public void tearDown() throws Exception {
+        System.setProperty("zookeeper.snapCount", snapCount);
+        super.tearDown();
+    }
+    
+    @Test
+    public void testNullData() throws IOException, 
+        InterruptedException, KeeperException {
+        String path = "/SIZE";
+        ZooKeeper zk = null;
+        zk = createClient();
+        try {
+            zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            // try sync zk exists 
+            zk.exists(path, false);
+            zk.exists(path, false, this , null);
+            cn.await(10, TimeUnit.SECONDS);
+            Assert.assertSame(0L, cn.getCount());
+        } finally {
+            if(zk != null)
+                zk.close();
+        }
+        
+    }
+
+    public void processResult(int rc, String path, Object ctx, Stat stat) {
+        cn.countDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/OOMTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/OOMTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/OOMTest.java
new file mode 100644
index 0000000..465df98
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/OOMTest.java
@@ -0,0 +1,161 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class OOMTest extends ZKTestCase implements Watcher {
+    @Test
+    public void testOOM() throws IOException, InterruptedException, KeeperException {
+        // This test takes too long tos run!
+        if (true)
+            return;
+        File tmpDir = ClientBase.createTmpDir();
+        // Grab some memory so that it is easier to cause an
+        // OOM condition;
+        ArrayList<byte[]> hog = new ArrayList<byte[]>();
+        while (true) {
+            try {
+                hog.add(new byte[1024 * 1024 * 2]);
+            } catch (OutOfMemoryError e) {
+                hog.remove(0);
+                break;
+            }
+        }
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+
+        final int PORT = PortAssignment.unique();
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        Assert.assertTrue("waiting for server up",
+                   ClientBase.waitForServerUp("127.0.0.1:" + PORT,
+                                              CONNECTION_TIMEOUT));
+
+        System.err.println("OOM Stage 0");
+        utestPrep(PORT);
+        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
+                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
+                + Runtime.getRuntime().maxMemory());
+        System.err.println("OOM Stage 1");
+        for (int i = 0; i < 1000; i++) {
+            System.out.println(i);
+            utestExists(PORT);
+        }
+        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
+                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
+                + Runtime.getRuntime().maxMemory());
+        System.err.println("OOM Stage 2");
+        for (int i = 0; i < 1000; i++) {
+            System.out.println(i);
+            utestGet(PORT);
+        }
+        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
+                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
+                + Runtime.getRuntime().maxMemory());
+        System.err.println("OOM Stage 3");
+        for (int i = 0; i < 1000; i++) {
+            System.out.println(i);
+            utestChildren(PORT);
+        }
+        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
+                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
+                + Runtime.getRuntime().maxMemory());
+        hog.get(0)[0] = (byte) 1;
+
+        f.shutdown();
+        zks.shutdown();
+        Assert.assertTrue("waiting for server down",
+                   ClientBase.waitForServerDown("127.0.0.1:" + PORT,
+                                                CONNECTION_TIMEOUT));
+    }
+
+    private void utestExists(int port)
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk =
+            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
+        for (int i = 0; i < 10000; i++) {
+            zk.exists("/this/path/doesnt_exist!", true);
+        }
+        zk.close();
+    }
+
+    private void utestPrep(int port)
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk =
+            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
+        for (int i = 0; i < 10000; i++) {
+            zk.create("/" + i, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        }
+        zk.close();
+    }
+
+    private void utestGet(int port)
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk =
+            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
+        for (int i = 0; i < 10000; i++) {
+            Stat stat = new Stat();
+            zk.getData("/" + i, true, stat);
+        }
+        zk.close();
+    }
+
+    private void utestChildren(int port)
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk =
+            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
+        for (int i = 0; i < 10000; i++) {
+            zk.getChildren("/" + i, true);
+        }
+        zk.close();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.proto.WatcherEvent)
+     */
+    public void process(WatchedEvent event) {
+        System.err.println("Got event " + event.getType() + " "
+                + event.getState() + " " + event.getPath());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java
new file mode 100644
index 0000000..ce21ab8
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java
@@ -0,0 +1,70 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.zookeeper.server.util.OSMXBean;
+
+public class OSMXBeanTest {
+    
+    private OSMXBean osMbean;
+    private Long ofdc = 0L;
+    private Long mfdc = 0L;
+    protected static final Logger LOG = LoggerFactory.getLogger(OSMXBeanTest.class);
+
+    @Before
+    public void initialize() {
+        this.osMbean = new OSMXBean();
+        Assert.assertNotNull("Could not initialize OSMXBean object!", osMbean);
+    }
+    
+    @Test
+    public final void testGetUnix() {
+        boolean isUnix = osMbean.getUnix();
+        if (!isUnix) {
+        	LOG.info("Running in a Windows system! Output won't be printed!");
+        } else {
+        	LOG.info("Running in a Unix or Linux system!");
+        }
+    }
+
+    @Test
+    public final void testGetOpenFileDescriptorCount() {
+        if (osMbean != null && osMbean.getUnix() == true) {
+            ofdc = osMbean.getOpenFileDescriptorCount();
+            LOG.info("open fdcount is: " + ofdc);
+        }   
+        Assert.assertFalse("The number of open file descriptor is negative",(ofdc < 0));
+    }
+
+    @Test
+    public final void testGetMaxFileDescriptorCount() {
+        if (osMbean != null && osMbean.getUnix() == true) {
+            mfdc = osMbean.getMaxFileDescriptorCount();
+            LOG.info("max fdcount is: " + mfdc);
+        }
+        Assert.assertFalse("The max file descriptor number is negative",(mfdc < 0));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java
new file mode 100644
index 0000000..9d373fc
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java
@@ -0,0 +1,43 @@
+/* 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.junit.Test;
+
+public class ObserverHierarchicalQuorumTest extends HierarchicalQuorumTest {
+    private static final Logger LOG = LoggerFactory.getLogger(QuorumBase.class);
+       
+    /**
+     * startServers(true) puts two observers into a 5 peer ensemble
+     */
+    void startServers() throws Exception {
+        startServers(true);
+    }
+           
+    protected void shutdown(QuorumPeer qp) {
+        QuorumBase.shutdown(qp);
+    }
+
+    @Test
+    public void testHierarchicalQuorum() throws Throwable {
+        cht.runHammer(5, 10);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverLETest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverLETest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverLETest.java
new file mode 100644
index 0000000..123ba0b
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverLETest.java
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.test;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumStats;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ObserverLETest extends ZKTestCase {
+    final QuorumBase qb = new QuorumBase();
+    final ClientTest ct = new ClientTest();
+
+    @Before
+    public void establishThreeParticipantOneObserverEnsemble() throws Exception {
+        qb.setUp(true);
+        ct.hostPort = qb.hostPort;
+        ct.setUpAll();
+        qb.s5.shutdown();
+    }
+
+    @After
+    public void shutdownQuorum() throws Exception {
+        ct.tearDownAll();
+        qb.tearDown();
+    }
+
+    /**
+     * See ZOOKEEPER-1294. Confirms that an observer will not support the quorum
+     * of a leader by forming a 5-node, 2-observer ensemble (so quorum size is 2).
+     * When all but the leader and one observer are shut down, the leader should
+     * enter the 'looking' state, not stay in the 'leading' state.
+     */
+    @Test
+    public void testLEWithObserver() throws Exception {
+        QuorumPeer leader = null;
+        for (QuorumPeer server : Arrays.asList(qb.s1, qb.s2, qb.s3)) {
+            if (server.getServerState().equals(
+                    QuorumStats.Provider.FOLLOWING_STATE)) {
+                server.shutdown();
+                assertTrue("Waiting for server down", ClientBase
+                        .waitForServerDown("127.0.0.1:"
+                                + server.getClientPort(),
+                                ClientBase.CONNECTION_TIMEOUT));
+            } else {
+                assertNull("More than one leader found", leader);
+                leader = server;
+            }
+        }
+        assertTrue("Leader is not in Looking state", ClientBase
+                .waitForServerState(leader, ClientBase.CONNECTION_TIMEOUT,
+                        QuorumStats.Provider.LOOKING_STATE));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java
new file mode 100644
index 0000000..03b4000
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ObserverQuorumHammerTest extends QuorumHammerTest {
+    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
+
+    
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        qb.setUp(true);
+        cht.hostPort = qb.hostPort;
+        cht.setUpAll();
+    }
+   
+    @Test
+    public void testHammerBasic() throws Throwable {
+        cht.testHammerBasic();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverTest.java
new file mode 100644
index 0000000..f7a82c6
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ObserverTest.java
@@ -0,0 +1,233 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.util.concurrent.CountDownLatch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException.ConnectionLossException;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooKeeper.States;
+import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ObserverTest extends QuorumPeerTestBase implements Watcher{
+    protected static final Logger LOG =
+        LoggerFactory.getLogger(ObserverTest.class);    
+      
+    CountDownLatch latch;
+    ZooKeeper zk;
+    WatchedEvent lastEvent = null;
+          
+    /**
+     * This test ensures two things:
+     * 1. That Observers can successfully proxy requests to the ensemble.
+     * 2. That Observers don't participate in leader elections.
+     * The second is tested by constructing an ensemble where a leader would
+     * be elected if and only if an Observer voted. 
+     * @throws Exception
+     */
+    @Test
+    public void testObserver() throws Exception {
+        ClientBase.setupTestEnv();
+        // We expect two notifications before we want to continue        
+        latch = new CountDownLatch(2);
+        
+        final int PORT_QP1 = PortAssignment.unique();
+        final int PORT_QP2 = PortAssignment.unique();
+        final int PORT_OBS = PortAssignment.unique();
+        final int PORT_QP_LE1 = PortAssignment.unique();
+        final int PORT_QP_LE2 = PortAssignment.unique();
+        final int PORT_OBS_LE = PortAssignment.unique();
+
+        final int CLIENT_PORT_QP1 = PortAssignment.unique();
+        final int CLIENT_PORT_QP2 = PortAssignment.unique();
+        final int CLIENT_PORT_OBS = PortAssignment.unique();
+
+        
+        String quorumCfgSection =
+            "electionAlg=3\n" + 
+            "server.1=127.0.0.1:" + (PORT_QP1)
+            + ":" + (PORT_QP_LE1)
+            + "\nserver.2=127.0.0.1:" + (PORT_QP2)
+            + ":" + (PORT_QP_LE2)
+            + "\nserver.3=127.0.0.1:" 
+            + (PORT_OBS)+ ":" + (PORT_OBS_LE) + ":observer";
+        String obsCfgSection =  quorumCfgSection + "\npeerType=observer";
+        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
+        MainThread q2 = new MainThread(2, CLIENT_PORT_QP2, quorumCfgSection);
+        MainThread q3 = new MainThread(3, CLIENT_PORT_OBS, obsCfgSection);
+        q1.start();
+        q2.start();
+        q3.start();
+        Assert.assertTrue("waiting for server 1 being up",
+                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1,
+                        CONNECTION_TIMEOUT));
+        Assert.assertTrue("waiting for server 2 being up",
+                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP2,
+                        CONNECTION_TIMEOUT));
+        Assert.assertTrue("waiting for server 3 being up",
+                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_OBS,
+                        CONNECTION_TIMEOUT));        
+        
+        zk = new ZooKeeper("127.0.0.1:" + CLIENT_PORT_OBS,
+                ClientBase.CONNECTION_TIMEOUT, this);
+        zk.create("/obstest", "test".getBytes(),Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        
+        // Assert that commands are getting forwarded correctly
+        Assert.assertEquals(new String(zk.getData("/obstest", null, null)), "test");
+        
+        // Now check that other commands don't blow everything up
+        zk.sync("/", null, null);
+        zk.setData("/obstest", "test2".getBytes(), -1);
+        zk.getChildren("/", false);
+        
+        Assert.assertEquals(zk.getState(), States.CONNECTED);
+        
+        LOG.info("Shutting down server 2");
+        // Now kill one of the other real servers        
+        q2.shutdown();
+                
+        Assert.assertTrue("Waiting for server 2 to shut down",
+                    ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_QP2, 
+                                    ClientBase.CONNECTION_TIMEOUT));
+
+        LOG.info("Server 2 down");
+
+        // Now the resulting ensemble shouldn't be quorate         
+        latch.await();        
+        Assert.assertNotSame("Client is still connected to non-quorate cluster", 
+                KeeperState.SyncConnected,lastEvent.getState());
+
+        LOG.info("Latch returned");
+
+        try {
+            Assert.assertFalse("Shouldn't get a response when cluster not quorate!",
+                    new String(zk.getData("/obstest", null, null)).equals("test"));
+        }
+        catch (ConnectionLossException c) {
+            LOG.info("Connection loss exception caught - ensemble not quorate (this is expected)");
+        }
+        
+        latch = new CountDownLatch(1);
+
+        LOG.info("Restarting server 2");
+
+        // Bring it back
+        q2 = new MainThread(2, CLIENT_PORT_QP2, quorumCfgSection);
+        q2.start();
+        
+        LOG.info("Waiting for server 2 to come up");
+        Assert.assertTrue("waiting for server 2 being up",
+                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP2,
+                        CONNECTION_TIMEOUT));
+        
+        LOG.info("Server 2 started, waiting for latch");
+
+        latch.await();
+        // It's possible our session expired - but this is ok, shows we 
+        // were able to talk to the ensemble
+        Assert.assertTrue("Client didn't reconnect to quorate ensemble (state was" +
+                lastEvent.getState() + ")",
+                (KeeperState.SyncConnected==lastEvent.getState() ||
+                KeeperState.Expired==lastEvent.getState())); 
+
+        LOG.info("Shutting down all servers");
+
+        q1.shutdown();
+        q2.shutdown();
+        q3.shutdown();
+        
+        LOG.info("Closing zk client");
+
+        zk.close();        
+        Assert.assertTrue("Waiting for server 1 to shut down",
+                ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_QP1, 
+                                ClientBase.CONNECTION_TIMEOUT));
+        Assert.assertTrue("Waiting for server 2 to shut down",
+                ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_QP2, 
+                                ClientBase.CONNECTION_TIMEOUT));
+        Assert.assertTrue("Waiting for server 3 to shut down",
+                ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_OBS, 
+                                ClientBase.CONNECTION_TIMEOUT));
+    
+    }
+    
+    /**
+     * Implementation of watcher interface.
+     */
+    public void process(WatchedEvent event) {
+        lastEvent = event;
+        latch.countDown();
+        LOG.info("Latch got event :: " + event);        
+    }    
+    
+    /**
+     * This test ensures that an Observer does not elect itself as a leader, or
+     * indeed come up properly, if it is the lone member of an ensemble.
+     * @throws Exception
+     */
+    @Test
+    public void testObserverOnly() throws Exception {
+        ClientBase.setupTestEnv();
+        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
+        
+        String quorumCfgSection =
+            "server.1=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + ":observer\npeerType=observer\n";
+                    
+        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
+        q1.start();
+        q1.join(ClientBase.CONNECTION_TIMEOUT);
+        Assert.assertFalse(q1.isAlive());
+    }    
+    
+    /**
+     * Ensure that observer only comes up when a proper ensemble is configured.
+     * (and will not come up with standalone server).
+     */
+    @Test
+    public void testObserverWithStandlone() throws Exception {
+        ClientBase.setupTestEnv();
+        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
+
+        String quorumCfgSection =
+            "server.1=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + ":observer\n"
+            + "server.2=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + "\npeerType=observer\n";
+
+        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
+        q1.start();
+        q1.join(ClientBase.CONNECTION_TIMEOUT);
+        Assert.assertFalse(q1.isAlive());
+    }    
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumBase.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumBase.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumBase.java
new file mode 100644
index 0000000..49cff35
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumBase.java
@@ -0,0 +1,341 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.server.quorum.Election;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.util.OSMXBean;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class QuorumBase extends ClientBase {
+    private static final Logger LOG = LoggerFactory.getLogger(QuorumBase.class);
+
+    File s1dir, s2dir, s3dir, s4dir, s5dir;
+    QuorumPeer s1, s2, s3, s4, s5;
+    protected int port1;
+    protected int port2;
+    protected int port3;
+    protected int port4;
+    protected int port5;
+    
+    protected int portLE1;
+    protected int portLE2;
+    protected int portLE3;
+    protected int portLE4;
+    protected int portLE5;
+
+    @Test
+    // This just avoids complaints by junit
+    public void testNull() {
+    }
+    
+    @Override
+    public void setUp() throws Exception {
+        setUp(false);
+    }
+        
+    protected void setUp(boolean withObservers) throws Exception {
+        LOG.info("QuorumBase.setup " + getTestName());
+        setupTestEnv();
+
+        JMXEnv.setUp();
+
+        setUpAll();
+
+        port1 = PortAssignment.unique();
+        port2 = PortAssignment.unique();
+        port3 = PortAssignment.unique();
+        port4 = PortAssignment.unique();
+        port5 = PortAssignment.unique();
+        
+        portLE1 = PortAssignment.unique();
+        portLE2 = PortAssignment.unique();
+        portLE3 = PortAssignment.unique();
+        portLE4 = PortAssignment.unique();
+        portLE5 = PortAssignment.unique();
+        
+        hostPort = "127.0.0.1:" + port1
+            + ",127.0.0.1:" + port2
+            + ",127.0.0.1:" + port3
+            + ",127.0.0.1:" + port4
+            + ",127.0.0.1:" + port5;
+        LOG.info("Ports are: " + hostPort);
+
+        s1dir = ClientBase.createTmpDir();
+        s2dir = ClientBase.createTmpDir();
+        s3dir = ClientBase.createTmpDir();
+        s4dir = ClientBase.createTmpDir();
+        s5dir = ClientBase.createTmpDir();
+
+        startServers(withObservers);
+
+        OSMXBean osMbean = new OSMXBean();
+        if (osMbean.getUnix() == true) {
+            LOG.info("Initial fdcount is: "
+                    + osMbean.getOpenFileDescriptorCount());
+        }
+
+        LOG.info("Setup finished");
+    }
+    
+    void startServers() throws Exception {
+        startServers(false);        
+    }
+    
+    void startServers(boolean withObservers) throws Exception {
+        int tickTime = 2000;
+        int initLimit = 3;
+        int syncLimit = 3;
+        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>();
+        peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000,
+                                                    portLE1 + 1000,
+                LearnerType.PARTICIPANT));
+        peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000,
+                                                    portLE2 + 1000,
+                LearnerType.PARTICIPANT));
+        peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000,
+                                                    portLE3 + 1000,
+                LearnerType.PARTICIPANT));
+        peers.put(Long.valueOf(4), new QuorumServer(4, "127.0.0.1", port4 + 1000,
+                                                    portLE4 + 1000,
+                LearnerType.PARTICIPANT));
+        peers.put(Long.valueOf(5), new QuorumServer(5, "127.0.0.1", port5 + 1000,
+                                                    portLE5 + 1000,
+                LearnerType.PARTICIPANT));
+        
+        if (withObservers) {
+            peers.get(Long.valueOf(4)).type = LearnerType.OBSERVER;        
+            peers.get(Long.valueOf(5)).type = LearnerType.OBSERVER;
+        }
+
+        LOG.info("creating QuorumPeer 1 port " + port1);
+        s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit);
+        Assert.assertEquals(port1, s1.getClientPort());
+        LOG.info("creating QuorumPeer 2 port " + port2);
+        s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit);
+        Assert.assertEquals(port2, s2.getClientPort());
+        LOG.info("creating QuorumPeer 3 port " + port3);
+        s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit);
+        Assert.assertEquals(port3, s3.getClientPort());
+        LOG.info("creating QuorumPeer 4 port " + port4);
+        s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit);
+        Assert.assertEquals(port4, s4.getClientPort());
+        LOG.info("creating QuorumPeer 5 port " + port5);
+        s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit);
+        Assert.assertEquals(port5, s5.getClientPort());
+        
+        if (withObservers) {
+            s4.setLearnerType(LearnerType.OBSERVER);
+            s5.setLearnerType(LearnerType.OBSERVER);
+        }
+        
+        LOG.info("QuorumPeer 1 voting view: " + s1.getVotingView());
+        LOG.info("QuorumPeer 2 voting view: " + s2.getVotingView());
+        LOG.info("QuorumPeer 3 voting view: " + s3.getVotingView());
+        LOG.info("QuorumPeer 4 voting view: " + s4.getVotingView());
+        LOG.info("QuorumPeer 5 voting view: " + s5.getVotingView());       
+        
+        LOG.info("start QuorumPeer 1");
+        s1.start();
+        LOG.info("start QuorumPeer 2");
+        s2.start();
+        LOG.info("start QuorumPeer 3");
+        s3.start();
+        LOG.info("start QuorumPeer 4");
+        s4.start();
+        LOG.info("start QuorumPeer 5");
+        s5.start();
+        LOG.info("started QuorumPeer 5");
+
+        LOG.info ("Checking ports " + hostPort);
+        for (String hp : hostPort.split(",")) {
+            Assert.assertTrue("waiting for server up",
+                       ClientBase.waitForServerUp(hp,
+                                    CONNECTION_TIMEOUT));
+            LOG.info(hp + " is accepting client connections");
+        }
+
+        // interesting to see what's there...
+        JMXEnv.dump();
+        // make sure we have these 5 servers listed
+        Set<String> ensureNames = new LinkedHashSet<String>();
+        for (int i = 1; i <= 5; i++) {
+            ensureNames.add("InMemoryDataTree");
+        }
+        for (int i = 1; i <= 5; i++) {
+            ensureNames.add("name0=ReplicatedServer_id" + i
+                 + ",name1=replica." + i + ",name2=");
+        }
+        for (int i = 1; i <= 5; i++) {
+            for (int j = 1; j <= 5; j++) {
+                ensureNames.add("name0=ReplicatedServer_id" + i
+                     + ",name1=replica." + j);
+            }
+        }
+        for (int i = 1; i <= 5; i++) {
+            ensureNames.add("name0=ReplicatedServer_id" + i);
+        }
+        JMXEnv.ensureAll(ensureNames.toArray(new String[ensureNames.size()]));
+    }
+    
+    
+    public void setupServers() throws IOException {        
+        setupServer(1);
+        setupServer(2);
+        setupServer(3);
+        setupServer(4);
+        setupServer(5);
+    }
+
+    HashMap<Long,QuorumServer> peers = null;
+    public void setupServer(int i) throws IOException {
+        int tickTime = 2000;
+        int initLimit = 3;
+        int syncLimit = 3;
+        
+        if(peers == null){
+            peers = new HashMap<Long,QuorumServer>();
+
+            peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000,
+                                                        portLE1 + 1000,
+                LearnerType.PARTICIPANT));
+            peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000,
+                                                        portLE2 + 1000,
+                LearnerType.PARTICIPANT));
+            peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000,
+                                                        portLE3 + 1000,
+                LearnerType.PARTICIPANT));
+            peers.put(Long.valueOf(4), new QuorumServer(4, "127.0.0.1", port4 + 1000,
+                                                        portLE4 + 1000,
+                LearnerType.PARTICIPANT));
+            peers.put(Long.valueOf(5), new QuorumServer(5, "127.0.0.1", port5 + 1000,
+                                                        portLE5 + 1000,
+                LearnerType.PARTICIPANT));
+        }
+        
+        switch(i){
+        case 1:
+            LOG.info("creating QuorumPeer 1 port " + port1);
+            s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit);
+            Assert.assertEquals(port1, s1.getClientPort());
+            break;
+        case 2:
+            LOG.info("creating QuorumPeer 2 port " + port2);
+            s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit);
+            Assert.assertEquals(port2, s2.getClientPort());
+            break;
+        case 3:  
+            LOG.info("creating QuorumPeer 3 port " + port3);
+            s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit);
+            Assert.assertEquals(port3, s3.getClientPort());
+            break;
+        case 4:
+            LOG.info("creating QuorumPeer 4 port " + port4);
+            s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit);
+            Assert.assertEquals(port4, s4.getClientPort());
+            break;
+        case 5:
+            LOG.info("creating QuorumPeer 5 port " + port5);
+            s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit);
+            Assert.assertEquals(port5, s5.getClientPort());
+        }
+    }
+    
+    @Override
+    public void tearDown() throws Exception {
+        LOG.info("TearDown started");
+        
+        OSMXBean osMbean = new OSMXBean();
+        if (osMbean.getUnix() == true) {
+            LOG.info("fdcount after test is: "
+                    + osMbean.getOpenFileDescriptorCount());
+        }
+
+        shutdownServers();
+
+        for (String hp : hostPort.split(",")) {
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(hp,
+                                           ClientBase.CONNECTION_TIMEOUT));
+            LOG.info(hp + " is no longer accepting client connections");
+        }
+
+        JMXEnv.tearDown();
+    }
+    public void shutdownServers() {
+        shutdown(s1);
+        shutdown(s2);
+        shutdown(s3);
+        shutdown(s4);
+        shutdown(s5);
+    }
+
+    public static void shutdown(QuorumPeer qp) {
+        try {
+            LOG.info("Shutting down quorum peer " + qp.getName());
+            qp.shutdown();
+            Election e = qp.getElectionAlg();
+            if (e != null) {
+                LOG.info("Shutting down leader election " + qp.getName());
+                e.shutdown();
+            } else {
+                LOG.info("No election available to shutdown " + qp.getName());
+            }
+            LOG.info("Waiting for " + qp.getName() + " to exit thread");
+            long readTimeout = qp.getTickTime() * qp.getInitLimit();
+            long connectTimeout = qp.getTickTime() * qp.getSyncLimit();
+            long maxTimeout = Math.max(readTimeout, connectTimeout);
+            maxTimeout = Math.max(maxTimeout, ClientBase.CONNECTION_TIMEOUT);
+            qp.join(maxTimeout * 2);
+            if (qp.isAlive()) {
+                Assert.fail("QP failed to shutdown in " + (maxTimeout * 2) + " seconds: " + qp.getName());
+            }
+        } catch (InterruptedException e) {
+            LOG.debug("QP interrupted: " + qp.getName(), e);
+        }
+    }
+
+    protected TestableZooKeeper createClient()
+        throws IOException, InterruptedException
+    {
+        return createClient(hostPort);
+    }
+
+    protected TestableZooKeeper createClient(String hp)
+        throws IOException, InterruptedException
+    {
+        CountdownWatcher watcher = new CountdownWatcher();
+        return createClient(watcher, hp);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java
new file mode 100644
index 0000000..e5b377e
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java
@@ -0,0 +1,51 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+import org.apache.zookeeper.ZKTestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class QuorumHammerTest extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(QuorumHammerTest.class);
+    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
+
+    protected final QuorumBase qb = new QuorumBase();
+    protected final ClientHammerTest cht = new ClientHammerTest();
+
+    @Before
+    public void setUp() throws Exception {
+        qb.setUp();
+        cht.hostPort = qb.hostPort;
+        cht.setUpAll();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        cht.tearDownAll();
+        qb.tearDown();
+    }
+
+    @Test
+    public void testHammerBasic() throws Throwable {
+        cht.testHammerBasic();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java
new file mode 100644
index 0000000..bef1a33
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java
@@ -0,0 +1,63 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.Quotas;
+import org.apache.zookeeper.StatsTrack;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooKeeperMain;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class QuorumQuotaTest extends QuorumBase {
+    private static final Logger LOG =
+        LoggerFactory.getLogger(QuorumQuotaTest.class);
+
+    @Test
+    public void testQuotaWithQuorum() throws Exception {
+        ZooKeeper zk = createClient();
+        zk.setData("/", "some".getBytes(), -1);
+        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        int i = 0;
+        for (i=0; i < 300;i++) {
+            zk.create("/a/" + i, "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        }
+        ZooKeeperMain.createQuota(zk, "/a", 1000L, 5000);
+        String statPath = Quotas.quotaZookeeper + "/a"+ "/" + Quotas.statNode;
+        byte[] data = zk.getData(statPath, false, new Stat());
+        StatsTrack st = new StatsTrack(new String(data));
+        Assert.assertTrue("bytes are set", st.getBytes() == 1204L);
+        Assert.assertTrue("num count is set", st.getCount() == 301);
+        for (i=300; i < 600; i++) {
+            zk.create("/a/" + i, "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        }
+        data = zk.getData(statPath, false, new Stat());
+        st = new StatsTrack(new String(data));
+        Assert.assertTrue("bytes are set", st.getBytes() == 2404L);
+        Assert.assertTrue("num count is set", st.getCount() == 601);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumTest.java
new file mode 100644
index 0000000..6f827ec
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumTest.java
@@ -0,0 +1,296 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.quorum.Leader;
+import org.apache.zookeeper.server.quorum.LearnerHandler;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class QuorumTest extends ZKTestCase {
+    private static final Logger LOG = LoggerFactory.getLogger(QuorumTest.class);
+    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
+
+    private final QuorumBase qb = new QuorumBase();
+    private final ClientTest ct = new ClientTest();
+
+    @Before
+    public void setUp() throws Exception {
+        qb.setUp();
+        ct.hostPort = qb.hostPort;
+        ct.setUpAll();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        ct.tearDownAll();
+        qb.tearDown();
+    }
+
+    @Test
+    public void testDeleteWithChildren() throws Exception {
+        ct.testDeleteWithChildren();
+    }
+
+    @Test
+    public void testPing() throws Exception {
+        ct.testPing();
+    }
+
+    @Test
+    public void testSequentialNodeNames()
+        throws IOException, InterruptedException, KeeperException
+    {
+        ct.testSequentialNodeNames();
+    }
+
+    @Test
+    public void testACLs() throws Exception {
+        ct.testACLs();
+    }
+
+    @Test
+    public void testClientwithoutWatcherObj() throws IOException,
+            InterruptedException, KeeperException
+    {
+        ct.testClientwithoutWatcherObj();
+    }
+
+    @Test
+    public void testClientWithWatcherObj() throws IOException,
+            InterruptedException, KeeperException
+    {
+        ct.testClientWithWatcherObj();
+    }
+
+    @Test
+    public void testGetView() {
+        Assert.assertEquals(5,qb.s1.getView().size());
+        Assert.assertEquals(5,qb.s2.getView().size());
+        Assert.assertEquals(5,qb.s3.getView().size());
+        Assert.assertEquals(5,qb.s4.getView().size());
+        Assert.assertEquals(5,qb.s5.getView().size());
+    }
+
+    @Test
+    public void testViewContains() {
+        // Test view contains self
+        Assert.assertTrue(qb.s1.viewContains(qb.s1.getId()));
+
+        // Test view contains other servers
+        Assert.assertTrue(qb.s1.viewContains(qb.s2.getId()));
+
+        // Test view does not contain non-existant servers
+        Assert.assertFalse(qb.s1.viewContains(-1L));
+    }
+
+    volatile int counter = 0;
+    volatile int errors = 0;
+    @Test
+    public void testLeaderShutdown() throws IOException, InterruptedException, KeeperException {
+        ZooKeeper zk = new DisconnectableZooKeeper(qb.hostPort, ClientBase.CONNECTION_TIMEOUT, new Watcher() {
+            public void process(WatchedEvent event) {
+        }});
+        zk.create("/blah", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/blah/blah", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        Leader leader = qb.s1.leader;
+        if (leader == null) leader = qb.s2.leader;
+        if (leader == null) leader = qb.s3.leader;
+        if (leader == null) leader = qb.s4.leader;
+        if (leader == null) leader = qb.s5.leader;
+        Assert.assertNotNull(leader);
+        for(int i = 0; i < 5000; i++) {
+            zk.setData("/blah/blah", new byte[0], -1, new AsyncCallback.StatCallback() {
+                public void processResult(int rc, String path, Object ctx,
+                        Stat stat) {
+                    counter++;
+                    if (rc != 0) {
+                        errors++;
+                    }
+                }
+            }, null);
+        }
+        for(LearnerHandler f : leader.getForwardingFollowers()) {
+            f.getSocket().shutdownInput();
+        }
+        for(int i = 0; i < 5000; i++) {
+            zk.setData("/blah/blah", new byte[0], -1, new AsyncCallback.StatCallback() {
+                public void processResult(int rc, String path, Object ctx,
+                        Stat stat) {
+                    counter++;
+                    if (rc != 0) {
+                        errors++;
+                    }
+                }
+            }, null);
+        }
+        // check if all the followers are alive
+        Assert.assertTrue(qb.s1.isAlive());
+        Assert.assertTrue(qb.s2.isAlive());
+        Assert.assertTrue(qb.s3.isAlive());
+        Assert.assertTrue(qb.s4.isAlive());
+        Assert.assertTrue(qb.s5.isAlive());
+        zk.close();
+    }
+
+    @Test
+    public void testMultipleWatcherObjs() throws IOException,
+            InterruptedException, KeeperException
+    {
+        ct.testMutipleWatcherObjs();
+    }
+
+    /**
+     * Make sure that we can change sessions
+     *  from follower to leader.
+     *
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws KeeperException
+     */
+    @Test
+    public void testSessionMoved() throws Exception {
+        String hostPorts[] = qb.hostPort.split(",");
+        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(hostPorts[0],
+                ClientBase.CONNECTION_TIMEOUT, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        zk.create("/sessionMoveTest", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+        // we want to loop through the list twice
+        for(int i = 0; i < hostPorts.length*2; i++) {
+            zk.dontReconnect();
+            // This should stomp the zk handle
+            DisconnectableZooKeeper zknew =
+                new DisconnectableZooKeeper(hostPorts[(i+1)%hostPorts.length],
+                    ClientBase.CONNECTION_TIMEOUT,
+                    new Watcher() {public void process(WatchedEvent event) {
+                    }},
+                    zk.getSessionId(),
+                    zk.getSessionPasswd());
+            zknew.setData("/", new byte[1], -1);
+            final int result[] = new int[1];
+            result[0] = Integer.MAX_VALUE;
+            zknew.sync("/", new AsyncCallback.VoidCallback() {
+                    public void processResult(int rc, String path, Object ctx) {
+                        synchronized(result) { result[0] = rc; result.notify(); }
+                    }
+                }, null);
+            synchronized(result) {
+                if(result[0] == Integer.MAX_VALUE) {
+                    result.wait(5000);
+                }
+            }
+            LOG.info(hostPorts[(i+1)%hostPorts.length] + " Sync returned " + result[0]);
+            Assert.assertTrue(result[0] == KeeperException.Code.OK.intValue());
+            try {
+                zk.setData("/", new byte[1], -1);
+                Assert.fail("Should have lost the connection");
+            } catch(KeeperException.ConnectionLossException e) {
+            }
+            zk = zknew;
+        }
+        zk.close();
+    }
+
+    private static class DiscoWatcher implements Watcher {
+        volatile boolean zkDisco = false;
+        public void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.Disconnected) {
+                zkDisco = true;
+            }
+        }
+    }
+
+    /**
+     * Connect to two different servers with two different handles using the same session and
+     * make sure we cannot do any changes.
+     */
+    @Test
+    @Ignore
+    public void testSessionMove() throws Exception {
+        String hps[] = qb.hostPort.split(",");
+        DiscoWatcher oldWatcher = new DiscoWatcher();
+        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(hps[0],
+                ClientBase.CONNECTION_TIMEOUT, oldWatcher);
+        zk.create("/t1", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+        zk.dontReconnect();
+        // This should stomp the zk handle
+        DiscoWatcher watcher = new DiscoWatcher();
+        DisconnectableZooKeeper zknew = new DisconnectableZooKeeper(hps[1],
+                ClientBase.CONNECTION_TIMEOUT, watcher, zk.getSessionId(),
+                zk.getSessionPasswd());
+        zknew.create("/t2", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+        try {
+            zk.create("/t3", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+            Assert.fail("Should have lost the connection");
+        } catch(KeeperException.ConnectionLossException e) {
+            // wait up to 30 seconds for the disco to be delivered
+            for (int i = 0; i < 30; i++) {
+                if (oldWatcher.zkDisco) {
+                    break;
+                }
+                Thread.sleep(1000);
+            }
+            Assert.assertTrue(oldWatcher.zkDisco);
+        }
+
+        ArrayList<ZooKeeper> toClose = new ArrayList<ZooKeeper>();
+        toClose.add(zknew);
+        // Let's just make sure it can still move
+        for(int i = 0; i < 10; i++) {
+            zknew.dontReconnect();
+            zknew = new DisconnectableZooKeeper(hps[1],
+                    ClientBase.CONNECTION_TIMEOUT, new DiscoWatcher(),
+                    zk.getSessionId(), zk.getSessionPasswd());
+            toClose.add(zknew);
+            zknew.create("/t-"+i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+        }
+        for (ZooKeeper z: toClose) {
+            z.close();
+        }
+        zk.close();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumUtil.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumUtil.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumUtil.java
new file mode 100644
index 0000000..1f2dbbc
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumUtil.java
@@ -0,0 +1,261 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.server.quorum.Election;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
+import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
+import org.apache.zookeeper.server.util.OSMXBean;
+import org.junit.Assert;
+
+/**
+ * Utility for quorum testing. Setups 2n+1 peers and allows to start/stop all
+ * peers, particular peer, n peers etc.
+ */
+public class QuorumUtil {
+
+    // TODO partitioning of peers and clients
+
+    // TODO refactor QuorumBase to be special case of this
+
+    private static final Logger LOG = LoggerFactory.getLogger(QuorumUtil.class);
+
+    public class PeerStruct {
+        public int id;
+        public QuorumPeer peer;
+        public File dataDir;
+        public int clientPort;
+    }
+
+    private final Map<Long, QuorumServer> peersView = new HashMap<Long, QuorumServer>();
+
+    private final Map<Integer, PeerStruct> peers = new HashMap<Integer, PeerStruct>();
+
+    public final int N;
+
+    public final int ALL;
+
+    private String hostPort;
+
+    private int tickTime;
+
+    private int initLimit;
+
+    private int syncLimit;
+
+    private int electionAlg;
+
+    /**
+     * Initializes 2n+1 quorum peers which will form a ZooKeeper ensemble.
+     *
+     * @param n
+     *            number of peers in the ensemble will be 2n+1
+     */
+    public QuorumUtil(int n, int syncLimit) throws RuntimeException {
+        try {
+            ClientBase.setupTestEnv();
+            JMXEnv.setUp();
+
+            N = n;
+            ALL = 2 * N + 1;
+            tickTime = 2000;
+            initLimit = 3;
+            this.syncLimit = syncLimit;
+            electionAlg = 3;
+            hostPort = "";
+
+            for (int i = 1; i <= ALL; ++i) {
+                PeerStruct ps = new PeerStruct();
+                ps.id = i;
+                ps.dataDir = ClientBase.createTmpDir();
+                ps.clientPort = PortAssignment.unique();
+                peers.put(i, ps);
+
+                peersView.put(Long.valueOf(i),
+                              new QuorumServer(i, "127.0.0.1", ps.clientPort + 1000,
+                                               PortAssignment.unique() + 1000,
+                                               LearnerType.PARTICIPANT));
+                hostPort += "127.0.0.1:" + ps.clientPort + ((i == ALL) ? "" : ",");
+            }
+            for (int i = 1; i <= ALL; ++i) {
+                PeerStruct ps = peers.get(i);
+                LOG.info("Creating QuorumPeer " + i + "; public port " + ps.clientPort);
+                ps.peer = new QuorumPeer(peersView, ps.dataDir, ps.dataDir, ps.clientPort,
+                        electionAlg, ps.id, tickTime, initLimit, syncLimit);
+                Assert.assertEquals(ps.clientPort, ps.peer.getClientPort());
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public QuorumUtil(int n) throws RuntimeException {
+        this(n, 3);
+    }
+
+    public PeerStruct getPeer(int id) {
+        return peers.get(id);
+    }
+
+    public void startAll() throws IOException {
+        shutdownAll();
+        for (int i = 1; i <= ALL; ++i) {
+            start(i);
+            LOG.info("Started QuorumPeer " + i);
+        }
+
+        LOG.info("Checking ports " + hostPort);
+        for (String hp : hostPort.split(",")) {
+            Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(hp,
+                    ClientBase.CONNECTION_TIMEOUT));
+            LOG.info(hp + " is accepting client connections");
+        }
+
+        // interesting to see what's there...
+        try {
+            JMXEnv.dump();
+            // make sure we have all servers listed
+            Set<String> ensureNames = new LinkedHashSet<String>();
+            for (int i = 1; i <= ALL; ++i) {
+                ensureNames.add("InMemoryDataTree");
+            }
+            for (int i = 1; i <= ALL; ++i) {
+                ensureNames
+                        .add("name0=ReplicatedServer_id" + i + ",name1=replica." + i + ",name2=");
+            }
+            for (int i = 1; i <= ALL; ++i) {
+                for (int j = 1; j <= ALL; ++j) {
+                    ensureNames.add("name0=ReplicatedServer_id" + i + ",name1=replica." + j);
+                }
+            }
+            for (int i = 1; i <= ALL; ++i) {
+                ensureNames.add("name0=ReplicatedServer_id" + i);
+            }
+            JMXEnv.ensureAll(ensureNames.toArray(new String[ensureNames.size()]));
+        } catch (IOException e) {
+            LOG.warn("IOException during JMXEnv operation", e);
+        } catch (InterruptedException e) {
+            LOG.warn("InterruptedException during JMXEnv operation", e);
+        }
+    }
+
+    /**
+     * Start first N+1 peers.
+     */
+    public void startQuorum() throws IOException {
+        shutdownAll();
+        for (int i = 1; i <= N + 1; ++i) {
+            start(i);
+        }
+        for (int i = 1; i <= N + 1; ++i) {
+            Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                    + getPeer(i).clientPort, ClientBase.CONNECTION_TIMEOUT));
+        }
+    }
+
+    public void start(int id) throws IOException {
+        PeerStruct ps = getPeer(id);
+        LOG.info("Creating QuorumPeer " + ps.id + "; public port " + ps.clientPort);
+        ps.peer = new QuorumPeer(peersView, ps.dataDir, ps.dataDir, ps.clientPort, electionAlg,
+                ps.id, tickTime, initLimit, syncLimit);
+        Assert.assertEquals(ps.clientPort, ps.peer.getClientPort());
+
+        ps.peer.start();    
+    }
+    
+    public void restart(int id) throws IOException {
+        start(id);
+        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                + getPeer(id).clientPort, ClientBase.CONNECTION_TIMEOUT));
+    }
+    
+    public void startThenShutdown(int id) throws IOException {
+        PeerStruct ps = getPeer(id);
+        LOG.info("Creating QuorumPeer " + ps.id + "; public port " + ps.clientPort);
+        ps.peer = new QuorumPeer(peersView, ps.dataDir, ps.dataDir, ps.clientPort, electionAlg,
+                ps.id, tickTime, initLimit, syncLimit);
+        Assert.assertEquals(ps.clientPort, ps.peer.getClientPort());
+
+        ps.peer.start();
+        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
+                + getPeer(id).clientPort, ClientBase.CONNECTION_TIMEOUT));
+        shutdown(id);
+    }
+
+    public void shutdownAll() {
+        for (int i = 1; i <= ALL; ++i) {
+            shutdown(i);
+        }
+        for (String hp : hostPort.split(",")) {
+            Assert.assertTrue("Waiting for server down", ClientBase.waitForServerDown(hp,
+                    ClientBase.CONNECTION_TIMEOUT));
+            LOG.info(hp + " is no longer accepting client connections");
+        }
+    }
+
+    public void shutdown(int id) {
+        QuorumPeer qp = getPeer(id).peer;
+        try {
+            LOG.info("Shutting down quorum peer " + qp.getName());
+            qp.shutdown();
+            Election e = qp.getElectionAlg();
+            if (e != null) {
+                LOG.info("Shutting down leader election " + qp.getName());
+                e.shutdown();
+            } else {
+                LOG.info("No election available to shutdown " + qp.getName());
+            }
+            LOG.info("Waiting for " + qp.getName() + " to exit thread");
+            qp.join(30000);
+            if (qp.isAlive()) {
+                Assert.fail("QP failed to shutdown in 30 seconds: " + qp.getName());
+            }
+        } catch (InterruptedException e) {
+            LOG.debug("QP interrupted: " + qp.getName(), e);
+        }
+    }
+
+    public String getConnString() {
+        return hostPort;
+    }
+
+    public void tearDown() throws Exception {
+        LOG.info("TearDown started");
+
+        OSMXBean osMbean = new OSMXBean();
+        if (osMbean.getUnix() == true) {    
+            LOG.info("fdcount after test is: " + osMbean.getOpenFileDescriptorCount());
+        }
+
+        shutdownAll();
+        JMXEnv.tearDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java
new file mode 100644
index 0000000..6e46edc
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java
@@ -0,0 +1,171 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.File;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class QuorumZxidSyncTest extends ZKTestCase {
+    QuorumBase qb = new QuorumBase();
+
+    @Before
+    public void setUp() throws Exception {
+        qb.setUp();
+    }
+
+    /**
+     * find out what happens when a follower connects to leader that is behind
+     */
+    @Test
+    public void testBehindLeader() throws Exception {
+        // crank up the epoch numbers
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        ZooKeeper zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        zk.create("/0", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.close();
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        zk.create("/1", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.close();
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        zk.create("/2", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.close();
+        qb.shutdownServers();
+        deleteFiles(qb.s1dir);
+        deleteFiles(qb.s2dir);
+        deleteFiles(qb.s3dir);
+        deleteFiles(qb.s4dir);
+        qb.setupServers();
+        qb.s1.start();
+        qb.s2.start();
+        qb.s3.start();
+        qb.s4.start();
+        Assert.assertTrue("Servers didn't come up", ClientBase.waitForServerUp(qb.hostPort, 10000));
+        qb.s5.start();
+        String hostPort = "127.0.0.1:" + qb.s5.getClientPort();
+        Assert.assertFalse("Servers came up, but shouldn't have since it's ahead of leader",
+                ClientBase.waitForServerUp(hostPort, 10000));
+    }
+
+    private void deleteFiles(File f) {
+        File v = new File(f, "version-2");
+        for(File c: v.listFiles()) {
+            c.delete();
+        }
+    }
+
+    /**
+     * find out what happens when the latest state is in the snapshots not
+     * the logs.
+     */
+    @Test
+    public void testLateLogs() throws Exception {
+        // crank up the epoch numbers
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        ZooKeeper zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        zk.create("/0", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.close();
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        zk.create("/1", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.close();
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        qb.shutdownServers();
+        deleteLogs(qb.s1dir);
+        deleteLogs(qb.s2dir);
+        deleteLogs(qb.s3dir);
+        deleteLogs(qb.s4dir);
+        deleteLogs(qb.s5dir);
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        zk.create("/2", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.close();
+        qb.shutdownServers();
+        qb.startServers();
+        ClientBase.waitForServerUp(qb.hostPort, 10000);
+        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
+            public void process(WatchedEvent event) {
+            }});
+        boolean saw2 = false;
+        for(String child: zk.getChildren("/", false)) {
+            if (child.equals("2")) {
+                saw2 = true;
+            }
+        }
+        zk.close();
+        Assert.assertTrue("Didn't see /2 (went back in time)", saw2);
+    }
+
+    private void deleteLogs(File f) {
+        File v = new File(f, "version-2");
+        for(File c: v.listFiles()) {
+            if (c.getName().startsWith("log")) {
+                c.delete();
+            }
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        qb.tearDown();
+    }
+}


[13/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathTrie.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathTrie.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathTrie.java
new file mode 100644
index 0000000..73053e0
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathTrie.java
@@ -0,0 +1,293 @@
+ /**
+ * 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.
+ */
+
+package org.apache.zookeeper.common;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * a class that implements prefix matching for 
+ * components of a filesystem path. the trie
+ * looks like a tree with edges mapping to 
+ * the component of a path.
+ * example /ab/bc/cf would map to a trie
+ *           /
+ *        ab/
+ *        (ab)
+ *      bc/
+ *       / 
+ *      (bc)
+ *   cf/
+ *   (cf)
+ */    
+public class PathTrie {
+    /**
+     * the logger for this class
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(PathTrie.class);
+    
+    /**
+     * the root node of PathTrie
+     */
+    private final TrieNode rootNode ;
+    
+    static class TrieNode {
+        boolean property = false;
+        final HashMap<String, TrieNode> children;
+        TrieNode parent = null;
+        /**
+         * create a trienode with parent
+         * as parameter
+         * @param parent the parent of this trienode
+         */
+        private TrieNode(TrieNode parent) {
+            children = new HashMap<String, TrieNode>();
+            this.parent = parent;
+        }
+        
+        /**
+         * get the parent of this node
+         * @return the parent node
+         */
+        TrieNode getParent() {
+            return this.parent;
+        }
+        
+        /**
+         * set the parent of this node
+         * @param parent the parent to set to
+         */
+        void setParent(TrieNode parent) {
+            this.parent = parent;
+        }
+        
+        /**
+         * a property that is set 
+         * for a node - making it 
+         * special.
+         */
+        void setProperty(boolean prop) {
+            this.property = prop;
+        }
+        
+        /** the property of this
+         * node 
+         * @return the property for this
+         * node
+         */
+        boolean getProperty() {
+            return this.property;
+        }
+        /**
+         * add a child to the existing node
+         * @param childName the string name of the child
+         * @param node the node that is the child
+         */
+        void addChild(String childName, TrieNode node) {
+            synchronized(children) {
+                if (children.containsKey(childName)) {
+                    return;
+                }
+                children.put(childName, node);
+            }
+        }
+     
+        /**
+         * delete child from this node
+         * @param childName the string name of the child to 
+         * be deleted
+         */
+        void deleteChild(String childName) {
+            synchronized(children) {
+                if (!children.containsKey(childName)) {
+                    return;
+                }
+                TrieNode childNode = children.get(childName);
+                // this is the only child node.
+                if (childNode.getChildren().length == 1) { 
+                    childNode.setParent(null);
+                    children.remove(childName);
+                }
+                else {
+                    // their are more child nodes
+                    // so just reset property.
+                    childNode.setProperty(false);
+                }
+            }
+        }
+        
+        /**
+         * return the child of a node mapping
+         * to the input childname
+         * @param childName the name of the child
+         * @return the child of a node
+         */
+        TrieNode getChild(String childName) {
+            synchronized(children) {
+               if (!children.containsKey(childName)) {
+                   return null;
+               }
+               else {
+                   return children.get(childName);
+               }
+            }
+        }
+
+        /**
+         * get the list of children of this 
+         * trienode.
+         * @param node to get its children
+         * @return the string list of its children
+         */
+        String[] getChildren() {
+           synchronized(children) {
+               return children.keySet().toArray(new String[0]);
+           }
+        }
+        
+        /**
+         * get the string representation
+         * for this node
+         */
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Children of trienode: ");
+            synchronized(children) {
+                for (String str: children.keySet()) {
+                    sb.append(" " + str);
+                }
+            }
+            return sb.toString();
+        }
+    }
+    
+    /**
+     * construct a new PathTrie with
+     * a root node of /
+     */
+    public PathTrie() {
+        this.rootNode = new TrieNode(null);
+    }
+    
+    /**
+     * add a path to the path trie 
+     * @param path
+     */
+    public void addPath(String path) {
+        if (path == null) {
+            return;
+        }
+        String[] pathComponents = path.split("/");
+        TrieNode parent = rootNode;
+        String part = null;
+        if (pathComponents.length <= 1) {
+            throw new IllegalArgumentException("Invalid path " + path);
+        }
+        for (int i=1; i<pathComponents.length; i++) {
+            part = pathComponents[i];
+            if (parent.getChild(part) == null) {
+                parent.addChild(part, new TrieNode(parent));
+            }
+            parent = parent.getChild(part);
+        }
+        parent.setProperty(true);
+    }
+    
+    /**
+     * delete a path from the trie
+     * @param path the path to be deleted
+     */
+    public void deletePath(String path) {
+        if (path == null) {
+            return;
+        }
+        String[] pathComponents = path.split("/");
+        TrieNode parent = rootNode;
+        String part = null;
+        if (pathComponents.length <= 1) { 
+            throw new IllegalArgumentException("Invalid path " + path);
+        }
+        for (int i=1; i<pathComponents.length; i++) {
+            part = pathComponents[i];
+            if (parent.getChild(part) == null) {
+                //the path does not exist 
+                return;
+            }
+            parent = parent.getChild(part);
+            LOG.info("{}",parent);
+        }
+        TrieNode realParent  = parent.getParent();
+        realParent.deleteChild(part);
+    }
+    
+    /**
+     * return the largest prefix for the input path.
+     * @param path the input path
+     * @return the largest prefix for the input path.
+     */
+    public String findMaxPrefix(String path) {
+        if (path == null) {
+            return null;
+        }
+        if ("/".equals(path)) {
+            return path;
+        }
+        String[] pathComponents = path.split("/");
+        TrieNode parent = rootNode;
+        List<String> components = new ArrayList<String>();
+        if (pathComponents.length <= 1) {
+            throw new IllegalArgumentException("Invalid path " + path);
+        }
+        int i = 1;
+        String part = null;
+        StringBuilder sb = new StringBuilder();
+        int lastindex = -1;
+        while((i < pathComponents.length)) {
+            if (parent.getChild(pathComponents[i]) != null) {
+                part = pathComponents[i];
+                parent = parent.getChild(part);
+                components.add(part);
+                if (parent.getProperty()) {
+                    lastindex = i-1;
+                }
+            }
+            else {
+                break;
+            }
+            i++;
+        }
+        for (int j=0; j< (lastindex+1); j++) {
+            sb.append("/" + components.get(j));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * clear all nodes
+     */
+    public void clear() {
+        for(String child : rootNode.getChildren()) {
+            rootNode.deleteChild(child);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathUtils.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathUtils.java
new file mode 100644
index 0000000..2a6c7ef
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/PathUtils.java
@@ -0,0 +1,103 @@
+ /**
+ * 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.
+ */
+
+package org.apache.zookeeper.common;
+
+
+/**
+ * Path related utilities
+ */    
+public class PathUtils {
+	
+	/** validate the provided znode path string
+	 * @param path znode path string
+	 * @param isSequential if the path is being created
+	 * with a sequential flag
+	 * @throws IllegalArgumentException if the path is invalid
+	 */
+	public static void validatePath(String path, boolean isSequential) 
+		throws IllegalArgumentException {
+		validatePath(isSequential? path + "1": path);
+	}
+	
+    /**
+     * Validate the provided znode path string
+     * @param path znode path string
+     * @throws IllegalArgumentException if the path is invalid
+     */
+    public static void validatePath(String path) throws IllegalArgumentException {
+        if (path == null) {
+            throw new IllegalArgumentException("Path cannot be null");
+        }
+        if (path.length() == 0) {
+            throw new IllegalArgumentException("Path length must be > 0");
+        }
+        if (path.charAt(0) != '/') {
+            throw new IllegalArgumentException(
+                         "Path must start with / character");
+        }
+        if (path.length() == 1) { // done checking - it's the root
+            return;
+        }
+        if (path.charAt(path.length() - 1) == '/') {
+            throw new IllegalArgumentException(
+                         "Path must not end with / character");
+        }
+
+        String reason = null;
+        char lastc = '/';
+        char chars[] = path.toCharArray();
+        char c;
+        for (int i = 1; i < chars.length; lastc = chars[i], i++) {
+            c = chars[i];
+
+            if (c == 0) {
+                reason = "null character not allowed @" + i;
+                break;
+            } else if (c == '/' && lastc == '/') {
+                reason = "empty node name specified @" + i;
+                break;
+            } else if (c == '.' && lastc == '.') {
+                if (chars[i-2] == '/' &&
+                        ((i + 1 == chars.length)
+                                || chars[i+1] == '/')) {
+                    reason = "relative paths not allowed @" + i;
+                    break;
+                }
+            } else if (c == '.') {
+                if (chars[i-1] == '/' &&
+                        ((i + 1 == chars.length)
+                                || chars[i+1] == '/')) {
+                    reason = "relative paths not allowed @" + i;
+                    break;
+                }
+            } else if (c > '\u0000' && c < '\u001f'
+                    || c > '\u007f' && c < '\u009F'
+                    || c > '\ud800' && c < '\uf8ff'
+                    || c > '\ufff0' && c < '\uffff') {
+                reason = "invalid character @" + i;
+                break;
+            }
+        }
+
+        if (reason != null) {
+            throw new IllegalArgumentException(
+                    "Invalid path string \"" + path + "\" caused by " + reason);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/common/Time.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/Time.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/Time.java
new file mode 100644
index 0000000..83e53f0
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/Time.java
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.common;
+
+import java.util.Date;
+
+public class Time {
+    /**
+     * Returns time in milliseconds as does System.currentTimeMillis(),
+     * but uses elapsed time from an arbitrary epoch more like System.nanoTime().
+     * The difference is that if somebody changes the system clock,
+     * Time.currentElapsedTime will change but nanoTime won't. On the other hand,
+     * all of ZK assumes that time is measured in milliseconds.
+     * @return  The time in milliseconds from some arbitrary point in time.
+     */
+    public static long currentElapsedTime() {
+        return System.nanoTime() / 1000000;
+    }
+
+    /**
+     * Explicitly returns system dependent current wall time.
+     * @return Current time in msec.
+     */
+    public static long currentWallTime() {
+        return System.currentTimeMillis();
+    }
+
+    /**
+     * This is to convert the elapsedTime to a Date.
+     * @return A date object indicated by the elapsedTime.
+     */
+    public static Date elapsedTimeToDate(long elapsedTime) {
+        long wallTime = currentWallTime() + elapsedTime - currentElapsedTime();
+        return new Date(wallTime);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/util/SecurityUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/util/SecurityUtils.java b/zookeeper-server/src/main/java/org/apache/zookeeper/util/SecurityUtils.java
new file mode 100644
index 0000000..67484e4
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/util/SecurityUtils.java
@@ -0,0 +1,298 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.util;
+
+import java.security.Principal;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.apache.zookeeper.SaslClientCallbackHandler;
+import org.apache.zookeeper.server.auth.KerberosName;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+import org.slf4j.Logger;
+
+public final class SecurityUtils {
+
+    public static final String QUORUM_HOSTNAME_PATTERN = "_HOST";
+
+    /**
+     * Create an instance of a SaslClient. It will return null if there is an exception.
+     *
+     * @param subject subject
+     * @param servicePrincipal principal
+     * @param protocol name of the protocol for which the authentication is being performed
+     * @param serverName name of the server to authenticate to
+     * @param LOG logger
+     * @param entity can be either zookeeper client or quorum learner
+     *
+     * @return saslclient object
+     * @throws SaslException
+     */
+    public static SaslClient createSaslClient(final Subject subject,
+            final String servicePrincipal, final String protocol,
+            final String serverName, final Logger LOG, final String entity) throws SaslException {
+        SaslClient saslClient;
+        // Use subject.getPrincipals().isEmpty() as an indication of which SASL
+        // mechanism to use: if empty, use DIGEST-MD5; otherwise, use GSSAPI.
+        if (subject.getPrincipals().isEmpty()) {
+            // no principals: must not be GSSAPI: use DIGEST-MD5 mechanism
+            // instead.
+            LOG.info("{} will use DIGEST-MD5 as SASL mechanism.", entity);
+            String[] mechs = { "DIGEST-MD5" };
+            String username = (String) (subject.getPublicCredentials()
+                    .toArray()[0]);
+            String password = (String) (subject.getPrivateCredentials()
+                    .toArray()[0]);
+            // 'domain' parameter is hard-wired between the server and client
+            saslClient = Sasl.createSaslClient(mechs, username, protocol,
+                    serverName, null, new SaslClientCallbackHandler(password, entity));
+            return saslClient;
+        } else { // GSSAPI.
+            final Object[] principals = subject.getPrincipals().toArray();
+            // determine client principal from subject.
+            final Principal clientPrincipal = (Principal) principals[0];
+            boolean usingNativeJgss = Boolean
+                    .getBoolean("sun.security.jgss.native");
+            if (usingNativeJgss) {
+                // http://docs.oracle.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
+                // """
+                // In addition, when performing operations as a particular
+                // Subject, e.g. Subject.doAs(...) or
+                // Subject.doAsPrivileged(...),
+                // the to-be-used GSSCredential should be added to Subject's
+                // private credential set. Otherwise, the GSS operations will
+                // fail since no credential is found.
+                // """
+                try {
+                    GSSManager manager = GSSManager.getInstance();
+                    Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
+                    GSSCredential cred = manager.createCredential(null,
+                            GSSContext.DEFAULT_LIFETIME, krb5Mechanism,
+                            GSSCredential.INITIATE_ONLY);
+                    subject.getPrivateCredentials().add(cred);
+                    LOG.debug("Added private credential to {} principal name: '{}'",
+                            entity, clientPrincipal);
+                } catch (GSSException ex) {
+                    LOG.warn("Cannot add private credential to subject; "
+                                    + "authentication at the server may fail", ex);
+                }
+            }
+            final KerberosName clientKerberosName = new KerberosName(
+                    clientPrincipal.getName());
+            // assume that server and client are in the same realm (by default;
+            // unless the system property
+            // "zookeeper.server.realm" is set).
+            String serverRealm = System.getProperty("zookeeper.server.realm",
+                    clientKerberosName.getRealm());
+            KerberosName serviceKerberosName = new KerberosName(
+                    servicePrincipal + "@" + serverRealm);
+            final String serviceName = serviceKerberosName.getServiceName();
+            final String serviceHostname = serviceKerberosName.getHostName();
+            final String clientPrincipalName = clientKerberosName.toString();
+            try {
+                saslClient = Subject.doAs(subject,
+                        new PrivilegedExceptionAction<SaslClient>() {
+                            public SaslClient run() throws SaslException {
+                                LOG.info("{} will use GSSAPI as SASL mechanism.", entity);
+                                String[] mechs = { "GSSAPI" };
+                                LOG.debug("creating sasl client: {}={};service={};serviceHostname={}",
+                                        new Object[] { entity, clientPrincipalName, serviceName, serviceHostname });
+                                SaslClient saslClient = Sasl.createSaslClient(
+                                        mechs, clientPrincipalName, serviceName,
+                                        serviceHostname, null,
+                                        new SaslClientCallbackHandler(null, entity));
+                                return saslClient;
+                            }
+                        });
+                return saslClient;
+            } catch (Exception e) {
+                LOG.error("Exception while trying to create SASL client", e);
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Create an instance of a SaslServer. It will return null if there is an exception.
+     *
+     * @param subject subject
+     * @param protocol protocol
+     * @param serverName server name
+     * @param callbackHandler login callback handler
+     * @param LOG logger
+     * @return sasl server object
+     */
+    public static SaslServer createSaslServer(final Subject subject,
+            final String protocol, final String serverName,
+            final CallbackHandler callbackHandler, final Logger LOG) {
+        if (subject != null) {
+            // server is using a JAAS-authenticated subject: determine service
+            // principal name and hostname from zk server's subject.
+            if (subject.getPrincipals().size() > 0) {
+                try {
+                    final Object[] principals = subject.getPrincipals()
+                            .toArray();
+                    final Principal servicePrincipal = (Principal) principals[0];
+
+                    // e.g. servicePrincipalNameAndHostname :=
+                    // "zookeeper/myhost.foo.com@FOO.COM"
+                    final String servicePrincipalNameAndHostname = servicePrincipal
+                            .getName();
+
+                    int indexOf = servicePrincipalNameAndHostname.indexOf("/");
+
+                    // e.g. servicePrincipalName := "zookeeper"
+                    final String servicePrincipalName = servicePrincipalNameAndHostname
+                            .substring(0, indexOf);
+
+                    // e.g. serviceHostnameAndKerbDomain :=
+                    // "myhost.foo.com@FOO.COM"
+                    final String serviceHostnameAndKerbDomain = servicePrincipalNameAndHostname
+                            .substring(indexOf + 1,
+                                    servicePrincipalNameAndHostname.length());
+
+                    indexOf = serviceHostnameAndKerbDomain.indexOf("@");
+                    // e.g. serviceHostname := "myhost.foo.com"
+                    final String serviceHostname = serviceHostnameAndKerbDomain
+                            .substring(0, indexOf);
+
+                    // TODO: should depend on zoo.cfg specified mechs, but if
+                    // subject is non-null, it can be assumed to be GSSAPI.
+                    final String mech = "GSSAPI";
+
+                    LOG.debug("serviceHostname is '" + serviceHostname + "'");
+                    LOG.debug("servicePrincipalName is '" + servicePrincipalName
+                            + "'");
+                    LOG.debug("SASL mechanism(mech) is '" + mech + "'");
+
+                    boolean usingNativeJgss = Boolean
+                            .getBoolean("sun.security.jgss.native");
+                    if (usingNativeJgss) {
+                        // http://docs.oracle.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
+                        // """
+                        // In addition, when performing operations as a
+                        // particular
+                        // Subject, e.g. Subject.doAs(...) or
+                        // Subject.doAsPrivileged(...), the to-be-used
+                        // GSSCredential should be added to Subject's
+                        // private credential set. Otherwise, the GSS operations
+                        // will fail since no credential is found.
+                        // """
+                        try {
+                            GSSManager manager = GSSManager.getInstance();
+                            Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
+                            GSSName gssName = manager.createName(
+                                    servicePrincipalName + "@"
+                                            + serviceHostname,
+                                    GSSName.NT_HOSTBASED_SERVICE);
+                            GSSCredential cred = manager.createCredential(
+                                    gssName, GSSContext.DEFAULT_LIFETIME,
+                                    krb5Mechanism, GSSCredential.ACCEPT_ONLY);
+                            subject.getPrivateCredentials().add(cred);
+                            LOG.debug("Added private credential to service principal name: '{}',"
+                                            + " GSSCredential name: {}", servicePrincipalName, cred.getName());
+                        } catch (GSSException ex) {
+                            LOG.warn("Cannot add private credential to subject; "
+                                            + "clients authentication may fail", ex);
+                        }
+                    }
+                    try {
+                        return Subject.doAs(subject,
+                                new PrivilegedExceptionAction<SaslServer>() {
+                                    public SaslServer run() {
+                                        try {
+                                            SaslServer saslServer;
+                                            saslServer = Sasl.createSaslServer(
+                                                    mech, servicePrincipalName,
+                                                    serviceHostname, null,
+                                                    callbackHandler);
+                                            return saslServer;
+                                        } catch (SaslException e) {
+                                            LOG.error("Zookeeper Server failed to create a SaslServer to interact with a client during session initiation: ", e);
+                                            return null;
+                                        }
+                                    }
+                                });
+                    } catch (PrivilegedActionException e) {
+                        // TODO: exit server at this point(?)
+                        LOG.error("Zookeeper Quorum member experienced a PrivilegedActionException exception while creating a SaslServer using a JAAS principal context:", e);
+                    }
+                } catch (IndexOutOfBoundsException e) {
+                    LOG.error("server principal name/hostname determination error: ", e);
+                }
+            } else {
+                // JAAS non-GSSAPI authentication: assuming and supporting only
+                // DIGEST-MD5 mechanism for now.
+                // TODO: use 'authMech=' value in zoo.cfg.
+                try {
+                    SaslServer saslServer = Sasl.createSaslServer("DIGEST-MD5",
+                            protocol, serverName, null, callbackHandler);
+                    return saslServer;
+                } catch (SaslException e) {
+                    LOG.error("Zookeeper Quorum member failed to create a SaslServer to interact with a client during session initiation", e);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Convert Kerberos principal name pattern to valid Kerberos principal name.
+     * If the principal name contains hostname pattern "_HOST" then it replaces
+     * with the given hostname, which should be fully-qualified domain name.
+     *
+     * @param principalConfig
+     *            the Kerberos principal name conf value to convert
+     * @param hostname
+     *            the fully-qualified domain name used for substitution
+     * @return converted Kerberos principal name
+     */
+    public static String getServerPrincipal(String principalConfig,
+            String hostname) {
+        String[] components = getComponents(principalConfig);
+        if (components == null || components.length != 2
+                || !components[1].equals(QUORUM_HOSTNAME_PATTERN)) {
+            return principalConfig;
+        } else {
+            return replacePattern(components, hostname);
+        }
+    }
+
+    private static String[] getComponents(String principalConfig) {
+        if (principalConfig == null)
+            return null;
+        return principalConfig.split("[/]");
+    }
+
+    private static String replacePattern(String[] components, String hostname) {
+        return components[0] + "/" + hostname.toLowerCase();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java b/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java
new file mode 100644
index 0000000..7285a2b
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java
@@ -0,0 +1,178 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.version.util;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class VerGen {
+    private static final String PACKAGE_NAME = "org.apache.zookeeper.version";
+    private static final String TYPE_NAME = "Info";
+
+    static void printUsage() {
+        System.out.print("Usage:\tjava  -cp <classpath> org.apache.zookeeper."
+                + "version.util.VerGen maj.min.micro[-qualifier] rev buildDate");
+        System.exit(1);
+    }
+
+    public static void generateFile(File outputDir, Version version, String rev, String buildDate) throws IOException
+    {
+        String path = PACKAGE_NAME.replaceAll("\\.", "/");
+        File pkgdir = new File(outputDir, path);
+        if (!pkgdir.exists()) {
+            // create the pkg directory
+            boolean ret = pkgdir.mkdirs();
+            if (!ret) {
+                System.out.println("Cannnot create directory: " + path);
+                System.exit(1);
+            }
+        } else if (!pkgdir.isDirectory()) {
+            // not a directory
+            System.out.println(path + " is not a directory.");
+            System.exit(1);
+        }
+        File file = new File(pkgdir, TYPE_NAME + ".java");
+        FileWriter w = null;
+        try {
+            w = new FileWriter(file);
+            w.write("// Do not edit!\n// File generated by org.apache.zookeeper"
+                    + ".version.util.VerGen.\n");
+            w.write("/**\n");
+            w.write("* Licensed to the Apache Software Foundation (ASF) under one\n");
+            w.write("* or more contributor license agreements.  See the NOTICE file\n");
+            w.write("* distributed with this work for additional information\n");
+            w.write("* regarding copyright ownership.  The ASF licenses this file\n");
+            w.write("* to you under the Apache License, Version 2.0 (the\n");
+            w.write("* \"License\"); you may not use this file except in compliance\n");
+            w.write("* with the License.  You may obtain a copy of the License at\n");
+            w.write("*\n");
+            w.write("*     http://www.apache.org/licenses/LICENSE-2.0\n");
+            w.write("*\n");
+            w.write("* Unless required by applicable law or agreed to in writing, software\n");
+            w.write("* distributed under the License is distributed on an \"AS IS\" BASIS,\n");
+            w.write("* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n");
+            w.write("* See the License for the specific language governing permissions and\n");
+            w.write("* limitations under the License.\n");
+            w.write("*/\n");
+            w.write("\n");
+            w.write("package " + PACKAGE_NAME + ";\n\n");
+            w.write("public interface " + TYPE_NAME + " {\n");
+            w.write("    int MAJOR=" + version.maj + ";\n");
+            w.write("    int MINOR=" + version.min + ";\n");
+            w.write("    int MICRO=" + version.micro + ";\n");
+            w.write("    String QUALIFIER="
+                    + (version.qualifier == null ? null :
+                        "\"" + version.qualifier + "\"")
+                    + ";\n");
+            if (rev.equals("-1")) {
+                System.out.println("Unknown REVISION number, using " + rev);
+            }
+            w.write("    int REVISION=-1; //TODO: remove as related to SVN VCS\n");
+            w.write("    String REVISION_HASH=\"" + rev + "\";\n");
+            w.write("    String BUILD_DATE=\"" + buildDate
+                    + "\";\n");
+            w.write("}\n");
+        } finally {
+            if (w != null) {
+                try {
+                    w.close();
+                } catch (IOException e) {
+                    System.out.println("Unable to close file writer"
+                            + e.getMessage());
+                }
+            }
+        }
+    }
+
+    public static class Version {
+        public int maj;
+        public int min;
+        public int micro;
+        public String qualifier;
+    }
+
+    public static Version parseVersionString(String input) {
+        Version result = new Version();
+
+        Pattern p = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)((\\.\\d+)*)(-(.+))?$");
+        Matcher m = p.matcher(input);
+
+        if (!m.matches()) {
+            return null;
+        }
+        result.maj = Integer.parseInt(m.group(1));
+        result.min = Integer.parseInt(m.group(2));
+        result.micro = Integer.parseInt(m.group(3));
+        if (m.groupCount() == 7) {
+            result.qualifier = m.group(7);
+        } else {
+            result.qualifier = null;
+        }
+        return result;
+    }
+
+    /**
+     * Emits a org.apache.zookeeper.version.Info interface file with version and
+     * revision information constants set to the values passed in as command
+     * line parameters. The file is created in the current directory. <br>
+     * Usage: java org.apache.zookeeper.version.util.VerGen maj.min.micro[-qualifier]
+     * rev buildDate
+     *
+     * @param args
+     *            <ul>
+     *            <li>maj - major version number
+     *            <li>min - minor version number
+     *            <li>micro - minor minor version number
+     *            <li>qualifier - optional qualifier (dash followed by qualifier text)
+     *            <li>rev - current Git revision number
+     *            <li>buildDate - date the build
+     *            </ul>
+     */
+    public static void main(String[] args) {
+        if (args.length != 3)
+            printUsage();
+        try {
+            Version version = parseVersionString(args[0]);
+            if (version == null) {
+                System.err.println(
+                        "Invalid version number format, must be \"x.y.z(-.*)?\"");
+                System.exit(1);
+            }
+            String rev = args[1];
+            if (rev == null || rev.trim().isEmpty()) {
+                rev = "-1";
+            } else {
+                rev = rev.trim();
+            }
+            generateFile(new File("."), version, rev, args[2]);
+        } catch (NumberFormatException e) {
+            System.err.println(
+                    "All version-related parameters must be valid integers!");
+            throw e;
+        } catch (IOException e) {
+            System.out.println("Unable to generate version.Info file: "
+                    + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/resources/lib/cobertura/README.txt
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/resources/lib/cobertura/README.txt b/zookeeper-server/src/main/resources/lib/cobertura/README.txt
new file mode 100644
index 0000000..f5ba88f
--- /dev/null
+++ b/zookeeper-server/src/main/resources/lib/cobertura/README.txt
@@ -0,0 +1,3 @@
+Download the cobertura binary from the following location and unpack it into this directory. Run "cobertura-report" target from build.xml to generate coverage report.
+
+http://cobertura.sourceforge.net/download.html


[28/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLTest.java
deleted file mode 100644
index 793265c..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ACLTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Id;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ACLTest extends ZKTestCase implements Watcher {
-    private static final Logger LOG = LoggerFactory.getLogger(ACLTest.class);
-    private static final String HOSTPORT =
-        "127.0.0.1:" + PortAssignment.unique();
-    private volatile CountDownLatch startSignal;
-
-    @Test
-    public void testDisconnectedAddAuth() throws Exception {
-        File tmpDir = ClientBase.createTmpDir();
-        ClientBase.setupTestEnv();
-        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-        SyncRequestProcessor.setSnapCount(1000);
-        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-        f.startup(zks);
-        try {
-            LOG.info("starting up the zookeeper server .. waiting");
-            Assert.assertTrue("waiting for server being up",
-                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
-            ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
-            try {
-                zk.addAuthInfo("digest", "pat:test".getBytes());
-                zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
-            } finally {
-                zk.close();
-            }
-        } finally {
-            f.shutdown();
-            zks.shutdown();
-            Assert.assertTrue("waiting for server down",
-                    ClientBase.waitForServerDown(HOSTPORT,
-                            ClientBase.CONNECTION_TIMEOUT));
-        }
-    }
-
-    /**
-     * Verify that acl optimization of storing just
-     * a few acls and there references in the data
-     * node is actually working.
-     */
-    @Test
-    public void testAcls() throws Exception {
-        File tmpDir = ClientBase.createTmpDir();
-        ClientBase.setupTestEnv();
-        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-        SyncRequestProcessor.setSnapCount(1000);
-        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-        f.startup(zks);
-        ZooKeeper zk;
-        String path;
-        try {
-            LOG.info("starting up the zookeeper server .. waiting");
-            Assert.assertTrue("waiting for server being up",
-                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
-            zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
-            LOG.info("starting creating acls");
-            for (int i = 0; i < 100; i++) {
-                path = "/" + i;
-                zk.create(path, path.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-            }
-            Assert.assertTrue("size of the acl map ", (1 == zks.getZKDatabase().getAclSize()));
-            for (int j = 100; j < 200; j++) {
-                path = "/" + j;
-                ACL acl = new ACL();
-                acl.setPerms(0);
-                Id id = new Id();
-                id.setId("1.1.1."+j);
-                id.setScheme("ip");
-                acl.setId(id);
-                ArrayList<ACL> list = new ArrayList<ACL>();
-                list.add(acl);
-                zk.create(path, path.getBytes(), list, CreateMode.PERSISTENT);
-            }
-            Assert.assertTrue("size of the acl map ", (101 == zks.getZKDatabase().getAclSize()));
-        } finally {
-            // now shutdown the server and restart it
-            f.shutdown();
-            zks.shutdown();
-            Assert.assertTrue("waiting for server down",
-                    ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
-        }
-        startSignal = new CountDownLatch(1);
-
-        zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-        f = ServerCnxnFactory.createFactory(PORT, -1);
-
-        f.startup(zks);
-        try {
-            Assert.assertTrue("waiting for server up",
-                       ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
-    
-            startSignal.await(CONNECTION_TIMEOUT,
-                    TimeUnit.MILLISECONDS);
-            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
-    
-            Assert.assertTrue("acl map ", (101 == zks.getZKDatabase().getAclSize()));
-            for (int j = 200; j < 205; j++) {
-                path = "/" + j;
-                ACL acl = new ACL();
-                acl.setPerms(0);
-                Id id = new Id();
-                id.setId("1.1.1."+j);
-                id.setScheme("ip");
-                acl.setId(id);
-                ArrayList<ACL> list = new ArrayList<ACL>();
-                list.add(acl);
-                zk.create(path, path.getBytes(), list, CreateMode.PERSISTENT);
-            }
-            Assert.assertTrue("acl map ", (106 == zks.getZKDatabase().getAclSize()));
-    
-            zk.close();
-        } finally {
-            f.shutdown();
-            zks.shutdown();
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown(HOSTPORT,
-                               ClientBase.CONNECTION_TIMEOUT));
-        }
-
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatcherEvent)
-     */
-    public void process(WatchedEvent event) {
-        LOG.info("Event:" + event.getState() + " " + event.getType() + " "
-                 + event.getPath());
-        if (event.getState() == KeeperState.SyncConnected) {
-            if (startSignal != null && startSignal.getCount() > 0) {
-                LOG.info("startsignal.countDown()");
-                startSignal.countDown();
-            } else {
-                LOG.warn("startsignal " + startSignal);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
deleted file mode 100644
index ebfc963..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-import static org.apache.zookeeper.test.ClientBase.verifyThreadTerminated;
-
-import java.util.LinkedList;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.AsyncCallback.StringCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class AsyncHammerTest extends ZKTestCase
-    implements StringCallback, VoidCallback, DataCallback
-{
-    private static final Logger LOG = LoggerFactory.getLogger(AsyncHammerTest.class);
-
-    private QuorumBase qb = new QuorumBase();
-
-    private volatile boolean bang;
-
-    public void setUp(boolean withObservers) throws Exception {
-        qb.setUp(withObservers);
-    }
-
-    protected void restart() throws Exception {
-        LOG.info("RESTARTING " + getTestName());
-        qb.tearDown();
-
-        // don't call setup - we don't want to reassign ports/dirs, etc...
-        JMXEnv.setUp();
-        qb.startServers();
-    }
-
-    public void tearDown() throws Exception {
-        LOG.info("Test clients shutting down");
-        qb.tearDown();
-    }
-
-    /**
-     * Create /test- sequence nodes asynchronously, max 30 outstanding
-     */
-    class HammerThread extends Thread implements StringCallback, VoidCallback {
-        private static final int MAX_OUTSTANDING = 30;
-
-        private TestableZooKeeper zk;
-        private int outstanding;
-
-        private volatile boolean failed = false;
-
-        public HammerThread(String name) {
-            super(name);
-        }
-
-        public void run() {
-            try {
-                CountdownWatcher watcher = new CountdownWatcher();
-                zk = new TestableZooKeeper(qb.hostPort, CONNECTION_TIMEOUT,
-                        watcher);
-                watcher.waitForConnected(CONNECTION_TIMEOUT);
-                while(bang) {
-                    incOutstanding(); // before create otw race
-                    zk.create("/test-", new byte[0], Ids.OPEN_ACL_UNSAFE,
-                            CreateMode.PERSISTENT_SEQUENTIAL, this, null);
-                }
-            } catch (InterruptedException e) {
-                if (bang) {
-                    LOG.error("sanity check Assert.failed!!!"); // sanity check
-                    return;
-                }
-            } catch (Exception e) {
-                LOG.error("Client create operation Assert.failed", e);
-                return;
-            } finally {
-                if (zk != null) {
-                    try {
-                        zk.close();
-                        if (!zk.testableWaitForShutdown(CONNECTION_TIMEOUT)) {
-                            failed = true;
-                            LOG.error("Client did not shutdown");
-                        }
-                    } catch (InterruptedException e) {
-                        LOG.info("Interrupted", e);
-                    }
-                }
-            }
-        }
-
-        private synchronized void incOutstanding() throws InterruptedException {
-            outstanding++;
-            while(outstanding > MAX_OUTSTANDING) {
-                wait();
-            }
-        }
-
-        private synchronized void decOutstanding() {
-            outstanding--;
-            Assert.assertTrue("outstanding >= 0", outstanding >= 0);
-            notifyAll();
-        }
-
-        public void process(WatchedEvent event) {
-            // ignore for purposes of this test
-        }
-
-        public void processResult(int rc, String path, Object ctx, String name) {
-            if (rc != KeeperException.Code.OK.intValue()) {
-                if (bang) {
-                    failed = true;
-                    LOG.error("Create Assert.failed for 0x"
-                            + Long.toHexString(zk.getSessionId())
-                            + "with rc:" + rc + " path:" + path);
-                }
-                decOutstanding();
-                return;
-            }
-            try {
-                decOutstanding();
-                zk.delete(name, -1, this, null);
-            } catch (Exception e) {
-                if (bang) {
-                    failed = true;
-                    LOG.error("Client delete Assert.failed", e);
-                }
-            }
-        }
-
-        public void processResult(int rc, String path, Object ctx) {
-            if (rc != KeeperException.Code.OK.intValue()) {
-                if (bang) {
-                    failed = true;
-                    LOG.error("Delete Assert.failed for 0x"
-                            + Long.toHexString(zk.getSessionId())
-                            + "with rc:" + rc + " path:" + path);
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testHammer() throws Exception {
-        setUp(false);
-        bang = true;
-        LOG.info("Starting hammers");
-        HammerThread[] hammers = new HammerThread[100];
-        for (int i = 0; i < hammers.length; i++) {
-            hammers[i] = new HammerThread("HammerThread-" + i);
-            hammers[i].start();
-        }
-        LOG.info("Started hammers");
-        Thread.sleep(5000); // allow the clients to run for max 5sec
-        bang = false;
-        LOG.info("Stopping hammers");
-        for (int i = 0; i < hammers.length; i++) {
-            hammers[i].interrupt();
-            verifyThreadTerminated(hammers[i], 60000);
-            Assert.assertFalse(hammers[i].failed);
-        }
-
-        // before restart
-        LOG.info("Hammers stopped, verifying consistency");
-        qb.verifyRootOfAllServersMatch(qb.hostPort);
-
-        restart();
-
-        // after restart
-        LOG.info("Verifying hammers 2");
-        qb.verifyRootOfAllServersMatch(qb.hostPort);
-        tearDown();
-    }
-
-    @Test
-    public void testObserversHammer() throws Exception {
-        setUp(true);
-        bang = true;
-        Thread[] hammers = new Thread[100];
-        for (int i = 0; i < hammers.length; i++) {
-            hammers[i] = new HammerThread("HammerThread-" + i);
-            hammers[i].start();
-        }
-        Thread.sleep(5000); // allow the clients to run for max 5sec
-        bang = false;
-        for (int i = 0; i < hammers.length; i++) {
-            hammers[i].interrupt();
-            verifyThreadTerminated(hammers[i], 60000);
-        }
-        // before restart
-        qb.verifyRootOfAllServersMatch(qb.hostPort);
-        tearDown();
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx, String name) {
-        synchronized(ctx) {
-            ((LinkedList<Integer>)ctx).add(rc);
-            ctx.notifyAll();
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx) {
-        synchronized(ctx) {
-            ((LinkedList<Integer>)ctx).add(rc);
-            ctx.notifyAll();
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx, byte[] data,
-            Stat stat) {
-        synchronized(ctx) {
-            ((LinkedList<Integer>)ctx).add(rc);
-            ctx.notifyAll();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOps.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOps.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOps.java
deleted file mode 100644
index 2dbe644..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOps.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.AsyncCallback.ACLCallback;
-import org.apache.zookeeper.AsyncCallback.Children2Callback;
-import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.AsyncCallback.StatCallback;
-import org.apache.zookeeper.AsyncCallback.StringCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.KeeperException.Code;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-
-public class AsyncOps {
-    /**
-     * This is the base class for all of the async callback classes. It will
-     * verify the expected value against the actual value.
-     * 
-     * Basic operation is that the subclasses will generate an "expected" value
-     * which is defined by the "toString" method of the subclass. This is
-     * passed through to the verify clause by specifying it as the ctx object
-     * of each async call (processResult methods get the ctx as part of
-     * the callback). Additionally the callback will also overwrite any
-     * instance fields with matching parameter arguments to the processResult
-     * method. The cb instance can then compare the expected to the
-     * actual value by again calling toString and comparing the two.
-     * 
-     * The format of each expected value differs (is defined) by subclass.
-     * Generally the expected value starts with the result code (rc) and path
-     * of the node being operated on, followed by the fields specific to
-     * each operation type (cb subclass). For example ChildrenCB specifies
-     * a list of the expected children suffixed onto the rc and path. See
-     * the toString() method of each subclass for details of it's format. 
-     */
-    public static abstract class AsyncCB {
-        protected final ZooKeeper zk;
-        protected long defaultTimeoutMillis = 30000;
-        
-        /** the latch is used to await the results from the server */
-        CountDownLatch latch;
-
-        Code rc = Code.OK;
-        String path = "/foo";
-        String expected;
-        
-        public AsyncCB(ZooKeeper zk, CountDownLatch latch) {
-            this.zk = zk;
-            this.latch = latch;
-        }
-        
-        public void setRC(Code rc) {
-            this.rc = rc;
-        }
-        
-        public void setPath(String path) {
-            this.path = path;
-        }
-        
-        public void processResult(Code rc, String path, Object ctx)
-        {
-            this.rc = rc;
-            this.path = path;
-            this.expected = (String)ctx;
-            latch.countDown();
-        }
-        
-        /** String format is rc:path:<suffix> where <suffix> is defined by each
-         * subclass individually. */
-        @Override
-        public String toString() {
-            return rc + ":" + path + ":"; 
-        }
-
-        protected void verify() {
-            try {
-                latch.await(defaultTimeoutMillis, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-                Assert.fail("unexpected interrupt");
-            }
-            // on the lookout for timeout
-            Assert.assertSame(0L, latch.getCount());
-            
-            String actual = toString();
-            
-            Assert.assertEquals(expected, actual);
-        }
-    }
-    
-    public static class StringCB extends AsyncCB implements StringCallback {
-        byte[] data = new byte[10];
-        List<ACL> acl = Ids.CREATOR_ALL_ACL;
-        CreateMode flags = CreateMode.PERSISTENT;
-        String name = path;
-        
-        StringCB(ZooKeeper zk) {
-            this(zk, new CountDownLatch(1));
-        }
-        
-        StringCB(ZooKeeper zk, CountDownLatch latch) {
-            super(zk, latch);
-        }
-        
-        public void setPath(String path) {
-            super.setPath(path);
-            this.name = path;
-        }
-        
-        public String nodeName() {
-            return path.substring(path.lastIndexOf('/') + 1);
-        }
-        
-        public void processResult(int rc, String path, Object ctx, String name)
-        {
-            this.name = name;
-            super.processResult(Code.get(rc), path, ctx);
-        }
-
-        public AsyncCB create() {
-            zk.create(path, data, acl, flags, this, toString());
-            return this;
-        }
-
-        public AsyncCB createEphemeral() {
-            zk.create(path, data, acl, CreateMode.EPHEMERAL, this, toString());
-            return this;
-        }
-        
-        public void verifyCreate() {
-            create();
-            verify();
-        }
-
-        public void verifyCreateEphemeral() {
-            createEphemeral();
-            verify();
-        }
-        
-        public void verifyCreateFailure_NodeExists() {
-            new StringCB(zk).verifyCreate();
-            
-            rc = Code.NODEEXISTS;
-            name = null;
-            zk.create(path, data, acl, flags, this, toString());
-            verify();
-        }
-
-        public void verifyCreateFailure_NoNode() {
-
-            rc = Code.NONODE;
-            name = null;
-            path = path + "/bar";
-            zk.create(path, data, acl, flags, this, toString());
-
-            verify();
-        }
-
-        public void verifyCreateFailure_NoChildForEphemeral() {
-            new StringCB(zk).verifyCreateEphemeral();
-
-            rc = Code.NOCHILDRENFOREPHEMERALS;
-            name = null;
-            path = path + "/bar";
-            zk.create(path, data, acl, flags, this, toString());
-
-            verify();
-        }
-
-        @Override
-        public String toString() {
-            return super.toString() + name; 
-        }
-    }
-
-    public static class ACLCB extends AsyncCB implements ACLCallback {
-        List<ACL> acl = Ids.CREATOR_ALL_ACL;
-        int version = 0;
-        Stat stat = new Stat();
-        byte[] data = "testing".getBytes();
-        
-        ACLCB(ZooKeeper zk) {
-            this(zk, new CountDownLatch(1));
-        }
-
-        ACLCB(ZooKeeper zk, CountDownLatch latch) {
-            super(zk, latch);
-            stat.setAversion(0);
-            stat.setCversion(0);
-            stat.setEphemeralOwner(0);
-            stat.setVersion(0);
-        }
-
-        public void processResult(int rc, String path, Object ctx,
-                List<ACL> acl, Stat stat)
-        {
-            this.acl = acl;
-            this.stat = stat;
-            super.processResult(Code.get(rc), path, ctx);
-        }
-        
-        public void verifyGetACL() {
-            new StringCB(zk).verifyCreate();
-
-            zk.getACL(path, stat, this, toString());
-            verify();
-        }
-
-        public void verifyGetACLFailure_NoNode(){
-            rc = Code.NONODE;
-            stat = null;
-            acl = null;
-            zk.getACL(path, stat, this, toString());
-
-            verify();
-        }
-        
-        public String toString(List<ACL> acls) {
-            if (acls == null) {
-                return "";
-            }
-
-            StringBuilder result = new StringBuilder();
-            for(ACL acl : acls) {
-                result.append(acl.getPerms() + "::");
-            }
-            return result.toString();
-        }
-        
-        @Override
-        public String toString() {
-            return super.toString() + toString(acl) + ":" 
-                + ":" + version + ":" + new String(data)
-                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
-                        + stat.getCversion() + ":" + stat.getEphemeralOwner()
-                        + ":" + stat.getVersion()); 
-        }
-    }
-
-    public static class ChildrenCB extends AsyncCB implements ChildrenCallback {
-        List<String> children = new ArrayList<String>();
-        
-        ChildrenCB(ZooKeeper zk) {
-            this(zk, new CountDownLatch(1));
-        }
-
-        ChildrenCB(ZooKeeper zk, CountDownLatch latch) {
-            super(zk, latch);
-        }
-        
-        public void processResult(int rc, String path, Object ctx,
-                List<String> children)
-        {
-            this.children =
-                (children == null ? new ArrayList<String>() : children);
-            Collections.sort(this.children);
-            super.processResult(Code.get(rc), path, ctx);
-        }
-        
-        public StringCB createNode() {
-            StringCB parent = new StringCB(zk);
-            parent.verifyCreate();
-
-            return parent;
-        }
-        
-        public StringCB createNode(StringCB parent) {
-            String childName = "bar";
-
-            return createNode(parent, childName);
-        }
-
-        public StringCB createNode(StringCB parent, String childName) {
-            StringCB child = new StringCB(zk);
-            child.setPath(parent.path + "/" + childName);
-            child.verifyCreate();
-            
-            return child;
-        }
-        
-        public void verifyGetChildrenEmpty() {
-            StringCB parent = createNode();
-            path = parent.path;
-            verify();
-        }
-
-        public void verifyGetChildrenSingle() {
-            StringCB parent = createNode();
-            StringCB child = createNode(parent);
-
-            path = parent.path;
-            children.add(child.nodeName());
-            
-            verify();
-        }
-        
-        public void verifyGetChildrenTwo() {
-            StringCB parent = createNode();
-            StringCB child1 = createNode(parent, "child1");
-            StringCB child2 = createNode(parent, "child2");
-        
-            path = parent.path;
-            children.add(child1.nodeName());
-            children.add(child2.nodeName());
-            
-            verify();
-        }
-        
-        public void verifyGetChildrenFailure_NoNode() {
-            rc = KeeperException.Code.NONODE;
-            verify();
-        }
-        
-        @Override
-        public void verify() {
-            zk.getChildren(path, false, this, toString());
-            super.verify();
-        }
-
-        @Override
-        public String toString() {
-            return super.toString() + children.toString();
-        }
-    }
-
-    public static class Children2CB extends AsyncCB implements Children2Callback {
-        List<String> children = new ArrayList<String>();
-
-        Children2CB(ZooKeeper zk) {
-            this(zk, new CountDownLatch(1));
-        }
-
-        Children2CB(ZooKeeper zk, CountDownLatch latch) {
-            super(zk, latch);
-        }
-
-        public void processResult(int rc, String path, Object ctx,
-                List<String> children, Stat stat)
-        {
-            this.children =
-                (children == null ? new ArrayList<String>() : children);
-            Collections.sort(this.children);
-            super.processResult(Code.get(rc), path, ctx);
-        }
-        
-        public StringCB createNode() {
-            StringCB parent = new StringCB(zk);
-            parent.verifyCreate();
-
-            return parent;
-        }
-        
-        public StringCB createNode(StringCB parent) {
-            String childName = "bar";
-
-            return createNode(parent, childName);
-        }
-
-        public StringCB createNode(StringCB parent, String childName) {
-            StringCB child = new StringCB(zk);
-            child.setPath(parent.path + "/" + childName);
-            child.verifyCreate();
-            
-            return child;
-        }
-        
-        public void verifyGetChildrenEmpty() {
-            StringCB parent = createNode();
-            path = parent.path;
-            verify();
-        }
-
-        public void verifyGetChildrenSingle() {
-            StringCB parent = createNode();
-            StringCB child = createNode(parent);
-
-            path = parent.path;
-            children.add(child.nodeName());
-            
-            verify();
-        }
-        
-        public void verifyGetChildrenTwo() {
-            StringCB parent = createNode();
-            StringCB child1 = createNode(parent, "child1");
-            StringCB child2 = createNode(parent, "child2");
-        
-            path = parent.path;
-            children.add(child1.nodeName());
-            children.add(child2.nodeName());
-            
-            verify();
-        }
-        
-        public void verifyGetChildrenFailure_NoNode() {
-            rc = KeeperException.Code.NONODE;
-            verify();
-        }
-        
-        @Override
-        public void verify() {
-            zk.getChildren(path, false, this, toString());
-            super.verify();
-        }
-        
-        @Override
-        public String toString() {
-            return super.toString() + children.toString(); 
-        }
-    }
-
-    public static class DataCB extends AsyncCB implements DataCallback {
-        byte[] data = new byte[10];
-        Stat stat = new Stat();
-        
-        DataCB(ZooKeeper zk) {
-            this(zk, new CountDownLatch(1));
-        }
-
-        DataCB(ZooKeeper zk, CountDownLatch latch) {
-            super(zk, latch);
-            stat.setAversion(0);
-            stat.setCversion(0);
-            stat.setEphemeralOwner(0);
-            stat.setVersion(0);
-        }
-        
-        public void processResult(int rc, String path, Object ctx, byte[] data,
-                Stat stat)
-        {
-            this.data = data;
-            this.stat = stat;
-            super.processResult(Code.get(rc), path, ctx);
-        }
-        
-        public void verifyGetData() {
-            new StringCB(zk).verifyCreate();
-
-            zk.getData(path, false, this, toString());
-            verify();
-        }
-        
-        public void verifyGetDataFailure_NoNode() {
-            rc = KeeperException.Code.NONODE;
-            data = null;
-            stat = null;
-            zk.getData(path, false, this, toString());
-            verify();
-        }
-        
-        @Override
-        public String toString() {
-            return super.toString()
-                + ":" + (data == null ? "null" : new String(data))
-                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
-                    + stat.getCversion() + ":" + stat.getEphemeralOwner()
-                    + ":" + stat.getVersion()); 
-        }
-    }
-
-    public static class StatCB extends AsyncCB implements StatCallback {
-        List<ACL> acl = Ids.CREATOR_ALL_ACL;
-        int version = 0;
-        Stat stat = new Stat();
-        byte[] data = "testing".getBytes();
-        
-        StatCB(ZooKeeper zk) {
-            this(zk, new CountDownLatch(1));
-        }
-
-        StatCB(ZooKeeper zk, CountDownLatch latch) {
-            super(zk, latch);
-            stat.setAversion(0);
-            stat.setCversion(0);
-            stat.setEphemeralOwner(0);
-            stat.setVersion(0);
-        }
-        
-        public void processResult(int rc, String path, Object ctx, Stat stat) {
-            this.stat = stat;
-            super.processResult(Code.get(rc), path, ctx);
-        }
-        
-        public void verifySetACL() {
-            stat.setAversion(1);
-            new StringCB(zk).verifyCreate();
-
-            zk.setACL(path, acl, version, this, toString());
-            verify();
-        }
-        
-        public void verifySetACLFailure_NoNode() {
-            rc = KeeperException.Code.NONODE;
-            stat = null;
-            zk.setACL(path, acl, version, this, toString());
-            verify();
-        }
-
-        public void verifySetACLFailure_BadVersion() {
-            new StringCB(zk).verifyCreate();
-
-            rc = Code.BADVERSION;
-            stat = null;
-            zk.setACL(path, acl, version + 1, this, toString());
-
-            verify();
-        }
-        
-        public void setData() {
-            zk.setData(path, data, version, this, toString());
-        }
-        
-        public void verifySetData() {
-            stat.setVersion(1);
-            new StringCB(zk).verifyCreate();
-
-            setData();
-            verify();
-        }
-        
-        public void verifySetDataFailure_NoNode() {
-            rc = KeeperException.Code.NONODE;
-            stat = null;
-            zk.setData(path, data, version, this, toString());
-            verify();
-        }
-
-        public void verifySetDataFailure_BadVersion() {
-            new StringCB(zk).verifyCreate();
-
-            rc = Code.BADVERSION;
-            stat = null;
-            zk.setData(path, data, version + 1, this, toString());
-
-            verify();
-        }
-        
-        public void verifyExists() {
-            new StringCB(zk).verifyCreate();
-
-            zk.exists(path, false, this, toString());
-            verify();
-        }
-        
-        public void verifyExistsFailure_NoNode() {
-            rc = KeeperException.Code.NONODE;
-            stat = null;
-            zk.exists(path, false, this, toString());
-            verify();
-        }
-        
-        @Override
-        public String toString() {
-            return super.toString() + version
-                + ":" + new String(data)
-                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
-                        + stat.getCversion() + ":" + stat.getEphemeralOwner()
-                        + ":" + stat.getVersion()); 
-        }
-    }
-
-    public static class VoidCB extends AsyncCB implements VoidCallback {
-        int version = 0;
-        
-        VoidCB(ZooKeeper zk) {
-            this(zk, new CountDownLatch(1));
-        }
-        
-        VoidCB(ZooKeeper zk, CountDownLatch latch) {
-            super(zk, latch);
-        }
-        
-        public void processResult(int rc, String path, Object ctx) {
-            super.processResult(Code.get(rc), path, ctx);
-        }
-
-        public void delete() {
-            zk.delete(path, version, this, toString());
-        }
-        
-        public void verifyDelete() {
-            new StringCB(zk).verifyCreate();
-
-            delete();
-            verify();
-        }
-        
-        public void verifyDeleteFailure_NoNode() {
-            rc = Code.NONODE;
-            zk.delete(path, version, this, toString());
-            verify();
-        }
-
-        public void verifyDeleteFailure_BadVersion() {
-            new StringCB(zk).verifyCreate();
-            rc = Code.BADVERSION;
-            zk.delete(path, version + 1, this, toString());
-            verify();
-        }
-
-        public void verifyDeleteFailure_NotEmpty() {
-            StringCB scb = new StringCB(zk);
-            scb.create();
-            scb.setPath(path + "/bar");
-            scb.create();
-
-            rc = Code.NOTEMPTY;
-            zk.delete(path, version, this, toString());
-            verify();
-        }
-        
-        public void sync() {
-            zk.sync(path, this, toString());
-        }
-        
-        public void verifySync() {
-            sync();
-            verify();
-        }
-        
-        @Override
-        public String toString() {
-            return super.toString() + version; 
-        }
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
deleted file mode 100644
index c807d72..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.util.concurrent.CountDownLatch;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.test.AsyncOps.ACLCB;
-import org.apache.zookeeper.test.AsyncOps.Children2CB;
-import org.apache.zookeeper.test.AsyncOps.ChildrenCB;
-import org.apache.zookeeper.test.AsyncOps.DataCB;
-import org.apache.zookeeper.test.AsyncOps.StatCB;
-import org.apache.zookeeper.test.AsyncOps.StringCB;
-import org.apache.zookeeper.test.AsyncOps.VoidCB;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class AsyncOpsTest extends ClientBase {
-    private static final Logger LOG = LoggerFactory.getLogger(AsyncOpsTest.class);
-
-    private ZooKeeper zk;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        LOG.info("Creating client " + getTestName());
-
-        zk = createClient();
-        zk.addAuthInfo("digest", "ben:passwd".getBytes());
-    }
-
-    @After
-    @Override
-    public void tearDown() throws Exception {
-        zk.close();
-
-        super.tearDown();
-
-        LOG.info("Test clients shutting down");
-    }
-
-    @Test
-    public void testAsyncCreate() {
-        new StringCB(zk).verifyCreate();
-    }
-
-    @Test
-    public void testAsyncCreateThree() {
-        CountDownLatch latch = new CountDownLatch(3);
-
-        StringCB op1 = new StringCB(zk, latch);
-        op1.setPath("/op1");
-        StringCB op2 = new StringCB(zk, latch);
-        op2.setPath("/op2");
-        StringCB op3 = new StringCB(zk, latch);
-        op3.setPath("/op3");
-
-        op1.create();
-        op2.create();
-        op3.create();
-
-        op1.verify();
-        op2.verify();
-        op3.verify();
-    }
-
-    @Test
-    public void testAsyncCreateFailure_NodeExists() {
-        new StringCB(zk).verifyCreateFailure_NodeExists();
-    }
-
-    @Test
-    public void testAsyncCreateFailure_NoNode() {
-        new StringCB(zk).verifyCreateFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncCreateFailure_NoChildForEphemeral() {
-        new StringCB(zk).verifyCreateFailure_NoChildForEphemeral();
-    }
-
-    @Test
-    public void testAsyncDelete() {
-        new VoidCB(zk).verifyDelete();
-    }
-
-    @Test
-    public void testAsyncDeleteFailure_NoNode() {
-        new VoidCB(zk).verifyDeleteFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncDeleteFailure_BadVersion() {
-        new VoidCB(zk).verifyDeleteFailure_BadVersion();
-    }
-
-    @Test
-    public void testAsyncDeleteFailure_NotEmpty() {
-        new VoidCB(zk).verifyDeleteFailure_NotEmpty();
-    }
-
-    @Test
-    public void testAsyncSync() {
-        new VoidCB(zk).verifySync();
-    }
-
-    @Test
-    public void testAsyncSetACL() {
-        new StatCB(zk).verifySetACL();
-    }
-
-    @Test
-    public void testAsyncSetACLFailure_NoNode() {
-        new StatCB(zk).verifySetACLFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncSetACLFailure_BadVersion() {
-        new StatCB(zk).verifySetACLFailure_BadVersion();
-    }
-
-    @Test
-    public void testAsyncSetData() {
-        new StatCB(zk).verifySetData();
-    }
-
-    @Test
-    public void testAsyncSetDataFailure_NoNode() {
-        new StatCB(zk).verifySetDataFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncSetDataFailure_BadVersion() {
-        new StatCB(zk).verifySetDataFailure_BadVersion();
-    }
-
-    @Test
-    public void testAsyncExists() {
-        new StatCB(zk).verifyExists();
-    }
-
-    @Test
-    public void testAsyncExistsFailure_NoNode() {
-        new StatCB(zk).verifyExistsFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncGetACL() {
-        new ACLCB(zk).verifyGetACL();
-    }
-
-    @Test
-    public void testAsyncGetACLFailure_NoNode() {
-        new ACLCB(zk).verifyGetACLFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncGetChildrenEmpty() {
-        new ChildrenCB(zk).verifyGetChildrenEmpty();
-    }
-
-    @Test
-    public void testAsyncGetChildrenSingle() {
-        new ChildrenCB(zk).verifyGetChildrenSingle();
-    }
-
-    @Test
-    public void testAsyncGetChildrenTwo() {
-        new ChildrenCB(zk).verifyGetChildrenTwo();
-    }
-
-    @Test
-    public void testAsyncGetChildrenFailure_NoNode() {
-        new ChildrenCB(zk).verifyGetChildrenFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncGetChildren2Empty() {
-        new Children2CB(zk).verifyGetChildrenEmpty();
-    }
-
-    @Test
-    public void testAsyncGetChildren2Single() {
-        new Children2CB(zk).verifyGetChildrenSingle();
-    }
-
-    @Test
-    public void testAsyncGetChildren2Two() {
-        new Children2CB(zk).verifyGetChildrenTwo();
-    }
-
-    @Test
-    public void testAsyncGetChildren2Failure_NoNode() {
-        new Children2CB(zk).verifyGetChildrenFailure_NoNode();
-    }
-
-    @Test
-    public void testAsyncGetData() {
-        new DataCB(zk).verifyGetData();
-    }
-
-    @Test
-    public void testAsyncGetDataFailure_NoNode() {
-        new DataCB(zk).verifyGetDataFailure_NoNode();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncTest.java
deleted file mode 100644
index 2182032..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AsyncTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.AsyncCallback.StringCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.KeeperException.Code;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class AsyncTest extends ZKTestCase
-    implements StringCallback, VoidCallback, DataCallback
-{
-    private static final Logger LOG = LoggerFactory.getLogger(AsyncTest.class);
-
-    private QuorumBase qb = new QuorumBase();
-
-    @Before
-    public void setUp() throws Exception {
-        qb.setUp();
-    }
-
-    public void restart() throws Exception {
-        JMXEnv.setUp();
-        qb.startServers();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        LOG.info("Test clients shutting down");
-        qb.tearDown();
-    }
-
-    private static class CountdownWatcher implements Watcher {
-        volatile CountDownLatch clientConnected = new CountDownLatch(1);
-
-        public void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.SyncConnected) {
-                clientConnected.countDown();
-            }
-        }
-    }
-
-    private ZooKeeper createClient() throws IOException,InterruptedException {
-        return createClient(qb.hostPort);
-    }
-
-    private ZooKeeper createClient(String hp)
-        throws IOException, InterruptedException
-    {
-        CountdownWatcher watcher = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper(hp, CONNECTION_TIMEOUT, watcher);
-        if(!watcher.clientConnected.await(CONNECTION_TIMEOUT,
-                TimeUnit.MILLISECONDS))
-        {
-            Assert.fail("Unable to connect to server");
-        }
-        return zk;
-    }
-
-    LinkedList<Integer> results = new LinkedList<Integer>();
-    @Test
-    public void testAsync()
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk = null;
-        zk = createClient();
-        try {
-            zk.addAuthInfo("digest", "ben:passwd".getBytes());
-            zk.create("/ben", new byte[0], Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT, this, results);
-            zk.create("/ben/2", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT, this, results);
-            zk.delete("/ben", -1, this, results);
-            zk.create("/ben2", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT, this, results);
-            zk.getData("/ben2", false, this, results);
-            synchronized (results) {
-                while (results.size() < 5) {
-                    results.wait();
-                }
-            }
-            Assert.assertEquals(0, (int) results.get(0));
-            Assert.assertEquals(Code.NOAUTH, Code.get(results.get(1)));
-            Assert.assertEquals(0, (int) results.get(2));
-            Assert.assertEquals(0, (int) results.get(3));
-            Assert.assertEquals(0, (int) results.get(4));
-        } finally {
-            zk.close();
-        }
-
-        zk = createClient();
-        try {
-            zk.addAuthInfo("digest", "ben:passwd2".getBytes());
-            try {
-                zk.getData("/ben2", false, new Stat());
-                Assert.fail("Should have received a permission error");
-            } catch (KeeperException e) {
-                Assert.assertEquals(Code.NOAUTH, e.code());
-            }
-        } finally {
-            zk.close();
-        }
-
-        zk = createClient();
-        try {
-            zk.addAuthInfo("digest", "ben:passwd".getBytes());
-            zk.getData("/ben2", false, new Stat());
-        } finally {
-            zk.close();
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx, String name) {
-        synchronized(ctx) {
-            ((LinkedList<Integer>)ctx).add(rc);
-            ctx.notifyAll();
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx) {
-        synchronized(ctx) {
-            ((LinkedList<Integer>)ctx).add(rc);
-            ctx.notifyAll();
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx, byte[] data,
-            Stat stat) {
-        synchronized(ctx) {
-            ((LinkedList<Integer>)ctx).add(rc);
-            ctx.notifyAll();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
deleted file mode 100644
index cbd2b77..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.common.AtomicFileOutputStream;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class AtomicFileOutputStreamTest extends ZKTestCase {
-    private static final String TEST_STRING = "hello world";
-    private static final String TEST_STRING_2 = "goodbye world";
-
-    private File testDir;
-    private File dstFile;
-
-    @Before
-    public void setupTestDir() throws IOException {
-        testDir = ClientBase.createEmptyTestDir();
-        dstFile = new File(testDir, "test.txt");
-    }
-    @After
-    public void cleanupTestDir() throws IOException {
-        ClientBase.recursiveDelete(testDir);
-    }
-
-    /**
-     * Test case where there is no existing file
-     */
-    @Test
-    public void testWriteNewFile() throws IOException {
-        OutputStream fos = new AtomicFileOutputStream(dstFile);
-        assertFalse(dstFile.exists());
-        fos.write(TEST_STRING.getBytes());
-        fos.flush();
-        assertFalse(dstFile.exists());
-        fos.close();
-        assertTrue(dstFile.exists());
-
-        String readBackData = ClientBase.readFile(dstFile);
-        assertEquals(TEST_STRING, readBackData);
-    }
-
-    /**
-     * Test case where there is no existing file
-     */
-    @Test
-    public void testOverwriteFile() throws IOException {
-        assertTrue("Creating empty dst file", dstFile.createNewFile());
-
-        OutputStream fos = new AtomicFileOutputStream(dstFile);
-
-        assertTrue("Empty file still exists", dstFile.exists());
-        fos.write(TEST_STRING.getBytes());
-        fos.flush();
-
-        // Original contents still in place
-        assertEquals("", ClientBase.readFile(dstFile));
-
-        fos.close();
-
-        // New contents replace original file
-        String readBackData = ClientBase.readFile(dstFile);
-        assertEquals(TEST_STRING, readBackData);
-    }
-
-    /**
-     * Test case where the flush() fails at close time - make sure that we clean
-     * up after ourselves and don't touch any existing file at the destination
-     */
-    @Test
-    public void testFailToFlush() throws IOException {
-        // Create a file at destination
-        FileOutputStream fos = new FileOutputStream(dstFile);
-        fos.write(TEST_STRING_2.getBytes());
-        fos.close();
-
-        OutputStream failingStream = createFailingStream();
-        failingStream.write(TEST_STRING.getBytes());
-        try {
-            failingStream.close();
-            fail("Close didn't throw exception");
-        } catch (IOException ioe) {
-            // expected
-        }
-
-        // Should not have touched original file
-        assertEquals(TEST_STRING_2, ClientBase.readFile(dstFile));
-
-        assertEquals("Temporary file should have been cleaned up",
-                dstFile.getName(), ClientBase.join(",", testDir.list()));
-    }
-
-    /**
-     * Create a stream that fails to flush at close time
-     */
-    private OutputStream createFailingStream() throws FileNotFoundException {
-        return new AtomicFileOutputStream(dstFile) {
-            @Override
-            public void flush() throws IOException {
-                throw new IOException("injected failure");
-            }
-        };
-    }
-
-    /**
-     * Ensure the tmp file is cleaned up and dstFile is not created when
-     * aborting a new file.
-     */
-    @Test
-    public void testAbortNewFile() throws IOException {
-        AtomicFileOutputStream fos = new AtomicFileOutputStream(dstFile);
-
-        fos.abort();
-
-        assertEquals(0, testDir.list().length);
-    }
-
-    /**
-     * Ensure the tmp file is cleaned up and dstFile is not created when
-     * aborting a new file.
-     */
-    @Test
-    public void testAbortNewFileAfterFlush() throws IOException {
-        AtomicFileOutputStream fos = new AtomicFileOutputStream(dstFile);
-        fos.write(TEST_STRING.getBytes());
-        fos.flush();
-
-        fos.abort();
-
-        assertEquals(0, testDir.list().length);
-    }
-
-    /**
-     * Ensure the tmp file is cleaned up and dstFile is untouched when
-     * aborting an existing file overwrite.
-     */
-    @Test
-    public void testAbortExistingFile() throws IOException {
-        FileOutputStream fos1 = new FileOutputStream(dstFile);
-        fos1.write(TEST_STRING.getBytes());
-        fos1.close();
-
-        AtomicFileOutputStream fos2 = new AtomicFileOutputStream(dstFile);
-
-        fos2.abort();
-
-        // Should not have touched original file
-        assertEquals(TEST_STRING, ClientBase.readFile(dstFile));
-        assertEquals(1, testDir.list().length);
-    }
-
-    /**
-     * Ensure the tmp file is cleaned up and dstFile is untouched when
-     * aborting an existing file overwrite.
-     */
-    @Test
-    public void testAbortExistingFileAfterFlush() throws IOException {
-        FileOutputStream fos1 = new FileOutputStream(dstFile);
-        fos1.write(TEST_STRING.getBytes());
-        fos1.close();
-
-        AtomicFileOutputStream fos2 = new AtomicFileOutputStream(dstFile);
-        fos2.write(TEST_STRING_2.getBytes());
-        fos2.flush();
-
-        fos2.abort();
-
-        // Should not have touched original file
-        assertEquals(TEST_STRING, ClientBase.readFile(dstFile));
-        assertEquals(1, testDir.list().length);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/AuthTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AuthTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/AuthTest.java
deleted file mode 100644
index 60e3453..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/AuthTest.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class AuthTest extends ClientBase {
-    static {
-        // password is test
-        System.setProperty("zookeeper.DigestAuthenticationProvider.superDigest",
-                "super:D/InIHSb7yEEbrWz8b9l71RjZJU=");    
-        System.setProperty("zookeeper.authProvider.1", "org.apache.zookeeper.test.InvalidAuthProvider");
-    }
-
-    private final CountDownLatch authFailed = new CountDownLatch(1);
-
-    @Override
-    protected TestableZooKeeper createClient(String hp)
-    throws IOException, InterruptedException
-    {
-        MyWatcher watcher = new MyWatcher();
-        return createClient(watcher, hp);
-    }
-
-    private class MyWatcher extends CountdownWatcher {
-        @Override
-        public synchronized void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.AuthFailed) {
-                authFailed.countDown();
-            }
-            else {
-                super.process(event);
-            }
-        }
-    }
-
-    @Test
-    public void testBadAuthNotifiesWatch() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            zk.addAuthInfo("FOO", "BAR".getBytes());
-            zk.getData("/path1", false, null);
-            Assert.fail("Should get auth state error");
-        } catch(KeeperException.AuthFailedException e) {
-            if(!authFailed.await(CONNECTION_TIMEOUT,
-                    TimeUnit.MILLISECONDS))
-            {
-                Assert.fail("Should have called my watcher");
-            }
-        }
-        finally {
-            zk.close();
-        }
-    }
-    
-    @Test
-    public void testBadAuthThenSendOtherCommands() throws Exception {
-        ZooKeeper zk = createClient();     
-        try {        
-            zk.addAuthInfo("INVALID", "BAR".getBytes());
-            zk.exists("/foobar", false);             
-            zk.getData("/path1", false, null);
-            Assert.fail("Should get auth state error");
-        } catch(KeeperException.AuthFailedException e) {
-            if(!authFailed.await(CONNECTION_TIMEOUT,
-                    TimeUnit.MILLISECONDS))
-            {
-                Assert.fail("Should have called my watcher");
-            }
-        }
-        finally {
-            zk.close();          
-        }
-    }
-
-    
-    @Test
-    public void testSuper() throws Exception {
-        ZooKeeper zk = createClient();
-        try {
-            zk.addAuthInfo("digest", "pat:pass".getBytes());
-            zk.create("/path1", null, Ids.CREATOR_ALL_ACL,
-                    CreateMode.PERSISTENT);
-            zk.close();
-            // verify no auth
-            zk = createClient();
-            try {
-                zk.getData("/path1", false, null);
-                Assert.fail("auth verification");
-            } catch (KeeperException.NoAuthException e) {
-                // expected
-            }
-            zk.close();
-            // verify bad pass Assert.fails
-            zk = createClient();
-            zk.addAuthInfo("digest", "pat:pass2".getBytes());
-            try {
-                zk.getData("/path1", false, null);
-                Assert.fail("auth verification");
-            } catch (KeeperException.NoAuthException e) {
-                // expected
-            }
-            zk.close();
-            // verify super with bad pass Assert.fails
-            zk = createClient();
-            zk.addAuthInfo("digest", "super:test2".getBytes());
-            try {
-                zk.getData("/path1", false, null);
-                Assert.fail("auth verification");
-            } catch (KeeperException.NoAuthException e) {
-                // expected
-            }
-            zk.close();
-            // verify super with correct pass success
-            zk = createClient();
-            zk.addAuthInfo("digest", "super:test".getBytes());
-            zk.getData("/path1", false, null);
-        } finally {
-            zk.close();
-        }
-    }
-    
-    @Test
-    public void testSuperACL() throws Exception {
-    	 ZooKeeper zk = createClient();
-         try {
-             zk.addAuthInfo("digest", "pat:pass".getBytes());
-             zk.create("/path1", null, Ids.CREATOR_ALL_ACL,
-                     CreateMode.PERSISTENT);
-             zk.close();
-             // verify super can do anything and ignores ACLs
-             zk = createClient();
-             zk.addAuthInfo("digest", "super:test".getBytes());
-             zk.getData("/path1", false, null);
-             
-             zk.setACL("/path1", Ids.READ_ACL_UNSAFE, -1);
-             zk.create("/path1/foo", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-           
-             
-             zk.setACL("/path1", Ids.OPEN_ACL_UNSAFE, -1);
-        	 
-         } finally {
-             zk.close();
-         }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
deleted file mode 100644
index 6d74e54..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.jute.BinaryInputArchive;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.junit.Before;
-import org.junit.Test;
-
-public class BufferSizeTest extends ClientBase {
-    public static final int TEST_MAXBUFFER = 100;
-    private static final File TEST_DATA = new File(
-            System.getProperty("test.data.dir", "build/test/data"),
-            "buffersize");
-    
-    private ZooKeeper zk;
-
-    @Before
-    public void setMaxBuffer() throws IOException, InterruptedException {
-        System.setProperty("jute.maxbuffer", "" + TEST_MAXBUFFER);
-        assertEquals("Can't set jute.maxbuffer!", TEST_MAXBUFFER, BinaryInputArchive.maxBuffer);
-        zk = createClient();
-    }
-    
-    @Test
-    public void testCreatesReqs() throws Exception {
-        testRequests(new ClientOp() {
-            @Override
-            public void execute(byte[] data) throws Exception {
-                zk.create("/create_test", data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            }
-        });
-    }
-    
-    @Test
-    public void testSetReqs() throws Exception {
-        final String path = "/set_test";
-        zk.create(path, new byte[1], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        testRequests(new ClientOp() {
-            @Override
-            public void execute(byte[] data) throws Exception {
-                zk.setData(path, data, -1);
-            }
-        });
-    }
-    
-    /** Issues requests containing data smaller, equal, and greater than TEST_MAXBUFFER. */
-    private void testRequests(ClientOp clientOp) throws Exception {
-        clientOp.execute(new byte[TEST_MAXBUFFER - 60]);
-        try {
-            // This should fail since the buffer size > the data size due to extra fields
-            clientOp.execute(new byte[TEST_MAXBUFFER]);
-            fail("Request exceeding jute.maxbuffer succeeded!");
-        } catch (KeeperException.ConnectionLossException e) {}
-        try {
-            clientOp.execute(new byte[TEST_MAXBUFFER + 10]);
-            fail("Request exceeding jute.maxbuffer succeeded!");
-        } catch (KeeperException.ConnectionLossException e) {}
-    }
-
-    private interface ClientOp {
-        void execute(byte[] data) throws Exception;
-    }
-
-    @Test
-    public void testStartup() throws Exception {
-        final String path = "/test_node";
-        zk.create(path, new byte[TEST_MAXBUFFER - 60], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.setData(path, new byte[TEST_MAXBUFFER - 50], -1);
-
-        stopServer();
-        startServer();
-    }
-    
-    @Test
-    public void testStartupFailureCreate() throws Exception {
-        // Empty snapshot and logfile containing a 5000-byte create
-        testStartupFailure(new File(TEST_DATA, "create"),
-                "Server started despite create exceeding jute.maxbuffer!");
-    }
-    
-    @Test
-    public void testStartupFailureSet() throws Exception {
-        // Empty snapshot and logfile containing a 1-byte create and 5000-byte set
-        testStartupFailure(new File(TEST_DATA, "set"),
-                "Server started despite set exceeding jute.maxbuffer!");
-    }
-    
-    @Test
-    public void testStartupFailureSnapshot() throws Exception {
-        // Snapshot containing 5000-byte znode and logfile containing create txn
-        testStartupFailure(new File(TEST_DATA, "snapshot"),
-                "Server started despite znode exceeding jute.maxbuffer!");
-    }
-    
-    private void testStartupFailure(File testDir, String failureMsg) throws Exception {
-        stopServer();
-        // Point server at testDir
-        tmpDir = testDir;
-        try {
-            startServer();
-            fail(failureMsg);
-        } catch (IOException e) {
-            LOG.info("Successfully caught IOException: " + e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
deleted file mode 100644
index e60ea04..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-
-public class ChrootAsyncTest extends AsyncOpsTest {
-    private static final Logger LOG = LoggerFactory.getLogger(ChrootAsyncTest.class);
-
-    @Override
-    public void setUp() throws Exception {
-        String hp = hostPort;
-        hostPort = hostPort + "/chrootasynctest";
-
-        super.setUp();
-
-        LOG.info("Creating client " + getTestName());
-
-        ZooKeeper zk = createClient(hp);
-        try {
-            zk.create("/chrootasynctest", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        } finally {
-            zk.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
deleted file mode 100644
index e0286e1..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.junit.Test;
-
-public class ChrootClientTest extends ClientTest {
-    private static final Logger LOG = LoggerFactory.getLogger(ChrootClientTest.class);
-
-    @Override
-    public void setUp() throws Exception {
-        String hp = hostPort;
-        hostPort = hostPort + "/chrootclienttest";
-
-        System.out.println(hostPort);
-        super.setUp();
-
-        LOG.info("STARTING " + getTestName());
-
-        ZooKeeper zk = createClient(hp);
-        try {
-            zk.create("/chrootclienttest", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        } finally {
-            zk.close();
-        }
-    }
-    
-    @Test
-    public void testPing() throws Exception {
-        // not necessary to repeat this, expensive and not chroot related
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootTest.java
deleted file mode 100644
index 3df068b..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ChrootTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-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.junit.Assert;
-import org.junit.Test;
-
-public class ChrootTest extends ClientBase {
-    private class MyWatcher implements Watcher {
-        private final String path;
-        private String eventPath;
-        private CountDownLatch latch = new CountDownLatch(1);
-
-        public MyWatcher(String path) {
-            this.path = path;
-        }
-        public void process(WatchedEvent event) {
-            System.out.println("latch:" + path + " " + event.getPath());
-            this.eventPath = event.getPath();
-            latch.countDown();
-        }
-        public boolean matches() throws InterruptedException {
-            if (!latch.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)) {
-                Assert.fail("No watch received within timeout period " + path);
-            }
-            return path.equals(eventPath);
-        }
-    }
-
-    @Test
-    public void testChrootSynchronous()
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk1 = createClient();
-        try {
-            zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        } finally {
-            if(zk1 != null)
-                zk1.close();
-        }
-        ZooKeeper zk2 = createClient(hostPort + "/ch1");
-        try {
-            Assert.assertEquals("/ch2",
-                    zk2.create("/ch2", null, Ids.OPEN_ACL_UNSAFE,
-                            CreateMode.PERSISTENT));
-        } finally {
-            if(zk2 != null)
-                zk2.close();
-        }
-
-        zk1 = createClient();
-        zk2 = createClient(hostPort + "/ch1");
-        try {
-            // check get
-            MyWatcher w1 = new MyWatcher("/ch1");
-            Assert.assertNotNull(zk1.exists("/ch1", w1));
-            MyWatcher w2 = new MyWatcher("/ch1/ch2");
-            Assert.assertNotNull(zk1.exists("/ch1/ch2", w2));
-
-            MyWatcher w3 = new MyWatcher("/ch2");
-            Assert.assertNotNull(zk2.exists("/ch2", w3));
-            
-            // set watches on child
-            MyWatcher w4 = new MyWatcher("/ch1");
-            zk1.getChildren("/ch1",w4);
-            MyWatcher w5 = new MyWatcher("/");
-            zk2.getChildren("/",w5);
-
-            // check set
-            zk1.setData("/ch1", "1".getBytes(), -1);
-            zk2.setData("/ch2", "2".getBytes(), -1);
-
-            // check watches
-            Assert.assertTrue(w1.matches());
-            Assert.assertTrue(w2.matches());
-            Assert.assertTrue(w3.matches());
-
-            // check exceptions
-            try {
-                zk2.setData("/ch3", "3".getBytes(), -1);
-            } catch (KeeperException.NoNodeException e) {
-                Assert.assertEquals("/ch3", e.getPath());
-            }
-
-            Assert.assertTrue(Arrays.equals("1".getBytes(),
-                    zk1.getData("/ch1", false, null)));
-            Assert.assertTrue(Arrays.equals("2".getBytes(),
-                    zk1.getData("/ch1/ch2", false, null)));
-            Assert.assertTrue(Arrays.equals("2".getBytes(),
-                    zk2.getData("/ch2", false, null)));
-
-            // check delete
-            zk2.delete("/ch2", -1);
-            Assert.assertTrue(w4.matches());
-            Assert.assertTrue(w5.matches());
-            
-            zk1.delete("/ch1", -1);
-            Assert.assertNull(zk1.exists("/ch1", false));
-            Assert.assertNull(zk1.exists("/ch1/ch2", false));
-            Assert.assertNull(zk2.exists("/ch2", false));
-        } finally {
-            if(zk1 != null)
-                zk1.close();
-            if(zk2 != null)
-                zk2.close();
-        }
-    }
-}


[12/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml b/zookeeper-server/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml
new file mode 100644
index 0000000..c28b238
--- /dev/null
+++ b/zookeeper-server/src/main/resources/lib/jdiff/zookeeper_3.1.1.xml
@@ -0,0 +1,2717 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<!-- on Wed Apr 22 05:04:00 UTC 2009 -->
+
+<!--
+   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.
+-->
+
+<api
+  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+  xsi:noNamespaceSchemaLocation='api.xsd'
+  name="zookeeper 3.1.1"
+  jdversion="1.0.9">
+
+<!--  Command line arguments =  -doclet jdiff.JDiff -docletpath /home/gkesavan/zk-3.1/src/java/lib/jdiff-1.0.9.jar:/home/gkesavan/zk-3.1/src/java/lib/xerces-1.4.4.jar -classpath /home/gkesavan/zk-3.1/src/java/lib/jdiff-1.0.9.jar:/home/gkesavan/zk-3.1/src/java/lib/junit-4.4.jar:/home/gkesavan/zk-3.1/src/java/lib/log4j-1.2.15.jar:/home/gkesavan/zk-3.1/src/java/lib/xerces-1.4.4.jar:/home/gkesavan/zk-3.1/build/classes -sourcepath /home/gkesavan/zk-3.1/src/java/main -apidir /home/gkesavan/zk-3.1/src/java/lib/jdiff -apiname zookeeper 3.1.1 -->
+<package name="org.apache.zookeeper">
+  <!-- start interface org.apache.zookeeper.AsyncCallback -->
+  <interface name="AsyncCallback"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+  </interface>
+  <!-- end interface org.apache.zookeeper.AsyncCallback -->
+  <!-- start interface org.apache.zookeeper.AsyncCallback.ACLCallback -->
+  <interface name="AsyncCallback.ACLCallback"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.AsyncCallback"/>
+    <method name="processResult"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rc" type="int"/>
+      <param name="path" type="java.lang.String"/>
+      <param name="ctx" type="java.lang.Object"/>
+      <param name="acl" type="java.util.List"/>
+      <param name="stat" type="org.apache.zookeeper.data.Stat"/>
+    </method>
+  </interface>
+  <!-- end interface org.apache.zookeeper.AsyncCallback.ACLCallback -->
+  <!-- start interface org.apache.zookeeper.AsyncCallback.ChildrenCallback -->
+  <interface name="AsyncCallback.ChildrenCallback"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.AsyncCallback"/>
+    <method name="processResult"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rc" type="int"/>
+      <param name="path" type="java.lang.String"/>
+      <param name="ctx" type="java.lang.Object"/>
+      <param name="children" type="java.util.List"/>
+    </method>
+  </interface>
+  <!-- end interface org.apache.zookeeper.AsyncCallback.ChildrenCallback -->
+  <!-- start interface org.apache.zookeeper.AsyncCallback.DataCallback -->
+  <interface name="AsyncCallback.DataCallback"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.AsyncCallback"/>
+    <method name="processResult"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rc" type="int"/>
+      <param name="path" type="java.lang.String"/>
+      <param name="ctx" type="java.lang.Object"/>
+      <param name="data" type="byte[]"/>
+      <param name="stat" type="org.apache.zookeeper.data.Stat"/>
+    </method>
+  </interface>
+  <!-- end interface org.apache.zookeeper.AsyncCallback.DataCallback -->
+  <!-- start interface org.apache.zookeeper.AsyncCallback.StatCallback -->
+  <interface name="AsyncCallback.StatCallback"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.AsyncCallback"/>
+    <method name="processResult"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rc" type="int"/>
+      <param name="path" type="java.lang.String"/>
+      <param name="ctx" type="java.lang.Object"/>
+      <param name="stat" type="org.apache.zookeeper.data.Stat"/>
+    </method>
+  </interface>
+  <!-- end interface org.apache.zookeeper.AsyncCallback.StatCallback -->
+  <!-- start interface org.apache.zookeeper.AsyncCallback.StringCallback -->
+  <interface name="AsyncCallback.StringCallback"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.AsyncCallback"/>
+    <method name="processResult"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rc" type="int"/>
+      <param name="path" type="java.lang.String"/>
+      <param name="ctx" type="java.lang.Object"/>
+      <param name="name" type="java.lang.String"/>
+    </method>
+  </interface>
+  <!-- end interface org.apache.zookeeper.AsyncCallback.StringCallback -->
+  <!-- start interface org.apache.zookeeper.AsyncCallback.VoidCallback -->
+  <interface name="AsyncCallback.VoidCallback"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.AsyncCallback"/>
+    <method name="processResult"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="rc" type="int"/>
+      <param name="path" type="java.lang.String"/>
+      <param name="ctx" type="java.lang.Object"/>
+    </method>
+  </interface>
+  <!-- end interface org.apache.zookeeper.AsyncCallback.VoidCallback -->
+  <!-- start class org.apache.zookeeper.ClientCnxn -->
+  <class name="ClientCnxn" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ClientCnxn" type="java.lang.String, int, org.apache.zookeeper.ZooKeeper, org.apache.zookeeper.ClientWatchManager"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="IOException" type="java.io.IOException"/>
+    </constructor>
+    <constructor name="ClientCnxn" type="java.lang.String, int, org.apache.zookeeper.ZooKeeper, org.apache.zookeeper.ClientWatchManager, long, byte[]"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Creates a connection object. The actual network connect doesn't get
+ established until needed.
+
+ @param hosts
+                a comma separated list of hosts that can be connected to.
+ @param sessionTimeout
+                the timeout for connections.
+ @param zooKeeper
+                the zookeeper object that this connection is related to.
+ @throws KeeperException
+ @throws IOException]]>
+      </doc>
+    </constructor>
+    <method name="getSessionId" return="long"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getSessionPasswd" return="byte[]"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="disconnect"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Shutdown the send/event threads. This method should not be called
+ directly - rather it should be called as part of close operation. This
+ method is primarily here to allow the tests to verify disconnection
+ behavior.]]>
+      </doc>
+    </method>
+    <method name="close"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[Close the connection, which includes; send session disconnect to the
+ server, shutdown the send/event threads.
+ 
+ @throws IOException]]>
+      </doc>
+    </method>
+    <method name="submitRequest" return="org.apache.zookeeper.proto.ReplyHeader"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="h" type="org.apache.zookeeper.proto.RequestHeader"/>
+      <param name="request" type="org.apache.jute.Record"/>
+      <param name="response" type="org.apache.jute.Record"/>
+      <param name="watchRegistration" type="org.apache.zookeeper.ZooKeeper.WatchRegistration"/>
+      <exception name="InterruptedException" type="java.lang.InterruptedException"/>
+    </method>
+    <method name="addAuthInfo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scheme" type="java.lang.String"/>
+      <param name="auth" type="byte[]"/>
+    </method>
+    <field name="disableAutoWatchReset" type="boolean"
+      transient="false" volatile="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[This controls whether automatic watch resetting is enabled.
+ Clients automatically reset watches during session reconnect, this
+ option allows the client to turn off this behavior by setting
+ the environment variable "zookeeper.disableAutoWatchReset" to "true"]]>
+      </doc>
+    </field>
+    <field name="packetLen" type="int"
+      transient="false" volatile="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <doc>
+    <![CDATA[This class manages the socket i/o for the client. ClientCnxn maintains a list
+ of available servers to connect to and "transparently" switches servers it is
+ connected to as needed.]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.ClientCnxn -->
+  <!-- start interface org.apache.zookeeper.ClientWatchManager -->
+  <interface name="ClientWatchManager"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="materialize" return="java.util.Set"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="state" type="org.apache.zookeeper.Watcher.Event.KeeperState"/>
+      <param name="type" type="org.apache.zookeeper.Watcher.Event.EventType"/>
+      <param name="path" type="java.lang.String"/>
+      <doc>
+      <![CDATA[Return a set of watchers that should be notified of the event. The 
+ manager must not notify the watcher(s), however it will update it's 
+ internal structure as if the watches had triggered. The intent being 
+ that the callee is now responsible for notifying the watchers of the 
+ event, possibly at some later time.
+ 
+ @param state event state
+ @param type event type
+ @param path event path
+ @return]]>
+      </doc>
+    </method>
+  </interface>
+  <!-- end interface org.apache.zookeeper.ClientWatchManager -->
+  <!-- start class org.apache.zookeeper.CreateMode -->
+  <class name="CreateMode" extends="java.lang.Enum"
+    abstract="false"
+    static="false" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="org.apache.zookeeper.CreateMode[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="org.apache.zookeeper.CreateMode"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="isEphemeral" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="isSequential" return="boolean"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toFlag" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="fromFlag" return="org.apache.zookeeper.CreateMode"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="flag" type="int"/>
+      <exception name="KeeperException" type="org.apache.zookeeper.KeeperException"/>
+      <doc>
+      <![CDATA[Map an integer value to a CreateMode value]]>
+      </doc>
+    </method>
+    <field name="PERSISTENT" type="org.apache.zookeeper.CreateMode"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The znode will not be automatically deleted upon client's disconnect.]]>
+      </doc>
+    </field>
+    <field name="PERSISTENT_SEQUENTIAL" type="org.apache.zookeeper.CreateMode"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The znode will not be automatically deleted upon client's disconnect,
+ and its name will be appended with a monotonically increasing number.]]>
+      </doc>
+    </field>
+    <field name="EPHEMERAL" type="org.apache.zookeeper.CreateMode"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The znode will be deleted upon the client's disconnect.]]>
+      </doc>
+    </field>
+    <field name="EPHEMERAL_SEQUENTIAL" type="org.apache.zookeeper.CreateMode"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The znode will be deleted upon the client's disconnect, and its name
+ will be appended with a monotonically increasing number.]]>
+      </doc>
+    </field>
+    <doc>
+    <![CDATA[CreateMode value determines how the znode is created on ZooKeeper.]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.CreateMode -->
+  <!-- start class org.apache.zookeeper.Environment -->
+  <class name="Environment" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Environment"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="list" return="java.util.List"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="logEnv"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="msg" type="java.lang.String"/>
+      <param name="log" type="org.apache.log4j.Logger"/>
+    </method>
+    <doc>
+    <![CDATA[Provide insight into the runtime environment.]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.Environment -->
+  <!-- start class org.apache.zookeeper.Environment.Entry -->
+  <class name="Environment.Entry" extends="java.lang.Object"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Environment.Entry" type="java.lang.String, java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getKey" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getValue" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+  </class>
+  <!-- end class org.apache.zookeeper.Environment.Entry -->
+  <!-- start class org.apache.zookeeper.KeeperException -->
+  <class name="KeeperException" extends="java.lang.Exception"
+    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException" type="org.apache.zookeeper.KeeperException.Code"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="create" return="org.apache.zookeeper.KeeperException"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="code" type="org.apache.zookeeper.KeeperException.Code"/>
+      <param name="path" type="java.lang.String"/>
+      <doc>
+      <![CDATA[All non-specific keeper exceptions should be constructed via
+ this factory method in order to guarantee consistency in error
+ codes and such.  If you know the error code, then you should
+ construct the special purpose exception directly.  That will
+ allow you to have the most specific possible declarations of
+ what exceptions might actually be thrown.
+
+ @param code The error code.
+ @param path The ZooKeeper path being operated on.
+ @return The specialized exception, presumably to be thrown by
+  the caller.]]>
+      </doc>
+    </method>
+    <method name="create" return="org.apache.zookeeper.KeeperException"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link #create(Code, String)}
+ instead">
+      <param name="code" type="int"/>
+      <param name="path" type="java.lang.String"/>
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link #create(Code, String)}
+ instead]]>
+      </doc>
+    </method>
+    <method name="create" return="org.apache.zookeeper.KeeperException"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link #create(Code)}
+ instead">
+      <param name="code" type="int"/>
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link #create(Code)}
+ instead]]>
+      </doc>
+    </method>
+    <method name="create" return="org.apache.zookeeper.KeeperException"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="code" type="org.apache.zookeeper.KeeperException.Code"/>
+      <doc>
+      <![CDATA[All non-specific keeper exceptions should be constructed via
+ this factory method in order to guarantee consistency in error
+ codes and such.  If you know the error code, then you should
+ construct the special purpose exception directly.  That will
+ allow you to have the most specific possible declarations of
+ what exceptions might actually be thrown.
+
+ @param code The error code of your new exception.  This will
+ also determine the specific type of the exception that is
+ returned.
+ @return The specialized exception, presumably to be thrown by
+ the caller.]]>
+      </doc>
+    </method>
+    <method name="setCode"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="deprecated in 3.1.0, exceptions should be immutable, this
+ method should not be used">
+      <param name="code" type="int"/>
+      <doc>
+      <![CDATA[Set the code for this exception
+ @param code error code
+ @deprecated deprecated in 3.1.0, exceptions should be immutable, this
+ method should not be used]]>
+      </doc>
+    </method>
+    <method name="getCode" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link #code()} instead">
+      <doc>
+      <![CDATA[Read the error code for this exception
+ @return the error code for this exception
+ @deprecated deprecated in 3.1.0, use {@link #code()} instead]]>
+      </doc>
+    </method>
+    <method name="code" return="org.apache.zookeeper.KeeperException.Code"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Read the error Code for this exception
+ @return the error Code for this exception]]>
+      </doc>
+    </method>
+    <method name="getPath" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Read the path for this exception
+ @return the path associated with this error, null if none]]>
+      </doc>
+    </method>
+    <method name="getMessage" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException -->
+  <!-- start class org.apache.zookeeper.KeeperException.APIErrorException -->
+  <class name="KeeperException.APIErrorException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.APIErrorException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.APIERROR]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.APIErrorException -->
+  <!-- start class org.apache.zookeeper.KeeperException.AuthFailedException -->
+  <class name="KeeperException.AuthFailedException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.AuthFailedException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.AUTHFAILED]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.AuthFailedException -->
+  <!-- start class org.apache.zookeeper.KeeperException.BadArgumentsException -->
+  <class name="KeeperException.BadArgumentsException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.BadArgumentsException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.BADARGUMENTS]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.BadArgumentsException -->
+  <!-- start class org.apache.zookeeper.KeeperException.BadVersionException -->
+  <class name="KeeperException.BadVersionException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.BadVersionException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.BADVERSION]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.BadVersionException -->
+  <!-- start class org.apache.zookeeper.KeeperException.Code -->
+  <class name="KeeperException.Code" extends="java.lang.Enum"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.KeeperException.CodeDeprecated"/>
+    <method name="values" return="org.apache.zookeeper.KeeperException.Code[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="org.apache.zookeeper.KeeperException.Code"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="intValue" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Get the int value for a particular Code.
+ @return error code as integer]]>
+      </doc>
+    </method>
+    <method name="get" return="org.apache.zookeeper.KeeperException.Code"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="code" type="int"/>
+      <doc>
+      <![CDATA[Get the Code value for a particular integer error code
+ @param code int error code
+ @return Code value corresponding to specified int code, or null]]>
+      </doc>
+    </method>
+    <field name="OK" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Everything is OK]]>
+      </doc>
+    </field>
+    <field name="SYSTEMERROR" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[System and server-side errors.
+ This is never thrown by the server, it shouldn't be used other than
+ to indicate a range. Specifically error codes greater than this
+ value, but lesser than {@link #APIERROR}, are system errors.]]>
+      </doc>
+    </field>
+    <field name="RUNTIMEINCONSISTENCY" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[A runtime inconsistency was found]]>
+      </doc>
+    </field>
+    <field name="DATAINCONSISTENCY" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[A data inconsistency was found]]>
+      </doc>
+    </field>
+    <field name="CONNECTIONLOSS" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Connection to the server has been lost]]>
+      </doc>
+    </field>
+    <field name="MARSHALLINGERROR" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Error while marshalling or unmarshalling data]]>
+      </doc>
+    </field>
+    <field name="UNIMPLEMENTED" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Operation is unimplemented]]>
+      </doc>
+    </field>
+    <field name="OPERATIONTIMEOUT" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Operation timeout]]>
+      </doc>
+    </field>
+    <field name="BADARGUMENTS" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Invalid arguments]]>
+      </doc>
+    </field>
+    <field name="APIERROR" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[API errors.
+ This is never thrown by the server, it shouldn't be used other than
+ to indicate a range. Specifically error codes greater than this
+ value are API errors (while values less than this indicate a
+ {@link #SYSTEMERROR}).]]>
+      </doc>
+    </field>
+    <field name="NONODE" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Node does not exist]]>
+      </doc>
+    </field>
+    <field name="NOAUTH" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Not authenticated]]>
+      </doc>
+    </field>
+    <field name="BADVERSION" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Version conflict]]>
+      </doc>
+    </field>
+    <field name="NOCHILDRENFOREPHEMERALS" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Ephemeral nodes may not have children]]>
+      </doc>
+    </field>
+    <field name="NODEEXISTS" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The node already exists]]>
+      </doc>
+    </field>
+    <field name="NOTEMPTY" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The node has children]]>
+      </doc>
+    </field>
+    <field name="SESSIONEXPIRED" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The session has been expired by the server]]>
+      </doc>
+    </field>
+    <field name="INVALIDCALLBACK" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Invalid callback specified]]>
+      </doc>
+    </field>
+    <field name="INVALIDACL" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Invalid ACL specified]]>
+      </doc>
+    </field>
+    <field name="AUTHFAILED" type="org.apache.zookeeper.KeeperException.Code"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Client authentication failed]]>
+      </doc>
+    </field>
+    <doc>
+    <![CDATA[Codes which represent the various KeeperException
+ types. This enum replaces the deprecated earlier static final int
+ constants. The old, deprecated, values are in "camel case" while the new
+ enum values are in all CAPS.]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.Code -->
+  <!-- start interface org.apache.zookeeper.KeeperException.CodeDeprecated -->
+  <interface name="KeeperException.CodeDeprecated"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <field name="Ok" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#OK} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#OK} instead]]>
+      </doc>
+    </field>
+    <field name="SystemError" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead]]>
+      </doc>
+    </field>
+    <field name="RuntimeInconsistency" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use
+ {@link Code#RUNTIMEINCONSISTENCY} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use
+ {@link Code#RUNTIMEINCONSISTENCY} instead]]>
+      </doc>
+    </field>
+    <field name="DataInconsistency" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY}
+ instead]]>
+      </doc>
+    </field>
+    <field name="ConnectionLoss" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS}
+ instead]]>
+      </doc>
+    </field>
+    <field name="MarshallingError" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR}
+ instead]]>
+      </doc>
+    </field>
+    <field name="Unimplemented" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED}
+ instead]]>
+      </doc>
+    </field>
+    <field name="OperationTimeout" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT}
+ instead]]>
+      </doc>
+    </field>
+    <field name="BadArguments" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#BADARGUMENTS}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#BADARGUMENTS}
+ instead]]>
+      </doc>
+    </field>
+    <field name="APIError" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#APIERROR} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#APIERROR} instead]]>
+      </doc>
+    </field>
+    <field name="NoNode" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#NONODE} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NONODE} instead]]>
+      </doc>
+    </field>
+    <field name="NoAuth" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#NOAUTH} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NOAUTH} instead]]>
+      </doc>
+    </field>
+    <field name="BadVersion" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#BADVERSION} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#BADVERSION} instead]]>
+      </doc>
+    </field>
+    <field name="NoChildrenForEphemerals" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use
+ {@link Code#NOCHILDRENFOREPHEMERALS}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use
+ {@link Code#NOCHILDRENFOREPHEMERALS}
+ instead]]>
+      </doc>
+    </field>
+    <field name="NodeExists" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead]]>
+      </doc>
+    </field>
+    <field name="NotEmpty" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead]]>
+      </doc>
+    </field>
+    <field name="SessionExpired" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead]]>
+      </doc>
+    </field>
+    <field name="InvalidCallback" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK}
+ instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK}
+ instead]]>
+      </doc>
+    </field>
+    <field name="InvalidACL" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#INVALIDACL} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#INVALIDACL} instead]]>
+      </doc>
+    </field>
+    <field name="AuthFailed" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead">
+      <doc>
+      <![CDATA[@deprecated deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead]]>
+      </doc>
+    </field>
+    <doc>
+    <![CDATA[This interface contains the original static final int constants
+ which have now been replaced with an enumeration in Code. Do not
+ reference this class directly, if necessary (legacy code) continue
+ to access the constants through Code.
+ Note: an interface is used here due to the fact that enums cannot
+ reference constants defined within the same enum as said constants
+ are considered initialized _after_ the enum itself. By using an
+ interface as a super type this allows the deprecated constants to
+ be initialized first and referenced when constructing the enums. I
+ didn't want to have constants declared twice. This
+ interface should be private, but it's declared public to enable
+ javadoc to include in the user API spec.]]>
+    </doc>
+  </interface>
+  <!-- end interface org.apache.zookeeper.KeeperException.CodeDeprecated -->
+  <!-- start class org.apache.zookeeper.KeeperException.ConnectionLossException -->
+  <class name="KeeperException.ConnectionLossException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.ConnectionLossException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.CONNECTIONLOSS]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.ConnectionLossException -->
+  <!-- start class org.apache.zookeeper.KeeperException.DataInconsistencyException -->
+  <class name="KeeperException.DataInconsistencyException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.DataInconsistencyException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.DATAINCONSISTENCY]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.DataInconsistencyException -->
+  <!-- start class org.apache.zookeeper.KeeperException.InvalidACLException -->
+  <class name="KeeperException.InvalidACLException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.InvalidACLException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.INVALIDACL]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.InvalidACLException -->
+  <!-- start class org.apache.zookeeper.KeeperException.InvalidCallbackException -->
+  <class name="KeeperException.InvalidCallbackException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.InvalidCallbackException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.INVALIDCALLBACK]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.InvalidCallbackException -->
+  <!-- start class org.apache.zookeeper.KeeperException.MarshallingErrorException -->
+  <class name="KeeperException.MarshallingErrorException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.MarshallingErrorException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.MARSHALLINGERROR]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.MarshallingErrorException -->
+  <!-- start class org.apache.zookeeper.KeeperException.NoAuthException -->
+  <class name="KeeperException.NoAuthException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.NoAuthException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.NOAUTH]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.NoAuthException -->
+  <!-- start class org.apache.zookeeper.KeeperException.NoChildrenForEphemeralsException -->
+  <class name="KeeperException.NoChildrenForEphemeralsException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.NoChildrenForEphemeralsException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.NOCHILDRENFOREPHEMERALS]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.NoChildrenForEphemeralsException -->
+  <!-- start class org.apache.zookeeper.KeeperException.NodeExistsException -->
+  <class name="KeeperException.NodeExistsException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.NodeExistsException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.NODEEXISTS]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.NodeExistsException -->
+  <!-- start class org.apache.zookeeper.KeeperException.NoNodeException -->
+  <class name="KeeperException.NoNodeException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.NoNodeException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.NONODE]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.NoNodeException -->
+  <!-- start class org.apache.zookeeper.KeeperException.NotEmptyException -->
+  <class name="KeeperException.NotEmptyException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.NotEmptyException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.NOTEMPTY]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.NotEmptyException -->
+  <!-- start class org.apache.zookeeper.KeeperException.OperationTimeoutException -->
+  <class name="KeeperException.OperationTimeoutException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.OperationTimeoutException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.OPERATIONTIMEOUT]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.OperationTimeoutException -->
+  <!-- start class org.apache.zookeeper.KeeperException.RuntimeInconsistencyException -->
+  <class name="KeeperException.RuntimeInconsistencyException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.RuntimeInconsistencyException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.RUNTIMEINCONSISTENCY]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.RuntimeInconsistencyException -->
+  <!-- start class org.apache.zookeeper.KeeperException.SessionExpiredException -->
+  <class name="KeeperException.SessionExpiredException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.SessionExpiredException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.SESSIONEXPIRED]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.SessionExpiredException -->
+  <!-- start class org.apache.zookeeper.KeeperException.SystemErrorException -->
+  <class name="KeeperException.SystemErrorException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.SystemErrorException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.SYSTEMERROR]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.SystemErrorException -->
+  <!-- start class org.apache.zookeeper.KeeperException.UnimplementedException -->
+  <class name="KeeperException.UnimplementedException" extends="org.apache.zookeeper.KeeperException"
+    abstract="false"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="KeeperException.UnimplementedException"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <doc>
+    <![CDATA[@see Code.UNIMPLEMENTED]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.KeeperException.UnimplementedException -->
+  <!-- start class org.apache.zookeeper.Quotas -->
+  <class name="Quotas" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="Quotas"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="quotaPath" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="path" type="java.lang.String"/>
+      <doc>
+      <![CDATA[return the quota path associated with this
+ prefix
+ @param path the actual path in zookeeper.
+ @return the limit quota path]]>
+      </doc>
+    </method>
+    <method name="statPath" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="path" type="java.lang.String"/>
+      <doc>
+      <![CDATA[return the stat quota path associated with this
+ prefix.
+ @param path the actual path in zookeeper
+ @return the stat quota path]]>
+      </doc>
+    </method>
+    <field name="procZookeeper" type="java.lang.String"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[the zookeeper nodes that acts as the management and status node]]>
+      </doc>
+    </field>
+    <field name="quotaZookeeper" type="java.lang.String"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[the zookeeper quota node that acts as the quota
+ management node for zookeeper]]>
+      </doc>
+    </field>
+    <field name="limitNode" type="java.lang.String"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[the limit node that has the limit of
+ a subtree]]>
+      </doc>
+    </field>
+    <field name="statNode" type="java.lang.String"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[the stat node that monitors the limit of
+ a subtree.]]>
+      </doc>
+    </field>
+    <doc>
+    <![CDATA[this class manages quotas
+ and has many other utils
+ for quota]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.Quotas -->
+  <!-- start class org.apache.zookeeper.ServerAdminClient -->
+  <class name="ServerAdminClient" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ServerAdminClient"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="ruok"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="host" type="java.lang.String"/>
+      <param name="port" type="int"/>
+    </method>
+    <method name="dump"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="host" type="java.lang.String"/>
+      <param name="port" type="int"/>
+    </method>
+    <method name="stat"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="host" type="java.lang.String"/>
+      <param name="port" type="int"/>
+    </method>
+    <method name="kill"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="host" type="java.lang.String"/>
+      <param name="port" type="int"/>
+    </method>
+    <method name="setTraceMask"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="host" type="java.lang.String"/>
+      <param name="port" type="int"/>
+      <param name="traceMaskStr" type="java.lang.String"/>
+    </method>
+    <method name="getTraceMask"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="host" type="java.lang.String"/>
+      <param name="port" type="int"/>
+    </method>
+    <method name="main"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="args" type="java.lang.String[]"/>
+    </method>
+  </class>
+  <!-- end class org.apache.zookeeper.ServerAdminClient -->
+  <!-- start class org.apache.zookeeper.StatsTrack -->
+  <class name="StatsTrack" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="StatsTrack"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[a default constructor for
+ stats]]>
+      </doc>
+    </constructor>
+    <constructor name="StatsTrack" type="java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[the stat string should be of the form count=int,bytes=long
+ if stats is called with null the count and bytes are initialized
+ to -1.
+ @param stats the stat string to be intialized with]]>
+      </doc>
+    </constructor>
+    <method name="getCount" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[get the count of nodes allowed as part of quota
+
+ @return the count as part of this string]]>
+      </doc>
+    </method>
+    <method name="setCount"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="count" type="int"/>
+      <doc>
+      <![CDATA[set the count for this stat tracker.
+
+ @param count
+            the count to set with]]>
+      </doc>
+    </method>
+    <method name="getBytes" return="long"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[get the count of bytes allowed as part of quota
+
+ @return the bytes as part of this string]]>
+      </doc>
+    </method>
+    <method name="setBytes"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="bytes" type="long"/>
+      <doc>
+      <![CDATA[set teh bytes for this stat tracker.
+
+ @param bytes
+            the bytes to set with]]>
+      </doc>
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <doc>
+    <![CDATA[a class that represents the stats associated with quotas]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.StatsTrack -->
+  <!-- start class org.apache.zookeeper.Version -->
+  <class name="Version" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <implements name="org.apache.zookeeper.version.Info"/>
+    <constructor name="Version"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <method name="getRevision" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getBuildDate" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getVersion" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getVersionRevision" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getFullVersion" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="printUsage"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="main"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="args" type="java.lang.String[]"/>
+      <doc>
+      <![CDATA[Prints the current version, revision and build date to the standard out.
+ 
+ @param args
+            <ul>
+            <li> --short - prints a short version string "1.2.3"
+            <li> --revision - prints a short version string with the SVN
+            repository revision "1.2.3-94"
+            <li> --full - prints the revision and the build date
+            </ul>]]>
+      </doc>
+    </method>
+  </class>
+  <!-- end class org.apache.zookeeper.Version -->
+  <!-- start class org.apache.zookeeper.WatchedEvent -->
+  <class name="WatchedEvent" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="WatchedEvent" type="org.apache.zookeeper.Watcher.Event.EventType, org.apache.zookeeper.Watcher.Event.KeeperState, java.lang.String"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Create a WatchedEvent with specified type, state and path]]>
+      </doc>
+    </constructor>
+    <constructor name="WatchedEvent" type="org.apache.zookeeper.proto.WatcherEvent"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Convert a WatcherEvent sent over the wire into a full-fledged WatcherEvent]]>
+      </doc>
+    </constructor>
+    <method name="getState" return="org.apache.zookeeper.Watcher.Event.KeeperState"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getType" return="org.apache.zookeeper.Watcher.Event.EventType"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getPath" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="toString" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="getWrapper" return="org.apache.zookeeper.proto.WatcherEvent"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Convert WatchedEvent to type that can be sent over network]]>
+      </doc>
+    </method>
+    <doc>
+    <![CDATA[A WatchedEvent represents a change on the ZooKeeper that a Watcher
+  is able to respond to.  The WatchedEvent includes exactly what happened,
+  the current state of the ZooKeeper, and the path of the znode that
+  was involved in the event.]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.WatchedEvent -->
+  <!-- start interface org.apache.zookeeper.Watcher -->
+  <interface name="Watcher"    abstract="true"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <method name="process"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="event" type="org.apache.zookeeper.WatchedEvent"/>
+    </method>
+    <doc>
+    <![CDATA[This interface specifies the public interface an event handler class must
+ implement. A ZooKeeper client will get various events from the ZooKeepr
+ server it connects to. An application using such a client handles these
+ events by registering a callback object with the client. The callback object
+ is expected to be an instance of a class that implements Watcher interface.]]>
+    </doc>
+  </interface>
+  <!-- end interface org.apache.zookeeper.Watcher -->
+  <!-- start interface org.apache.zookeeper.Watcher.Event -->
+  <interface name="Watcher.Event"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <doc>
+    <![CDATA[This interface defines the possible states an Event may represent]]>
+    </doc>
+  </interface>
+  <!-- end interface org.apache.zookeeper.Watcher.Event -->
+  <!-- start class org.apache.zookeeper.Watcher.Event.EventType -->
+  <class name="Watcher.Event.EventType" extends="java.lang.Enum"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="org.apache.zookeeper.Watcher.Event.EventType[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="org.apache.zookeeper.Watcher.Event.EventType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="getIntValue" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="fromInt" return="org.apache.zookeeper.Watcher.Event.EventType"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="intValue" type="int"/>
+    </method>
+    <field name="None" type="org.apache.zookeeper.Watcher.Event.EventType"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="NodeCreated" type="org.apache.zookeeper.Watcher.Event.EventType"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="NodeDeleted" type="org.apache.zookeeper.Watcher.Event.EventType"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="NodeDataChanged" type="org.apache.zookeeper.Watcher.Event.EventType"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="NodeChildrenChanged" type="org.apache.zookeeper.Watcher.Event.EventType"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <doc>
+    <![CDATA[Enumeration of types of events that may occur on the ZooKeeper]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.Watcher.Event.EventType -->
+  <!-- start class org.apache.zookeeper.Watcher.Event.KeeperState -->
+  <class name="Watcher.Event.KeeperState" extends="java.lang.Enum"
+    abstract="false"
+    static="true" final="true" visibility="public"
+    deprecated="not deprecated">
+    <method name="values" return="org.apache.zookeeper.Watcher.Event.KeeperState[]"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="valueOf" return="org.apache.zookeeper.Watcher.Event.KeeperState"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="name" type="java.lang.String"/>
+    </method>
+    <method name="getIntValue" return="int"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </method>
+    <method name="fromInt" return="org.apache.zookeeper.Watcher.Event.KeeperState"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="intValue" type="int"/>
+    </method>
+    <field name="Unknown" type="org.apache.zookeeper.Watcher.Event.KeeperState"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Unused, this state is never generated by the server]]>
+      </doc>
+    </field>
+    <field name="Disconnected" type="org.apache.zookeeper.Watcher.Event.KeeperState"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The client is in the disconnected state - it is not connected
+ to any server in the ensemble.]]>
+      </doc>
+    </field>
+    <field name="NoSyncConnected" type="org.apache.zookeeper.Watcher.Event.KeeperState"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[Unused, this state is never generated by the server]]>
+      </doc>
+    </field>
+    <field name="SyncConnected" type="org.apache.zookeeper.Watcher.Event.KeeperState"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The client is in the connected state - it is connected
+ to a server in the ensemble (one of the servers specified
+ in the host connection parameter during ZooKeeper client
+ creation).]]>
+      </doc>
+    </field>
+    <field name="Expired" type="org.apache.zookeeper.Watcher.Event.KeeperState"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The serving cluster has expired this session. The ZooKeeper
+ client connection (the session) is no longer valid. You must
+ create a new client connection (instantiate a new ZooKeeper
+ instance) if you with to access the ensemble.]]>
+      </doc>
+    </field>
+    <doc>
+    <![CDATA[Enumeration of states the ZooKeeper may be at the event]]>
+    </doc>
+  </class>
+  <!-- end class org.apache.zookeeper.Watcher.Event.KeeperState -->
+  <!-- start class org.apache.zookeeper.ZooDefs -->
+  <class name="ZooDefs" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ZooDefs"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+    </constructor>
+    <field name="opNames" type="java.lang.String[]"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+  </class>
+  <!-- end class org.apache.zookeeper.ZooDefs -->
+  <!-- start interface org.apache.zookeeper.ZooDefs.Ids -->
+  <interface name="ZooDefs.Ids"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <field name="ANYONE_ID_UNSAFE" type="org.apache.zookeeper.data.Id"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[This Id represents anyone.]]>
+      </doc>
+    </field>
+    <field name="AUTH_IDS" type="org.apache.zookeeper.data.Id"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[This Id is only usable to set ACLs. It will get substituted with the
+ Id's the client authenticated with.]]>
+      </doc>
+    </field>
+    <field name="OPEN_ACL_UNSAFE" type="java.util.ArrayList"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[This is a completely open ACL with the exception of ADMIN permission.]]>
+      </doc>
+    </field>
+    <field name="CREATOR_ALL_ACL" type="java.util.ArrayList"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[This ACL gives the creators authentication id's all permissions.]]>
+      </doc>
+    </field>
+    <field name="READ_ACL_UNSAFE" type="java.util.ArrayList"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[This ACL gives the world the ability to read.]]>
+      </doc>
+    </field>
+  </interface>
+  <!-- end interface org.apache.zookeeper.ZooDefs.Ids -->
+  <!-- start interface org.apache.zookeeper.ZooDefs.OpCode -->
+  <interface name="ZooDefs.OpCode"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <field name="notification" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="create" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="delete" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="exists" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="getData" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="setData" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="getACL" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="setACL" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="getChildren" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="sync" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="ping" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="auth" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="setWatches" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="createSession" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="closeSession" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="error" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+  </interface>
+  <!-- end interface org.apache.zookeeper.ZooDefs.OpCode -->
+  <!-- start interface org.apache.zookeeper.ZooDefs.Perms -->
+  <interface name="ZooDefs.Perms"    abstract="true"
+    static="true" final="false" visibility="public"
+    deprecated="not deprecated">
+    <field name="READ" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="WRITE" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="CREATE" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="DELETE" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="ADMIN" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+    <field name="ALL" type="int"
+      transient="false" volatile="false"
+      static="true" final="true" visibility="public"
+      deprecated="not deprecated">
+    </field>
+  </interface>
+  <!-- end interface org.apache.zookeeper.ZooDefs.Perms -->
+  <!-- start class org.apache.zookeeper.ZooKeeper -->
+  <class name="ZooKeeper" extends="java.lang.Object"
+    abstract="false"
+    static="false" final="false" visibility="public"
+    deprecated="not deprecated">
+    <constructor name="ZooKeeper" type="java.lang.String, int, org.apache.zookeeper.Watcher"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[To create a client(ZooKeeper) object, the application needs to pass a
+ string containing a comma separated list of host:port pairs, each 
+ corresponding to a ZooKeeper server.
+ <p>
+ The client object will pick an arbitrary server and try to connect to it.
+ If failed, it will try the next one in the list, until a connection is
+ established, or all the servers have been tried.
+
+ @param host
+            comma separated host:port pairs, each corresponding to a zk
+            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
+ @param sessionTimeout
+            session timeout in milliseconds
+ @param watcher
+            a watcher object which will be notified of state changes, may
+            also be notified for node events
+
+ @throws IOException in cases of network failure]]>
+      </doc>
+    </constructor>
+    <constructor name="ZooKeeper" type="java.lang.String, int, org.apache.zookeeper.Watcher, long, byte[]"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="IOException" type="java.io.IOException"/>
+      <doc>
+      <![CDATA[To create a client(ZooKeeper) object, the application needs to pass a
+ string containing a comma separated list of host:port pairs, each
+ corresponding to a ZooKeeper server.
+ <p>
+ The client object will pick an arbitrary server and try to connect to it.
+ If failed, it will try the next one in the list, until a connection is
+ established, or all the servers have been tried.
+ <p>
+ Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
+ client connection, these values must be passed as sessionId and
+ sessionPasswd respectively if reconnecting. Otherwise, if not
+ reconnecting, use the other constructor which does not require these
+ parameters.
+
+ @param host
+            comma separated host:port pairs, each corresponding to a zk
+            server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
+ @param sessionTimeout
+            session timeout in milliseconds
+ @param watcher
+            a watcher object which will be notified of state changes, may
+            also be notified for node events
+ @param sessionId
+            specific session id to use if reconnecting
+ @param sessionPasswd
+            password for this session
+
+ @throws IOException in cases of network failure]]>
+      </doc>
+    </constructor>
+    <method name="getSessionId" return="long"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The session id for this ZooKeeper client instance. The value returned is
+ not valid until the client connects to a server and may change after a
+ re-connect.
+
+ @return current session id]]>
+      </doc>
+    </method>
+    <method name="getSessionPasswd" return="byte[]"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <doc>
+      <![CDATA[The session password for this ZooKeeper client instance. The value
+ returned is not valid until the client connects to a server and may
+ change after a re-connect.
+
+ @return current session password]]>
+      </doc>
+    </method>
+    <method name="addAuthInfo"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="scheme" type="java.lang.String"/>
+      <param name="auth" type="byte[]"/>
+    </method>
+    <method name="register"
+      abstract="false" native="false" synchronized="true"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="watcher" type="org.apache.zookeeper.Watcher"/>
+    </method>
+    <method name="close"
+      abstract="false" native="false" synchronized="true"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <exception name="InterruptedException" type="java.lang.InterruptedException"/>
+      <doc>
+      <![CDATA[Close this client object. Once the client is closed, its session becomes
+ invalid. All the ephemeral nodes in the ZooKeeper server associated with
+ the session will be removed. The watches left on those nodes (and on
+ their parents) will be triggered.
+
+ @throws InterruptedException
+
+ @throws IOException
+ @throws InterruptedException]]>
+      </doc>
+    </method>
+    <method name="create" return="java.lang.String"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="path" type="java.lang.String"/>
+      <param name="data" type="byte[]"/>
+      <param name="acl" type="java.util.List"/>
+      <param name="createMode" type="org.apache.zookeeper.CreateMode"/>
+      <exception name="KeeperException" type="org.apache.zookeeper.KeeperException"/>
+      <exception name="InterruptedException" type="java.lang.InterruptedException"/>
+      <doc>
+      <![CDATA[Create a node with the given path. The node data will be the given data,
+ and node acl will be the given acl.
+ <p>
+ The flags argument specifies whether the created node will be ephemeral
+ or not.
+ <p>
+ An ephemeral node will be removed by the ZooKeeper automatically when the
+ session associated with the creation of the node expires.
+ <p>
+ The flags argument can also specify to create a sequential node. The
+ actual path name of a sequential node will be the given path plus a
+ suffix "_i" where i is the current sequential number of the node. Once
+ such a node is created, the sequential number will be incremented by one.
+ <p>
+ If a node with the same actual path already exists in the ZooKeeper, a
+ KeeperException with error code KeeperException.NodeExists will be
+ thrown. Note that since a different actual path is used for each
+ invocation of creating sequential node with the same path argument, the
+ call will never throw "file exists" KeeperException.
+ <p>
+ If the parent node does not exist in the ZooKeeper, a KeeperException
+ with error code KeeperException.NoNode will be thrown.
+ <p>
+ An ephemeral node cannot have children. If the parent node of the given
+ path is ephemeral, a KeeperException with error code
+ KeeperException.NoChildrenForEphemerals will be thrown.
+ <p>
+ This operation, if successful, will trigger all the watches left on the
+ node of the given path by exists and getData API calls, and the watches
+ left on the parent node by getChildren API calls.
+ <p>
+ If a node is created successfully, the ZooKeeper server will trigger the
+ watches on the path left by exists calls, and the watches on the parent
+ of the node by getChildren calls.
+ <p>
+ The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
+ Arrays larger than this will cause a KeeperExecption to be thrown.
+
+ @param path
+                the path for the node
+ @param data
+                the initial data for the node
+ @param acl
+                the acl for the node
+ @param flags
+                specifying whether the node to be created is ephemeral
+                and/or sequential
+ @return the actual path of the created node
+ @throws KeeperException if the server returns a non-zero error code
+ @throws org.apache.zookeeper.KeeperException.InvalidACLException if the ACL is invalid
+ @throws InterruptedException if the transaction is interrupted
+ @throws IllegalArgumentException if an invalid path is specified]]>
+      </doc>
+    </method>
+    <method name="validatePath"
+      abstract="false" native="false" synchronized="false"
+      static="true" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="path" type="java.lang.String"/>
+      <exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"/>
+      <doc>
+      <![CDATA[Validate the provided znode path string
+ @param path znode path string
+ @throws IllegalArgumentException if the path is invalid]]>
+      </doc>
+    </method>
+    <method name="create"
+      abstract="false" native="false" synchronized="false"
+      static="false" final="false" visibility="public"
+      deprecated="not deprecated">
+      <param name="path" type="java.lang.String"/>
+      <param name="data" type="byte[]"/>
+      <param name="acl" type="java.util.List"/>
+      <param name="createMode" type="org.apache.zookeeper.CreateMode"/>
+      <param name="cb" type="org.apache.zookeeper.AsyncCallback.StringCallback"/>
+      <param name="ctx" type="java.lang.Object"/>
+      <doc>
+      <![CDATA[The Asynchronous version of create. The request doesn't actually until
+ the asynchronous callback is called.
+
+ @see #create(String, byte[], List<ACL>, CreateMode)]]>
+      </doc>
+    </

<TRUNCATED>

[34/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java
deleted file mode 100644
index 720619d..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Set;
-
-import org.apache.zookeeper.ClientCnxn.EndOfStreamException;
-import org.apache.zookeeper.ClientCnxn.Packet;
-import org.apache.zookeeper.ZooDefs.OpCode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClientCnxnSocketNIO extends ClientCnxnSocket {
-    private static final Logger LOG = LoggerFactory
-            .getLogger(ClientCnxnSocketNIO.class);
-
-    private final Selector selector = Selector.open();
-
-    private SelectionKey sockKey;
-
-    ClientCnxnSocketNIO() throws IOException {
-        super();
-    }
-
-    @Override
-    boolean isConnected() {
-        return sockKey != null;
-    }
-    
-    /**
-     * @return true if a packet was received
-     * @throws InterruptedException
-     * @throws IOException
-     */
-    void doIO(List<Packet> pendingQueue, LinkedList<Packet> outgoingQueue, ClientCnxn cnxn)
-      throws InterruptedException, IOException {
-        SocketChannel sock = (SocketChannel) sockKey.channel();
-        if (sock == null) {
-            throw new IOException("Socket is null!");
-        }
-        if (sockKey.isReadable()) {
-            int rc = sock.read(incomingBuffer);
-            if (rc < 0) {
-                throw new EndOfStreamException(
-                        "Unable to read additional data from server sessionid 0x"
-                                + Long.toHexString(sessionId)
-                                + ", likely server has closed socket");
-            }
-            if (!incomingBuffer.hasRemaining()) {
-                incomingBuffer.flip();
-                if (incomingBuffer == lenBuffer) {
-                    recvCount++;
-                    readLength();
-                } else if (!initialized) {
-                    readConnectResult();
-                    enableRead();
-                    if (findSendablePacket(outgoingQueue,
-                            cnxn.sendThread.clientTunneledAuthenticationInProgress()) != null) {
-                        // Since SASL authentication has completed (if client is configured to do so),
-                        // outgoing packets waiting in the outgoingQueue can now be sent.
-                        enableWrite();
-                    }
-                    lenBuffer.clear();
-                    incomingBuffer = lenBuffer;
-                    updateLastHeard();
-                    initialized = true;
-                } else {
-                    sendThread.readResponse(incomingBuffer);
-                    lenBuffer.clear();
-                    incomingBuffer = lenBuffer;
-                    updateLastHeard();
-                }
-            }
-        }
-        if (sockKey.isWritable()) {
-            synchronized(outgoingQueue) {
-                Packet p = findSendablePacket(outgoingQueue,
-                        cnxn.sendThread.clientTunneledAuthenticationInProgress());
-
-                if (p != null) {
-                    updateLastSend();
-                    // If we already started writing p, p.bb will already exist
-                    if (p.bb == null) {
-                        if ((p.requestHeader != null) &&
-                                (p.requestHeader.getType() != OpCode.ping) &&
-                                (p.requestHeader.getType() != OpCode.auth)) {
-                            p.requestHeader.setXid(cnxn.getXid());
-                        }
-                        p.createBB();
-                    }
-                    sock.write(p.bb);
-                    if (!p.bb.hasRemaining()) {
-                        sentCount++;
-                        outgoingQueue.removeFirstOccurrence(p);
-                        if (p.requestHeader != null
-                                && p.requestHeader.getType() != OpCode.ping
-                                && p.requestHeader.getType() != OpCode.auth) {
-                            synchronized (pendingQueue) {
-                                pendingQueue.add(p);
-                            }
-                        }
-                    }
-                }
-                if (outgoingQueue.isEmpty()) {
-                    // No more packets to send: turn off write interest flag.
-                    // Will be turned on later by a later call to enableWrite(),
-                    // from within ZooKeeperSaslClient (if client is configured
-                    // to attempt SASL authentication), or in either doIO() or
-                    // in doTransport() if not.
-                    disableWrite();
-                } else if (!initialized && p != null && !p.bb.hasRemaining()) {
-                    // On initial connection, write the complete connect request
-                    // packet, but then disable further writes until after
-                    // receiving a successful connection response.  If the
-                    // session is expired, then the server sends the expiration
-                    // response and immediately closes its end of the socket.  If
-                    // the client is simultaneously writing on its end, then the
-                    // TCP stack may choose to abort with RST, in which case the
-                    // client would never receive the session expired event.  See
-                    // http://docs.oracle.com/javase/6/docs/technotes/guides/net/articles/connection_release.html
-                    disableWrite();
-                } else {
-                    // Just in case
-                    enableWrite();
-                }
-            }
-        }
-    }
-
-    private Packet findSendablePacket(LinkedList<Packet> outgoingQueue,
-                                      boolean clientTunneledAuthenticationInProgress) {
-        synchronized (outgoingQueue) {
-            if (outgoingQueue.isEmpty()) {
-                return null;
-            }
-            if (outgoingQueue.getFirst().bb != null // If we've already starting sending the first packet, we better finish
-                || !clientTunneledAuthenticationInProgress) {
-                return outgoingQueue.getFirst();
-            }
-
-            // Since client's authentication with server is in progress,
-            // send only the null-header packet queued by primeConnection().
-            // This packet must be sent so that the SASL authentication process
-            // can proceed, but all other packets should wait until
-            // SASL authentication completes.
-            ListIterator<Packet> iter = outgoingQueue.listIterator();
-            while (iter.hasNext()) {
-                Packet p = iter.next();
-                if (p.requestHeader == null) {
-                    // We've found the priming-packet. Move it to the beginning of the queue.
-                    iter.remove();
-                    outgoingQueue.add(0, p);
-                    return p;
-                } else {
-                    // Non-priming packet: defer it until later, leaving it in the queue
-                    // until authentication completes.
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("deferring non-priming packet: " + p +
-                                "until SASL authentication completes.");
-                    }
-                }
-            }
-            // no sendable packet found.
-            return null;
-        }
-    }
-
-    @Override
-    void cleanup() {
-        if (sockKey != null) {
-            SocketChannel sock = (SocketChannel) sockKey.channel();
-            sockKey.cancel();
-            try {
-                sock.socket().shutdownInput();
-            } catch (IOException e) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Ignoring exception during shutdown input", e);
-                }
-            }
-            try {
-                sock.socket().shutdownOutput();
-            } catch (IOException e) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Ignoring exception during shutdown output",
-                            e);
-                }
-            }
-            try {
-                sock.socket().close();
-            } catch (IOException e) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Ignoring exception during socket close", e);
-                }
-            }
-            try {
-                sock.close();
-            } catch (IOException e) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Ignoring exception during channel close", e);
-                }
-            }
-        }
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("SendThread interrupted during sleep, ignoring");
-            }
-        }
-        sockKey = null;
-    }
- 
-    @Override
-    void close() {
-        try {
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Doing client selector close");
-            }
-            selector.close();
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Closed client selector");
-            }
-        } catch (IOException e) {
-            LOG.warn("Ignoring exception during selector close", e);
-        }
-    }
-    
-    /**
-     * create a socket channel.
-     * @return the created socket channel
-     * @throws IOException
-     */
-    SocketChannel createSock() throws IOException {
-        SocketChannel sock;
-        sock = SocketChannel.open();
-        sock.configureBlocking(false);
-        sock.socket().setSoLinger(false, -1);
-        sock.socket().setTcpNoDelay(true);
-        return sock;
-    }
-
-    /**
-     * register with the selection and connect
-     * @param sock the {@link SocketChannel} 
-     * @param addr the address of remote host
-     * @throws IOException
-     */
-    void registerAndConnect(SocketChannel sock, InetSocketAddress addr) 
-    throws IOException {
-        sockKey = sock.register(selector, SelectionKey.OP_CONNECT);
-        boolean immediateConnect = sock.connect(addr);
-        if (immediateConnect) {
-            sendThread.primeConnection();
-        }
-    }
-    
-    @Override
-    void connect(InetSocketAddress addr) throws IOException {
-        SocketChannel sock = createSock();
-        try {
-           registerAndConnect(sock, addr);
-        } catch (IOException e) {
-            LOG.error("Unable to open socket to " + addr);
-            sock.close();
-            throw e;
-        }
-        initialized = false;
-
-        /*
-         * Reset incomingBuffer
-         */
-        lenBuffer.clear();
-        incomingBuffer = lenBuffer;
-    }
-
-    /**
-     * Returns the address to which the socket is connected.
-     * 
-     * @return ip address of the remote side of the connection or null if not
-     *         connected
-     */
-    @Override
-    SocketAddress getRemoteSocketAddress() {
-        // a lot could go wrong here, so rather than put in a bunch of code
-        // to check for nulls all down the chain let's do it the simple
-        // yet bulletproof way
-        try {
-            return ((SocketChannel) sockKey.channel()).socket()
-                    .getRemoteSocketAddress();
-        } catch (NullPointerException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Returns the local address to which the socket is bound.
-     * 
-     * @return ip address of the remote side of the connection or null if not
-     *         connected
-     */
-    @Override
-    SocketAddress getLocalSocketAddress() {
-        // a lot could go wrong here, so rather than put in a bunch of code
-        // to check for nulls all down the chain let's do it the simple
-        // yet bulletproof way
-        try {
-            return ((SocketChannel) sockKey.channel()).socket()
-                    .getLocalSocketAddress();
-        } catch (NullPointerException e) {
-            return null;
-        }
-    }
-
-    @Override
-    synchronized void wakeupCnxn() {
-        selector.wakeup();
-    }
-    
-    @Override
-    void doTransport(int waitTimeOut, List<Packet> pendingQueue, LinkedList<Packet> outgoingQueue,
-                     ClientCnxn cnxn)
-            throws IOException, InterruptedException {
-        selector.select(waitTimeOut);
-        Set<SelectionKey> selected;
-        synchronized (this) {
-            selected = selector.selectedKeys();
-        }
-        // Everything below and until we get back to the select is
-        // non blocking, so time is effectively a constant. That is
-        // Why we just have to do this once, here
-        updateNow();
-        for (SelectionKey k : selected) {
-            SocketChannel sc = ((SocketChannel) k.channel());
-            if ((k.readyOps() & SelectionKey.OP_CONNECT) != 0) {
-                if (sc.finishConnect()) {
-                    updateLastSendAndHeard();
-                    sendThread.primeConnection();
-                }
-            } else if ((k.readyOps() & (SelectionKey.OP_READ | SelectionKey.OP_WRITE)) != 0) {
-                doIO(pendingQueue, outgoingQueue, cnxn);
-            }
-        }
-        if (sendThread.getZkState().isConnected()) {
-            synchronized(outgoingQueue) {
-                if (findSendablePacket(outgoingQueue,
-                        cnxn.sendThread.clientTunneledAuthenticationInProgress()) != null) {
-                    enableWrite();
-                }
-            }
-        }
-        selected.clear();
-    }
-
-    //TODO should this be synchronized?
-    @Override
-    void testableCloseSocket() throws IOException {
-        LOG.info("testableCloseSocket() called");
-        ((SocketChannel) sockKey.channel()).socket().close();
-    }
-
-    @Override
-    synchronized void enableWrite() {
-        int i = sockKey.interestOps();
-        if ((i & SelectionKey.OP_WRITE) == 0) {
-            sockKey.interestOps(i | SelectionKey.OP_WRITE);
-        }
-    }
-
-    @Override
-    public synchronized void disableWrite() {
-        int i = sockKey.interestOps();
-        if ((i & SelectionKey.OP_WRITE) != 0) {
-            sockKey.interestOps(i & (~SelectionKey.OP_WRITE));
-        }
-    }
-
-    synchronized private void enableRead() {
-        int i = sockKey.interestOps();
-        if ((i & SelectionKey.OP_READ) == 0) {
-            sockKey.interestOps(i | SelectionKey.OP_READ);
-        }
-    }
-
-    @Override
-    synchronized void enableReadWriteOnly() {
-        sockKey.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
-    }
-
-    Selector getSelector() {
-        return selector;
-    }
-
-    @Override
-    void sendPacket(Packet p) throws IOException {
-        SocketChannel sock = (SocketChannel) sockKey.channel();
-        if (sock == null) {
-            throw new IOException("Socket is null!");
-        }
-        p.createBB();
-        ByteBuffer pbb = p.bb;
-        sock.write(pbb);
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java
deleted file mode 100644
index d56374d..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.util.Set;
-
-/**
- */
-public interface ClientWatchManager {
-    /**
-     * Return a set of watchers that should be notified of the event. The 
-     * manager must not notify the watcher(s), however it will update it's 
-     * internal structure as if the watches had triggered. The intent being 
-     * that the callee is now responsible for notifying the watchers of the 
-     * event, possibly at some later time.
-     * 
-     * @param state event state
-     * @param type event type
-     * @param path event path
-     * @return may be empty set but must not be null
-     */
-    public Set<Watcher> materialize(Watcher.Event.KeeperState state,
-        Watcher.Event.EventType type, String path);
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java b/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java
deleted file mode 100644
index 84f5be0..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.KeeperException;
-
-/***
- *  CreateMode value determines how the znode is created on ZooKeeper.
- */
-@InterfaceAudience.Public
-public enum CreateMode {
-    
-    /**
-     * The znode will not be automatically deleted upon client's disconnect.
-     */
-    PERSISTENT (0, false, false),
-    /**
-    * The znode will not be automatically deleted upon client's disconnect,
-    * and its name will be appended with a monotonically increasing number.
-    */
-    PERSISTENT_SEQUENTIAL (2, false, true),
-    /**
-     * The znode will be deleted upon the client's disconnect.
-     */
-    EPHEMERAL (1, true, false),
-    /**
-     * The znode will be deleted upon the client's disconnect, and its name
-     * will be appended with a monotonically increasing number.
-     */
-    EPHEMERAL_SEQUENTIAL (3, true, true);
-
-    private static final Logger LOG = LoggerFactory.getLogger(CreateMode.class);
-
-    private boolean ephemeral;
-    private boolean sequential;
-    private int flag;
-
-    CreateMode(int flag, boolean ephemeral, boolean sequential) {
-        this.flag = flag;
-        this.ephemeral = ephemeral;
-        this.sequential = sequential;
-    }
-
-    public boolean isEphemeral() { 
-        return ephemeral;
-    }
-
-    public boolean isSequential() { 
-        return sequential;
-    }
-
-    public int toFlag() {
-        return flag;
-    }
-
-    /**
-     * Map an integer value to a CreateMode value
-     */
-    static public CreateMode fromFlag(int flag) throws KeeperException {
-        switch(flag) {
-        case 0: return CreateMode.PERSISTENT;
-
-        case 1: return CreateMode.EPHEMERAL;
-
-        case 2: return CreateMode.PERSISTENT_SEQUENTIAL;
-
-        case 3: return CreateMode.EPHEMERAL_SEQUENTIAL ;
-
-        default:
-            String errMsg = "Received an invalid flag value: " + flag
-                    + " to convert to a CreateMode";
-            LOG.error(errMsg);
-            throw new KeeperException.BadArgumentsException(errMsg);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java
deleted file mode 100644
index 51797a1..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provide insight into the runtime environment.
- *
- */
-public class Environment {
-    public static final String JAAS_CONF_KEY = "java.security.auth.login.config";
-
-    public static class Entry {
-        private String k;
-        private String v;
-        public Entry(String k, String v) {
-            this.k = k;
-            this.v = v;
-        }
-        public String getKey() { return k; }
-        public String getValue() { return v; }
-        
-        @Override
-        public String toString() {
-            return k + "=" + v;
-        }
-    }
-
-    private static void put(ArrayList<Entry> l, String k, String v) {
-        l.add(new Entry(k,v));
-    }
-
-    public static List<Entry> list() {
-        ArrayList<Entry> l = new ArrayList<Entry>();
-        put(l, "zookeeper.version", Version.getFullVersion());
-
-        try {
-            put(l, "host.name",
-                InetAddress.getLocalHost().getCanonicalHostName());
-        } catch (UnknownHostException e) {
-            put(l, "host.name", "<NA>");
-        }
-
-        put(l, "java.version",
-                System.getProperty("java.version", "<NA>"));
-        put(l, "java.vendor",
-                System.getProperty("java.vendor", "<NA>"));
-        put(l, "java.home",
-                System.getProperty("java.home", "<NA>"));
-        put(l, "java.class.path",
-                System.getProperty("java.class.path", "<NA>"));
-        put(l, "java.library.path",
-                System.getProperty("java.library.path", "<NA>"));
-        put(l, "java.io.tmpdir",
-                System.getProperty("java.io.tmpdir", "<NA>"));
-        put(l, "java.compiler",
-                System.getProperty("java.compiler", "<NA>"));
-        put(l, "os.name",
-                System.getProperty("os.name", "<NA>"));
-        put(l, "os.arch",
-                System.getProperty("os.arch", "<NA>"));
-        put(l, "os.version",
-                System.getProperty("os.version", "<NA>"));
-        put(l, "user.name",
-                System.getProperty("user.name", "<NA>"));
-        put(l, "user.home",
-                System.getProperty("user.home", "<NA>"));
-        put(l, "user.dir",
-                System.getProperty("user.dir", "<NA>"));
-        
-        return l;
-    }
-    
-    public static void logEnv(String msg, Logger log) {
-        List<Entry> env = Environment.list();
-        for (Entry e : env) {
-            log.info(msg + e.toString());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java b/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java
deleted file mode 100644
index bdf4203..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java
+++ /dev/null
@@ -1,728 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.yetus.audience.InterfaceAudience;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@SuppressWarnings("serial")
-@InterfaceAudience.Public
-public abstract class KeeperException extends Exception {
-    /**
-     * All multi-requests that result in an exception retain the results
-     * here so that it is possible to examine the problems in the catch
-     * scope.  Non-multi requests will get a null if they try to access
-     * these results.
-     */
-    private List<OpResult> results;
-
-    /**
-     * All non-specific keeper exceptions should be constructed via
-     * this factory method in order to guarantee consistency in error
-     * codes and such.  If you know the error code, then you should
-     * construct the special purpose exception directly.  That will
-     * allow you to have the most specific possible declarations of
-     * what exceptions might actually be thrown.
-     *
-     * @param code The error code.
-     * @param path The ZooKeeper path being operated on.
-     * @return The specialized exception, presumably to be thrown by
-     *  the caller.
-     */
-    public static KeeperException create(Code code, String path) {
-        KeeperException r = create(code);
-        r.path = path;
-        return r;
-    }
-
-    /**
-     * @deprecated deprecated in 3.1.0, use {@link #create(Code, String)}
-     * instead
-     */
-    @Deprecated
-    public static KeeperException create(int code, String path) {
-        KeeperException r = create(Code.get(code));
-        r.path = path;
-        return r;
-    }
-
-    /**
-     * @deprecated deprecated in 3.1.0, use {@link #create(Code)}
-     * instead
-     */
-    @Deprecated
-    public static KeeperException create(int code) {
-        return create(Code.get(code));
-    }
-
-    /**
-     * All non-specific keeper exceptions should be constructed via
-     * this factory method in order to guarantee consistency in error
-     * codes and such.  If you know the error code, then you should
-     * construct the special purpose exception directly.  That will
-     * allow you to have the most specific possible declarations of
-     * what exceptions might actually be thrown.
-     *
-     * @param code The error code of your new exception.  This will
-     * also determine the specific type of the exception that is
-     * returned.
-     * @return The specialized exception, presumably to be thrown by
-     * the caller.
-     */
-    public static KeeperException create(Code code) {
-        switch (code) {
-            case SYSTEMERROR:
-                return new SystemErrorException();
-            case RUNTIMEINCONSISTENCY:
-                return new RuntimeInconsistencyException();
-            case DATAINCONSISTENCY:
-                return new DataInconsistencyException();
-            case CONNECTIONLOSS:
-                return new ConnectionLossException();
-            case MARSHALLINGERROR:
-                return new MarshallingErrorException();
-            case UNIMPLEMENTED:
-                return new UnimplementedException();
-            case OPERATIONTIMEOUT:
-                return new OperationTimeoutException();
-            case BADARGUMENTS:
-                return new BadArgumentsException();
-            case APIERROR:
-                return new APIErrorException();
-            case NONODE:
-                return new NoNodeException();
-            case NOAUTH:
-                return new NoAuthException();
-            case BADVERSION:
-                return new BadVersionException();
-            case NOCHILDRENFOREPHEMERALS:
-                return new NoChildrenForEphemeralsException();
-            case NODEEXISTS:
-                return new NodeExistsException();
-            case INVALIDACL:
-                return new InvalidACLException();
-            case AUTHFAILED:
-                return new AuthFailedException();
-            case NOTEMPTY:
-                return new NotEmptyException();
-            case SESSIONEXPIRED:
-                return new SessionExpiredException();
-            case INVALIDCALLBACK:
-                return new InvalidCallbackException();
-            case SESSIONMOVED:
-                return new SessionMovedException();
-            case NOTREADONLY:
-                return new NotReadOnlyException();
-
-            case OK:
-            default:
-                throw new IllegalArgumentException("Invalid exception code");
-        }
-    }
-
-    /**
-     * Set the code for this exception
-     * @param code error code
-     * @deprecated deprecated in 3.1.0, exceptions should be immutable, this
-     * method should not be used
-     */
-    @Deprecated
-    public void setCode(int code) {
-        this.code = Code.get(code);
-    }
-
-    /** This interface contains the original static final int constants
-     * which have now been replaced with an enumeration in Code. Do not
-     * reference this class directly, if necessary (legacy code) continue
-     * to access the constants through Code.
-     * Note: an interface is used here due to the fact that enums cannot
-     * reference constants defined within the same enum as said constants
-     * are considered initialized _after_ the enum itself. By using an
-     * interface as a super type this allows the deprecated constants to
-     * be initialized first and referenced when constructing the enums. I
-     * didn't want to have constants declared twice. This
-     * interface should be private, but it's declared public to enable
-     * javadoc to include in the user API spec.
-     */
-    @Deprecated
-    @InterfaceAudience.Public
-    public interface CodeDeprecated {
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#OK} instead
-         */
-        @Deprecated
-        public static final int Ok = 0;
-
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead
-         */
-        @Deprecated
-        public static final int SystemError = -1;
-        /**
-         * @deprecated deprecated in 3.1.0, use
-         * {@link Code#RUNTIMEINCONSISTENCY} instead
-         */
-        @Deprecated
-        public static final int RuntimeInconsistency = -2;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY}
-         * instead
-         */
-        @Deprecated
-        public static final int DataInconsistency = -3;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS}
-         * instead
-         */
-        @Deprecated
-        public static final int ConnectionLoss = -4;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR}
-         * instead
-         */
-        @Deprecated
-        public static final int MarshallingError = -5;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED}
-         * instead
-         */
-        @Deprecated
-        public static final int Unimplemented = -6;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT}
-         * instead
-         */
-        @Deprecated
-        public static final int OperationTimeout = -7;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#BADARGUMENTS}
-         * instead
-         */
-        @Deprecated
-        public static final int BadArguments = -8;
-
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#APIERROR} instead
-         */
-        @Deprecated
-        public static final int APIError = -100;
-
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#NONODE} instead
-         */
-        @Deprecated
-        public static final int NoNode = -101;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#NOAUTH} instead
-         */
-        @Deprecated
-        public static final int NoAuth = -102;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#BADVERSION} instead
-         */
-        @Deprecated
-        public static final int BadVersion = -103;
-        /**
-         * @deprecated deprecated in 3.1.0, use
-         * {@link Code#NOCHILDRENFOREPHEMERALS}
-         * instead
-         */
-        @Deprecated
-        public static final int NoChildrenForEphemerals = -108;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead
-         */
-        @Deprecated
-        public static final int NodeExists = -110;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead
-         */
-        @Deprecated
-        public static final int NotEmpty = -111;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead
-         */
-        @Deprecated
-        public static final int SessionExpired = -112;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK}
-         * instead
-         */
-        @Deprecated
-        public static final int InvalidCallback = -113;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDACL} instead
-         */
-        @Deprecated
-        public static final int InvalidACL = -114;
-        /**
-         * @deprecated deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead
-         */
-        @Deprecated
-        public static final int AuthFailed = -115;
-        /**
-         * This value will be used directly in {@link CODE#SESSIONMOVED}
-         */
-        // public static final int SessionMoved = -118;
-    }
-
-    /** Codes which represent the various KeeperException
-     * types. This enum replaces the deprecated earlier static final int
-     * constants. The old, deprecated, values are in "camel case" while the new
-     * enum values are in all CAPS.
-     */
-    @InterfaceAudience.Public
-    public static enum Code implements CodeDeprecated {
-        /** Everything is OK */
-        OK (Ok),
-
-        /** System and server-side errors.
-         * This is never thrown by the server, it shouldn't be used other than
-         * to indicate a range. Specifically error codes greater than this
-         * value, but lesser than {@link #APIERROR}, are system errors.
-         */
-        SYSTEMERROR (SystemError),
-
-        /** A runtime inconsistency was found */
-        RUNTIMEINCONSISTENCY (RuntimeInconsistency),
-        /** A data inconsistency was found */
-        DATAINCONSISTENCY (DataInconsistency),
-        /** Connection to the server has been lost */
-        CONNECTIONLOSS (ConnectionLoss),
-        /** Error while marshalling or unmarshalling data */
-        MARSHALLINGERROR (MarshallingError),
-        /** Operation is unimplemented */
-        UNIMPLEMENTED (Unimplemented),
-        /** Operation timeout */
-        OPERATIONTIMEOUT (OperationTimeout),
-        /** Invalid arguments */
-        BADARGUMENTS (BadArguments),
-        
-        /** API errors.
-         * This is never thrown by the server, it shouldn't be used other than
-         * to indicate a range. Specifically error codes greater than this
-         * value are API errors (while values less than this indicate a
-         * {@link #SYSTEMERROR}).
-         */
-        APIERROR (APIError),
-
-        /** Node does not exist */
-        NONODE (NoNode),
-        /** Not authenticated */
-        NOAUTH (NoAuth),
-        /** Version conflict */
-        BADVERSION (BadVersion),
-        /** Ephemeral nodes may not have children */
-        NOCHILDRENFOREPHEMERALS (NoChildrenForEphemerals),
-        /** The node already exists */
-        NODEEXISTS (NodeExists),
-        /** The node has children */
-        NOTEMPTY (NotEmpty),
-        /** The session has been expired by the server */
-        SESSIONEXPIRED (SessionExpired),
-        /** Invalid callback specified */
-        INVALIDCALLBACK (InvalidCallback),
-        /** Invalid ACL specified */
-        INVALIDACL (InvalidACL),
-        /** Client authentication failed */
-        AUTHFAILED (AuthFailed),
-        /** Session moved to another server, so operation is ignored */
-        SESSIONMOVED (-118),
-        /** State-changing request is passed to read-only server */
-        NOTREADONLY (-119);
-
-        private static final Map<Integer,Code> lookup
-            = new HashMap<Integer,Code>();
-
-        static {
-            for(Code c : EnumSet.allOf(Code.class))
-                lookup.put(c.code, c);
-        }
-
-        private final int code;
-        Code(int code) {
-            this.code = code;
-        }
-
-        /**
-         * Get the int value for a particular Code.
-         * @return error code as integer
-         */
-        public int intValue() { return code; }
-
-        /**
-         * Get the Code value for a particular integer error code
-         * @param code int error code
-         * @return Code value corresponding to specified int code, or null
-         */
-        public static Code get(int code) {
-            return lookup.get(code);
-        }
-    }
-
-    static String getCodeMessage(Code code) {
-        switch (code) {
-            case OK:
-                return "ok";
-            case SYSTEMERROR:
-                return "SystemError";
-            case RUNTIMEINCONSISTENCY:
-                return "RuntimeInconsistency";
-            case DATAINCONSISTENCY:
-                return "DataInconsistency";
-            case CONNECTIONLOSS:
-                return "ConnectionLoss";
-            case MARSHALLINGERROR:
-                return "MarshallingError";
-            case UNIMPLEMENTED:
-                return "Unimplemented";
-            case OPERATIONTIMEOUT:
-                return "OperationTimeout";
-            case BADARGUMENTS:
-                return "BadArguments";
-            case APIERROR:
-                return "APIError";
-            case NONODE:
-                return "NoNode";
-            case NOAUTH:
-                return "NoAuth";
-            case BADVERSION:
-                return "BadVersion";
-            case NOCHILDRENFOREPHEMERALS:
-                return "NoChildrenForEphemerals";
-            case NODEEXISTS:
-                return "NodeExists";
-            case INVALIDACL:
-                return "InvalidACL";
-            case AUTHFAILED:
-                return "AuthFailed";
-            case NOTEMPTY:
-                return "Directory not empty";
-            case SESSIONEXPIRED:
-                return "Session expired";
-            case INVALIDCALLBACK:
-                return "Invalid callback";
-            case SESSIONMOVED:
-                return "Session moved";
-            case NOTREADONLY:
-                return "Not a read-only call";
-            default:
-                return "Unknown error " + code;
-        }
-    }
-
-    private Code code;
-
-    private String path;
-
-    public KeeperException(Code code) {
-        this.code = code;
-    }
-
-    KeeperException(Code code, String path) {
-        this.code = code;
-        this.path = path;
-    }
-
-    /**
-     * Read the error code for this exception
-     * @return the error code for this exception
-     * @deprecated deprecated in 3.1.0, use {@link #code()} instead
-     */
-    @Deprecated
-    public int getCode() {
-        return code.code;
-    }
-
-    /**
-     * Read the error Code for this exception
-     * @return the error Code for this exception
-     */
-    public Code code() {
-        return code;
-    }
-
-    /**
-     * Read the path for this exception
-     * @return the path associated with this error, null if none
-     */
-    public String getPath() {
-        return path;
-    }
-
-    @Override
-    public String getMessage() {
-        if (path == null) {
-            return "KeeperErrorCode = " + getCodeMessage(code);
-        }
-        return "KeeperErrorCode = " + getCodeMessage(code) + " for " + path;
-    }
-
-    void setMultiResults(List<OpResult> results) {
-        this.results = results;
-    }
-
-    /**
-     * If this exception was thrown by a multi-request then the (partial) results
-     * and error codes can be retrieved using this getter.
-     * @return A copy of the list of results from the operations in the multi-request.
-     *
-     * @since 3.4.0
-     *
-     */
-    public List<OpResult> getResults() {
-        return results != null ? new ArrayList<OpResult>(results) : null;
-    }
-
-    /**
-     *  @see Code#APIERROR
-     */
-    @InterfaceAudience.Public
-    public static class APIErrorException extends KeeperException {
-        public APIErrorException() {
-            super(Code.APIERROR);
-        }
-    }
-
-    /**
-     *  @see Code#AUTHFAILED
-     */
-    @InterfaceAudience.Public
-    public static class AuthFailedException extends KeeperException {
-        public AuthFailedException() {
-            super(Code.AUTHFAILED);
-        }
-    }
-
-    /**
-     *  @see Code#BADARGUMENTS
-     */
-    @InterfaceAudience.Public
-    public static class BadArgumentsException extends KeeperException {
-        public BadArgumentsException() {
-            super(Code.BADARGUMENTS);
-        }
-        public BadArgumentsException(String path) {
-            super(Code.BADARGUMENTS, path);
-        }
-    }
-
-    /**
-     * @see Code#BADVERSION
-     */
-    @InterfaceAudience.Public
-    public static class BadVersionException extends KeeperException {
-        public BadVersionException() {
-            super(Code.BADVERSION);
-        }
-        public BadVersionException(String path) {
-            super(Code.BADVERSION, path);
-        }
-    }
-
-    /**
-     * @see Code#CONNECTIONLOSS
-     */
-    @InterfaceAudience.Public
-    public static class ConnectionLossException extends KeeperException {
-        public ConnectionLossException() {
-            super(Code.CONNECTIONLOSS);
-        }
-    }
-
-    /**
-     * @see Code#DATAINCONSISTENCY
-     */
-    @InterfaceAudience.Public
-    public static class DataInconsistencyException extends KeeperException {
-        public DataInconsistencyException() {
-            super(Code.DATAINCONSISTENCY);
-        }
-    }
-
-    /**
-     * @see Code#INVALIDACL
-     */
-    @InterfaceAudience.Public
-    public static class InvalidACLException extends KeeperException {
-        public InvalidACLException() {
-            super(Code.INVALIDACL);
-        }
-        public InvalidACLException(String path) {
-            super(Code.INVALIDACL, path);
-        }
-    }
-
-    /**
-     * @see Code#INVALIDCALLBACK
-     */
-    @InterfaceAudience.Public
-    public static class InvalidCallbackException extends KeeperException {
-        public InvalidCallbackException() {
-            super(Code.INVALIDCALLBACK);
-        }
-    }
-
-    /**
-     * @see Code#MARSHALLINGERROR
-     */
-    @InterfaceAudience.Public
-    public static class MarshallingErrorException extends KeeperException {
-        public MarshallingErrorException() {
-            super(Code.MARSHALLINGERROR);
-        }
-    }
-
-    /**
-     * @see Code#NOAUTH
-     */
-    @InterfaceAudience.Public
-    public static class NoAuthException extends KeeperException {
-        public NoAuthException() {
-            super(Code.NOAUTH);
-        }
-    }
-
-    /**
-     * @see Code#NOCHILDRENFOREPHEMERALS
-     */
-    @InterfaceAudience.Public
-    public static class NoChildrenForEphemeralsException extends KeeperException {
-        public NoChildrenForEphemeralsException() {
-            super(Code.NOCHILDRENFOREPHEMERALS);
-        }
-        public NoChildrenForEphemeralsException(String path) {
-            super(Code.NOCHILDRENFOREPHEMERALS, path);
-        }
-    }
-
-    /**
-     * @see Code#NODEEXISTS
-     */
-    @InterfaceAudience.Public
-    public static class NodeExistsException extends KeeperException {
-        public NodeExistsException() {
-            super(Code.NODEEXISTS);
-        }
-        public NodeExistsException(String path) {
-            super(Code.NODEEXISTS, path);
-        }
-    }
-
-    /**
-     * @see Code#NONODE
-     */
-    @InterfaceAudience.Public
-    public static class NoNodeException extends KeeperException {
-        public NoNodeException() {
-            super(Code.NONODE);
-        }
-        public NoNodeException(String path) {
-            super(Code.NONODE, path);
-        }
-    }
-
-    /**
-     * @see Code#NOTEMPTY
-     */
-    @InterfaceAudience.Public
-    public static class NotEmptyException extends KeeperException {
-        public NotEmptyException() {
-            super(Code.NOTEMPTY);
-        }
-        public NotEmptyException(String path) {
-            super(Code.NOTEMPTY, path);
-        }
-    }
-
-    /**
-     * @see Code#OPERATIONTIMEOUT
-     */
-    @InterfaceAudience.Public
-    public static class OperationTimeoutException extends KeeperException {
-        public OperationTimeoutException() {
-            super(Code.OPERATIONTIMEOUT);
-        }
-    }
-
-    /**
-     * @see Code#RUNTIMEINCONSISTENCY
-     */
-    @InterfaceAudience.Public
-    public static class RuntimeInconsistencyException extends KeeperException {
-        public RuntimeInconsistencyException() {
-            super(Code.RUNTIMEINCONSISTENCY);
-        }
-    }
-
-    /**
-     * @see Code#SESSIONEXPIRED
-     */
-    @InterfaceAudience.Public
-    public static class SessionExpiredException extends KeeperException {
-        public SessionExpiredException() {
-            super(Code.SESSIONEXPIRED);
-        }
-    }
-
-    /**
-     * @see Code#SESSIONMOVED
-     */
-    @InterfaceAudience.Public
-    public static class SessionMovedException extends KeeperException {
-        public SessionMovedException() {
-            super(Code.SESSIONMOVED);
-        }
-    }
-
-    /**
-     * @see Code#NOTREADONLY
-     */
-    @InterfaceAudience.Public
-    public static class NotReadOnlyException extends KeeperException {
-        public NotReadOnlyException() {
-            super(Code.NOTREADONLY);
-        }
-    }
-
-    /**
-     * @see Code#SYSTEMERROR
-     */
-    @InterfaceAudience.Public
-    public static class SystemErrorException extends KeeperException {
-        public SystemErrorException() {
-            super(Code.SYSTEMERROR);
-        }
-    }
-
-    /**
-     * @see Code#UNIMPLEMENTED
-     */
-    @InterfaceAudience.Public
-    public static class UnimplementedException extends KeeperException {
-        public UnimplementedException() {
-            super(Code.UNIMPLEMENTED);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java
deleted file mode 100644
index c4975be..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper;
-
-/** 
- * This class is responsible for refreshing Kerberos credentials for
- * logins for both Zookeeper client and server.
- * See ZooKeeperSaslServer for server-side usage.
- * See ZooKeeperSaslClient for client-side usage.
- */
-
-import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.callback.CallbackHandler;
-
-import org.apache.zookeeper.client.ZooKeeperSaslClient;
-import org.apache.zookeeper.common.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import javax.security.auth.kerberos.KerberosTicket;
-import javax.security.auth.Subject;
-import java.util.Date;
-import java.util.Random;
-import java.util.Set;
-
-public class Login {
-    private static final Logger LOG = LoggerFactory.getLogger(Login.class);
-    public CallbackHandler callbackHandler;
-
-    // LoginThread will sleep until 80% of time from last refresh to
-    // ticket's expiry has been reached, at which time it will wake
-    // and try to renew the ticket.
-    private static final float TICKET_RENEW_WINDOW = 0.80f;
-
-    /**
-     * Percentage of random jitter added to the renewal time
-     */
-    private static final float TICKET_RENEW_JITTER = 0.05f;
-
-    // Regardless of TICKET_RENEW_WINDOW setting above and the ticket expiry time,
-    // thread will not sleep between refresh attempts any less than 1 minute (60*1000 milliseconds = 1 minute).
-    // Change the '1' to e.g. 5, to change this to 5 minutes.
-    private static final long MIN_TIME_BEFORE_RELOGIN = 1 * 60 * 1000L;
-
-    private Subject subject = null;
-    private Thread t = null;
-    private boolean isKrbTicket = false;
-    private boolean isUsingTicketCache = false;
-    private boolean isUsingKeytab = false;
-
-    /** Random number generator */
-    private static Random rng = new Random();
-
-    private LoginContext login = null;
-    private String loginContextName = null;
-    private String keytabFile = null;
-    private String principal = null;
-
-    // Initialize 'lastLogin' to do a login at first time
-    private long lastLogin = Time.currentElapsedTime() - MIN_TIME_BEFORE_RELOGIN;
-
-    /**
-     * LoginThread constructor. The constructor starts the thread used
-     * to periodically re-login to the Kerberos Ticket Granting Server.
-     * @param loginContextName
-     *               name of section in JAAS file that will be use to login.
-     *               Passed as first param to javax.security.auth.login.LoginContext().
-     *
-     * @param callbackHandler
-     *               Passed as second param to javax.security.auth.login.LoginContext().
-     * @throws javax.security.auth.login.LoginException
-     *               Thrown if authentication fails.
-     */
-    public Login(final String loginContextName, CallbackHandler callbackHandler)
-            throws LoginException {
-        this.callbackHandler = callbackHandler;
-        login = login(loginContextName);
-        this.loginContextName = loginContextName;
-        subject = login.getSubject();
-        isKrbTicket = !subject.getPrivateCredentials(KerberosTicket.class).isEmpty();
-        AppConfigurationEntry entries[] = Configuration.getConfiguration().getAppConfigurationEntry(loginContextName);
-        for (AppConfigurationEntry entry: entries) {
-            // there will only be a single entry, so this for() loop will only be iterated through once.
-            if (entry.getOptions().get("useTicketCache") != null) {
-                String val = (String)entry.getOptions().get("useTicketCache");
-                if (val.equals("true")) {
-                    isUsingTicketCache = true;
-                }
-            }
-            if (entry.getOptions().get("keyTab") != null) {
-                keytabFile = (String)entry.getOptions().get("keyTab");
-                isUsingKeytab = true;
-            }
-            if (entry.getOptions().get("principal") != null) {
-                principal = (String)entry.getOptions().get("principal");
-            }
-            break;
-        }
-
-        if (!isKrbTicket) {
-            // if no TGT, do not bother with ticket management.
-            return;
-        }
-
-        // Refresh the Ticket Granting Ticket (TGT) periodically. How often to refresh is determined by the
-        // TGT's existing expiry date and the configured MIN_TIME_BEFORE_RELOGIN. For testing and development,
-        // you can decrease the interval of expiration of tickets (for example, to 3 minutes) by running :
-        //  "modprinc -maxlife 3mins <principal>" in kadmin.
-        t = new Thread(new Runnable() {
-            public void run() {
-                LOG.info("TGT refresh thread started.");
-                while (true) {  // renewal thread's main loop. if it exits from here, thread will exit.
-                    KerberosTicket tgt = getTGT();
-                    long now = Time.currentWallTime();
-                    long nextRefresh;
-                    Date nextRefreshDate;
-                    if (tgt == null) {
-                        nextRefresh = now + MIN_TIME_BEFORE_RELOGIN;
-                        nextRefreshDate = new Date(nextRefresh);
-                        LOG.warn("No TGT found: will try again at " + nextRefreshDate);
-                    } else {
-                        nextRefresh = getRefreshTime(tgt);
-                        long expiry = tgt.getEndTime().getTime();
-                        Date expiryDate = new Date(expiry);
-                        if ((isUsingTicketCache) && (tgt.getEndTime().equals(tgt.getRenewTill()))) {
-                            LOG.error("The TGT cannot be renewed beyond the next expiry date: " + expiryDate + "." +
-                                    "This process will not be able to authenticate new SASL connections after that " +
-                                    "time (for example, it will not be authenticate a new connection with a Zookeeper " +
-                                    "Quorum member).  Ask your system administrator to either increase the " +
-                                    "'renew until' time by doing : 'modprinc -maxrenewlife " + principal + "' within " +
-                                    "kadmin, or instead, to generate a keytab for " + principal + ". Because the TGT's " +
-                                    "expiry cannot be further extended by refreshing, exiting refresh thread now.");
-                            return;
-                        }
-                        // determine how long to sleep from looking at ticket's expiry.
-                        // We should not allow the ticket to expire, but we should take into consideration
-                        // MIN_TIME_BEFORE_RELOGIN. Will not sleep less than MIN_TIME_BEFORE_RELOGIN, unless doing so
-                        // would cause ticket expiration.
-                        if ((nextRefresh > expiry) ||
-                                ((now + MIN_TIME_BEFORE_RELOGIN) > expiry)) {
-                            // expiry is before next scheduled refresh).
-                            nextRefresh = now;
-                        } else {
-                            if (nextRefresh < (now + MIN_TIME_BEFORE_RELOGIN)) {
-                                // next scheduled refresh is sooner than (now + MIN_TIME_BEFORE_LOGIN).
-                                Date until = new Date(nextRefresh);
-                                Date newuntil = new Date(now + MIN_TIME_BEFORE_RELOGIN);
-                                LOG.warn("TGT refresh thread time adjusted from : " + until + " to : " + newuntil + " since "
-                                        + "the former is sooner than the minimum refresh interval ("
-                                        + MIN_TIME_BEFORE_RELOGIN / 1000 + " seconds) from now.");
-                            }
-                            nextRefresh = Math.max(nextRefresh, now + MIN_TIME_BEFORE_RELOGIN);
-                        }
-                        nextRefreshDate = new Date(nextRefresh);
-                        if (nextRefresh > expiry) {
-                            LOG.error("next refresh: " + nextRefreshDate + " is later than expiry " + expiryDate
-                                    + ". This may indicate a clock skew problem. Check that this host and the KDC's "
-                                    + "hosts' clocks are in sync. Exiting refresh thread.");
-                            return;
-                        }
-                    }
-                    if (now == nextRefresh) {
-                        LOG.info("refreshing now because expiry is before next scheduled refresh time.");
-                    } else if (now < nextRefresh) {
-                        Date until = new Date(nextRefresh);
-                        LOG.info("TGT refresh sleeping until: " + until.toString());
-                        try {
-                            Thread.sleep(nextRefresh - now);
-                        } catch (InterruptedException ie) {
-                            LOG.warn("TGT renewal thread has been interrupted and will exit.");
-                            break;
-                        }
-                    }
-                    else {
-                        LOG.error("nextRefresh:" + nextRefreshDate + " is in the past: exiting refresh thread. Check"
-                                + " clock sync between this host and KDC - (KDC's clock is likely ahead of this host)."
-                                + " Manual intervention will be required for this client to successfully authenticate."
-                                + " Exiting refresh thread.");
-                        break;
-                    }
-                    if (isUsingTicketCache) {
-                        String cmd = "/usr/bin/kinit";
-                        if (System.getProperty("zookeeper.kinit") != null) {
-                            cmd = System.getProperty("zookeeper.kinit");
-                        }
-                        String kinitArgs = "-R";
-                        int retry = 1;
-                        while (retry >= 0) {
-                            try {
-                                LOG.debug("running ticket cache refresh command: " + cmd + " " + kinitArgs);
-                                Shell.execCommand(cmd, kinitArgs);
-                                break;
-                            } catch (Exception e) {
-                                if (retry > 0) {
-                                    --retry;
-                                    // sleep for 10 seconds
-                                    try {
-                                        Thread.sleep(10 * 1000);
-                                    } catch (InterruptedException ie) {
-                                        LOG.error("Interrupted while renewing TGT, exiting Login thread");
-                                        return;
-                                    }
-                                } else {
-                                    LOG.warn("Could not renew TGT due to problem running shell command: '" + cmd
-                                            + " " + kinitArgs + "'" + "; exception was:" + e + ". Exiting refresh thread.",e);
-                                    return;
-                                }
-                            }
-                        }
-                    }
-                    try {
-                        int retry = 1;
-                        while (retry >= 0) {
-                            try {
-                                reLogin();
-                                break;
-                            } catch (LoginException le) {
-                                if (retry > 0) {
-                                    --retry;
-                                    // sleep for 10 seconds.
-                                    try {
-                                        Thread.sleep(10 * 1000);
-                                    } catch (InterruptedException e) {
-                                        LOG.error("Interrupted during login retry after LoginException:", le);
-                                        throw le;
-                                    }
-                                } else {
-                                    LOG.error("Could not refresh TGT for principal: " + principal + ".", le);
-                                }
-                            }
-                        }
-                    } catch (LoginException le) {
-                        LOG.error("Failed to refresh TGT: refresh thread exiting now.",le);
-                        break;
-                    }
-                }
-            }
-        });
-        t.setDaemon(true);
-    }
-
-    public void startThreadIfNeeded() {
-        // thread object 't' will be null if a refresh thread is not needed.
-        if (t != null) {
-            t.start();
-        }
-    }
-
-    public void shutdown() {
-        if ((t != null) && (t.isAlive())) {
-            t.interrupt();
-            try {
-                t.join();
-            } catch (InterruptedException e) {
-                LOG.warn("error while waiting for Login thread to shutdown: " + e);
-            }
-        }
-    }
-
-    public Subject getSubject() {
-        return subject;
-    }
-
-    public String getLoginContextName() {
-        return loginContextName;
-    }
-
-    private synchronized LoginContext login(final String loginContextName) throws LoginException {
-        if (loginContextName == null) {
-            throw new LoginException("loginContext name (JAAS file section header) was null. " +
-                    "Please check your java.security.login.auth.config (=" +
-                    System.getProperty("java.security.login.auth.config") +
-                    ") and your " + ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY + "(=" + 
-                    System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client") + ")");
-        }
-        LoginContext loginContext = new LoginContext(loginContextName,callbackHandler);
-        loginContext.login();
-        LOG.info("{} successfully logged in.", loginContextName);
-        return loginContext;
-    }
-
-    // c.f. org.apache.hadoop.security.UserGroupInformation.
-    private long getRefreshTime(KerberosTicket tgt) {
-        long start = tgt.getStartTime().getTime();
-        long expires = tgt.getEndTime().getTime();
-        LOG.info("TGT valid starting at:        " + tgt.getStartTime().toString());
-        LOG.info("TGT expires:                  " + tgt.getEndTime().toString());
-        long proposedRefresh = start + (long) ((expires - start) *
-                (TICKET_RENEW_WINDOW + (TICKET_RENEW_JITTER * rng.nextDouble())));
-        if (proposedRefresh > expires) {
-            // proposedRefresh is too far in the future: it's after ticket expires: simply return now.
-            return Time.currentWallTime();
-        }
-        else {
-            return proposedRefresh;
-        }
-    }
-
-    private synchronized KerberosTicket getTGT() {
-        Set<KerberosTicket> tickets = subject.getPrivateCredentials(KerberosTicket.class);
-        for(KerberosTicket ticket: tickets) {
-            KerberosPrincipal server = ticket.getServer();
-            if (server.getName().equals("krbtgt/" + server.getRealm() + "@" + server.getRealm())) {
-                LOG.debug("Client principal is \"" + ticket.getClient().getName() + "\".");
-                LOG.debug("Server principal is \"" + ticket.getServer().getName() + "\".");
-                return ticket;
-            }
-        }
-        return null;
-    }
-
-    private boolean hasSufficientTimeElapsed() {
-        long now = Time.currentElapsedTime();
-        if (now - getLastLogin() < MIN_TIME_BEFORE_RELOGIN ) {
-            LOG.warn("Not attempting to re-login since the last re-login was " +
-                    "attempted less than " + (MIN_TIME_BEFORE_RELOGIN/1000) + " seconds"+
-                    " before.");
-            return false;
-        }
-        // register most recent relogin attempt
-        setLastLogin(now);
-        return true;
-    }
-
-    /**
-     * Returns login object
-     * @return login
-     */
-    private LoginContext getLogin() {
-        return login;
-    }
-
-    /**
-     * Set the login object
-     * @param login
-     */
-    private void setLogin(LoginContext login) {
-        this.login = login;
-    }
-
-    /**
-     * Set the last login time.
-     * @param time the number of milliseconds since the beginning of time
-     */
-    private void setLastLogin(long time) {
-        lastLogin = time;
-    }
-
-    /**
-     * Get the time of the last login.
-     * @return the number of milliseconds since the beginning of time.
-     */
-    private long getLastLogin() {
-        return lastLogin;
-    }
-
-    /**
-     * Re-login a principal. This method assumes that {@link #login(String)} has happened already.
-     * @throws javax.security.auth.login.LoginException on a failure
-     */
-    // c.f. HADOOP-6559
-    private synchronized void reLogin()
-            throws LoginException {
-        if (!isKrbTicket) {
-            return;
-        }
-        LoginContext login = getLogin();
-        if (login  == null) {
-            throw new LoginException("login must be done first");
-        }
-        if (!hasSufficientTimeElapsed()) {
-            return;
-        }
-        LOG.info("Initiating logout for " + principal);
-        synchronized (Login.class) {
-            //clear up the kerberos state. But the tokens are not cleared! As per
-            //the Java kerberos login module code, only the kerberos credentials
-            //are cleared
-            login.logout();
-            //login and also update the subject field of this instance to
-            //have the new credentials (pass it to the LoginContext constructor)
-            login = new LoginContext(loginContextName, getSubject());
-            LOG.info("Initiating re-login for " + principal);
-            login.login();
-            setLogin(login);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java b/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java
deleted file mode 100644
index 70f7623..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.jute.InputArchive;
-import org.apache.jute.OutputArchive;
-import org.apache.jute.Record;
-import org.apache.zookeeper.proto.CreateResponse;
-import org.apache.zookeeper.proto.MultiHeader;
-import org.apache.zookeeper.proto.SetDataResponse;
-import org.apache.zookeeper.proto.ErrorResponse;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Handles the response from a multi request.  Such a response consists of
- * a sequence of responses each prefixed by a MultiResponse that indicates
- * the type of the response.  The end of the list is indicated by a MultiHeader
- * with a negative type.  Each individual response is in the same format as
- * with the corresponding operation in the original request list.
- */
-public class MultiResponse implements Record, Iterable<OpResult> {
-    private List<OpResult> results = new ArrayList<OpResult>();
-
-    public void add(OpResult x) {
-        results.add(x);
-    }
-
-    @Override
-    public Iterator<OpResult> iterator() {
-        return results.iterator();
-    }
-
-    public int size() {
-        return results.size();
-    }
-
-    @Override
-    public void serialize(OutputArchive archive, String tag) throws IOException {
-        archive.startRecord(this, tag);
-
-        int index = 0;
-        for (OpResult result : results) {
-            int err = result.getType() == ZooDefs.OpCode.error ? ((OpResult.ErrorResult)result).getErr() : 0;
-
-            new MultiHeader(result.getType(), false, err).serialize(archive, tag);
-
-            switch (result.getType()) {
-                case ZooDefs.OpCode.create:
-                    new CreateResponse(((OpResult.CreateResult) result).getPath()).serialize(archive, tag);
-                    break;
-                case ZooDefs.OpCode.delete:
-                case ZooDefs.OpCode.check:
-                    break;
-                case ZooDefs.OpCode.setData:
-                    new SetDataResponse(((OpResult.SetDataResult) result).getStat()).serialize(archive, tag);
-                    break;
-                case ZooDefs.OpCode.error:
-                    new ErrorResponse(((OpResult.ErrorResult) result).getErr()).serialize(archive, tag);
-                    break;
-                default:
-                    throw new IOException("Invalid type " + result.getType() + " in MultiResponse");
-            }
-        }
-        new MultiHeader(-1, true, -1).serialize(archive, tag);
-        archive.endRecord(this, tag);
-    }
-
-    @Override
-    public void deserialize(InputArchive archive, String tag) throws IOException {
-        results = new ArrayList<OpResult>();
-
-        archive.startRecord(tag);
-        MultiHeader h = new MultiHeader();
-        h.deserialize(archive, tag);
-        while (!h.getDone()) {
-            switch (h.getType()) {
-                case ZooDefs.OpCode.create:
-                    CreateResponse cr = new CreateResponse();
-                    cr.deserialize(archive, tag);
-                    results.add(new OpResult.CreateResult(cr.getPath()));
-                    break;
-
-                case ZooDefs.OpCode.delete:
-                    results.add(new OpResult.DeleteResult());
-                    break;
-
-                case ZooDefs.OpCode.setData:
-                    SetDataResponse sdr = new SetDataResponse();
-                    sdr.deserialize(archive, tag);
-                    results.add(new OpResult.SetDataResult(sdr.getStat()));
-                    break;
-
-                case ZooDefs.OpCode.check:
-                    results.add(new OpResult.CheckResult());
-                    break;
-
-                case ZooDefs.OpCode.error:
-                    //FIXME: need way to more cleanly serialize/deserialize exceptions
-                    ErrorResponse er = new ErrorResponse();
-                    er.deserialize(archive, tag);
-                    results.add(new OpResult.ErrorResult(er.getErr()));
-                    break;
-
-                default:
-                    throw new IOException("Invalid type " + h.getType() + " in MultiResponse");
-            }
-            h.deserialize(archive, tag);
-        }
-        archive.endRecord(tag);
-    }
-
-    public List<OpResult> getResultList() {
-        return results;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof MultiResponse)) return false;
-
-        MultiResponse other = (MultiResponse) o;
-
-        if (results != null) {
-            Iterator<OpResult> i = other.results.iterator();
-            for (OpResult result : results) {
-                if (i.hasNext()) {
-                    if (!result.equals(i.next())) {
-                        return false;
-                    }
-                } else {
-                    return false;
-                }
-            }
-            return !i.hasNext();
-        }
-        else return other.results == null;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = results.size();
-        for (OpResult result : results) {
-            hash = (hash * 35) + result.hashCode();
-        }
-        return hash;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java b/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java
deleted file mode 100644
index 801969a..0000000
--- a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.zookeeper;
-
-import org.apache.jute.InputArchive;
-import org.apache.jute.OutputArchive;
-import org.apache.jute.Record;
-import org.apache.zookeeper.proto.*;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Encodes a composite transaction.  In the wire format, each transaction
- * consists of a single MultiHeader followed by the appropriate request.
- * Each of these MultiHeaders has a type which indicates
- * the type of the following transaction or a negative number if no more transactions
- * are included.
- */
-public class MultiTransactionRecord implements Record, Iterable<Op> {
-    private List<Op> ops = new ArrayList<Op>();
-
-    public MultiTransactionRecord() {
-    }
-
-    public MultiTransactionRecord(Iterable<Op> ops) {
-        for (Op op : ops) {
-            add(op);
-        }
-    }
-
-    @Override
-    public Iterator<Op> iterator() {
-        return ops.iterator() ;
-    }
-
-    public void add(Op op) {
-        ops.add(op);
-    }
-
-    public int size() {
-        return ops.size();
-    }
-
-    @Override
-    public void serialize(OutputArchive archive, String tag) throws IOException {
-        archive.startRecord(this, tag);
-        int index = 0 ;
-        for (Op op : ops) {
-            MultiHeader h = new MultiHeader(op.getType(), false, -1);
-            h.serialize(archive, tag);
-            switch (op.getType()) {
-               case ZooDefs.OpCode.create:
-                    op.toRequestRecord().serialize(archive, tag);
-                    break;
-                case ZooDefs.OpCode.delete:
-                    op.toRequestRecord().serialize(archive, tag);
-                    break;
-                case ZooDefs.OpCode.setData:
-                    op.toRequestRecord().serialize(archive, tag);
-                    break;
-                case ZooDefs.OpCode.check:
-                    op.toRequestRecord().serialize(archive, tag);
-                    break;
-                default:
-                    throw new IOException("Invalid type of op");
-            }
-        }
-        new MultiHeader(-1, true, -1).serialize(archive, tag);
-        archive.endRecord(this, tag);
-    }
-
-    @Override
-    public void deserialize(InputArchive archive, String tag) throws IOException {
-        archive.startRecord(tag);
-        MultiHeader h = new MultiHeader();
-        h.deserialize(archive, tag);
-
-        while (!h.getDone()) {
-            switch (h.getType()) {
-               case ZooDefs.OpCode.create:
-                    CreateRequest cr = new CreateRequest();
-                    cr.deserialize(archive, tag);
-                    add(Op.create(cr.getPath(), cr.getData(), cr.getAcl(), cr.getFlags()));
-                    break;
-                case ZooDefs.OpCode.delete:
-                    DeleteRequest dr = new DeleteRequest();
-                    dr.deserialize(archive, tag);
-                    add(Op.delete(dr.getPath(), dr.getVersion()));
-                    break;
-                case ZooDefs.OpCode.setData:
-                    SetDataRequest sdr = new SetDataRequest();
-                    sdr.deserialize(archive, tag);
-                    add(Op.setData(sdr.getPath(), sdr.getData(), sdr.getVersion()));
-                    break;
-                case ZooDefs.OpCode.check:
-                    CheckVersionRequest cvr = new CheckVersionRequest();
-                    cvr.deserialize(archive, tag);
-                    add(Op.check(cvr.getPath(), cvr.getVersion()));
-                    break;
-                default:
-                    throw new IOException("Invalid type of op");
-            }
-            h.deserialize(archive, tag);
-        }
-        archive.endRecord(tag);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof MultiTransactionRecord)) return false;
-
-        MultiTransactionRecord that = (MultiTransactionRecord) o;
-
-        if (ops != null) {
-            Iterator<Op> other = that.ops.iterator();
-            for (Op op : ops) {
-                boolean hasMoreData = other.hasNext();
-                if (!hasMoreData) {
-                    return false;
-                }
-                Op otherOp = other.next();
-                if (!op.equals(otherOp)) {
-                    return false;
-                }
-            }
-            return !other.hasNext();
-        } else {
-            return that.ops == null;
-        }
-
-    }
-
-    @Override
-    public int hashCode() {
-        int h = 1023;
-        for (Op op : ops) {
-            h = h * 25 + op.hashCode();
-        }
-        return h;
-    }
-}


[17/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/CreateMode.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/CreateMode.java b/zookeeper-server/src/main/java/org/apache/zookeeper/CreateMode.java
new file mode 100644
index 0000000..84f5be0
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/CreateMode.java
@@ -0,0 +1,94 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.KeeperException;
+
+/***
+ *  CreateMode value determines how the znode is created on ZooKeeper.
+ */
+@InterfaceAudience.Public
+public enum CreateMode {
+    
+    /**
+     * The znode will not be automatically deleted upon client's disconnect.
+     */
+    PERSISTENT (0, false, false),
+    /**
+    * The znode will not be automatically deleted upon client's disconnect,
+    * and its name will be appended with a monotonically increasing number.
+    */
+    PERSISTENT_SEQUENTIAL (2, false, true),
+    /**
+     * The znode will be deleted upon the client's disconnect.
+     */
+    EPHEMERAL (1, true, false),
+    /**
+     * The znode will be deleted upon the client's disconnect, and its name
+     * will be appended with a monotonically increasing number.
+     */
+    EPHEMERAL_SEQUENTIAL (3, true, true);
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreateMode.class);
+
+    private boolean ephemeral;
+    private boolean sequential;
+    private int flag;
+
+    CreateMode(int flag, boolean ephemeral, boolean sequential) {
+        this.flag = flag;
+        this.ephemeral = ephemeral;
+        this.sequential = sequential;
+    }
+
+    public boolean isEphemeral() { 
+        return ephemeral;
+    }
+
+    public boolean isSequential() { 
+        return sequential;
+    }
+
+    public int toFlag() {
+        return flag;
+    }
+
+    /**
+     * Map an integer value to a CreateMode value
+     */
+    static public CreateMode fromFlag(int flag) throws KeeperException {
+        switch(flag) {
+        case 0: return CreateMode.PERSISTENT;
+
+        case 1: return CreateMode.EPHEMERAL;
+
+        case 2: return CreateMode.PERSISTENT_SEQUENTIAL;
+
+        case 3: return CreateMode.EPHEMERAL_SEQUENTIAL ;
+
+        default:
+            String errMsg = "Received an invalid flag value: " + flag
+                    + " to convert to a CreateMode";
+            LOG.error(errMsg);
+            throw new KeeperException.BadArgumentsException(errMsg);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Environment.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Environment.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Environment.java
new file mode 100644
index 0000000..51797a1
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Environment.java
@@ -0,0 +1,103 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provide insight into the runtime environment.
+ *
+ */
+public class Environment {
+    public static final String JAAS_CONF_KEY = "java.security.auth.login.config";
+
+    public static class Entry {
+        private String k;
+        private String v;
+        public Entry(String k, String v) {
+            this.k = k;
+            this.v = v;
+        }
+        public String getKey() { return k; }
+        public String getValue() { return v; }
+        
+        @Override
+        public String toString() {
+            return k + "=" + v;
+        }
+    }
+
+    private static void put(ArrayList<Entry> l, String k, String v) {
+        l.add(new Entry(k,v));
+    }
+
+    public static List<Entry> list() {
+        ArrayList<Entry> l = new ArrayList<Entry>();
+        put(l, "zookeeper.version", Version.getFullVersion());
+
+        try {
+            put(l, "host.name",
+                InetAddress.getLocalHost().getCanonicalHostName());
+        } catch (UnknownHostException e) {
+            put(l, "host.name", "<NA>");
+        }
+
+        put(l, "java.version",
+                System.getProperty("java.version", "<NA>"));
+        put(l, "java.vendor",
+                System.getProperty("java.vendor", "<NA>"));
+        put(l, "java.home",
+                System.getProperty("java.home", "<NA>"));
+        put(l, "java.class.path",
+                System.getProperty("java.class.path", "<NA>"));
+        put(l, "java.library.path",
+                System.getProperty("java.library.path", "<NA>"));
+        put(l, "java.io.tmpdir",
+                System.getProperty("java.io.tmpdir", "<NA>"));
+        put(l, "java.compiler",
+                System.getProperty("java.compiler", "<NA>"));
+        put(l, "os.name",
+                System.getProperty("os.name", "<NA>"));
+        put(l, "os.arch",
+                System.getProperty("os.arch", "<NA>"));
+        put(l, "os.version",
+                System.getProperty("os.version", "<NA>"));
+        put(l, "user.name",
+                System.getProperty("user.name", "<NA>"));
+        put(l, "user.home",
+                System.getProperty("user.home", "<NA>"));
+        put(l, "user.dir",
+                System.getProperty("user.dir", "<NA>"));
+        
+        return l;
+    }
+    
+    public static void logEnv(String msg, Logger log) {
+        List<Entry> env = Environment.list();
+        for (Entry e : env) {
+            log.info(msg + e.toString());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/KeeperException.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/KeeperException.java b/zookeeper-server/src/main/java/org/apache/zookeeper/KeeperException.java
new file mode 100644
index 0000000..bdf4203
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/KeeperException.java
@@ -0,0 +1,728 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.yetus.audience.InterfaceAudience;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@SuppressWarnings("serial")
+@InterfaceAudience.Public
+public abstract class KeeperException extends Exception {
+    /**
+     * All multi-requests that result in an exception retain the results
+     * here so that it is possible to examine the problems in the catch
+     * scope.  Non-multi requests will get a null if they try to access
+     * these results.
+     */
+    private List<OpResult> results;
+
+    /**
+     * All non-specific keeper exceptions should be constructed via
+     * this factory method in order to guarantee consistency in error
+     * codes and such.  If you know the error code, then you should
+     * construct the special purpose exception directly.  That will
+     * allow you to have the most specific possible declarations of
+     * what exceptions might actually be thrown.
+     *
+     * @param code The error code.
+     * @param path The ZooKeeper path being operated on.
+     * @return The specialized exception, presumably to be thrown by
+     *  the caller.
+     */
+    public static KeeperException create(Code code, String path) {
+        KeeperException r = create(code);
+        r.path = path;
+        return r;
+    }
+
+    /**
+     * @deprecated deprecated in 3.1.0, use {@link #create(Code, String)}
+     * instead
+     */
+    @Deprecated
+    public static KeeperException create(int code, String path) {
+        KeeperException r = create(Code.get(code));
+        r.path = path;
+        return r;
+    }
+
+    /**
+     * @deprecated deprecated in 3.1.0, use {@link #create(Code)}
+     * instead
+     */
+    @Deprecated
+    public static KeeperException create(int code) {
+        return create(Code.get(code));
+    }
+
+    /**
+     * All non-specific keeper exceptions should be constructed via
+     * this factory method in order to guarantee consistency in error
+     * codes and such.  If you know the error code, then you should
+     * construct the special purpose exception directly.  That will
+     * allow you to have the most specific possible declarations of
+     * what exceptions might actually be thrown.
+     *
+     * @param code The error code of your new exception.  This will
+     * also determine the specific type of the exception that is
+     * returned.
+     * @return The specialized exception, presumably to be thrown by
+     * the caller.
+     */
+    public static KeeperException create(Code code) {
+        switch (code) {
+            case SYSTEMERROR:
+                return new SystemErrorException();
+            case RUNTIMEINCONSISTENCY:
+                return new RuntimeInconsistencyException();
+            case DATAINCONSISTENCY:
+                return new DataInconsistencyException();
+            case CONNECTIONLOSS:
+                return new ConnectionLossException();
+            case MARSHALLINGERROR:
+                return new MarshallingErrorException();
+            case UNIMPLEMENTED:
+                return new UnimplementedException();
+            case OPERATIONTIMEOUT:
+                return new OperationTimeoutException();
+            case BADARGUMENTS:
+                return new BadArgumentsException();
+            case APIERROR:
+                return new APIErrorException();
+            case NONODE:
+                return new NoNodeException();
+            case NOAUTH:
+                return new NoAuthException();
+            case BADVERSION:
+                return new BadVersionException();
+            case NOCHILDRENFOREPHEMERALS:
+                return new NoChildrenForEphemeralsException();
+            case NODEEXISTS:
+                return new NodeExistsException();
+            case INVALIDACL:
+                return new InvalidACLException();
+            case AUTHFAILED:
+                return new AuthFailedException();
+            case NOTEMPTY:
+                return new NotEmptyException();
+            case SESSIONEXPIRED:
+                return new SessionExpiredException();
+            case INVALIDCALLBACK:
+                return new InvalidCallbackException();
+            case SESSIONMOVED:
+                return new SessionMovedException();
+            case NOTREADONLY:
+                return new NotReadOnlyException();
+
+            case OK:
+            default:
+                throw new IllegalArgumentException("Invalid exception code");
+        }
+    }
+
+    /**
+     * Set the code for this exception
+     * @param code error code
+     * @deprecated deprecated in 3.1.0, exceptions should be immutable, this
+     * method should not be used
+     */
+    @Deprecated
+    public void setCode(int code) {
+        this.code = Code.get(code);
+    }
+
+    /** This interface contains the original static final int constants
+     * which have now been replaced with an enumeration in Code. Do not
+     * reference this class directly, if necessary (legacy code) continue
+     * to access the constants through Code.
+     * Note: an interface is used here due to the fact that enums cannot
+     * reference constants defined within the same enum as said constants
+     * are considered initialized _after_ the enum itself. By using an
+     * interface as a super type this allows the deprecated constants to
+     * be initialized first and referenced when constructing the enums. I
+     * didn't want to have constants declared twice. This
+     * interface should be private, but it's declared public to enable
+     * javadoc to include in the user API spec.
+     */
+    @Deprecated
+    @InterfaceAudience.Public
+    public interface CodeDeprecated {
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#OK} instead
+         */
+        @Deprecated
+        public static final int Ok = 0;
+
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead
+         */
+        @Deprecated
+        public static final int SystemError = -1;
+        /**
+         * @deprecated deprecated in 3.1.0, use
+         * {@link Code#RUNTIMEINCONSISTENCY} instead
+         */
+        @Deprecated
+        public static final int RuntimeInconsistency = -2;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY}
+         * instead
+         */
+        @Deprecated
+        public static final int DataInconsistency = -3;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS}
+         * instead
+         */
+        @Deprecated
+        public static final int ConnectionLoss = -4;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR}
+         * instead
+         */
+        @Deprecated
+        public static final int MarshallingError = -5;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED}
+         * instead
+         */
+        @Deprecated
+        public static final int Unimplemented = -6;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT}
+         * instead
+         */
+        @Deprecated
+        public static final int OperationTimeout = -7;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#BADARGUMENTS}
+         * instead
+         */
+        @Deprecated
+        public static final int BadArguments = -8;
+
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#APIERROR} instead
+         */
+        @Deprecated
+        public static final int APIError = -100;
+
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#NONODE} instead
+         */
+        @Deprecated
+        public static final int NoNode = -101;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#NOAUTH} instead
+         */
+        @Deprecated
+        public static final int NoAuth = -102;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#BADVERSION} instead
+         */
+        @Deprecated
+        public static final int BadVersion = -103;
+        /**
+         * @deprecated deprecated in 3.1.0, use
+         * {@link Code#NOCHILDRENFOREPHEMERALS}
+         * instead
+         */
+        @Deprecated
+        public static final int NoChildrenForEphemerals = -108;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead
+         */
+        @Deprecated
+        public static final int NodeExists = -110;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead
+         */
+        @Deprecated
+        public static final int NotEmpty = -111;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead
+         */
+        @Deprecated
+        public static final int SessionExpired = -112;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK}
+         * instead
+         */
+        @Deprecated
+        public static final int InvalidCallback = -113;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDACL} instead
+         */
+        @Deprecated
+        public static final int InvalidACL = -114;
+        /**
+         * @deprecated deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead
+         */
+        @Deprecated
+        public static final int AuthFailed = -115;
+        /**
+         * This value will be used directly in {@link CODE#SESSIONMOVED}
+         */
+        // public static final int SessionMoved = -118;
+    }
+
+    /** Codes which represent the various KeeperException
+     * types. This enum replaces the deprecated earlier static final int
+     * constants. The old, deprecated, values are in "camel case" while the new
+     * enum values are in all CAPS.
+     */
+    @InterfaceAudience.Public
+    public static enum Code implements CodeDeprecated {
+        /** Everything is OK */
+        OK (Ok),
+
+        /** System and server-side errors.
+         * This is never thrown by the server, it shouldn't be used other than
+         * to indicate a range. Specifically error codes greater than this
+         * value, but lesser than {@link #APIERROR}, are system errors.
+         */
+        SYSTEMERROR (SystemError),
+
+        /** A runtime inconsistency was found */
+        RUNTIMEINCONSISTENCY (RuntimeInconsistency),
+        /** A data inconsistency was found */
+        DATAINCONSISTENCY (DataInconsistency),
+        /** Connection to the server has been lost */
+        CONNECTIONLOSS (ConnectionLoss),
+        /** Error while marshalling or unmarshalling data */
+        MARSHALLINGERROR (MarshallingError),
+        /** Operation is unimplemented */
+        UNIMPLEMENTED (Unimplemented),
+        /** Operation timeout */
+        OPERATIONTIMEOUT (OperationTimeout),
+        /** Invalid arguments */
+        BADARGUMENTS (BadArguments),
+        
+        /** API errors.
+         * This is never thrown by the server, it shouldn't be used other than
+         * to indicate a range. Specifically error codes greater than this
+         * value are API errors (while values less than this indicate a
+         * {@link #SYSTEMERROR}).
+         */
+        APIERROR (APIError),
+
+        /** Node does not exist */
+        NONODE (NoNode),
+        /** Not authenticated */
+        NOAUTH (NoAuth),
+        /** Version conflict */
+        BADVERSION (BadVersion),
+        /** Ephemeral nodes may not have children */
+        NOCHILDRENFOREPHEMERALS (NoChildrenForEphemerals),
+        /** The node already exists */
+        NODEEXISTS (NodeExists),
+        /** The node has children */
+        NOTEMPTY (NotEmpty),
+        /** The session has been expired by the server */
+        SESSIONEXPIRED (SessionExpired),
+        /** Invalid callback specified */
+        INVALIDCALLBACK (InvalidCallback),
+        /** Invalid ACL specified */
+        INVALIDACL (InvalidACL),
+        /** Client authentication failed */
+        AUTHFAILED (AuthFailed),
+        /** Session moved to another server, so operation is ignored */
+        SESSIONMOVED (-118),
+        /** State-changing request is passed to read-only server */
+        NOTREADONLY (-119);
+
+        private static final Map<Integer,Code> lookup
+            = new HashMap<Integer,Code>();
+
+        static {
+            for(Code c : EnumSet.allOf(Code.class))
+                lookup.put(c.code, c);
+        }
+
+        private final int code;
+        Code(int code) {
+            this.code = code;
+        }
+
+        /**
+         * Get the int value for a particular Code.
+         * @return error code as integer
+         */
+        public int intValue() { return code; }
+
+        /**
+         * Get the Code value for a particular integer error code
+         * @param code int error code
+         * @return Code value corresponding to specified int code, or null
+         */
+        public static Code get(int code) {
+            return lookup.get(code);
+        }
+    }
+
+    static String getCodeMessage(Code code) {
+        switch (code) {
+            case OK:
+                return "ok";
+            case SYSTEMERROR:
+                return "SystemError";
+            case RUNTIMEINCONSISTENCY:
+                return "RuntimeInconsistency";
+            case DATAINCONSISTENCY:
+                return "DataInconsistency";
+            case CONNECTIONLOSS:
+                return "ConnectionLoss";
+            case MARSHALLINGERROR:
+                return "MarshallingError";
+            case UNIMPLEMENTED:
+                return "Unimplemented";
+            case OPERATIONTIMEOUT:
+                return "OperationTimeout";
+            case BADARGUMENTS:
+                return "BadArguments";
+            case APIERROR:
+                return "APIError";
+            case NONODE:
+                return "NoNode";
+            case NOAUTH:
+                return "NoAuth";
+            case BADVERSION:
+                return "BadVersion";
+            case NOCHILDRENFOREPHEMERALS:
+                return "NoChildrenForEphemerals";
+            case NODEEXISTS:
+                return "NodeExists";
+            case INVALIDACL:
+                return "InvalidACL";
+            case AUTHFAILED:
+                return "AuthFailed";
+            case NOTEMPTY:
+                return "Directory not empty";
+            case SESSIONEXPIRED:
+                return "Session expired";
+            case INVALIDCALLBACK:
+                return "Invalid callback";
+            case SESSIONMOVED:
+                return "Session moved";
+            case NOTREADONLY:
+                return "Not a read-only call";
+            default:
+                return "Unknown error " + code;
+        }
+    }
+
+    private Code code;
+
+    private String path;
+
+    public KeeperException(Code code) {
+        this.code = code;
+    }
+
+    KeeperException(Code code, String path) {
+        this.code = code;
+        this.path = path;
+    }
+
+    /**
+     * Read the error code for this exception
+     * @return the error code for this exception
+     * @deprecated deprecated in 3.1.0, use {@link #code()} instead
+     */
+    @Deprecated
+    public int getCode() {
+        return code.code;
+    }
+
+    /**
+     * Read the error Code for this exception
+     * @return the error Code for this exception
+     */
+    public Code code() {
+        return code;
+    }
+
+    /**
+     * Read the path for this exception
+     * @return the path associated with this error, null if none
+     */
+    public String getPath() {
+        return path;
+    }
+
+    @Override
+    public String getMessage() {
+        if (path == null) {
+            return "KeeperErrorCode = " + getCodeMessage(code);
+        }
+        return "KeeperErrorCode = " + getCodeMessage(code) + " for " + path;
+    }
+
+    void setMultiResults(List<OpResult> results) {
+        this.results = results;
+    }
+
+    /**
+     * If this exception was thrown by a multi-request then the (partial) results
+     * and error codes can be retrieved using this getter.
+     * @return A copy of the list of results from the operations in the multi-request.
+     *
+     * @since 3.4.0
+     *
+     */
+    public List<OpResult> getResults() {
+        return results != null ? new ArrayList<OpResult>(results) : null;
+    }
+
+    /**
+     *  @see Code#APIERROR
+     */
+    @InterfaceAudience.Public
+    public static class APIErrorException extends KeeperException {
+        public APIErrorException() {
+            super(Code.APIERROR);
+        }
+    }
+
+    /**
+     *  @see Code#AUTHFAILED
+     */
+    @InterfaceAudience.Public
+    public static class AuthFailedException extends KeeperException {
+        public AuthFailedException() {
+            super(Code.AUTHFAILED);
+        }
+    }
+
+    /**
+     *  @see Code#BADARGUMENTS
+     */
+    @InterfaceAudience.Public
+    public static class BadArgumentsException extends KeeperException {
+        public BadArgumentsException() {
+            super(Code.BADARGUMENTS);
+        }
+        public BadArgumentsException(String path) {
+            super(Code.BADARGUMENTS, path);
+        }
+    }
+
+    /**
+     * @see Code#BADVERSION
+     */
+    @InterfaceAudience.Public
+    public static class BadVersionException extends KeeperException {
+        public BadVersionException() {
+            super(Code.BADVERSION);
+        }
+        public BadVersionException(String path) {
+            super(Code.BADVERSION, path);
+        }
+    }
+
+    /**
+     * @see Code#CONNECTIONLOSS
+     */
+    @InterfaceAudience.Public
+    public static class ConnectionLossException extends KeeperException {
+        public ConnectionLossException() {
+            super(Code.CONNECTIONLOSS);
+        }
+    }
+
+    /**
+     * @see Code#DATAINCONSISTENCY
+     */
+    @InterfaceAudience.Public
+    public static class DataInconsistencyException extends KeeperException {
+        public DataInconsistencyException() {
+            super(Code.DATAINCONSISTENCY);
+        }
+    }
+
+    /**
+     * @see Code#INVALIDACL
+     */
+    @InterfaceAudience.Public
+    public static class InvalidACLException extends KeeperException {
+        public InvalidACLException() {
+            super(Code.INVALIDACL);
+        }
+        public InvalidACLException(String path) {
+            super(Code.INVALIDACL, path);
+        }
+    }
+
+    /**
+     * @see Code#INVALIDCALLBACK
+     */
+    @InterfaceAudience.Public
+    public static class InvalidCallbackException extends KeeperException {
+        public InvalidCallbackException() {
+            super(Code.INVALIDCALLBACK);
+        }
+    }
+
+    /**
+     * @see Code#MARSHALLINGERROR
+     */
+    @InterfaceAudience.Public
+    public static class MarshallingErrorException extends KeeperException {
+        public MarshallingErrorException() {
+            super(Code.MARSHALLINGERROR);
+        }
+    }
+
+    /**
+     * @see Code#NOAUTH
+     */
+    @InterfaceAudience.Public
+    public static class NoAuthException extends KeeperException {
+        public NoAuthException() {
+            super(Code.NOAUTH);
+        }
+    }
+
+    /**
+     * @see Code#NOCHILDRENFOREPHEMERALS
+     */
+    @InterfaceAudience.Public
+    public static class NoChildrenForEphemeralsException extends KeeperException {
+        public NoChildrenForEphemeralsException() {
+            super(Code.NOCHILDRENFOREPHEMERALS);
+        }
+        public NoChildrenForEphemeralsException(String path) {
+            super(Code.NOCHILDRENFOREPHEMERALS, path);
+        }
+    }
+
+    /**
+     * @see Code#NODEEXISTS
+     */
+    @InterfaceAudience.Public
+    public static class NodeExistsException extends KeeperException {
+        public NodeExistsException() {
+            super(Code.NODEEXISTS);
+        }
+        public NodeExistsException(String path) {
+            super(Code.NODEEXISTS, path);
+        }
+    }
+
+    /**
+     * @see Code#NONODE
+     */
+    @InterfaceAudience.Public
+    public static class NoNodeException extends KeeperException {
+        public NoNodeException() {
+            super(Code.NONODE);
+        }
+        public NoNodeException(String path) {
+            super(Code.NONODE, path);
+        }
+    }
+
+    /**
+     * @see Code#NOTEMPTY
+     */
+    @InterfaceAudience.Public
+    public static class NotEmptyException extends KeeperException {
+        public NotEmptyException() {
+            super(Code.NOTEMPTY);
+        }
+        public NotEmptyException(String path) {
+            super(Code.NOTEMPTY, path);
+        }
+    }
+
+    /**
+     * @see Code#OPERATIONTIMEOUT
+     */
+    @InterfaceAudience.Public
+    public static class OperationTimeoutException extends KeeperException {
+        public OperationTimeoutException() {
+            super(Code.OPERATIONTIMEOUT);
+        }
+    }
+
+    /**
+     * @see Code#RUNTIMEINCONSISTENCY
+     */
+    @InterfaceAudience.Public
+    public static class RuntimeInconsistencyException extends KeeperException {
+        public RuntimeInconsistencyException() {
+            super(Code.RUNTIMEINCONSISTENCY);
+        }
+    }
+
+    /**
+     * @see Code#SESSIONEXPIRED
+     */
+    @InterfaceAudience.Public
+    public static class SessionExpiredException extends KeeperException {
+        public SessionExpiredException() {
+            super(Code.SESSIONEXPIRED);
+        }
+    }
+
+    /**
+     * @see Code#SESSIONMOVED
+     */
+    @InterfaceAudience.Public
+    public static class SessionMovedException extends KeeperException {
+        public SessionMovedException() {
+            super(Code.SESSIONMOVED);
+        }
+    }
+
+    /**
+     * @see Code#NOTREADONLY
+     */
+    @InterfaceAudience.Public
+    public static class NotReadOnlyException extends KeeperException {
+        public NotReadOnlyException() {
+            super(Code.NOTREADONLY);
+        }
+    }
+
+    /**
+     * @see Code#SYSTEMERROR
+     */
+    @InterfaceAudience.Public
+    public static class SystemErrorException extends KeeperException {
+        public SystemErrorException() {
+            super(Code.SYSTEMERROR);
+        }
+    }
+
+    /**
+     * @see Code#UNIMPLEMENTED
+     */
+    @InterfaceAudience.Public
+    public static class UnimplementedException extends KeeperException {
+        public UnimplementedException() {
+            super(Code.UNIMPLEMENTED);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java
new file mode 100644
index 0000000..c4975be
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java
@@ -0,0 +1,407 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+/** 
+ * This class is responsible for refreshing Kerberos credentials for
+ * logins for both Zookeeper client and server.
+ * See ZooKeeperSaslServer for server-side usage.
+ * See ZooKeeperSaslClient for client-side usage.
+ */
+
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.zookeeper.client.ZooKeeperSaslClient;
+import org.apache.zookeeper.common.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.Subject;
+import java.util.Date;
+import java.util.Random;
+import java.util.Set;
+
+public class Login {
+    private static final Logger LOG = LoggerFactory.getLogger(Login.class);
+    public CallbackHandler callbackHandler;
+
+    // LoginThread will sleep until 80% of time from last refresh to
+    // ticket's expiry has been reached, at which time it will wake
+    // and try to renew the ticket.
+    private static final float TICKET_RENEW_WINDOW = 0.80f;
+
+    /**
+     * Percentage of random jitter added to the renewal time
+     */
+    private static final float TICKET_RENEW_JITTER = 0.05f;
+
+    // Regardless of TICKET_RENEW_WINDOW setting above and the ticket expiry time,
+    // thread will not sleep between refresh attempts any less than 1 minute (60*1000 milliseconds = 1 minute).
+    // Change the '1' to e.g. 5, to change this to 5 minutes.
+    private static final long MIN_TIME_BEFORE_RELOGIN = 1 * 60 * 1000L;
+
+    private Subject subject = null;
+    private Thread t = null;
+    private boolean isKrbTicket = false;
+    private boolean isUsingTicketCache = false;
+    private boolean isUsingKeytab = false;
+
+    /** Random number generator */
+    private static Random rng = new Random();
+
+    private LoginContext login = null;
+    private String loginContextName = null;
+    private String keytabFile = null;
+    private String principal = null;
+
+    // Initialize 'lastLogin' to do a login at first time
+    private long lastLogin = Time.currentElapsedTime() - MIN_TIME_BEFORE_RELOGIN;
+
+    /**
+     * LoginThread constructor. The constructor starts the thread used
+     * to periodically re-login to the Kerberos Ticket Granting Server.
+     * @param loginContextName
+     *               name of section in JAAS file that will be use to login.
+     *               Passed as first param to javax.security.auth.login.LoginContext().
+     *
+     * @param callbackHandler
+     *               Passed as second param to javax.security.auth.login.LoginContext().
+     * @throws javax.security.auth.login.LoginException
+     *               Thrown if authentication fails.
+     */
+    public Login(final String loginContextName, CallbackHandler callbackHandler)
+            throws LoginException {
+        this.callbackHandler = callbackHandler;
+        login = login(loginContextName);
+        this.loginContextName = loginContextName;
+        subject = login.getSubject();
+        isKrbTicket = !subject.getPrivateCredentials(KerberosTicket.class).isEmpty();
+        AppConfigurationEntry entries[] = Configuration.getConfiguration().getAppConfigurationEntry(loginContextName);
+        for (AppConfigurationEntry entry: entries) {
+            // there will only be a single entry, so this for() loop will only be iterated through once.
+            if (entry.getOptions().get("useTicketCache") != null) {
+                String val = (String)entry.getOptions().get("useTicketCache");
+                if (val.equals("true")) {
+                    isUsingTicketCache = true;
+                }
+            }
+            if (entry.getOptions().get("keyTab") != null) {
+                keytabFile = (String)entry.getOptions().get("keyTab");
+                isUsingKeytab = true;
+            }
+            if (entry.getOptions().get("principal") != null) {
+                principal = (String)entry.getOptions().get("principal");
+            }
+            break;
+        }
+
+        if (!isKrbTicket) {
+            // if no TGT, do not bother with ticket management.
+            return;
+        }
+
+        // Refresh the Ticket Granting Ticket (TGT) periodically. How often to refresh is determined by the
+        // TGT's existing expiry date and the configured MIN_TIME_BEFORE_RELOGIN. For testing and development,
+        // you can decrease the interval of expiration of tickets (for example, to 3 minutes) by running :
+        //  "modprinc -maxlife 3mins <principal>" in kadmin.
+        t = new Thread(new Runnable() {
+            public void run() {
+                LOG.info("TGT refresh thread started.");
+                while (true) {  // renewal thread's main loop. if it exits from here, thread will exit.
+                    KerberosTicket tgt = getTGT();
+                    long now = Time.currentWallTime();
+                    long nextRefresh;
+                    Date nextRefreshDate;
+                    if (tgt == null) {
+                        nextRefresh = now + MIN_TIME_BEFORE_RELOGIN;
+                        nextRefreshDate = new Date(nextRefresh);
+                        LOG.warn("No TGT found: will try again at " + nextRefreshDate);
+                    } else {
+                        nextRefresh = getRefreshTime(tgt);
+                        long expiry = tgt.getEndTime().getTime();
+                        Date expiryDate = new Date(expiry);
+                        if ((isUsingTicketCache) && (tgt.getEndTime().equals(tgt.getRenewTill()))) {
+                            LOG.error("The TGT cannot be renewed beyond the next expiry date: " + expiryDate + "." +
+                                    "This process will not be able to authenticate new SASL connections after that " +
+                                    "time (for example, it will not be authenticate a new connection with a Zookeeper " +
+                                    "Quorum member).  Ask your system administrator to either increase the " +
+                                    "'renew until' time by doing : 'modprinc -maxrenewlife " + principal + "' within " +
+                                    "kadmin, or instead, to generate a keytab for " + principal + ". Because the TGT's " +
+                                    "expiry cannot be further extended by refreshing, exiting refresh thread now.");
+                            return;
+                        }
+                        // determine how long to sleep from looking at ticket's expiry.
+                        // We should not allow the ticket to expire, but we should take into consideration
+                        // MIN_TIME_BEFORE_RELOGIN. Will not sleep less than MIN_TIME_BEFORE_RELOGIN, unless doing so
+                        // would cause ticket expiration.
+                        if ((nextRefresh > expiry) ||
+                                ((now + MIN_TIME_BEFORE_RELOGIN) > expiry)) {
+                            // expiry is before next scheduled refresh).
+                            nextRefresh = now;
+                        } else {
+                            if (nextRefresh < (now + MIN_TIME_BEFORE_RELOGIN)) {
+                                // next scheduled refresh is sooner than (now + MIN_TIME_BEFORE_LOGIN).
+                                Date until = new Date(nextRefresh);
+                                Date newuntil = new Date(now + MIN_TIME_BEFORE_RELOGIN);
+                                LOG.warn("TGT refresh thread time adjusted from : " + until + " to : " + newuntil + " since "
+                                        + "the former is sooner than the minimum refresh interval ("
+                                        + MIN_TIME_BEFORE_RELOGIN / 1000 + " seconds) from now.");
+                            }
+                            nextRefresh = Math.max(nextRefresh, now + MIN_TIME_BEFORE_RELOGIN);
+                        }
+                        nextRefreshDate = new Date(nextRefresh);
+                        if (nextRefresh > expiry) {
+                            LOG.error("next refresh: " + nextRefreshDate + " is later than expiry " + expiryDate
+                                    + ". This may indicate a clock skew problem. Check that this host and the KDC's "
+                                    + "hosts' clocks are in sync. Exiting refresh thread.");
+                            return;
+                        }
+                    }
+                    if (now == nextRefresh) {
+                        LOG.info("refreshing now because expiry is before next scheduled refresh time.");
+                    } else if (now < nextRefresh) {
+                        Date until = new Date(nextRefresh);
+                        LOG.info("TGT refresh sleeping until: " + until.toString());
+                        try {
+                            Thread.sleep(nextRefresh - now);
+                        } catch (InterruptedException ie) {
+                            LOG.warn("TGT renewal thread has been interrupted and will exit.");
+                            break;
+                        }
+                    }
+                    else {
+                        LOG.error("nextRefresh:" + nextRefreshDate + " is in the past: exiting refresh thread. Check"
+                                + " clock sync between this host and KDC - (KDC's clock is likely ahead of this host)."
+                                + " Manual intervention will be required for this client to successfully authenticate."
+                                + " Exiting refresh thread.");
+                        break;
+                    }
+                    if (isUsingTicketCache) {
+                        String cmd = "/usr/bin/kinit";
+                        if (System.getProperty("zookeeper.kinit") != null) {
+                            cmd = System.getProperty("zookeeper.kinit");
+                        }
+                        String kinitArgs = "-R";
+                        int retry = 1;
+                        while (retry >= 0) {
+                            try {
+                                LOG.debug("running ticket cache refresh command: " + cmd + " " + kinitArgs);
+                                Shell.execCommand(cmd, kinitArgs);
+                                break;
+                            } catch (Exception e) {
+                                if (retry > 0) {
+                                    --retry;
+                                    // sleep for 10 seconds
+                                    try {
+                                        Thread.sleep(10 * 1000);
+                                    } catch (InterruptedException ie) {
+                                        LOG.error("Interrupted while renewing TGT, exiting Login thread");
+                                        return;
+                                    }
+                                } else {
+                                    LOG.warn("Could not renew TGT due to problem running shell command: '" + cmd
+                                            + " " + kinitArgs + "'" + "; exception was:" + e + ". Exiting refresh thread.",e);
+                                    return;
+                                }
+                            }
+                        }
+                    }
+                    try {
+                        int retry = 1;
+                        while (retry >= 0) {
+                            try {
+                                reLogin();
+                                break;
+                            } catch (LoginException le) {
+                                if (retry > 0) {
+                                    --retry;
+                                    // sleep for 10 seconds.
+                                    try {
+                                        Thread.sleep(10 * 1000);
+                                    } catch (InterruptedException e) {
+                                        LOG.error("Interrupted during login retry after LoginException:", le);
+                                        throw le;
+                                    }
+                                } else {
+                                    LOG.error("Could not refresh TGT for principal: " + principal + ".", le);
+                                }
+                            }
+                        }
+                    } catch (LoginException le) {
+                        LOG.error("Failed to refresh TGT: refresh thread exiting now.",le);
+                        break;
+                    }
+                }
+            }
+        });
+        t.setDaemon(true);
+    }
+
+    public void startThreadIfNeeded() {
+        // thread object 't' will be null if a refresh thread is not needed.
+        if (t != null) {
+            t.start();
+        }
+    }
+
+    public void shutdown() {
+        if ((t != null) && (t.isAlive())) {
+            t.interrupt();
+            try {
+                t.join();
+            } catch (InterruptedException e) {
+                LOG.warn("error while waiting for Login thread to shutdown: " + e);
+            }
+        }
+    }
+
+    public Subject getSubject() {
+        return subject;
+    }
+
+    public String getLoginContextName() {
+        return loginContextName;
+    }
+
+    private synchronized LoginContext login(final String loginContextName) throws LoginException {
+        if (loginContextName == null) {
+            throw new LoginException("loginContext name (JAAS file section header) was null. " +
+                    "Please check your java.security.login.auth.config (=" +
+                    System.getProperty("java.security.login.auth.config") +
+                    ") and your " + ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY + "(=" + 
+                    System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client") + ")");
+        }
+        LoginContext loginContext = new LoginContext(loginContextName,callbackHandler);
+        loginContext.login();
+        LOG.info("{} successfully logged in.", loginContextName);
+        return loginContext;
+    }
+
+    // c.f. org.apache.hadoop.security.UserGroupInformation.
+    private long getRefreshTime(KerberosTicket tgt) {
+        long start = tgt.getStartTime().getTime();
+        long expires = tgt.getEndTime().getTime();
+        LOG.info("TGT valid starting at:        " + tgt.getStartTime().toString());
+        LOG.info("TGT expires:                  " + tgt.getEndTime().toString());
+        long proposedRefresh = start + (long) ((expires - start) *
+                (TICKET_RENEW_WINDOW + (TICKET_RENEW_JITTER * rng.nextDouble())));
+        if (proposedRefresh > expires) {
+            // proposedRefresh is too far in the future: it's after ticket expires: simply return now.
+            return Time.currentWallTime();
+        }
+        else {
+            return proposedRefresh;
+        }
+    }
+
+    private synchronized KerberosTicket getTGT() {
+        Set<KerberosTicket> tickets = subject.getPrivateCredentials(KerberosTicket.class);
+        for(KerberosTicket ticket: tickets) {
+            KerberosPrincipal server = ticket.getServer();
+            if (server.getName().equals("krbtgt/" + server.getRealm() + "@" + server.getRealm())) {
+                LOG.debug("Client principal is \"" + ticket.getClient().getName() + "\".");
+                LOG.debug("Server principal is \"" + ticket.getServer().getName() + "\".");
+                return ticket;
+            }
+        }
+        return null;
+    }
+
+    private boolean hasSufficientTimeElapsed() {
+        long now = Time.currentElapsedTime();
+        if (now - getLastLogin() < MIN_TIME_BEFORE_RELOGIN ) {
+            LOG.warn("Not attempting to re-login since the last re-login was " +
+                    "attempted less than " + (MIN_TIME_BEFORE_RELOGIN/1000) + " seconds"+
+                    " before.");
+            return false;
+        }
+        // register most recent relogin attempt
+        setLastLogin(now);
+        return true;
+    }
+
+    /**
+     * Returns login object
+     * @return login
+     */
+    private LoginContext getLogin() {
+        return login;
+    }
+
+    /**
+     * Set the login object
+     * @param login
+     */
+    private void setLogin(LoginContext login) {
+        this.login = login;
+    }
+
+    /**
+     * Set the last login time.
+     * @param time the number of milliseconds since the beginning of time
+     */
+    private void setLastLogin(long time) {
+        lastLogin = time;
+    }
+
+    /**
+     * Get the time of the last login.
+     * @return the number of milliseconds since the beginning of time.
+     */
+    private long getLastLogin() {
+        return lastLogin;
+    }
+
+    /**
+     * Re-login a principal. This method assumes that {@link #login(String)} has happened already.
+     * @throws javax.security.auth.login.LoginException on a failure
+     */
+    // c.f. HADOOP-6559
+    private synchronized void reLogin()
+            throws LoginException {
+        if (!isKrbTicket) {
+            return;
+        }
+        LoginContext login = getLogin();
+        if (login  == null) {
+            throw new LoginException("login must be done first");
+        }
+        if (!hasSufficientTimeElapsed()) {
+            return;
+        }
+        LOG.info("Initiating logout for " + principal);
+        synchronized (Login.class) {
+            //clear up the kerberos state. But the tokens are not cleared! As per
+            //the Java kerberos login module code, only the kerberos credentials
+            //are cleared
+            login.logout();
+            //login and also update the subject field of this instance to
+            //have the new credentials (pass it to the LoginContext constructor)
+            login = new LoginContext(loginContextName, getSubject());
+            LOG.info("Initiating re-login for " + principal);
+            login.login();
+            setLogin(login);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/MultiResponse.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/MultiResponse.java b/zookeeper-server/src/main/java/org/apache/zookeeper/MultiResponse.java
new file mode 100644
index 0000000..70f7623
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/MultiResponse.java
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.jute.InputArchive;
+import org.apache.jute.OutputArchive;
+import org.apache.jute.Record;
+import org.apache.zookeeper.proto.CreateResponse;
+import org.apache.zookeeper.proto.MultiHeader;
+import org.apache.zookeeper.proto.SetDataResponse;
+import org.apache.zookeeper.proto.ErrorResponse;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Handles the response from a multi request.  Such a response consists of
+ * a sequence of responses each prefixed by a MultiResponse that indicates
+ * the type of the response.  The end of the list is indicated by a MultiHeader
+ * with a negative type.  Each individual response is in the same format as
+ * with the corresponding operation in the original request list.
+ */
+public class MultiResponse implements Record, Iterable<OpResult> {
+    private List<OpResult> results = new ArrayList<OpResult>();
+
+    public void add(OpResult x) {
+        results.add(x);
+    }
+
+    @Override
+    public Iterator<OpResult> iterator() {
+        return results.iterator();
+    }
+
+    public int size() {
+        return results.size();
+    }
+
+    @Override
+    public void serialize(OutputArchive archive, String tag) throws IOException {
+        archive.startRecord(this, tag);
+
+        int index = 0;
+        for (OpResult result : results) {
+            int err = result.getType() == ZooDefs.OpCode.error ? ((OpResult.ErrorResult)result).getErr() : 0;
+
+            new MultiHeader(result.getType(), false, err).serialize(archive, tag);
+
+            switch (result.getType()) {
+                case ZooDefs.OpCode.create:
+                    new CreateResponse(((OpResult.CreateResult) result).getPath()).serialize(archive, tag);
+                    break;
+                case ZooDefs.OpCode.delete:
+                case ZooDefs.OpCode.check:
+                    break;
+                case ZooDefs.OpCode.setData:
+                    new SetDataResponse(((OpResult.SetDataResult) result).getStat()).serialize(archive, tag);
+                    break;
+                case ZooDefs.OpCode.error:
+                    new ErrorResponse(((OpResult.ErrorResult) result).getErr()).serialize(archive, tag);
+                    break;
+                default:
+                    throw new IOException("Invalid type " + result.getType() + " in MultiResponse");
+            }
+        }
+        new MultiHeader(-1, true, -1).serialize(archive, tag);
+        archive.endRecord(this, tag);
+    }
+
+    @Override
+    public void deserialize(InputArchive archive, String tag) throws IOException {
+        results = new ArrayList<OpResult>();
+
+        archive.startRecord(tag);
+        MultiHeader h = new MultiHeader();
+        h.deserialize(archive, tag);
+        while (!h.getDone()) {
+            switch (h.getType()) {
+                case ZooDefs.OpCode.create:
+                    CreateResponse cr = new CreateResponse();
+                    cr.deserialize(archive, tag);
+                    results.add(new OpResult.CreateResult(cr.getPath()));
+                    break;
+
+                case ZooDefs.OpCode.delete:
+                    results.add(new OpResult.DeleteResult());
+                    break;
+
+                case ZooDefs.OpCode.setData:
+                    SetDataResponse sdr = new SetDataResponse();
+                    sdr.deserialize(archive, tag);
+                    results.add(new OpResult.SetDataResult(sdr.getStat()));
+                    break;
+
+                case ZooDefs.OpCode.check:
+                    results.add(new OpResult.CheckResult());
+                    break;
+
+                case ZooDefs.OpCode.error:
+                    //FIXME: need way to more cleanly serialize/deserialize exceptions
+                    ErrorResponse er = new ErrorResponse();
+                    er.deserialize(archive, tag);
+                    results.add(new OpResult.ErrorResult(er.getErr()));
+                    break;
+
+                default:
+                    throw new IOException("Invalid type " + h.getType() + " in MultiResponse");
+            }
+            h.deserialize(archive, tag);
+        }
+        archive.endRecord(tag);
+    }
+
+    public List<OpResult> getResultList() {
+        return results;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof MultiResponse)) return false;
+
+        MultiResponse other = (MultiResponse) o;
+
+        if (results != null) {
+            Iterator<OpResult> i = other.results.iterator();
+            for (OpResult result : results) {
+                if (i.hasNext()) {
+                    if (!result.equals(i.next())) {
+                        return false;
+                    }
+                } else {
+                    return false;
+                }
+            }
+            return !i.hasNext();
+        }
+        else return other.results == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = results.size();
+        for (OpResult result : results) {
+            hash = (hash * 35) + result.hashCode();
+        }
+        return hash;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java b/zookeeper-server/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java
new file mode 100644
index 0000000..801969a
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.jute.InputArchive;
+import org.apache.jute.OutputArchive;
+import org.apache.jute.Record;
+import org.apache.zookeeper.proto.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Encodes a composite transaction.  In the wire format, each transaction
+ * consists of a single MultiHeader followed by the appropriate request.
+ * Each of these MultiHeaders has a type which indicates
+ * the type of the following transaction or a negative number if no more transactions
+ * are included.
+ */
+public class MultiTransactionRecord implements Record, Iterable<Op> {
+    private List<Op> ops = new ArrayList<Op>();
+
+    public MultiTransactionRecord() {
+    }
+
+    public MultiTransactionRecord(Iterable<Op> ops) {
+        for (Op op : ops) {
+            add(op);
+        }
+    }
+
+    @Override
+    public Iterator<Op> iterator() {
+        return ops.iterator() ;
+    }
+
+    public void add(Op op) {
+        ops.add(op);
+    }
+
+    public int size() {
+        return ops.size();
+    }
+
+    @Override
+    public void serialize(OutputArchive archive, String tag) throws IOException {
+        archive.startRecord(this, tag);
+        int index = 0 ;
+        for (Op op : ops) {
+            MultiHeader h = new MultiHeader(op.getType(), false, -1);
+            h.serialize(archive, tag);
+            switch (op.getType()) {
+               case ZooDefs.OpCode.create:
+                    op.toRequestRecord().serialize(archive, tag);
+                    break;
+                case ZooDefs.OpCode.delete:
+                    op.toRequestRecord().serialize(archive, tag);
+                    break;
+                case ZooDefs.OpCode.setData:
+                    op.toRequestRecord().serialize(archive, tag);
+                    break;
+                case ZooDefs.OpCode.check:
+                    op.toRequestRecord().serialize(archive, tag);
+                    break;
+                default:
+                    throw new IOException("Invalid type of op");
+            }
+        }
+        new MultiHeader(-1, true, -1).serialize(archive, tag);
+        archive.endRecord(this, tag);
+    }
+
+    @Override
+    public void deserialize(InputArchive archive, String tag) throws IOException {
+        archive.startRecord(tag);
+        MultiHeader h = new MultiHeader();
+        h.deserialize(archive, tag);
+
+        while (!h.getDone()) {
+            switch (h.getType()) {
+               case ZooDefs.OpCode.create:
+                    CreateRequest cr = new CreateRequest();
+                    cr.deserialize(archive, tag);
+                    add(Op.create(cr.getPath(), cr.getData(), cr.getAcl(), cr.getFlags()));
+                    break;
+                case ZooDefs.OpCode.delete:
+                    DeleteRequest dr = new DeleteRequest();
+                    dr.deserialize(archive, tag);
+                    add(Op.delete(dr.getPath(), dr.getVersion()));
+                    break;
+                case ZooDefs.OpCode.setData:
+                    SetDataRequest sdr = new SetDataRequest();
+                    sdr.deserialize(archive, tag);
+                    add(Op.setData(sdr.getPath(), sdr.getData(), sdr.getVersion()));
+                    break;
+                case ZooDefs.OpCode.check:
+                    CheckVersionRequest cvr = new CheckVersionRequest();
+                    cvr.deserialize(archive, tag);
+                    add(Op.check(cvr.getPath(), cvr.getVersion()));
+                    break;
+                default:
+                    throw new IOException("Invalid type of op");
+            }
+            h.deserialize(archive, tag);
+        }
+        archive.endRecord(tag);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof MultiTransactionRecord)) return false;
+
+        MultiTransactionRecord that = (MultiTransactionRecord) o;
+
+        if (ops != null) {
+            Iterator<Op> other = that.ops.iterator();
+            for (Op op : ops) {
+                boolean hasMoreData = other.hasNext();
+                if (!hasMoreData) {
+                    return false;
+                }
+                Op otherOp = other.next();
+                if (!op.equals(otherOp)) {
+                    return false;
+                }
+            }
+            return !other.hasNext();
+        } else {
+            return that.ops == null;
+        }
+
+    }
+
+    @Override
+    public int hashCode() {
+        int h = 1023;
+        for (Op op : ops) {
+            h = h * 25 + op.hashCode();
+        }
+        return h;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Op.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Op.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Op.java
new file mode 100644
index 0000000..1bc2061
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Op.java
@@ -0,0 +1,351 @@
+/*
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.jute.Record;
+import org.apache.zookeeper.common.PathUtils;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.proto.CheckVersionRequest;
+import org.apache.zookeeper.proto.CreateRequest;
+import org.apache.zookeeper.proto.DeleteRequest;
+import org.apache.zookeeper.proto.SetDataRequest;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Represents a single operation in a multi-operation transaction.  Each operation can be a create, update
+ * or delete or can just be a version check.
+ *
+ * Sub-classes of Op each represent each detailed type but should not normally be referenced except via
+ * the provided factory methods.
+ *
+ * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode)
+ * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode, org.apache.zookeeper.AsyncCallback.StringCallback, Object)
+ * @see ZooKeeper#delete(String, int)
+ * @see ZooKeeper#setData(String, byte[], int)
+ */
+public abstract class Op {
+    private int type;
+    private String path;
+
+    // prevent untyped construction
+    private Op(int type, String path) {
+        this.type = type;
+        this.path = path;
+    }
+
+    /**
+     * Constructs a create operation.  Arguments are as for the ZooKeeper method of the same name.
+     * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode)
+     * @see CreateMode#fromFlag(int)
+     *
+     * @param path
+     *                the path for the node
+     * @param data
+     *                the initial data for the node
+     * @param acl
+     *                the acl for the node
+     * @param flags
+     *                specifying whether the node to be created is ephemeral
+     *                and/or sequential but using the integer encoding.
+     */
+    public static Op create(String path, byte[] data, List<ACL> acl, int flags) {
+        return new Create(path, data, acl, flags);
+    }
+
+    /**
+     * Constructs a create operation.  Arguments are as for the ZooKeeper method of the same name.
+     * @see ZooKeeper#create(String, byte[], java.util.List, CreateMode)
+     *
+     * @param path
+     *                the path for the node
+     * @param data
+     *                the initial data for the node
+     * @param acl
+     *                the acl for the node
+     * @param createMode
+     *                specifying whether the node to be created is ephemeral
+     *                and/or sequential
+     */
+    public static Op create(String path, byte[] data, List<ACL> acl, CreateMode createMode) {
+        return new Create(path, data, acl, createMode);
+    }
+
+    /**
+     * Constructs a delete operation.  Arguments are as for the ZooKeeper method of the same name.
+     * @see ZooKeeper#delete(String, int)
+     *
+     * @param path
+     *                the path of the node to be deleted.
+     * @param version
+     *                the expected node version.
+     */
+    public static Op delete(String path, int version) {
+        return new Delete(path, version);
+    }
+
+    /**
+     * Constructs an update operation.  Arguments are as for the ZooKeeper method of the same name.
+     * @see ZooKeeper#setData(String, byte[], int)
+     *
+     * @param path
+     *                the path of the node
+     * @param data
+     *                the data to set
+     * @param version
+     *                the expected matching version
+     */
+    public static Op setData(String path, byte[] data, int version) {
+        return new SetData(path, data, version);
+    }
+
+
+    /**
+     * Constructs an version check operation.  Arguments are as for the ZooKeeper.setData method except that
+     * no data is provided since no update is intended.  The purpose for this is to allow read-modify-write
+     * operations that apply to multiple znodes, but where some of the znodes are involved only in the read,
+     * not the write.  A similar effect could be achieved by writing the same data back, but that leads to
+     * way more version updates than are necessary and more writing in general.
+     *
+     * @param path
+     *                the path of the node
+     * @param version
+     *                the expected matching version
+     */
+    public static Op check(String path, int version) {
+        return new Check(path, version);
+    }
+
+    /**
+     * Gets the integer type code for an Op.  This code should be as from ZooDefs.OpCode
+     * @see ZooDefs.OpCode
+     * @return  The type code.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the path for an Op.
+     * @return  The path.
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * Encodes an op for wire transmission.
+     * @return An appropriate Record structure.
+     */
+    public abstract Record toRequestRecord() ;
+
+    /**
+     * Reconstructs the transaction with the chroot prefix.
+     * 
+     * @return transaction with chroot.
+     */
+    abstract Op withChroot(String addRootPrefix);
+
+    /**
+     * Performs client path validations.
+     * 
+     * @throws IllegalArgumentException
+     *             if an invalid path is specified
+     * @throws KeeperException.BadArgumentsException
+     *             if an invalid create mode flag is specified
+     */
+    void validate() throws KeeperException {
+        PathUtils.validatePath(path);
+    }
+
+    //////////////////
+    // these internal classes are public, but should not generally be referenced.
+    //
+    public static class Create extends Op {
+        private byte[] data;
+        private List<ACL> acl;
+        private int flags;
+
+        private Create(String path, byte[] data, List<ACL> acl, int flags) {
+            super(ZooDefs.OpCode.create, path);
+            this.data = data;
+            this.acl = acl;
+            this.flags = flags;
+        }
+
+        private Create(String path, byte[] data, List<ACL> acl, CreateMode createMode) {
+            super(ZooDefs.OpCode.create, path);
+            this.data = data;
+            this.acl = acl;
+            this.flags = createMode.toFlag();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof Create)) return false;
+
+            Create op = (Create) o;
+
+            boolean aclEquals = true;
+            Iterator<ACL> i = op.acl.iterator();
+            for (ACL acl : op.acl) {
+                boolean hasMoreData = i.hasNext();
+                if (!hasMoreData) {
+                    aclEquals = false;
+                    break;
+                }
+                ACL otherAcl = i.next();
+                if (!acl.equals(otherAcl)) {
+                    aclEquals = false;
+                    break;
+                }
+            }
+            return !i.hasNext() && getType() == op.getType() && Arrays.equals(data, op.data) && flags == op.flags && aclEquals;
+        }
+
+        @Override
+        public int hashCode() {
+            return getType() + getPath().hashCode() + Arrays.hashCode(data);
+        }
+
+        @Override
+        public Record toRequestRecord() {
+            return new CreateRequest(getPath(), data, acl, flags);
+        }
+
+        @Override
+        Op withChroot(String path) {
+            return new Create(path, data, acl, flags);
+        }
+
+        @Override
+        void validate() throws KeeperException {
+            CreateMode createMode = CreateMode.fromFlag(flags);
+            PathUtils.validatePath(getPath(), createMode.isSequential());
+        }
+    }
+
+    public static class Delete extends Op {
+        private int version;
+
+        private Delete(String path, int version) {
+            super(ZooDefs.OpCode.delete, path);
+            this.version = version;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof Delete)) return false;
+
+            Delete op = (Delete) o;
+
+            return getType() == op.getType() && version == op.version 
+                   && getPath().equals(op.getPath());
+        }
+
+        @Override
+        public int hashCode() {
+            return getType() + getPath().hashCode() + version;
+        }
+
+        @Override
+        public Record toRequestRecord() {
+            return new DeleteRequest(getPath(), version);
+        }
+
+        @Override
+        Op withChroot(String path) {
+            return new Delete(path, version);
+        }
+    }
+
+    public static class SetData extends Op {
+        private byte[] data;
+        private int version;
+
+        private SetData(String path, byte[] data, int version) {
+            super(ZooDefs.OpCode.setData, path);
+            this.data = data;
+            this.version = version;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof SetData)) return false;
+
+            SetData op = (SetData) o;
+
+            return getType() == op.getType() && version == op.version 
+                   && getPath().equals(op.getPath()) && Arrays.equals(data, op.data);
+        }
+
+        @Override
+        public int hashCode() {
+            return getType() + getPath().hashCode() + Arrays.hashCode(data) + version;
+        }
+
+        @Override
+        public Record toRequestRecord() {
+            return new SetDataRequest(getPath(), data, version);
+        }
+
+        @Override
+        Op withChroot(String path) {
+            return new SetData(path, data, version);
+        }
+    }
+
+    public static class Check extends Op {
+        private int version;
+
+        private Check(String path, int version) {
+            super(ZooDefs.OpCode.check, path);
+            this.version = version;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof Check)) return false;
+
+            Check op = (Check) o;
+
+            return getType() == op.getType() && getPath().equals(op.getPath()) && version == op.version;
+        }
+
+        @Override
+        public int hashCode() {
+            return getType() + getPath().hashCode() + version;
+        }
+
+        @Override
+        public Record toRequestRecord() {
+            return new CheckVersionRequest(getPath(), version);
+        }
+
+        @Override
+        Op withChroot(String path) {
+            return new Check(path, version);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/OpResult.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/OpResult.java b/zookeeper-server/src/main/java/org/apache/zookeeper/OpResult.java
new file mode 100644
index 0000000..45331d1
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/OpResult.java
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+
+import org.apache.zookeeper.data.Stat;
+
+/**
+ * Encodes the result of a single part of a multiple operation commit.
+ */
+public abstract class OpResult {
+    private int type;
+
+    private OpResult(int type) {
+        this.type = type;
+    }
+
+    /**
+     * Encodes the return type as from ZooDefs.OpCode.  Can be used
+     * to dispatch to the correct cast needed for getting the desired
+     * additional result data.
+     * @see ZooDefs.OpCode
+     * @return an integer identifying what kind of operation this result came from.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * A result from a create operation.  This kind of result allows the
+     * path to be retrieved since the create might have been a sequential
+     * create.
+     */
+    public static class CreateResult extends OpResult {
+        private String path;
+
+        public CreateResult(String path) {
+            super(ZooDefs.OpCode.create);
+            this.path = path;
+        }
+
+        public String getPath() {
+            return path;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof CreateResult)) return false;
+
+            CreateResult other = (CreateResult) o;
+            return getType() == other.getType() && path.equals(other.getPath());
+        }
+
+        @Override
+        public int hashCode() {
+            return getType() * 35 + path.hashCode();
+        }
+    }
+
+    /**
+     * A result from a delete operation.  No special values are available.
+     */
+    public static class DeleteResult extends OpResult {
+        public DeleteResult() {
+            super(ZooDefs.OpCode.delete);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof DeleteResult)) return false;
+
+            DeleteResult opResult = (DeleteResult) o;
+            return getType() == opResult.getType();
+        }
+
+        @Override
+        public int hashCode() {
+            return getType();
+        }
+    }
+
+    /**
+     * A result from a setData operation.  This kind of result provides access
+     * to the Stat structure from the update.
+     */
+    public static class SetDataResult extends OpResult {
+        private Stat stat;
+
+        public SetDataResult(Stat stat) {
+            super(ZooDefs.OpCode.setData);
+            this.stat = stat;
+        }
+
+        public Stat getStat() {
+            return stat;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof SetDataResult)) return false;
+
+            SetDataResult other = (SetDataResult) o;
+            return getType() == other.getType() && stat.getMzxid() == other.stat.getMzxid();
+        }
+
+        @Override
+        public int hashCode() {
+            return (int) (getType() * 35 + stat.getMzxid());
+        }
+    }
+
+    /**
+     * A result from a version check operation.  No special values are available.
+     */
+    public static class CheckResult extends OpResult {
+        public CheckResult() {
+            super(ZooDefs.OpCode.check);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof CheckResult)) return false;
+
+            CheckResult other = (CheckResult) o;
+            return getType() == other.getType();
+        }
+
+        @Override
+        public int hashCode() {
+            return getType();
+        }
+    }
+
+    /**
+     * An error result from any kind of operation.  The point of error results
+     * is that they contain an error code which helps understand what happened.
+     * @see KeeperException.Code
+     *
+     */
+    public static class ErrorResult extends OpResult {
+        private int err;
+
+        public ErrorResult(int err) {
+            super(ZooDefs.OpCode.error);
+            this.err = err;
+        }
+
+        public int getErr() {
+            return err;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof ErrorResult)) return false;
+
+            ErrorResult other = (ErrorResult) o;
+            return getType() == other.getType() && err == other.getErr();
+        }
+
+        @Override
+        public int hashCode() {
+            return getType() * 35 + err;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Quotas.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Quotas.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Quotas.java
new file mode 100644
index 0000000..b82e339
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Quotas.java
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+/**
+ * this class manages quotas
+ * and has many other utils
+ * for quota
+ */
+public class Quotas {
+
+    /** the zookeeper nodes that acts as the management and status node **/
+    public static final String procZookeeper = "/zookeeper";
+
+    /** the zookeeper quota node that acts as the quota
+     * management node for zookeeper */
+    public static final String quotaZookeeper = "/zookeeper/quota";
+
+    /**
+     * the limit node that has the limit of
+     * a subtree
+     */
+    public static final String limitNode = "zookeeper_limits";
+
+    /**
+     * the stat node that monitors the limit of
+     * a subtree.
+     */
+    public static final String statNode = "zookeeper_stats";
+
+    /**
+     * return the quota path associated with this
+     * prefix
+     * @param path the actual path in zookeeper.
+     * @return the limit quota path
+     */
+    public static String quotaPath(String path) {
+        return quotaZookeeper + path +
+        "/" + limitNode;
+    }
+
+    /**
+     * return the stat quota path associated with this
+     * prefix.
+     * @param path the actual path in zookeeper
+     * @return the stat quota path
+     */
+    public static String statPath(String path) {
+        return quotaZookeeper + path + "/" +
+        statNode;
+    }
+}


[09/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientBase.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientBase.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientBase.java
new file mode 100644
index 0000000..7de4f3c
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientBase.java
@@ -0,0 +1,757 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.zookeeper.common.Time;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.common.IOUtils;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.ServerCnxnFactoryAccessor;
+import org.apache.zookeeper.server.ZKDatabase;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.persistence.FilePadding;
+import org.apache.zookeeper.server.persistence.FileTxnLog;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.util.OSMXBean;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class ClientBase extends ZKTestCase {
+    protected static final Logger LOG = LoggerFactory.getLogger(ClientBase.class);
+
+    public static int CONNECTION_TIMEOUT = 30000;
+    static final File BASETEST =
+        new File(System.getProperty("build.test.dir", "build"));
+
+    protected int port = PortAssignment.unique();
+    protected String hostPort = "127.0.0.1:" + port;
+    protected String ipv6HostPort = "[0:0:0:0:0:0:0:1]:" + port;
+    protected int maxCnxns = 0;
+    protected ServerCnxnFactory serverFactory = null;
+    protected File tmpDir = null;
+    
+    long initialFdCount;
+    
+    public ClientBase() {
+        super();
+    }
+
+    /**
+     * In general don't use this. Only use in the special case that you
+     * want to ignore results (for whatever reason) in your test. Don't
+     * use empty watchers in real code!
+     *
+     */
+    protected class NullWatcher implements Watcher {
+        public void process(WatchedEvent event) { /* nada */ }
+    }
+
+    public static class CountdownWatcher implements Watcher {
+        // XXX this doesn't need to be volatile! (Should probably be final)
+        volatile CountDownLatch clientConnected;
+        // Set to true when connected to a read-only server, or a read-write (quorum) server.
+        volatile boolean connected;
+        // Set to true when connected to a quorum server.
+        volatile boolean syncConnected;
+        // Set to true when connected to a quorum server in read-only mode
+        volatile boolean readOnlyConnected;
+
+        public CountdownWatcher() {
+            reset();
+        }
+        synchronized public void reset() {
+            clientConnected = new CountDownLatch(1);
+            connected = false;
+            syncConnected = false;
+            readOnlyConnected = false;
+        }
+        synchronized public void process(WatchedEvent event) {
+            KeeperState state = event.getState();
+            if (state == KeeperState.SyncConnected) {
+                connected = true;
+                syncConnected = true;
+                readOnlyConnected = false;
+            } else if (state == KeeperState.ConnectedReadOnly) {
+                connected = true;
+                syncConnected = false;
+                readOnlyConnected = true;
+            } else {
+                connected = false;
+                syncConnected = false;
+                readOnlyConnected = false;
+            }
+
+            notifyAll();
+            if (connected) {
+                clientConnected.countDown();
+            }
+        }
+        synchronized public boolean isConnected() {
+            return connected;
+        }
+        synchronized public void waitForConnected(long timeout)
+            throws InterruptedException, TimeoutException
+        {
+            long expire = Time.currentElapsedTime() + timeout;
+            long left = timeout;
+            while(!connected && left > 0) {
+                wait(left);
+                left = expire - Time.currentElapsedTime();
+            }
+            if (!connected) {
+                throw new TimeoutException("Did not connect");
+
+            }
+        }
+        synchronized public void waitForSyncConnected(long timeout)
+                throws InterruptedException, TimeoutException
+        {
+            long expire = System.currentTimeMillis() + timeout;
+            long left = timeout;
+            while(!syncConnected && left > 0) {
+                wait(left);
+                left = expire - System.currentTimeMillis();
+            }
+            if (!syncConnected) {
+                throw new TimeoutException("Failed to connect to read-write ZooKeeper server.");
+            }
+        }
+        synchronized public void waitForReadOnlyConnected(long timeout)
+                throws InterruptedException, TimeoutException
+        {
+            long expire = System.currentTimeMillis() + timeout;
+            long left = timeout;
+            while(!readOnlyConnected && left > 0) {
+                wait(left);
+                left = expire - System.currentTimeMillis();
+            }
+            if (!readOnlyConnected) {
+                throw new TimeoutException("Failed to connect in read-only mode to ZooKeeper server.");
+            }
+        }
+        synchronized public void waitForDisconnected(long timeout)
+            throws InterruptedException, TimeoutException
+        {
+            long expire = Time.currentElapsedTime() + timeout;
+            long left = timeout;
+            while(connected && left > 0) {
+                wait(left);
+                left = expire - Time.currentElapsedTime();
+            }
+            if (connected) {
+                throw new TimeoutException("Did not disconnect");
+
+            }
+        }
+    }
+
+    protected TestableZooKeeper createClient()
+        throws IOException, InterruptedException
+    {
+        return createClient(hostPort);
+    }
+
+    protected TestableZooKeeper createClient(String hp)
+        throws IOException, InterruptedException
+    {
+        CountdownWatcher watcher = new CountdownWatcher();
+        return createClient(watcher, hp);
+    }
+
+    protected TestableZooKeeper createClient(CountdownWatcher watcher)
+        throws IOException, InterruptedException
+    {
+        return createClient(watcher, hostPort);
+    }
+
+    private LinkedList<ZooKeeper> allClients;
+    private boolean allClientsSetup = false;
+
+    protected TestableZooKeeper createClient(CountdownWatcher watcher, String hp)
+        throws IOException, InterruptedException
+    {
+        return createClient(watcher, hp, CONNECTION_TIMEOUT);
+    }
+
+    protected TestableZooKeeper createClient(CountdownWatcher watcher,
+            String hp, int timeout)
+        throws IOException, InterruptedException
+    {
+        watcher.reset();
+        TestableZooKeeper zk = new TestableZooKeeper(hp, timeout, watcher);
+        if (!watcher.clientConnected.await(timeout, TimeUnit.MILLISECONDS))
+        {
+            Assert.fail("Unable to connect to server");
+        }
+        synchronized(this) {
+            if (!allClientsSetup) {
+                LOG.error("allClients never setup");
+                Assert.fail("allClients never setup");
+            }
+            if (allClients != null) {
+                allClients.add(zk);
+                JMXEnv.ensureAll(getHexSessionId(zk.getSessionId()));
+            } else {
+                // test done - close the zk, not needed
+                zk.close();
+            }
+        }
+
+        return zk;
+    }
+
+    public static class HostPort {
+        String host;
+        int port;
+        public HostPort(String host, int port) {
+            this.host = host;
+            this.port = port;
+        }
+    }
+    public static List<HostPort> parseHostPortList(String hplist) {
+        ArrayList<HostPort> alist = new ArrayList<HostPort>();
+        for (String hp: hplist.split(",")) {
+            int idx = hp.lastIndexOf(':');
+            String host = hp.substring(0, idx);
+            int port;
+            try {
+                port = Integer.parseInt(hp.substring(idx + 1));
+            } catch(RuntimeException e) {
+                throw new RuntimeException("Problem parsing " + hp + e.toString());
+            }
+            alist.add(new HostPort(host,port));
+        }
+        return alist;
+    }
+
+    public static boolean waitForServerUp(String hp, long timeout) {
+        long start = Time.currentElapsedTime();
+        while (true) {
+            try {
+                // if there are multiple hostports, just take the first one
+                HostPort hpobj = parseHostPortList(hp).get(0);
+                String result = send4LetterWord(hpobj.host, hpobj.port, "stat");
+                if (result.startsWith("Zookeeper version:") &&
+                        !result.contains("READ-ONLY")) {
+                    return true;
+                }
+            } catch (IOException e) {
+                // ignore as this is expected
+                LOG.info("server " + hp + " not up " + e);
+            }
+
+            if (Time.currentElapsedTime() > start + timeout) {
+                break;
+            }
+            try {
+                Thread.sleep(250);
+            } catch (InterruptedException e) {
+                // ignore
+            }
+        }
+        return false;
+    }
+    public static boolean waitForServerDown(String hp, long timeout) {
+        long start = Time.currentElapsedTime();
+        while (true) {
+            try {
+                HostPort hpobj = parseHostPortList(hp).get(0);
+                send4LetterWord(hpobj.host, hpobj.port, "stat");
+            } catch (IOException e) {
+                return true;
+            }
+
+            if (Time.currentElapsedTime() > start + timeout) {
+                break;
+            }
+            try {
+                Thread.sleep(250);
+            } catch (InterruptedException e) {
+                // ignore
+            }
+        }
+        return false;
+    }
+
+    public static boolean waitForServerState(QuorumPeer qp, int timeout,
+            String serverState) {
+        long start = Time.currentElapsedTime();
+        while (true) {
+            try {
+                Thread.sleep(250);
+            } catch (InterruptedException e) {
+                // ignore
+            }
+            if (qp.getServerState().equals(serverState))
+                return true;
+            if (Time.currentElapsedTime() > start + timeout) {
+                return false;
+            }
+        }
+    }
+
+    static void verifyThreadTerminated(Thread thread, long millis)
+        throws InterruptedException
+    {
+        thread.join(millis);
+        if (thread.isAlive()) {
+            LOG.error("Thread " + thread.getName() + " : "
+                    + Arrays.toString(thread.getStackTrace()));
+            Assert.assertFalse("thread " + thread.getName()
+                    + " still alive after join", true);
+        }
+    }
+
+    public static File createEmptyTestDir() throws IOException {
+        return createTmpDir(BASETEST, false);
+    }
+
+    public static File createTmpDir() throws IOException {
+        return createTmpDir(BASETEST, true);
+    }
+
+    static File createTmpDir(File parentDir, boolean createInitFile) throws IOException {
+        File tmpFile = File.createTempFile("test", ".junit", parentDir);
+        // don't delete tmpFile - this ensures we don't attempt to create
+        // a tmpDir with a duplicate name
+        File tmpDir = new File(tmpFile + ".dir");
+        Assert.assertFalse(tmpDir.exists()); // never true if tmpfile does it's job
+        Assert.assertTrue(tmpDir.mkdirs());
+
+        // todo not every tmp directory needs this file
+        if (createInitFile) {
+            createInitializeFile(tmpDir);
+        }
+
+        return tmpDir;
+    }
+
+    public static void createInitializeFile(File dir) throws IOException {
+        File initFile = new File(dir, "initialize");
+        if (!initFile.exists()) {
+            Assert.assertTrue(initFile.createNewFile());
+        }
+    }
+
+    private static int getPort(String hostPort) {
+        String[] split = hostPort.split(":");
+        String portstr = split[split.length-1];
+        String[] pc = portstr.split("/");
+        if (pc.length > 1) {
+            portstr = pc[0];
+        }
+        return Integer.parseInt(portstr);
+    }
+
+    /**
+     * Starting the given server instance
+     */
+    public static void startServerInstance(File dataDir,
+            ServerCnxnFactory factory, String hostPort) throws IOException,
+            InterruptedException {
+        final int port = getPort(hostPort);
+        LOG.info("STARTING server instance 127.0.0.1:{}", port);
+        ZooKeeperServer zks = new ZooKeeperServer(dataDir, dataDir, 3000);
+        factory.startup(zks);
+        Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(
+                "127.0.0.1:" + port, CONNECTION_TIMEOUT));
+    }
+
+    /**
+     * This method instantiates a new server. Starting of the server
+     * instance has been moved to a separate method
+     * {@link ClientBase#startServerInstance(File, ServerCnxnFactory, String)}.
+     * Because any exception on starting the server would leave the server
+     * running and the caller would not be able to shutdown the instance. This
+     * may affect other test cases.
+     * 
+     * @return newly created server instance
+     * 
+     * @see <a
+     *      href="https://issues.apache.org/jira/browse/ZOOKEEPER-1852">ZOOKEEPER-1852</a>
+     *      for more information.
+     */
+    public static ServerCnxnFactory createNewServerInstance(
+            ServerCnxnFactory factory, String hostPort, int maxCnxns)
+            throws IOException, InterruptedException {
+        final int port = getPort(hostPort);
+        LOG.info("CREATING server instance 127.0.0.1:{}", port);
+        if (factory == null) {
+            factory = ServerCnxnFactory.createFactory(port, maxCnxns);
+        }
+        return factory;
+    }
+
+    static void shutdownServerInstance(ServerCnxnFactory factory,
+            String hostPort)
+    {
+        if (factory != null) {
+            ZKDatabase zkDb = null;
+            {
+                ZooKeeperServer zs = getServer(factory);
+                if (zs != null) {
+                    zkDb = zs.getZKDatabase();
+                }
+            }
+            factory.shutdown();
+            try {
+                if (zkDb != null) {
+                    zkDb.close();
+                }
+            } catch (IOException ie) {
+                LOG.warn("Error closing logs ", ie);
+            }
+            final int PORT = getPort(hostPort);
+
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown("127.0.0.1:" + PORT,
+                                                    CONNECTION_TIMEOUT));
+        }
+    }
+
+    /**
+     * Test specific setup
+     */
+    public static void setupTestEnv() {
+        // during the tests we run with 100K prealloc in the logs.
+        // on windows systems prealloc of 64M was seen to take ~15seconds
+        // resulting in test Assert.failure (client timeout on first session).
+        // set env and directly in order to handle static init/gc issues
+        System.setProperty("zookeeper.preAllocSize", "100");
+        FilePadding.setPreallocSize(100 * 1024);
+    }
+
+    protected void setUpAll() throws Exception {
+        allClients = new LinkedList<ZooKeeper>();
+        allClientsSetup = true;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        /* some useful information - log the number of fds used before
+         * and after a test is run. Helps to verify we are freeing resources
+         * correctly. Unfortunately this only works on unix systems (the
+         * only place sun has implemented as part of the mgmt bean api.
+         */
+        OSMXBean osMbean = new OSMXBean();
+        if (osMbean.getUnix() == true) {
+            initialFdCount = osMbean.getOpenFileDescriptorCount();  	
+            LOG.info("Initial fdcount is: "
+                    + initialFdCount);
+        }
+
+        setupTestEnv();
+
+        JMXEnv.setUp();
+
+        setUpAll();
+
+        tmpDir = createTmpDir(BASETEST, true);
+
+        startServer();
+
+        LOG.info("Client test setup finished");
+    }
+
+    protected void startServer() throws Exception {
+        LOG.info("STARTING server");
+        serverFactory = createNewServerInstance(serverFactory, hostPort,
+                maxCnxns);
+        startServerInstance(tmpDir, serverFactory, hostPort);
+        // ensure that server and data bean are registered
+        Set<ObjectName> children = JMXEnv.ensureParent("InMemoryDataTree",
+                "StandaloneServer_port");
+        // Remove beans which are related to zk client sessions. Strong
+        // assertions cannot be done for these client sessions because
+        // registeration of these beans with server will happen only on their
+        // respective reconnection interval
+        verifyUnexpectedBeans(children);
+    }
+
+    private void verifyUnexpectedBeans(Set<ObjectName> children) {
+        if (allClients != null) {
+            for (ZooKeeper zkc : allClients) {
+                Iterator<ObjectName> childItr = children.iterator();
+                while (childItr.hasNext()) {
+                    ObjectName clientBean = childItr.next();
+                    if (clientBean.toString().contains(
+                            getHexSessionId(zkc.getSessionId()))) {
+                        LOG.info("found name:" + zkc.getSessionId()
+                                + " client bean:" + clientBean.toString());
+                        childItr.remove();
+                    }
+                }
+            }
+        }
+        for (ObjectName bean : children) {
+            LOG.info("unexpected:" + bean.toString());
+        }
+        TestCase.assertEquals("Unexpected bean exists!", 0, children.size());
+    }
+
+    /**
+     * Returns a string representation of the given long value session id
+     * 
+     * @param sessionId
+     *            long value of session id
+     * @return string representation of session id
+     */
+    protected static String getHexSessionId(long sessionId) {
+        return "0x" + Long.toHexString(sessionId);
+    }
+
+    protected void stopServer() throws Exception {
+        LOG.info("STOPPING server");
+        shutdownServerInstance(serverFactory, hostPort);
+        serverFactory = null;
+        // ensure no beans are leftover
+        JMXEnv.ensureOnly();
+    }
+
+
+    protected static ZooKeeperServer getServer(ServerCnxnFactory fac) {
+        ZooKeeperServer zs = ServerCnxnFactoryAccessor.getZkServer(fac);
+
+        return zs;
+    }
+
+    protected void tearDownAll() throws Exception {
+        synchronized (this) {
+            if (allClients != null) for (ZooKeeper zk : allClients) {
+                try {
+                    if (zk != null)
+                        zk.close();
+                } catch (InterruptedException e) {
+                    LOG.warn("ignoring interrupt", e);
+                }
+            }
+            allClients = null;
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        LOG.info("tearDown starting");
+
+        tearDownAll();
+
+        stopServer();
+
+        if (tmpDir != null) {
+            Assert.assertTrue("delete " + tmpDir.toString(), recursiveDelete(tmpDir));
+        }
+
+        // This has to be set to null when the same instance of this class is reused between test cases
+        serverFactory = null;
+
+        JMXEnv.tearDown();
+
+        /* some useful information - log the number of fds used before
+         * and after a test is run. Helps to verify we are freeing resources
+         * correctly. Unfortunately this only works on unix systems (the
+         * only place sun has implemented as part of the mgmt bean api.
+         */
+        OSMXBean osMbean = new OSMXBean();
+        if (osMbean.getUnix() == true) {
+            long fdCount = osMbean.getOpenFileDescriptorCount();     
+            String message = "fdcount after test is: "
+                    + fdCount + " at start it was " + initialFdCount;
+            LOG.info(message);
+            if (fdCount > initialFdCount) {
+                LOG.info("sleeping for 20 secs");
+                //Thread.sleep(60000);
+                //assertTrue(message, fdCount <= initialFdCount);
+            }
+        }
+    }
+
+    public static MBeanServerConnection jmxConn() throws IOException {
+        return JMXEnv.conn();
+    }
+
+    public static boolean recursiveDelete(File d) {
+        if (d.isDirectory()) {
+            File children[] = d.listFiles();
+            for (File f : children) {
+                Assert.assertTrue("delete " + f.toString(), recursiveDelete(f));
+            }
+        }
+        return d.delete();
+    }
+
+    public static void logAllStackTraces() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Starting logAllStackTraces()\n");
+        Map<Thread, StackTraceElement[]> threads = Thread.getAllStackTraces();
+        for (Entry<Thread, StackTraceElement[]> e: threads.entrySet()) {
+            sb.append("Thread " + e.getKey().getName() + "\n");
+            for (StackTraceElement elem: e.getValue()) {
+                sb.append("\tat " + elem + "\n");
+            }
+        }
+        sb.append("Ending logAllStackTraces()\n");
+        LOG.error(sb.toString());
+    }
+
+    /*
+     * Verify that all of the servers see the same number of nodes
+     * at the root
+     */
+    void verifyRootOfAllServersMatch(String hostPort)
+        throws InterruptedException, KeeperException, IOException
+    {
+        String parts[] = hostPort.split(",");
+
+        // run through till the counts no longer change on each server
+        // max 15 tries, with 2 second sleeps, so approx 30 seconds
+        int[] counts = new int[parts.length];
+        int failed = 0;
+        for (int j = 0; j < 100; j++) {
+            int newcounts[] = new int[parts.length];
+            int i = 0;
+            for (String hp : parts) {
+                try {
+                    ZooKeeper zk = createClient(hp);
+
+                    try {
+                        newcounts[i++] = zk.getChildren("/", false).size();
+                    } finally {
+                        zk.close();
+                    }
+                } catch (Throwable t) {
+                    failed++;
+                    // if session creation Assert.fails dump the thread stack
+                    // and try the next server
+                    logAllStackTraces();
+                }
+            }
+
+            if (Arrays.equals(newcounts, counts)) {
+                LOG.info("Found match with array:"
+                        + Arrays.toString(newcounts));
+                counts = newcounts;
+                break;
+            } else {
+                counts = newcounts;
+                Thread.sleep(10000);
+            }
+
+            // don't keep this up too long, will Assert.assert false below
+            if (failed > 10) {
+                break;
+            }
+        }
+
+        // verify all the servers reporting same number of nodes
+        String logmsg = "node count not consistent{} {}";
+        for (int i = 1; i < parts.length; i++) {
+            if (counts[i-1] != counts[i]) {            	
+                LOG.error(logmsg, Integer.valueOf(counts[i-1]), Integer.valueOf(counts[i]));
+            } else {
+                LOG.info(logmsg, Integer.valueOf(counts[i-1]), Integer.valueOf(counts[i]));
+            }
+        }
+    }
+
+    public static String readFile(File file) throws IOException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
+        try {
+            IOUtils.copyBytes(is, os, 1024, true);
+        } finally {
+            is.close();
+        }
+        return os.toString();
+    }
+
+    public static String join(String separator, Object[] parts) {
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for (Object part : parts) {
+            if (!first) {
+                sb.append(separator);
+                first = false;
+            }
+            sb.append(part);
+        }
+        return sb.toString();
+    }
+
+    public static ZooKeeper createZKClient(String cxnString) throws Exception {
+        return createZKClient(cxnString, CONNECTION_TIMEOUT);
+    }
+
+    /**
+     * Returns ZooKeeper client after connecting to ZooKeeper Server. Session
+     * timeout is {@link #CONNECTION_TIMEOUT}
+     *
+     * @param cxnString
+     *            connection string in the form of host:port
+     * @param sessionTimeout
+     * @throws IOException
+     *             in cases of network failure
+     */
+    public static ZooKeeper createZKClient(String cxnString, int sessionTimeout) throws IOException {
+        CountdownWatcher watcher = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper(cxnString, sessionTimeout, watcher);
+        try {
+            watcher.waitForConnected(CONNECTION_TIMEOUT);
+        } catch (InterruptedException e) {
+            Assert.fail("ZooKeeper client can not connect to " + cxnString);
+        }
+        catch (TimeoutException e) {
+            Assert.fail("ZooKeeper client can not connect to " + cxnString);
+        }
+        return zk;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java
new file mode 100644
index 0000000..025ccbe
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java
@@ -0,0 +1,246 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.zookeeper.common.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ClientHammerTest extends ClientBase {
+    protected static final Logger LOG = LoggerFactory.getLogger(ClientHammerTest.class);
+
+    private static final long HAMMERTHREAD_LATENCY = 5;
+
+    private static abstract class HammerThread extends Thread {
+        protected final int count;
+        protected volatile int current = 0;
+
+        HammerThread(String name, int count) {
+            super(name);
+            this.count = count;
+        }
+    }
+
+    private static class BasicHammerThread extends HammerThread {
+        private final ZooKeeper zk;
+        private final String prefix;
+
+        BasicHammerThread(String name, ZooKeeper zk, String prefix, int count) {
+            super(name, count);
+            this.zk = zk;
+            this.prefix = prefix;
+        }
+
+        public void run() {
+            byte b[] = new byte[256];
+            try {
+                for (; current < count; current++) {
+                    // Simulate a bit of network latency...
+                    Thread.sleep(HAMMERTHREAD_LATENCY);
+                    zk.create(prefix + current, b, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+                }
+            } catch (Throwable t) {
+                LOG.error("Client create operation Assert.failed", t);
+            } finally {
+                try {
+                    zk.close();
+                } catch (InterruptedException e) {
+                    LOG.warn("Unexpected", e);
+                }
+            }
+        }
+    }
+
+    private static class SuperHammerThread extends HammerThread {
+        private final ClientHammerTest parent;
+        private final String prefix;
+
+        SuperHammerThread(String name, ClientHammerTest parent, String prefix,
+                int count)
+        {
+            super(name, count);
+            this.parent = parent;
+            this.prefix = prefix;
+        }
+
+        public void run() {
+            byte b[] = new byte[256];
+            try {
+                for (; current < count; current++) {
+                    ZooKeeper zk = parent.createClient();
+                    try {
+                        zk.create(prefix + current, b, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+                    } finally {
+                        try {
+                            zk.close();
+                        } catch (InterruptedException e) {
+                            LOG.warn("Unexpected", e);
+                        }
+                    }
+                }
+            } catch (Throwable t) {
+                LOG.error("Client create operation Assert.failed", t);
+            }
+        }
+    }
+
+    /**
+     * Separate threads each creating a number of nodes. Each thread
+     * is using a non-shared (owned by thread) client for all node creations.
+     * @throws Throwable
+     */
+    @Test
+    public void testHammerBasic() throws Throwable {
+        runHammer(10, 1000);
+    }
+
+    public void runHammer(final int threadCount, final int childCount)
+        throws Throwable
+    {
+        try {
+            HammerThread[] threads = new HammerThread[threadCount];
+            long start = Time.currentElapsedTime();
+            for (int i = 0; i < threads.length; i++) {
+                ZooKeeper zk = createClient();
+                String prefix = "/test-" + i;
+                zk.create(prefix, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+                prefix += "/";
+                HammerThread thread =
+                    new BasicHammerThread("BasicHammerThread-" + i, zk, prefix,
+                            childCount);
+                thread.start();
+
+                threads[i] = thread;
+            }
+
+            verifyHammer(start, threads, childCount);
+        } catch (Throwable t) {
+            LOG.error("test Assert.failed", t);
+            throw t;
+        }
+    }
+
+    /**
+     * Separate threads each creating a number of nodes. Each thread
+     * is creating a new client for each node creation.
+     * @throws Throwable
+     */
+    @Test
+    public void testHammerSuper() throws Throwable {
+        try {
+            final int threadCount = 5;
+            final int childCount = 10;
+
+            HammerThread[] threads = new HammerThread[threadCount];
+            long start = Time.currentElapsedTime();
+            for (int i = 0; i < threads.length; i++) {
+                String prefix = "/test-" + i;
+                {
+                    ZooKeeper zk = createClient();
+                    try {
+                        zk.create(prefix, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+                    } finally {
+                        zk.close();
+                    }
+                }
+                prefix += "/";
+                HammerThread thread =
+                    new SuperHammerThread("SuperHammerThread-" + i, this,
+                            prefix, childCount);
+                thread.start();
+
+                threads[i] = thread;
+            }
+
+            verifyHammer(start, threads, childCount);
+        } catch (Throwable t) {
+            LOG.error("test Assert.failed", t);
+            throw t;
+        }
+    }
+
+    public void verifyHammer(long start, HammerThread[] threads, int childCount)
+        throws IOException, InterruptedException, KeeperException
+    {
+        // look for the clients to finish their create operations
+        LOG.info("Starting check for completed hammers");
+        int workingCount = threads.length;
+        for (int i = 0; i < 120; i++) {
+            Thread.sleep(10000);
+            for (HammerThread h : threads) {
+                if (!h.isAlive() || h.current == h.count) {
+                    workingCount--;
+                }
+            }
+            if (workingCount == 0) {
+                break;
+            }
+            workingCount = threads.length;
+        }
+        if (workingCount > 0) {
+            for (HammerThread h : threads) {
+                LOG.warn(h.getName() + " never finished creation, current:"
+                        + h.current);
+            }
+        } else {
+            LOG.info("Hammer threads completed creation operations");
+        }
+
+        for (HammerThread h : threads) {
+            final int safetyFactor = 3;
+            verifyThreadTerminated(h,
+                    threads.length * childCount
+                    * HAMMERTHREAD_LATENCY * safetyFactor);
+        }
+        LOG.info(new Date() + " Total time "
+                + (Time.currentElapsedTime() - start));
+
+        ZooKeeper zk = createClient();
+        try {
+            LOG.info("******************* Connected to ZooKeeper" + new Date());
+            for (int i = 0; i < threads.length; i++) {
+                LOG.info("Doing thread: " + i + " " + new Date());
+                List<String> children =
+                    zk.getChildren("/test-" + i, false);
+                Assert.assertEquals(childCount, children.size());
+                children = zk.getChildren("/test-" + i, false, null);
+                Assert.assertEquals(childCount, children.size());
+            }
+            for (int i = 0; i < threads.length; i++) {
+                List<String> children =
+                    zk.getChildren("/test-" + i, false);
+                Assert.assertEquals(childCount, children.size());
+                children = zk.getChildren("/test-" + i, false, null);
+                Assert.assertEquals(childCount, children.size());
+            }
+        } finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java
new file mode 100644
index 0000000..95c55e2
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java
@@ -0,0 +1,127 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ClientPortBindTest extends ZKTestCase implements Watcher {
+    protected static final Logger LOG = 
+        LoggerFactory.getLogger(ClientPortBindTest.class);
+
+    private volatile CountDownLatch startSignal;
+
+    /**
+     * Verify that the server binds to the specified address
+     */
+    @Test
+    public void testBindByAddress() throws Exception {
+        String bindAddress = null;
+        Enumeration<NetworkInterface> intfs =
+            NetworkInterface.getNetworkInterfaces();
+        // if we have a loopback and it has an address use it
+        while(intfs.hasMoreElements()) {
+            NetworkInterface i = intfs.nextElement();
+            try {
+                if (i.isLoopback()) {
+                  Enumeration<InetAddress> addrs = i.getInetAddresses();
+                  while (addrs.hasMoreElements()) {
+                    InetAddress a = addrs.nextElement();
+                    if(a.isLoopbackAddress()) {
+                      bindAddress = a.getHostAddress();
+                      break;
+                    }
+                  }
+                }
+            } catch (SocketException se) {
+                LOG.warn("Couldn't find  loopback interface: " + se.getMessage());
+            }
+        }
+        if (bindAddress == null) {
+            LOG.warn("Unable to determine loop back address, skipping test");
+            return;
+        }
+        final int PORT = PortAssignment.unique();
+
+        LOG.info("Using " + bindAddress + " as the bind address");
+        final String HOSTPORT = bindAddress + ":" + PORT;
+        LOG.info("Using " + HOSTPORT + " as the host/port");
+
+
+        File tmpDir = ClientBase.createTmpDir();
+
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(
+                new InetSocketAddress(bindAddress, PORT), -1);
+        f.startup(zks);
+        LOG.info("starting up the the server, waiting");
+
+        Assert.assertTrue("waiting for server up",
+                   ClientBase.waitForServerUp(HOSTPORT,
+                                   CONNECTION_TIMEOUT));
+
+        startSignal = new CountDownLatch(1);
+        ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+        try {
+            boolean isZero = startSignal.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS);
+            Assert.assertTrue("count == " + startSignal.getCount(), isZero);
+            zk.close();
+        } finally {
+            f.shutdown();
+            zks.shutdown();
+
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(HOSTPORT,
+                                                    CONNECTION_TIMEOUT));
+        }
+    }
+
+    public void process(WatchedEvent event) {
+        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
+        if (event.getState() == KeeperState.SyncConnected
+                && startSignal != null && startSignal.getCount() > 0)
+        {
+            startSignal.countDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientRetry.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientRetry.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientRetry.java
new file mode 100644
index 0000000..d0b6b43
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientRetry.java
@@ -0,0 +1,72 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooKeeper.States;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ClientRetry extends ClientBase {
+
+    @Override
+    public void setUp() throws Exception {
+        maxCnxns = 1;
+        super.setUp();
+    }
+    /*
+     * This is a simple test - try to connect two clients to a server
+     * accepting a maximum of one connection from each address. Check that
+     * only one is accepted. Close that connection, and check that the other
+     * eventually connects.
+     *
+     * There is a possibility of a false positive here, as when zk2 is tested
+     * for having connected it might not have been given enough time, and finish
+     * connecting after the test is done. Since the
+     * server doesn't tell the client why it hasn't connected, there's no
+     * obvious way to detect the difference.
+     */
+    @Test
+    public void testClientRetry() throws IOException, InterruptedException, TimeoutException{
+        CountdownWatcher cdw1 = new CountdownWatcher();
+        CountdownWatcher cdw2 = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper(hostPort, 10000, cdw1);
+        try {
+            cdw1.waitForConnected(CONNECTION_TIMEOUT);
+            ZooKeeper zk2 = new ZooKeeper(hostPort, 10000, cdw2);
+            try {
+                States s1 = zk.getState();
+                States s2 = zk2.getState();
+                Assert.assertSame(s1,States.CONNECTED);
+                Assert.assertSame(s2,States.CONNECTING);
+                cdw1.reset();
+                cdw1.waitForDisconnected(CONNECTION_TIMEOUT);
+                cdw2.waitForConnected(CONNECTION_TIMEOUT);
+                Assert.assertSame(zk2.getState(),States.CONNECTED);
+            } finally {
+                zk2.close();
+            }
+        } finally {
+            zk.close();
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientTest.java
new file mode 100644
index 0000000..9dc4861
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ClientTest.java
@@ -0,0 +1,805 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.KeeperException.InvalidACLException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooDefs.Perms;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.proto.ExistsRequest;
+import org.apache.zookeeper.proto.ExistsResponse;
+import org.apache.zookeeper.proto.ReplyHeader;
+import org.apache.zookeeper.proto.RequestHeader;
+import org.apache.zookeeper.server.PrepRequestProcessor;
+import org.apache.zookeeper.server.util.OSMXBean;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClientTest extends ClientBase {
+    protected static final Logger LOG = LoggerFactory.getLogger(ClientTest.class);
+
+    /** Verify that pings are sent, keeping the "idle" client alive */
+    @Test
+    public void testPing() throws Exception {
+        ZooKeeper zkIdle = null;
+        ZooKeeper zkWatchCreator = null;
+        try {
+            CountdownWatcher watcher = new CountdownWatcher();
+            zkIdle = createClient(watcher, hostPort, 10000);
+
+            zkWatchCreator = createClient();
+
+            for (int i = 0; i < 10; i++) {
+                zkWatchCreator.create("/" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+            }
+            for (int i = 0; i < 10; i++) {
+                zkIdle.exists("/" + i, true);
+            }
+            for (int i = 0; i < 10; i++) {
+                Thread.sleep(1000);
+                zkWatchCreator.delete("/" + i, -1);
+            }
+            // The bug will manifest itself here because zkIdle will expire
+            zkIdle.exists("/0", false);
+        } finally {
+            if (zkIdle != null) {
+                zkIdle.close();
+            }
+            if (zkWatchCreator != null) {
+                zkWatchCreator.close();
+            }
+        }
+    }
+
+    @Test
+    public void testClientwithoutWatcherObj() throws IOException,
+            InterruptedException, KeeperException
+    {
+        performClientTest(false, hostPort);
+    }
+
+    @Test
+    public void testClientWithWatcherObj() throws IOException,
+            InterruptedException, KeeperException
+    {
+        performClientTest(true, hostPort);
+    }
+
+    @Test
+    public void testClientWithIPv6Address() throws IOException,
+            InterruptedException, KeeperException
+    {
+        assumeIPv6Available();
+        performClientTest(true, ipv6HostPort);
+    }
+
+    /** Exercise the testable functions, verify tostring, etc... */
+    @Test
+    public void testTestability() throws Exception {
+        TestableZooKeeper zk = createClient();
+        try {
+            LOG.info("{}",zk.testableLocalSocketAddress());
+            LOG.info("{}",zk.testableRemoteSocketAddress());
+            LOG.info("{}",zk.toString());
+        } finally {
+            zk.close();
+            zk.testableWaitForShutdown(CONNECTION_TIMEOUT);
+            LOG.info("{}",zk.testableLocalSocketAddress());
+            LOG.info("{}",zk.testableRemoteSocketAddress());
+            LOG.info("{}",zk.toString());
+        }
+    }
+
+    @Test
+    public void testACLs() throws Exception {
+        ZooKeeper zk = null;
+        try {
+            zk = createClient();
+            try {
+                zk.create("/acltest", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+                Assert.fail("Should have received an invalid acl error");
+            } catch(InvalidACLException e) {
+                LOG.info("Test successful, invalid acl received : "
+                        + e.getMessage());
+            }
+            try {
+                ArrayList<ACL> testACL = new ArrayList<ACL>();
+                testACL.add(new ACL(Perms.ALL | Perms.ADMIN, Ids.AUTH_IDS));
+                testACL.add(new ACL(Perms.ALL | Perms.ADMIN, new Id("ip", "127.0.0.1/8")));
+                zk.create("/acltest", new byte[0], testACL, CreateMode.PERSISTENT);
+                Assert.fail("Should have received an invalid acl error");
+            } catch(InvalidACLException e) {
+                LOG.info("Test successful, invalid acl received : "
+                        + e.getMessage());
+            }
+            zk.addAuthInfo("digest", "ben:passwd".getBytes());
+            zk.create("/acltest", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+            zk.close();
+            zk = createClient();
+            zk.addAuthInfo("digest", "ben:passwd2".getBytes());
+            try {
+                zk.getData("/acltest", false, new Stat());
+                Assert.fail("Should have received a permission error");
+            } catch (KeeperException e) {
+                Assert.assertEquals(Code.NOAUTH, e.code());
+            }
+            zk.addAuthInfo("digest", "ben:passwd".getBytes());
+            zk.getData("/acltest", false, new Stat());
+            zk.setACL("/acltest", Ids.OPEN_ACL_UNSAFE, -1);
+            zk.close();
+            zk = createClient();
+            zk.getData("/acltest", false, new Stat());
+            List<ACL> acls = zk.getACL("/acltest", new Stat());
+            Assert.assertEquals(1, acls.size());
+            Assert.assertEquals(Ids.OPEN_ACL_UNSAFE, acls);
+
+            // The stat parameter should be optional.
+            acls = zk.getACL("/acltest", null);
+            Assert.assertEquals(1, acls.size());
+            Assert.assertEquals(Ids.OPEN_ACL_UNSAFE, acls);
+
+            zk.close();
+        } finally {
+            if (zk != null) {
+                zk.close();
+            }
+        }
+    }
+
+    private class MyWatcher extends CountdownWatcher {
+        LinkedBlockingQueue<WatchedEvent> events =
+            new LinkedBlockingQueue<WatchedEvent>();
+
+        public void process(WatchedEvent event) {
+            super.process(event);
+            if (event.getType() != EventType.None) {
+                try {
+                    events.put(event);
+                } catch (InterruptedException e) {
+                    LOG.warn("ignoring interrupt during event.put");
+                }
+            }
+        }
+    }
+
+    /**
+     * Register multiple watchers and verify that they all get notified and
+     * in the right order.
+     */
+    @Test
+    public void testMutipleWatcherObjs()
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk = createClient(new CountdownWatcher(), hostPort);
+        try {
+            MyWatcher watchers[] = new MyWatcher[100];
+            MyWatcher watchers2[] = new MyWatcher[watchers.length];
+            for (int i = 0; i < watchers.length; i++) {
+                watchers[i] = new MyWatcher();
+                watchers2[i] = new MyWatcher();
+                zk.create("/foo-" + i, ("foodata" + i).getBytes(),
+                        Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            }
+            Stat stat = new Stat();
+
+            //
+            // test get/exists with single set of watchers
+            //   get all, then exists all
+            //
+            for (int i = 0; i < watchers.length; i++) {
+                Assert.assertNotNull(zk.getData("/foo-" + i, watchers[i], stat));
+            }
+            for (int i = 0; i < watchers.length; i++) {
+                Assert.assertNotNull(zk.exists("/foo-" + i, watchers[i]));
+            }
+            // trigger the watches
+            for (int i = 0; i < watchers.length; i++) {
+                zk.setData("/foo-" + i, ("foodata2-" + i).getBytes(), -1);
+                zk.setData("/foo-" + i, ("foodata3-" + i).getBytes(), -1);
+            }
+            for (int i = 0; i < watchers.length; i++) {
+                WatchedEvent event =
+                    watchers[i].events.poll(10, TimeUnit.SECONDS);
+                Assert.assertEquals("/foo-" + i, event.getPath());
+                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
+                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
+
+                // small chance that an unexpected message was delivered
+                //  after this check, but we would catch that next time
+                //  we check events
+                Assert.assertEquals(0, watchers[i].events.size());
+            }
+
+            //
+            // test get/exists with single set of watchers
+            //  get/exists together
+            //
+            for (int i = 0; i < watchers.length; i++) {
+                Assert.assertNotNull(zk.getData("/foo-" + i, watchers[i], stat));
+                Assert.assertNotNull(zk.exists("/foo-" + i, watchers[i]));
+            }
+            // trigger the watches
+            for (int i = 0; i < watchers.length; i++) {
+                zk.setData("/foo-" + i, ("foodata4-" + i).getBytes(), -1);
+                zk.setData("/foo-" + i, ("foodata5-" + i).getBytes(), -1);
+            }
+            for (int i = 0; i < watchers.length; i++) {
+                WatchedEvent event =
+                    watchers[i].events.poll(10, TimeUnit.SECONDS);
+                Assert.assertEquals("/foo-" + i, event.getPath());
+                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
+                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
+
+                // small chance that an unexpected message was delivered
+                //  after this check, but we would catch that next time
+                //  we check events
+                Assert.assertEquals(0, watchers[i].events.size());
+            }
+
+            //
+            // test get/exists with two sets of watchers
+            //
+            for (int i = 0; i < watchers.length; i++) {
+                Assert.assertNotNull(zk.getData("/foo-" + i, watchers[i], stat));
+                Assert.assertNotNull(zk.exists("/foo-" + i, watchers2[i]));
+            }
+            // trigger the watches
+            for (int i = 0; i < watchers.length; i++) {
+                zk.setData("/foo-" + i, ("foodata6-" + i).getBytes(), -1);
+                zk.setData("/foo-" + i, ("foodata7-" + i).getBytes(), -1);
+            }
+            for (int i = 0; i < watchers.length; i++) {
+                WatchedEvent event =
+                    watchers[i].events.poll(10, TimeUnit.SECONDS);
+                Assert.assertEquals("/foo-" + i, event.getPath());
+                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
+                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
+
+                // small chance that an unexpected message was delivered
+                //  after this check, but we would catch that next time
+                //  we check events
+                Assert.assertEquals(0, watchers[i].events.size());
+
+                // watchers2
+                WatchedEvent event2 =
+                    watchers2[i].events.poll(10, TimeUnit.SECONDS);
+                Assert.assertEquals("/foo-" + i, event2.getPath());
+                Assert.assertEquals(EventType.NodeDataChanged, event2.getType());
+                Assert.assertEquals(KeeperState.SyncConnected, event2.getState());
+
+                // small chance that an unexpected message was delivered
+                //  after this check, but we would catch that next time
+                //  we check events
+                Assert.assertEquals(0, watchers2[i].events.size());
+            }
+
+        } finally {
+            if (zk != null) {
+                zk.close();
+            }
+        }
+    }
+
+    private void performClientTest(boolean withWatcherObj, String hostPort)
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk = null;
+        try {
+            MyWatcher watcher = new MyWatcher();
+            zk = createClient(watcher, hostPort);
+            LOG.info("Before create /benwashere");
+            zk.create("/benwashere", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            LOG.info("After create /benwashere");
+            try {
+                zk.setData("/benwashere", "hi".getBytes(), 57);
+                Assert.fail("Should have gotten BadVersion exception");
+            } catch(KeeperException.BadVersionException e) {
+                // expected that
+            } catch (KeeperException e) {
+                Assert.fail("Should have gotten BadVersion exception");
+            }
+            LOG.info("Before delete /benwashere");
+            zk.delete("/benwashere", 0);
+            LOG.info("After delete /benwashere");
+            zk.close();
+            //LOG.info("Closed client: " + zk.describeCNXN());
+            Thread.sleep(2000);
+
+            zk = createClient(watcher, hostPort);
+            //LOG.info("Created a new client: " + zk.describeCNXN());
+            LOG.info("Before delete /");
+
+            try {
+                zk.delete("/", -1);
+                Assert.fail("deleted root!");
+            } catch(KeeperException.BadArgumentsException e) {
+                // good, expected that
+            }
+            Stat stat = new Stat();
+            // Test basic create, ls, and getData
+            zk.create("/pat", "Pat was here".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            LOG.info("Before create /ben");
+            zk.create("/pat/ben", "Ben was here".getBytes(),
+                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            LOG.info("Before getChildren /pat");
+            List<String> children = zk.getChildren("/pat", false);
+            Assert.assertEquals(1, children.size());
+            Assert.assertEquals("ben", children.get(0));
+            List<String> children2 = zk.getChildren("/pat", false, null);
+            Assert.assertEquals(children, children2);
+            String value = new String(zk.getData("/pat/ben", false, stat));
+            Assert.assertEquals("Ben was here", value);
+            // Test stat and watch of non existent node
+
+            try {
+                if (withWatcherObj) {
+                    Assert.assertEquals(null, zk.exists("/frog", watcher));
+                } else {
+                    Assert.assertEquals(null, zk.exists("/frog", true));
+                }
+                LOG.info("Comment: asseting passed for frog setting /");
+            } catch (KeeperException.NoNodeException e) {
+                // OK, expected that
+            }
+            zk.create("/frog", "hi".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            // the first poll is just a session delivery
+            LOG.info("Comment: checking for events length "
+                     + watcher.events.size());
+            WatchedEvent event = watcher.events.poll(10, TimeUnit.SECONDS);
+            Assert.assertEquals("/frog", event.getPath());
+            Assert.assertEquals(EventType.NodeCreated, event.getType());
+            Assert.assertEquals(KeeperState.SyncConnected, event.getState());
+            // Test child watch and create with sequence
+            zk.getChildren("/pat/ben", true);
+            for (int i = 0; i < 10; i++) {
+                zk.create("/pat/ben/" + i + "-", Integer.toString(i).getBytes(),
+                        Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            }
+            children = zk.getChildren("/pat/ben", false);
+            Collections.sort(children);
+            Assert.assertEquals(10, children.size());
+            for (int i = 0; i < 10; i++) {
+                final String name = children.get(i);
+                Assert.assertTrue("starts with -", name.startsWith(i + "-"));
+                byte b[];
+                if (withWatcherObj) {
+                    b = zk.getData("/pat/ben/" + name, watcher, stat);
+                } else {
+                    b = zk.getData("/pat/ben/" + name, true, stat);
+                }
+                Assert.assertEquals(Integer.toString(i), new String(b));
+                zk.setData("/pat/ben/" + name, "new".getBytes(),
+                        stat.getVersion());
+                if (withWatcherObj) {
+                    stat = zk.exists("/pat/ben/" + name, watcher);
+                } else {
+                stat = zk.exists("/pat/ben/" + name, true);
+                }
+                zk.delete("/pat/ben/" + name, stat.getVersion());
+            }
+            event = watcher.events.poll(10, TimeUnit.SECONDS);
+            Assert.assertEquals("/pat/ben", event.getPath());
+            Assert.assertEquals(EventType.NodeChildrenChanged, event.getType());
+            Assert.assertEquals(KeeperState.SyncConnected, event.getState());
+            for (int i = 0; i < 10; i++) {
+                event = watcher.events.poll(10, TimeUnit.SECONDS);
+                final String name = children.get(i);
+                Assert.assertEquals("/pat/ben/" + name, event.getPath());
+                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
+                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
+                event = watcher.events.poll(10, TimeUnit.SECONDS);
+                Assert.assertEquals("/pat/ben/" + name, event.getPath());
+                Assert.assertEquals(EventType.NodeDeleted, event.getType());
+                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
+            }
+            zk.create("/good\u0040path", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+
+            zk.create("/duplicate", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            try {
+                zk.create("/duplicate", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+                Assert.fail("duplicate create allowed");
+            } catch(KeeperException.NodeExistsException e) {
+                // OK, expected that
+            }
+        } finally {
+            if (zk != null) {
+                zk.close();
+            }
+        }
+    }
+    
+    // Test that sequential filenames are being created correctly,
+    // with 0-padding in the filename
+    @Test
+    public void testSequentialNodeNames()
+        throws IOException, InterruptedException, KeeperException
+    {
+        String path = "/SEQUENCE";
+        String file = "TEST";
+        String filepath = path + "/" + file;
+
+        ZooKeeper zk = null;
+        try {
+            zk = createClient();
+            zk.create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            List<String> children = zk.getChildren(path, false);
+            Assert.assertEquals(1, children.size());
+            Assert.assertEquals(file + "0000000000", children.get(0));
+
+            zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            children = zk.getChildren(path, false);
+            Assert.assertEquals(2, children.size());
+            Assert.assertTrue("contains child 1",  children.contains(file + "0000000001"));
+
+            zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            children = zk.getChildren(path, false);
+            Assert.assertEquals(3, children.size());
+            Assert.assertTrue("contains child 2",
+                       children.contains(file + "0000000002"));
+
+            // The pattern is holding so far.  Let's run the counter a bit
+            // to be sure it continues to spit out the correct answer
+            for(int i = children.size(); i < 105; i++)
+               zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+
+            children = zk.getChildren(path, false);
+            Assert.assertTrue("contains child 104",
+                       children.contains(file + "0000000104"));
+
+        }
+        finally {
+            if(zk != null)
+                zk.close();
+        }
+    }
+    
+    // Test that data provided when 
+    // creating sequential nodes is stored properly
+    @Test
+    public void testSequentialNodeData() throws Exception {
+        ZooKeeper zk= null;
+        String queue_handle = "/queue";
+        try {
+            zk = createClient();
+
+            zk.create(queue_handle, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            zk.create(queue_handle + "/element", "0".getBytes(),
+                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            zk.create(queue_handle + "/element", "1".getBytes(),
+                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            List<String> children = zk.getChildren(queue_handle, true);
+            Assert.assertEquals(children.size(), 2);
+            String child1 = children.get(0);
+            String child2 = children.get(1);
+            int compareResult = child1.compareTo(child2);
+            Assert.assertNotSame(compareResult, 0);
+            if (compareResult < 0) {
+            } else {
+                String temp = child1;
+                child1 = child2;
+                child2 = temp;
+            }
+            String child1data = new String(zk.getData(queue_handle
+                    + "/" + child1, false, null));
+            String child2data = new String(zk.getData(queue_handle
+                    + "/" + child2, false, null));
+            Assert.assertEquals(child1data, "0");
+            Assert.assertEquals(child2data, "1");
+        } finally {
+            if (zk != null) {
+                zk.close();
+            }
+        }
+
+    }
+
+    @Test
+    public void testLargeNodeData() throws Exception {
+        ZooKeeper zk= null;
+        String queue_handle = "/large";
+        try {
+            zk = createClient();
+
+            zk.create(queue_handle, new byte[500000], Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        } finally {
+            if (zk != null) {
+                zk.close();
+            }
+        }
+
+    }
+
+    private void verifyCreateFails(String path, ZooKeeper zk) throws Exception {
+        try {
+            zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        } catch (IllegalArgumentException e) {
+            // this is good
+            return;
+        }
+        Assert.fail("bad path \"" + path + "\" not caught");
+    }
+
+    // Test that the path string is validated
+    @Test
+    public void testPathValidation() throws Exception {
+        ZooKeeper zk = createClient();
+
+        verifyCreateFails(null, zk);
+        verifyCreateFails("", zk);
+        verifyCreateFails("//", zk);
+        verifyCreateFails("///", zk);
+        verifyCreateFails("////", zk);
+        verifyCreateFails("/.", zk);
+        verifyCreateFails("/..", zk);
+        verifyCreateFails("/./", zk);
+        verifyCreateFails("/../", zk);
+        verifyCreateFails("/foo/./", zk);
+        verifyCreateFails("/foo/../", zk);
+        verifyCreateFails("/foo/.", zk);
+        verifyCreateFails("/foo/..", zk);
+        verifyCreateFails("/./.", zk);
+        verifyCreateFails("/../..", zk);
+        verifyCreateFails("/\u0001foo", zk);
+        verifyCreateFails("/foo/bar/", zk);
+        verifyCreateFails("/foo//bar", zk);
+        verifyCreateFails("/foo/bar//", zk);
+
+        verifyCreateFails("foo", zk);
+        verifyCreateFails("a", zk);
+
+        zk.create("/createseqpar", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT);
+        // next two steps - related to sequential processing
+        // 1) verify that empty child name Assert.fails if not sequential
+        try {
+            zk.create("/createseqpar/", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            Assert.assertTrue(false);
+        } catch(IllegalArgumentException be) {
+            // catch this.
+        }
+
+        // 2) verify that empty child name success if sequential 
+        zk.create("/createseqpar/", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT_SEQUENTIAL);
+        zk.create("/createseqpar/.", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT_SEQUENTIAL);
+        zk.create("/createseqpar/..", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT_SEQUENTIAL);
+        try {
+            zk.create("/createseqpar//", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT_SEQUENTIAL);
+            Assert.assertTrue(false);
+        } catch(IllegalArgumentException be) {
+            // catch this.
+        }
+        try {
+            zk.create("/createseqpar/./", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT_SEQUENTIAL);
+            Assert.assertTrue(false);
+        } catch(IllegalArgumentException be) {
+            // catch this.
+        }
+        try {
+            zk.create("/createseqpar/../", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT_SEQUENTIAL);
+            Assert.assertTrue(false);
+        } catch(IllegalArgumentException be) {
+            // catch this.
+        }
+
+        
+        //check for the code path that throws at server
+        PrepRequestProcessor.setFailCreate(true);
+        try {
+            zk.create("/m", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            Assert.assertTrue(false);
+        } catch(KeeperException.BadArgumentsException be) {
+            // catch this.
+        }
+        PrepRequestProcessor.setFailCreate(false);
+        zk.create("/.foo", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/.f.", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/..f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/..f..", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f.c", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f\u0040f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f/.f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f/f.", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f/..f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f/f..", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f/.f/f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/f/f./f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+    }
+
+//    private void notestConnections()
+//        throws IOException, InterruptedException, KeeperException
+//    {
+//        ZooKeeper zk;
+//        for(int i = 0; i < 2000; i++) {
+//            if (i % 100 == 0) {
+//                LOG.info("Testing " + i + " connections");
+//            }
+//            // We want to make sure socket descriptors are going away
+//            zk = new ZooKeeper(hostPort, 30000, this);
+//            zk.getData("/", false, new Stat());
+//            zk.close();
+//        }
+//    }
+
+    @Test
+    public void testDeleteWithChildren() throws Exception {
+        ZooKeeper zk = createClient();
+        zk.create("/parent", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.create("/parent/child", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        try {
+            zk.delete("/parent", -1);
+            Assert.fail("Should have received a not equals message");
+        } catch (KeeperException e) {
+            Assert.assertEquals(KeeperException.Code.NOTEMPTY, e.code());
+        }
+        zk.delete("/parent/child", -1);
+        zk.delete("/parent", -1);
+        zk.close();
+    }
+
+    private class VerifyClientCleanup extends Thread {
+        int count;
+        int current = 0;
+
+        VerifyClientCleanup(String name, int count) {
+            super(name);
+            this.count = count;
+        }
+
+        public void run() {
+            try {
+                for (; current < count; current++) {
+                    TestableZooKeeper zk = createClient();
+                    zk.close();
+                    // we've asked to close, wait for it to finish closing
+                    // all the sub-threads otw the selector may not be
+                    // closed when we check (false positive on test Assert.failure
+                    zk.testableWaitForShutdown(CONNECTION_TIMEOUT);
+                }
+            } catch (Throwable t) {
+                LOG.error("test Assert.failed", t);
+            }
+        }
+    }
+
+    /**
+     * Verify that the client is cleaning up properly. Open/close a large
+     * number of sessions. Essentially looking to see if sockets/selectors
+     * are being cleaned up properly during close.
+     *
+     * @throws Throwable
+     */
+    @Test
+    public void testClientCleanup() throws Throwable {
+        OSMXBean osMbean = new OSMXBean();
+        if (osMbean.getUnix() == false) {
+            LOG.warn("skipping testClientCleanup, only available on Unix");
+            return;
+        }
+
+        final int threadCount = 3;
+        final int clientCount = 10;
+
+        /* Log the number of fds used before and after a test is run. Verifies
+         * we are freeing resources correctly. Unfortunately this only works
+         * on unix systems (the only place sun has implemented as part of the
+         * mgmt bean api).
+         */
+        long initialFdCount = osMbean.getOpenFileDescriptorCount();
+
+        VerifyClientCleanup threads[] = new VerifyClientCleanup[threadCount];
+
+        for (int i = 0; i < threads.length; i++) {
+            threads[i] = new VerifyClientCleanup("VCC" + i, clientCount);
+            threads[i].start();
+        }
+
+        for (int i = 0; i < threads.length; i++) {
+            threads[i].join(CONNECTION_TIMEOUT);
+            Assert.assertTrue(threads[i].current == threads[i].count);
+        }
+
+        // if this Assert.fails it means we are not cleaning up after the closed
+        // sessions.
+        long currentCount = osMbean.getOpenFileDescriptorCount();
+        final String logmsg = "open fds after test ({}) are not significantly higher than before ({})";
+        
+        if (currentCount > initialFdCount + 10) {
+            // consider as error
+        	LOG.error(logmsg,Long.valueOf(currentCount),Long.valueOf(initialFdCount));
+        } else {
+        	LOG.info(logmsg,Long.valueOf(currentCount),Long.valueOf(initialFdCount));
+        }
+    }
+
+
+    /**
+     * We create a perfectly valid 'exists' request, except that the opcode is wrong.
+     * @return
+     * @throws Exception
+     */
+    @Test
+    public void testNonExistingOpCode() throws Exception  {
+        final CountDownLatch clientDisconnected = new CountDownLatch(1);
+        Watcher watcher = new Watcher() {
+            @Override
+            public synchronized void process(WatchedEvent event) {
+                if (event.getState() == KeeperState.Disconnected) {
+                    clientDisconnected.countDown();
+                }
+            }
+        };
+        TestableZooKeeper zk = new TestableZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
+
+        final String path = "/m1";
+
+        RequestHeader h = new RequestHeader();
+        h.setType(888);  // This code does not exists
+        ExistsRequest request = new ExistsRequest();
+        request.setPath(path);
+        request.setWatch(false);
+        ExistsResponse response = new ExistsResponse();
+
+        ReplyHeader r = zk.submitRequest(h, request, response, null);
+
+        Assert.assertEquals(r.getErr(), Code.UNIMPLEMENTED.intValue());
+
+        // Sending a nonexisting opcode should cause the server to disconnect
+        Assert.assertTrue("failed to disconnect",
+                clientDisconnected.await(5000, TimeUnit.MILLISECONDS));
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
new file mode 100644
index 0000000..a169b7b
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.client.ConnectStringParser;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ConnectStringParserTest extends ZKTestCase{
+
+    @Test
+    public void testSingleServerChrootPath(){
+        String chrootPath = "/hallo/welt";
+        String servers = "10.10.10.1";
+        assertChrootPath(chrootPath,
+                new ConnectStringParser(servers+chrootPath));
+    }
+
+    @Test
+    public void testMultipleServersChrootPath(){
+        String chrootPath = "/hallo/welt";
+        String servers = "10.10.10.1,10.10.10.2";
+        assertChrootPath(chrootPath,
+                new ConnectStringParser(servers+chrootPath));
+    }
+
+    @Test
+    public void testParseServersWithoutPort(){
+        String servers = "10.10.10.1,10.10.10.2";
+        ConnectStringParser parser = new ConnectStringParser(servers);
+
+        Assert.assertEquals("10.10.10.1", parser.getServerAddresses().get(0).getHostName());
+        Assert.assertEquals("10.10.10.2", parser.getServerAddresses().get(1).getHostName());
+    }
+
+    @Test
+    public void testParseServersWithPort(){
+        String servers = "10.10.10.1:112,10.10.10.2:110";
+        ConnectStringParser parser = new ConnectStringParser(servers);
+
+        Assert.assertEquals("10.10.10.1", parser.getServerAddresses().get(0).getHostName());
+        Assert.assertEquals("10.10.10.2", parser.getServerAddresses().get(1).getHostName());
+
+        Assert.assertEquals(112, parser.getServerAddresses().get(0).getPort());
+        Assert.assertEquals(110, parser.getServerAddresses().get(1).getPort());
+    }
+
+    private void assertChrootPath(String expected, ConnectStringParser parser){
+        Assert.assertEquals(expected, parser.getChrootPath());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/CreateModeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/CreateModeTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/CreateModeTest.java
new file mode 100644
index 0000000..a3b838a
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/CreateModeTest.java
@@ -0,0 +1,81 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.util.EnumSet;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.KeeperException.Code;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CreateModeTest extends ZKTestCase {
+    
+    @Test
+    public void testBasicCreateMode() {
+        CreateMode cm = CreateMode.PERSISTENT;
+        Assert.assertEquals(cm.toFlag(), 0);
+        Assert.assertFalse(cm.isEphemeral());
+        Assert.assertFalse(cm.isSequential());
+        
+        cm = CreateMode.EPHEMERAL;
+        Assert.assertEquals(cm.toFlag(), 1);
+        Assert.assertTrue(cm.isEphemeral());
+        Assert.assertFalse(cm.isSequential());
+        
+        cm = CreateMode.PERSISTENT_SEQUENTIAL;
+        Assert.assertEquals(cm.toFlag(), 2);
+        Assert.assertFalse(cm.isEphemeral());
+        Assert.assertTrue(cm.isSequential());
+        
+        cm = CreateMode.EPHEMERAL_SEQUENTIAL;
+        Assert.assertEquals(cm.toFlag(), 3);
+        Assert.assertTrue(cm.isEphemeral());
+        Assert.assertTrue(cm.isSequential());
+    }
+    
+    @Test
+    public void testFlagConversion() throws KeeperException {
+        // Ensure we get the same value back after round trip conversion
+        EnumSet<CreateMode> allModes = EnumSet.allOf(CreateMode.class);
+
+        for(CreateMode cm : allModes) {
+            Assert.assertEquals(cm, CreateMode.fromFlag( cm.toFlag() ) );
+        }
+    }
+
+    @Test
+    public void testInvalidFlagConversion() throws KeeperException {
+        try {
+            CreateMode cm = CreateMode.fromFlag(99);
+            Assert.fail("Shouldn't be able to convert 99 to a CreateMode.");
+        } catch(KeeperException ke) {
+            Assert.assertEquals(Code.BADARGUMENTS, ke.code());
+        }
+
+        try {
+            CreateMode cm = CreateMode.fromFlag(-1);
+            Assert.fail("Shouldn't be able to convert -1 to a CreateMode.");
+        } catch(KeeperException ke) {
+            Assert.assertEquals(Code.BADARGUMENTS, ke.code());
+        }
+    }
+}


[27/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientBase.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientBase.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientBase.java
deleted file mode 100644
index 7de4f3c..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientBase.java
+++ /dev/null
@@ -1,757 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.client.FourLetterWordMain.send4LetterWord;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.management.MBeanServerConnection;
-import javax.management.ObjectName;
-
-import junit.framework.TestCase;
-
-import org.apache.zookeeper.common.Time;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.common.IOUtils;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.ServerCnxnFactoryAccessor;
-import org.apache.zookeeper.server.ZKDatabase;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.apache.zookeeper.server.persistence.FilePadding;
-import org.apache.zookeeper.server.persistence.FileTxnLog;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.util.OSMXBean;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class ClientBase extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(ClientBase.class);
-
-    public static int CONNECTION_TIMEOUT = 30000;
-    static final File BASETEST =
-        new File(System.getProperty("build.test.dir", "build"));
-
-    protected int port = PortAssignment.unique();
-    protected String hostPort = "127.0.0.1:" + port;
-    protected String ipv6HostPort = "[0:0:0:0:0:0:0:1]:" + port;
-    protected int maxCnxns = 0;
-    protected ServerCnxnFactory serverFactory = null;
-    protected File tmpDir = null;
-    
-    long initialFdCount;
-    
-    public ClientBase() {
-        super();
-    }
-
-    /**
-     * In general don't use this. Only use in the special case that you
-     * want to ignore results (for whatever reason) in your test. Don't
-     * use empty watchers in real code!
-     *
-     */
-    protected class NullWatcher implements Watcher {
-        public void process(WatchedEvent event) { /* nada */ }
-    }
-
-    public static class CountdownWatcher implements Watcher {
-        // XXX this doesn't need to be volatile! (Should probably be final)
-        volatile CountDownLatch clientConnected;
-        // Set to true when connected to a read-only server, or a read-write (quorum) server.
-        volatile boolean connected;
-        // Set to true when connected to a quorum server.
-        volatile boolean syncConnected;
-        // Set to true when connected to a quorum server in read-only mode
-        volatile boolean readOnlyConnected;
-
-        public CountdownWatcher() {
-            reset();
-        }
-        synchronized public void reset() {
-            clientConnected = new CountDownLatch(1);
-            connected = false;
-            syncConnected = false;
-            readOnlyConnected = false;
-        }
-        synchronized public void process(WatchedEvent event) {
-            KeeperState state = event.getState();
-            if (state == KeeperState.SyncConnected) {
-                connected = true;
-                syncConnected = true;
-                readOnlyConnected = false;
-            } else if (state == KeeperState.ConnectedReadOnly) {
-                connected = true;
-                syncConnected = false;
-                readOnlyConnected = true;
-            } else {
-                connected = false;
-                syncConnected = false;
-                readOnlyConnected = false;
-            }
-
-            notifyAll();
-            if (connected) {
-                clientConnected.countDown();
-            }
-        }
-        synchronized public boolean isConnected() {
-            return connected;
-        }
-        synchronized public void waitForConnected(long timeout)
-            throws InterruptedException, TimeoutException
-        {
-            long expire = Time.currentElapsedTime() + timeout;
-            long left = timeout;
-            while(!connected && left > 0) {
-                wait(left);
-                left = expire - Time.currentElapsedTime();
-            }
-            if (!connected) {
-                throw new TimeoutException("Did not connect");
-
-            }
-        }
-        synchronized public void waitForSyncConnected(long timeout)
-                throws InterruptedException, TimeoutException
-        {
-            long expire = System.currentTimeMillis() + timeout;
-            long left = timeout;
-            while(!syncConnected && left > 0) {
-                wait(left);
-                left = expire - System.currentTimeMillis();
-            }
-            if (!syncConnected) {
-                throw new TimeoutException("Failed to connect to read-write ZooKeeper server.");
-            }
-        }
-        synchronized public void waitForReadOnlyConnected(long timeout)
-                throws InterruptedException, TimeoutException
-        {
-            long expire = System.currentTimeMillis() + timeout;
-            long left = timeout;
-            while(!readOnlyConnected && left > 0) {
-                wait(left);
-                left = expire - System.currentTimeMillis();
-            }
-            if (!readOnlyConnected) {
-                throw new TimeoutException("Failed to connect in read-only mode to ZooKeeper server.");
-            }
-        }
-        synchronized public void waitForDisconnected(long timeout)
-            throws InterruptedException, TimeoutException
-        {
-            long expire = Time.currentElapsedTime() + timeout;
-            long left = timeout;
-            while(connected && left > 0) {
-                wait(left);
-                left = expire - Time.currentElapsedTime();
-            }
-            if (connected) {
-                throw new TimeoutException("Did not disconnect");
-
-            }
-        }
-    }
-
-    protected TestableZooKeeper createClient()
-        throws IOException, InterruptedException
-    {
-        return createClient(hostPort);
-    }
-
-    protected TestableZooKeeper createClient(String hp)
-        throws IOException, InterruptedException
-    {
-        CountdownWatcher watcher = new CountdownWatcher();
-        return createClient(watcher, hp);
-    }
-
-    protected TestableZooKeeper createClient(CountdownWatcher watcher)
-        throws IOException, InterruptedException
-    {
-        return createClient(watcher, hostPort);
-    }
-
-    private LinkedList<ZooKeeper> allClients;
-    private boolean allClientsSetup = false;
-
-    protected TestableZooKeeper createClient(CountdownWatcher watcher, String hp)
-        throws IOException, InterruptedException
-    {
-        return createClient(watcher, hp, CONNECTION_TIMEOUT);
-    }
-
-    protected TestableZooKeeper createClient(CountdownWatcher watcher,
-            String hp, int timeout)
-        throws IOException, InterruptedException
-    {
-        watcher.reset();
-        TestableZooKeeper zk = new TestableZooKeeper(hp, timeout, watcher);
-        if (!watcher.clientConnected.await(timeout, TimeUnit.MILLISECONDS))
-        {
-            Assert.fail("Unable to connect to server");
-        }
-        synchronized(this) {
-            if (!allClientsSetup) {
-                LOG.error("allClients never setup");
-                Assert.fail("allClients never setup");
-            }
-            if (allClients != null) {
-                allClients.add(zk);
-                JMXEnv.ensureAll(getHexSessionId(zk.getSessionId()));
-            } else {
-                // test done - close the zk, not needed
-                zk.close();
-            }
-        }
-
-        return zk;
-    }
-
-    public static class HostPort {
-        String host;
-        int port;
-        public HostPort(String host, int port) {
-            this.host = host;
-            this.port = port;
-        }
-    }
-    public static List<HostPort> parseHostPortList(String hplist) {
-        ArrayList<HostPort> alist = new ArrayList<HostPort>();
-        for (String hp: hplist.split(",")) {
-            int idx = hp.lastIndexOf(':');
-            String host = hp.substring(0, idx);
-            int port;
-            try {
-                port = Integer.parseInt(hp.substring(idx + 1));
-            } catch(RuntimeException e) {
-                throw new RuntimeException("Problem parsing " + hp + e.toString());
-            }
-            alist.add(new HostPort(host,port));
-        }
-        return alist;
-    }
-
-    public static boolean waitForServerUp(String hp, long timeout) {
-        long start = Time.currentElapsedTime();
-        while (true) {
-            try {
-                // if there are multiple hostports, just take the first one
-                HostPort hpobj = parseHostPortList(hp).get(0);
-                String result = send4LetterWord(hpobj.host, hpobj.port, "stat");
-                if (result.startsWith("Zookeeper version:") &&
-                        !result.contains("READ-ONLY")) {
-                    return true;
-                }
-            } catch (IOException e) {
-                // ignore as this is expected
-                LOG.info("server " + hp + " not up " + e);
-            }
-
-            if (Time.currentElapsedTime() > start + timeout) {
-                break;
-            }
-            try {
-                Thread.sleep(250);
-            } catch (InterruptedException e) {
-                // ignore
-            }
-        }
-        return false;
-    }
-    public static boolean waitForServerDown(String hp, long timeout) {
-        long start = Time.currentElapsedTime();
-        while (true) {
-            try {
-                HostPort hpobj = parseHostPortList(hp).get(0);
-                send4LetterWord(hpobj.host, hpobj.port, "stat");
-            } catch (IOException e) {
-                return true;
-            }
-
-            if (Time.currentElapsedTime() > start + timeout) {
-                break;
-            }
-            try {
-                Thread.sleep(250);
-            } catch (InterruptedException e) {
-                // ignore
-            }
-        }
-        return false;
-    }
-
-    public static boolean waitForServerState(QuorumPeer qp, int timeout,
-            String serverState) {
-        long start = Time.currentElapsedTime();
-        while (true) {
-            try {
-                Thread.sleep(250);
-            } catch (InterruptedException e) {
-                // ignore
-            }
-            if (qp.getServerState().equals(serverState))
-                return true;
-            if (Time.currentElapsedTime() > start + timeout) {
-                return false;
-            }
-        }
-    }
-
-    static void verifyThreadTerminated(Thread thread, long millis)
-        throws InterruptedException
-    {
-        thread.join(millis);
-        if (thread.isAlive()) {
-            LOG.error("Thread " + thread.getName() + " : "
-                    + Arrays.toString(thread.getStackTrace()));
-            Assert.assertFalse("thread " + thread.getName()
-                    + " still alive after join", true);
-        }
-    }
-
-    public static File createEmptyTestDir() throws IOException {
-        return createTmpDir(BASETEST, false);
-    }
-
-    public static File createTmpDir() throws IOException {
-        return createTmpDir(BASETEST, true);
-    }
-
-    static File createTmpDir(File parentDir, boolean createInitFile) throws IOException {
-        File tmpFile = File.createTempFile("test", ".junit", parentDir);
-        // don't delete tmpFile - this ensures we don't attempt to create
-        // a tmpDir with a duplicate name
-        File tmpDir = new File(tmpFile + ".dir");
-        Assert.assertFalse(tmpDir.exists()); // never true if tmpfile does it's job
-        Assert.assertTrue(tmpDir.mkdirs());
-
-        // todo not every tmp directory needs this file
-        if (createInitFile) {
-            createInitializeFile(tmpDir);
-        }
-
-        return tmpDir;
-    }
-
-    public static void createInitializeFile(File dir) throws IOException {
-        File initFile = new File(dir, "initialize");
-        if (!initFile.exists()) {
-            Assert.assertTrue(initFile.createNewFile());
-        }
-    }
-
-    private static int getPort(String hostPort) {
-        String[] split = hostPort.split(":");
-        String portstr = split[split.length-1];
-        String[] pc = portstr.split("/");
-        if (pc.length > 1) {
-            portstr = pc[0];
-        }
-        return Integer.parseInt(portstr);
-    }
-
-    /**
-     * Starting the given server instance
-     */
-    public static void startServerInstance(File dataDir,
-            ServerCnxnFactory factory, String hostPort) throws IOException,
-            InterruptedException {
-        final int port = getPort(hostPort);
-        LOG.info("STARTING server instance 127.0.0.1:{}", port);
-        ZooKeeperServer zks = new ZooKeeperServer(dataDir, dataDir, 3000);
-        factory.startup(zks);
-        Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(
-                "127.0.0.1:" + port, CONNECTION_TIMEOUT));
-    }
-
-    /**
-     * This method instantiates a new server. Starting of the server
-     * instance has been moved to a separate method
-     * {@link ClientBase#startServerInstance(File, ServerCnxnFactory, String)}.
-     * Because any exception on starting the server would leave the server
-     * running and the caller would not be able to shutdown the instance. This
-     * may affect other test cases.
-     * 
-     * @return newly created server instance
-     * 
-     * @see <a
-     *      href="https://issues.apache.org/jira/browse/ZOOKEEPER-1852">ZOOKEEPER-1852</a>
-     *      for more information.
-     */
-    public static ServerCnxnFactory createNewServerInstance(
-            ServerCnxnFactory factory, String hostPort, int maxCnxns)
-            throws IOException, InterruptedException {
-        final int port = getPort(hostPort);
-        LOG.info("CREATING server instance 127.0.0.1:{}", port);
-        if (factory == null) {
-            factory = ServerCnxnFactory.createFactory(port, maxCnxns);
-        }
-        return factory;
-    }
-
-    static void shutdownServerInstance(ServerCnxnFactory factory,
-            String hostPort)
-    {
-        if (factory != null) {
-            ZKDatabase zkDb = null;
-            {
-                ZooKeeperServer zs = getServer(factory);
-                if (zs != null) {
-                    zkDb = zs.getZKDatabase();
-                }
-            }
-            factory.shutdown();
-            try {
-                if (zkDb != null) {
-                    zkDb.close();
-                }
-            } catch (IOException ie) {
-                LOG.warn("Error closing logs ", ie);
-            }
-            final int PORT = getPort(hostPort);
-
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown("127.0.0.1:" + PORT,
-                                                    CONNECTION_TIMEOUT));
-        }
-    }
-
-    /**
-     * Test specific setup
-     */
-    public static void setupTestEnv() {
-        // during the tests we run with 100K prealloc in the logs.
-        // on windows systems prealloc of 64M was seen to take ~15seconds
-        // resulting in test Assert.failure (client timeout on first session).
-        // set env and directly in order to handle static init/gc issues
-        System.setProperty("zookeeper.preAllocSize", "100");
-        FilePadding.setPreallocSize(100 * 1024);
-    }
-
-    protected void setUpAll() throws Exception {
-        allClients = new LinkedList<ZooKeeper>();
-        allClientsSetup = true;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        /* some useful information - log the number of fds used before
-         * and after a test is run. Helps to verify we are freeing resources
-         * correctly. Unfortunately this only works on unix systems (the
-         * only place sun has implemented as part of the mgmt bean api.
-         */
-        OSMXBean osMbean = new OSMXBean();
-        if (osMbean.getUnix() == true) {
-            initialFdCount = osMbean.getOpenFileDescriptorCount();  	
-            LOG.info("Initial fdcount is: "
-                    + initialFdCount);
-        }
-
-        setupTestEnv();
-
-        JMXEnv.setUp();
-
-        setUpAll();
-
-        tmpDir = createTmpDir(BASETEST, true);
-
-        startServer();
-
-        LOG.info("Client test setup finished");
-    }
-
-    protected void startServer() throws Exception {
-        LOG.info("STARTING server");
-        serverFactory = createNewServerInstance(serverFactory, hostPort,
-                maxCnxns);
-        startServerInstance(tmpDir, serverFactory, hostPort);
-        // ensure that server and data bean are registered
-        Set<ObjectName> children = JMXEnv.ensureParent("InMemoryDataTree",
-                "StandaloneServer_port");
-        // Remove beans which are related to zk client sessions. Strong
-        // assertions cannot be done for these client sessions because
-        // registeration of these beans with server will happen only on their
-        // respective reconnection interval
-        verifyUnexpectedBeans(children);
-    }
-
-    private void verifyUnexpectedBeans(Set<ObjectName> children) {
-        if (allClients != null) {
-            for (ZooKeeper zkc : allClients) {
-                Iterator<ObjectName> childItr = children.iterator();
-                while (childItr.hasNext()) {
-                    ObjectName clientBean = childItr.next();
-                    if (clientBean.toString().contains(
-                            getHexSessionId(zkc.getSessionId()))) {
-                        LOG.info("found name:" + zkc.getSessionId()
-                                + " client bean:" + clientBean.toString());
-                        childItr.remove();
-                    }
-                }
-            }
-        }
-        for (ObjectName bean : children) {
-            LOG.info("unexpected:" + bean.toString());
-        }
-        TestCase.assertEquals("Unexpected bean exists!", 0, children.size());
-    }
-
-    /**
-     * Returns a string representation of the given long value session id
-     * 
-     * @param sessionId
-     *            long value of session id
-     * @return string representation of session id
-     */
-    protected static String getHexSessionId(long sessionId) {
-        return "0x" + Long.toHexString(sessionId);
-    }
-
-    protected void stopServer() throws Exception {
-        LOG.info("STOPPING server");
-        shutdownServerInstance(serverFactory, hostPort);
-        serverFactory = null;
-        // ensure no beans are leftover
-        JMXEnv.ensureOnly();
-    }
-
-
-    protected static ZooKeeperServer getServer(ServerCnxnFactory fac) {
-        ZooKeeperServer zs = ServerCnxnFactoryAccessor.getZkServer(fac);
-
-        return zs;
-    }
-
-    protected void tearDownAll() throws Exception {
-        synchronized (this) {
-            if (allClients != null) for (ZooKeeper zk : allClients) {
-                try {
-                    if (zk != null)
-                        zk.close();
-                } catch (InterruptedException e) {
-                    LOG.warn("ignoring interrupt", e);
-                }
-            }
-            allClients = null;
-        }
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        LOG.info("tearDown starting");
-
-        tearDownAll();
-
-        stopServer();
-
-        if (tmpDir != null) {
-            Assert.assertTrue("delete " + tmpDir.toString(), recursiveDelete(tmpDir));
-        }
-
-        // This has to be set to null when the same instance of this class is reused between test cases
-        serverFactory = null;
-
-        JMXEnv.tearDown();
-
-        /* some useful information - log the number of fds used before
-         * and after a test is run. Helps to verify we are freeing resources
-         * correctly. Unfortunately this only works on unix systems (the
-         * only place sun has implemented as part of the mgmt bean api.
-         */
-        OSMXBean osMbean = new OSMXBean();
-        if (osMbean.getUnix() == true) {
-            long fdCount = osMbean.getOpenFileDescriptorCount();     
-            String message = "fdcount after test is: "
-                    + fdCount + " at start it was " + initialFdCount;
-            LOG.info(message);
-            if (fdCount > initialFdCount) {
-                LOG.info("sleeping for 20 secs");
-                //Thread.sleep(60000);
-                //assertTrue(message, fdCount <= initialFdCount);
-            }
-        }
-    }
-
-    public static MBeanServerConnection jmxConn() throws IOException {
-        return JMXEnv.conn();
-    }
-
-    public static boolean recursiveDelete(File d) {
-        if (d.isDirectory()) {
-            File children[] = d.listFiles();
-            for (File f : children) {
-                Assert.assertTrue("delete " + f.toString(), recursiveDelete(f));
-            }
-        }
-        return d.delete();
-    }
-
-    public static void logAllStackTraces() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Starting logAllStackTraces()\n");
-        Map<Thread, StackTraceElement[]> threads = Thread.getAllStackTraces();
-        for (Entry<Thread, StackTraceElement[]> e: threads.entrySet()) {
-            sb.append("Thread " + e.getKey().getName() + "\n");
-            for (StackTraceElement elem: e.getValue()) {
-                sb.append("\tat " + elem + "\n");
-            }
-        }
-        sb.append("Ending logAllStackTraces()\n");
-        LOG.error(sb.toString());
-    }
-
-    /*
-     * Verify that all of the servers see the same number of nodes
-     * at the root
-     */
-    void verifyRootOfAllServersMatch(String hostPort)
-        throws InterruptedException, KeeperException, IOException
-    {
-        String parts[] = hostPort.split(",");
-
-        // run through till the counts no longer change on each server
-        // max 15 tries, with 2 second sleeps, so approx 30 seconds
-        int[] counts = new int[parts.length];
-        int failed = 0;
-        for (int j = 0; j < 100; j++) {
-            int newcounts[] = new int[parts.length];
-            int i = 0;
-            for (String hp : parts) {
-                try {
-                    ZooKeeper zk = createClient(hp);
-
-                    try {
-                        newcounts[i++] = zk.getChildren("/", false).size();
-                    } finally {
-                        zk.close();
-                    }
-                } catch (Throwable t) {
-                    failed++;
-                    // if session creation Assert.fails dump the thread stack
-                    // and try the next server
-                    logAllStackTraces();
-                }
-            }
-
-            if (Arrays.equals(newcounts, counts)) {
-                LOG.info("Found match with array:"
-                        + Arrays.toString(newcounts));
-                counts = newcounts;
-                break;
-            } else {
-                counts = newcounts;
-                Thread.sleep(10000);
-            }
-
-            // don't keep this up too long, will Assert.assert false below
-            if (failed > 10) {
-                break;
-            }
-        }
-
-        // verify all the servers reporting same number of nodes
-        String logmsg = "node count not consistent{} {}";
-        for (int i = 1; i < parts.length; i++) {
-            if (counts[i-1] != counts[i]) {            	
-                LOG.error(logmsg, Integer.valueOf(counts[i-1]), Integer.valueOf(counts[i]));
-            } else {
-                LOG.info(logmsg, Integer.valueOf(counts[i-1]), Integer.valueOf(counts[i]));
-            }
-        }
-    }
-
-    public static String readFile(File file) throws IOException {
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
-        try {
-            IOUtils.copyBytes(is, os, 1024, true);
-        } finally {
-            is.close();
-        }
-        return os.toString();
-    }
-
-    public static String join(String separator, Object[] parts) {
-        StringBuilder sb = new StringBuilder();
-        boolean first = true;
-        for (Object part : parts) {
-            if (!first) {
-                sb.append(separator);
-                first = false;
-            }
-            sb.append(part);
-        }
-        return sb.toString();
-    }
-
-    public static ZooKeeper createZKClient(String cxnString) throws Exception {
-        return createZKClient(cxnString, CONNECTION_TIMEOUT);
-    }
-
-    /**
-     * Returns ZooKeeper client after connecting to ZooKeeper Server. Session
-     * timeout is {@link #CONNECTION_TIMEOUT}
-     *
-     * @param cxnString
-     *            connection string in the form of host:port
-     * @param sessionTimeout
-     * @throws IOException
-     *             in cases of network failure
-     */
-    public static ZooKeeper createZKClient(String cxnString, int sessionTimeout) throws IOException {
-        CountdownWatcher watcher = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper(cxnString, sessionTimeout, watcher);
-        try {
-            watcher.waitForConnected(CONNECTION_TIMEOUT);
-        } catch (InterruptedException e) {
-            Assert.fail("ZooKeeper client can not connect to " + cxnString);
-        }
-        catch (TimeoutException e) {
-            Assert.fail("ZooKeeper client can not connect to " + cxnString);
-        }
-        return zk;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java
deleted file mode 100644
index 025ccbe..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientHammerTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.Date;
-import java.util.List;
-
-import org.apache.zookeeper.common.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ClientHammerTest extends ClientBase {
-    protected static final Logger LOG = LoggerFactory.getLogger(ClientHammerTest.class);
-
-    private static final long HAMMERTHREAD_LATENCY = 5;
-
-    private static abstract class HammerThread extends Thread {
-        protected final int count;
-        protected volatile int current = 0;
-
-        HammerThread(String name, int count) {
-            super(name);
-            this.count = count;
-        }
-    }
-
-    private static class BasicHammerThread extends HammerThread {
-        private final ZooKeeper zk;
-        private final String prefix;
-
-        BasicHammerThread(String name, ZooKeeper zk, String prefix, int count) {
-            super(name, count);
-            this.zk = zk;
-            this.prefix = prefix;
-        }
-
-        public void run() {
-            byte b[] = new byte[256];
-            try {
-                for (; current < count; current++) {
-                    // Simulate a bit of network latency...
-                    Thread.sleep(HAMMERTHREAD_LATENCY);
-                    zk.create(prefix + current, b, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-                }
-            } catch (Throwable t) {
-                LOG.error("Client create operation Assert.failed", t);
-            } finally {
-                try {
-                    zk.close();
-                } catch (InterruptedException e) {
-                    LOG.warn("Unexpected", e);
-                }
-            }
-        }
-    }
-
-    private static class SuperHammerThread extends HammerThread {
-        private final ClientHammerTest parent;
-        private final String prefix;
-
-        SuperHammerThread(String name, ClientHammerTest parent, String prefix,
-                int count)
-        {
-            super(name, count);
-            this.parent = parent;
-            this.prefix = prefix;
-        }
-
-        public void run() {
-            byte b[] = new byte[256];
-            try {
-                for (; current < count; current++) {
-                    ZooKeeper zk = parent.createClient();
-                    try {
-                        zk.create(prefix + current, b, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-                    } finally {
-                        try {
-                            zk.close();
-                        } catch (InterruptedException e) {
-                            LOG.warn("Unexpected", e);
-                        }
-                    }
-                }
-            } catch (Throwable t) {
-                LOG.error("Client create operation Assert.failed", t);
-            }
-        }
-    }
-
-    /**
-     * Separate threads each creating a number of nodes. Each thread
-     * is using a non-shared (owned by thread) client for all node creations.
-     * @throws Throwable
-     */
-    @Test
-    public void testHammerBasic() throws Throwable {
-        runHammer(10, 1000);
-    }
-
-    public void runHammer(final int threadCount, final int childCount)
-        throws Throwable
-    {
-        try {
-            HammerThread[] threads = new HammerThread[threadCount];
-            long start = Time.currentElapsedTime();
-            for (int i = 0; i < threads.length; i++) {
-                ZooKeeper zk = createClient();
-                String prefix = "/test-" + i;
-                zk.create(prefix, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-                prefix += "/";
-                HammerThread thread =
-                    new BasicHammerThread("BasicHammerThread-" + i, zk, prefix,
-                            childCount);
-                thread.start();
-
-                threads[i] = thread;
-            }
-
-            verifyHammer(start, threads, childCount);
-        } catch (Throwable t) {
-            LOG.error("test Assert.failed", t);
-            throw t;
-        }
-    }
-
-    /**
-     * Separate threads each creating a number of nodes. Each thread
-     * is creating a new client for each node creation.
-     * @throws Throwable
-     */
-    @Test
-    public void testHammerSuper() throws Throwable {
-        try {
-            final int threadCount = 5;
-            final int childCount = 10;
-
-            HammerThread[] threads = new HammerThread[threadCount];
-            long start = Time.currentElapsedTime();
-            for (int i = 0; i < threads.length; i++) {
-                String prefix = "/test-" + i;
-                {
-                    ZooKeeper zk = createClient();
-                    try {
-                        zk.create(prefix, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-                    } finally {
-                        zk.close();
-                    }
-                }
-                prefix += "/";
-                HammerThread thread =
-                    new SuperHammerThread("SuperHammerThread-" + i, this,
-                            prefix, childCount);
-                thread.start();
-
-                threads[i] = thread;
-            }
-
-            verifyHammer(start, threads, childCount);
-        } catch (Throwable t) {
-            LOG.error("test Assert.failed", t);
-            throw t;
-        }
-    }
-
-    public void verifyHammer(long start, HammerThread[] threads, int childCount)
-        throws IOException, InterruptedException, KeeperException
-    {
-        // look for the clients to finish their create operations
-        LOG.info("Starting check for completed hammers");
-        int workingCount = threads.length;
-        for (int i = 0; i < 120; i++) {
-            Thread.sleep(10000);
-            for (HammerThread h : threads) {
-                if (!h.isAlive() || h.current == h.count) {
-                    workingCount--;
-                }
-            }
-            if (workingCount == 0) {
-                break;
-            }
-            workingCount = threads.length;
-        }
-        if (workingCount > 0) {
-            for (HammerThread h : threads) {
-                LOG.warn(h.getName() + " never finished creation, current:"
-                        + h.current);
-            }
-        } else {
-            LOG.info("Hammer threads completed creation operations");
-        }
-
-        for (HammerThread h : threads) {
-            final int safetyFactor = 3;
-            verifyThreadTerminated(h,
-                    threads.length * childCount
-                    * HAMMERTHREAD_LATENCY * safetyFactor);
-        }
-        LOG.info(new Date() + " Total time "
-                + (Time.currentElapsedTime() - start));
-
-        ZooKeeper zk = createClient();
-        try {
-            LOG.info("******************* Connected to ZooKeeper" + new Date());
-            for (int i = 0; i < threads.length; i++) {
-                LOG.info("Doing thread: " + i + " " + new Date());
-                List<String> children =
-                    zk.getChildren("/test-" + i, false);
-                Assert.assertEquals(childCount, children.size());
-                children = zk.getChildren("/test-" + i, false, null);
-                Assert.assertEquals(childCount, children.size());
-            }
-            for (int i = 0; i < threads.length; i++) {
-                List<String> children =
-                    zk.getChildren("/test-" + i, false);
-                Assert.assertEquals(childCount, children.size());
-                children = zk.getChildren("/test-" + i, false, null);
-                Assert.assertEquals(childCount, children.size());
-            }
-        } finally {
-            zk.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java
deleted file mode 100644
index 95c55e2..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientPortBindTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Enumeration;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ClientPortBindTest extends ZKTestCase implements Watcher {
-    protected static final Logger LOG = 
-        LoggerFactory.getLogger(ClientPortBindTest.class);
-
-    private volatile CountDownLatch startSignal;
-
-    /**
-     * Verify that the server binds to the specified address
-     */
-    @Test
-    public void testBindByAddress() throws Exception {
-        String bindAddress = null;
-        Enumeration<NetworkInterface> intfs =
-            NetworkInterface.getNetworkInterfaces();
-        // if we have a loopback and it has an address use it
-        while(intfs.hasMoreElements()) {
-            NetworkInterface i = intfs.nextElement();
-            try {
-                if (i.isLoopback()) {
-                  Enumeration<InetAddress> addrs = i.getInetAddresses();
-                  while (addrs.hasMoreElements()) {
-                    InetAddress a = addrs.nextElement();
-                    if(a.isLoopbackAddress()) {
-                      bindAddress = a.getHostAddress();
-                      break;
-                    }
-                  }
-                }
-            } catch (SocketException se) {
-                LOG.warn("Couldn't find  loopback interface: " + se.getMessage());
-            }
-        }
-        if (bindAddress == null) {
-            LOG.warn("Unable to determine loop back address, skipping test");
-            return;
-        }
-        final int PORT = PortAssignment.unique();
-
-        LOG.info("Using " + bindAddress + " as the bind address");
-        final String HOSTPORT = bindAddress + ":" + PORT;
-        LOG.info("Using " + HOSTPORT + " as the host/port");
-
-
-        File tmpDir = ClientBase.createTmpDir();
-
-        ClientBase.setupTestEnv();
-        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(
-                new InetSocketAddress(bindAddress, PORT), -1);
-        f.startup(zks);
-        LOG.info("starting up the the server, waiting");
-
-        Assert.assertTrue("waiting for server up",
-                   ClientBase.waitForServerUp(HOSTPORT,
-                                   CONNECTION_TIMEOUT));
-
-        startSignal = new CountDownLatch(1);
-        ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
-        try {
-            boolean isZero = startSignal.await(CONNECTION_TIMEOUT,
-                    TimeUnit.MILLISECONDS);
-            Assert.assertTrue("count == " + startSignal.getCount(), isZero);
-            zk.close();
-        } finally {
-            f.shutdown();
-            zks.shutdown();
-
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown(HOSTPORT,
-                                                    CONNECTION_TIMEOUT));
-        }
-    }
-
-    public void process(WatchedEvent event) {
-        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
-        if (event.getState() == KeeperState.SyncConnected
-                && startSignal != null && startSignal.getCount() > 0)
-        {
-            startSignal.countDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientRetry.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientRetry.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientRetry.java
deleted file mode 100644
index d0b6b43..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientRetry.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooKeeper.States;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ClientRetry extends ClientBase {
-
-    @Override
-    public void setUp() throws Exception {
-        maxCnxns = 1;
-        super.setUp();
-    }
-    /*
-     * This is a simple test - try to connect two clients to a server
-     * accepting a maximum of one connection from each address. Check that
-     * only one is accepted. Close that connection, and check that the other
-     * eventually connects.
-     *
-     * There is a possibility of a false positive here, as when zk2 is tested
-     * for having connected it might not have been given enough time, and finish
-     * connecting after the test is done. Since the
-     * server doesn't tell the client why it hasn't connected, there's no
-     * obvious way to detect the difference.
-     */
-    @Test
-    public void testClientRetry() throws IOException, InterruptedException, TimeoutException{
-        CountdownWatcher cdw1 = new CountdownWatcher();
-        CountdownWatcher cdw2 = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper(hostPort, 10000, cdw1);
-        try {
-            cdw1.waitForConnected(CONNECTION_TIMEOUT);
-            ZooKeeper zk2 = new ZooKeeper(hostPort, 10000, cdw2);
-            try {
-                States s1 = zk.getState();
-                States s2 = zk2.getState();
-                Assert.assertSame(s1,States.CONNECTED);
-                Assert.assertSame(s2,States.CONNECTING);
-                cdw1.reset();
-                cdw1.waitForDisconnected(CONNECTION_TIMEOUT);
-                cdw2.waitForConnected(CONNECTION_TIMEOUT);
-                Assert.assertSame(zk2.getState(),States.CONNECTED);
-            } finally {
-                zk2.close();
-            }
-        } finally {
-            zk.close();
-        }
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientTest.java
deleted file mode 100644
index 9dc4861..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ClientTest.java
+++ /dev/null
@@ -1,805 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.KeeperException.Code;
-import org.apache.zookeeper.KeeperException.InvalidACLException;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooDefs.Perms;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Id;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.proto.ExistsRequest;
-import org.apache.zookeeper.proto.ExistsResponse;
-import org.apache.zookeeper.proto.ReplyHeader;
-import org.apache.zookeeper.proto.RequestHeader;
-import org.apache.zookeeper.server.PrepRequestProcessor;
-import org.apache.zookeeper.server.util.OSMXBean;
-import org.junit.Assert;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClientTest extends ClientBase {
-    protected static final Logger LOG = LoggerFactory.getLogger(ClientTest.class);
-
-    /** Verify that pings are sent, keeping the "idle" client alive */
-    @Test
-    public void testPing() throws Exception {
-        ZooKeeper zkIdle = null;
-        ZooKeeper zkWatchCreator = null;
-        try {
-            CountdownWatcher watcher = new CountdownWatcher();
-            zkIdle = createClient(watcher, hostPort, 10000);
-
-            zkWatchCreator = createClient();
-
-            for (int i = 0; i < 10; i++) {
-                zkWatchCreator.create("/" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-            }
-            for (int i = 0; i < 10; i++) {
-                zkIdle.exists("/" + i, true);
-            }
-            for (int i = 0; i < 10; i++) {
-                Thread.sleep(1000);
-                zkWatchCreator.delete("/" + i, -1);
-            }
-            // The bug will manifest itself here because zkIdle will expire
-            zkIdle.exists("/0", false);
-        } finally {
-            if (zkIdle != null) {
-                zkIdle.close();
-            }
-            if (zkWatchCreator != null) {
-                zkWatchCreator.close();
-            }
-        }
-    }
-
-    @Test
-    public void testClientwithoutWatcherObj() throws IOException,
-            InterruptedException, KeeperException
-    {
-        performClientTest(false, hostPort);
-    }
-
-    @Test
-    public void testClientWithWatcherObj() throws IOException,
-            InterruptedException, KeeperException
-    {
-        performClientTest(true, hostPort);
-    }
-
-    @Test
-    public void testClientWithIPv6Address() throws IOException,
-            InterruptedException, KeeperException
-    {
-        assumeIPv6Available();
-        performClientTest(true, ipv6HostPort);
-    }
-
-    /** Exercise the testable functions, verify tostring, etc... */
-    @Test
-    public void testTestability() throws Exception {
-        TestableZooKeeper zk = createClient();
-        try {
-            LOG.info("{}",zk.testableLocalSocketAddress());
-            LOG.info("{}",zk.testableRemoteSocketAddress());
-            LOG.info("{}",zk.toString());
-        } finally {
-            zk.close();
-            zk.testableWaitForShutdown(CONNECTION_TIMEOUT);
-            LOG.info("{}",zk.testableLocalSocketAddress());
-            LOG.info("{}",zk.testableRemoteSocketAddress());
-            LOG.info("{}",zk.toString());
-        }
-    }
-
-    @Test
-    public void testACLs() throws Exception {
-        ZooKeeper zk = null;
-        try {
-            zk = createClient();
-            try {
-                zk.create("/acltest", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-                Assert.fail("Should have received an invalid acl error");
-            } catch(InvalidACLException e) {
-                LOG.info("Test successful, invalid acl received : "
-                        + e.getMessage());
-            }
-            try {
-                ArrayList<ACL> testACL = new ArrayList<ACL>();
-                testACL.add(new ACL(Perms.ALL | Perms.ADMIN, Ids.AUTH_IDS));
-                testACL.add(new ACL(Perms.ALL | Perms.ADMIN, new Id("ip", "127.0.0.1/8")));
-                zk.create("/acltest", new byte[0], testACL, CreateMode.PERSISTENT);
-                Assert.fail("Should have received an invalid acl error");
-            } catch(InvalidACLException e) {
-                LOG.info("Test successful, invalid acl received : "
-                        + e.getMessage());
-            }
-            zk.addAuthInfo("digest", "ben:passwd".getBytes());
-            zk.create("/acltest", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-            zk.close();
-            zk = createClient();
-            zk.addAuthInfo("digest", "ben:passwd2".getBytes());
-            try {
-                zk.getData("/acltest", false, new Stat());
-                Assert.fail("Should have received a permission error");
-            } catch (KeeperException e) {
-                Assert.assertEquals(Code.NOAUTH, e.code());
-            }
-            zk.addAuthInfo("digest", "ben:passwd".getBytes());
-            zk.getData("/acltest", false, new Stat());
-            zk.setACL("/acltest", Ids.OPEN_ACL_UNSAFE, -1);
-            zk.close();
-            zk = createClient();
-            zk.getData("/acltest", false, new Stat());
-            List<ACL> acls = zk.getACL("/acltest", new Stat());
-            Assert.assertEquals(1, acls.size());
-            Assert.assertEquals(Ids.OPEN_ACL_UNSAFE, acls);
-
-            // The stat parameter should be optional.
-            acls = zk.getACL("/acltest", null);
-            Assert.assertEquals(1, acls.size());
-            Assert.assertEquals(Ids.OPEN_ACL_UNSAFE, acls);
-
-            zk.close();
-        } finally {
-            if (zk != null) {
-                zk.close();
-            }
-        }
-    }
-
-    private class MyWatcher extends CountdownWatcher {
-        LinkedBlockingQueue<WatchedEvent> events =
-            new LinkedBlockingQueue<WatchedEvent>();
-
-        public void process(WatchedEvent event) {
-            super.process(event);
-            if (event.getType() != EventType.None) {
-                try {
-                    events.put(event);
-                } catch (InterruptedException e) {
-                    LOG.warn("ignoring interrupt during event.put");
-                }
-            }
-        }
-    }
-
-    /**
-     * Register multiple watchers and verify that they all get notified and
-     * in the right order.
-     */
-    @Test
-    public void testMutipleWatcherObjs()
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk = createClient(new CountdownWatcher(), hostPort);
-        try {
-            MyWatcher watchers[] = new MyWatcher[100];
-            MyWatcher watchers2[] = new MyWatcher[watchers.length];
-            for (int i = 0; i < watchers.length; i++) {
-                watchers[i] = new MyWatcher();
-                watchers2[i] = new MyWatcher();
-                zk.create("/foo-" + i, ("foodata" + i).getBytes(),
-                        Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            }
-            Stat stat = new Stat();
-
-            //
-            // test get/exists with single set of watchers
-            //   get all, then exists all
-            //
-            for (int i = 0; i < watchers.length; i++) {
-                Assert.assertNotNull(zk.getData("/foo-" + i, watchers[i], stat));
-            }
-            for (int i = 0; i < watchers.length; i++) {
-                Assert.assertNotNull(zk.exists("/foo-" + i, watchers[i]));
-            }
-            // trigger the watches
-            for (int i = 0; i < watchers.length; i++) {
-                zk.setData("/foo-" + i, ("foodata2-" + i).getBytes(), -1);
-                zk.setData("/foo-" + i, ("foodata3-" + i).getBytes(), -1);
-            }
-            for (int i = 0; i < watchers.length; i++) {
-                WatchedEvent event =
-                    watchers[i].events.poll(10, TimeUnit.SECONDS);
-                Assert.assertEquals("/foo-" + i, event.getPath());
-                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
-                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
-
-                // small chance that an unexpected message was delivered
-                //  after this check, but we would catch that next time
-                //  we check events
-                Assert.assertEquals(0, watchers[i].events.size());
-            }
-
-            //
-            // test get/exists with single set of watchers
-            //  get/exists together
-            //
-            for (int i = 0; i < watchers.length; i++) {
-                Assert.assertNotNull(zk.getData("/foo-" + i, watchers[i], stat));
-                Assert.assertNotNull(zk.exists("/foo-" + i, watchers[i]));
-            }
-            // trigger the watches
-            for (int i = 0; i < watchers.length; i++) {
-                zk.setData("/foo-" + i, ("foodata4-" + i).getBytes(), -1);
-                zk.setData("/foo-" + i, ("foodata5-" + i).getBytes(), -1);
-            }
-            for (int i = 0; i < watchers.length; i++) {
-                WatchedEvent event =
-                    watchers[i].events.poll(10, TimeUnit.SECONDS);
-                Assert.assertEquals("/foo-" + i, event.getPath());
-                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
-                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
-
-                // small chance that an unexpected message was delivered
-                //  after this check, but we would catch that next time
-                //  we check events
-                Assert.assertEquals(0, watchers[i].events.size());
-            }
-
-            //
-            // test get/exists with two sets of watchers
-            //
-            for (int i = 0; i < watchers.length; i++) {
-                Assert.assertNotNull(zk.getData("/foo-" + i, watchers[i], stat));
-                Assert.assertNotNull(zk.exists("/foo-" + i, watchers2[i]));
-            }
-            // trigger the watches
-            for (int i = 0; i < watchers.length; i++) {
-                zk.setData("/foo-" + i, ("foodata6-" + i).getBytes(), -1);
-                zk.setData("/foo-" + i, ("foodata7-" + i).getBytes(), -1);
-            }
-            for (int i = 0; i < watchers.length; i++) {
-                WatchedEvent event =
-                    watchers[i].events.poll(10, TimeUnit.SECONDS);
-                Assert.assertEquals("/foo-" + i, event.getPath());
-                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
-                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
-
-                // small chance that an unexpected message was delivered
-                //  after this check, but we would catch that next time
-                //  we check events
-                Assert.assertEquals(0, watchers[i].events.size());
-
-                // watchers2
-                WatchedEvent event2 =
-                    watchers2[i].events.poll(10, TimeUnit.SECONDS);
-                Assert.assertEquals("/foo-" + i, event2.getPath());
-                Assert.assertEquals(EventType.NodeDataChanged, event2.getType());
-                Assert.assertEquals(KeeperState.SyncConnected, event2.getState());
-
-                // small chance that an unexpected message was delivered
-                //  after this check, but we would catch that next time
-                //  we check events
-                Assert.assertEquals(0, watchers2[i].events.size());
-            }
-
-        } finally {
-            if (zk != null) {
-                zk.close();
-            }
-        }
-    }
-
-    private void performClientTest(boolean withWatcherObj, String hostPort)
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk = null;
-        try {
-            MyWatcher watcher = new MyWatcher();
-            zk = createClient(watcher, hostPort);
-            LOG.info("Before create /benwashere");
-            zk.create("/benwashere", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            LOG.info("After create /benwashere");
-            try {
-                zk.setData("/benwashere", "hi".getBytes(), 57);
-                Assert.fail("Should have gotten BadVersion exception");
-            } catch(KeeperException.BadVersionException e) {
-                // expected that
-            } catch (KeeperException e) {
-                Assert.fail("Should have gotten BadVersion exception");
-            }
-            LOG.info("Before delete /benwashere");
-            zk.delete("/benwashere", 0);
-            LOG.info("After delete /benwashere");
-            zk.close();
-            //LOG.info("Closed client: " + zk.describeCNXN());
-            Thread.sleep(2000);
-
-            zk = createClient(watcher, hostPort);
-            //LOG.info("Created a new client: " + zk.describeCNXN());
-            LOG.info("Before delete /");
-
-            try {
-                zk.delete("/", -1);
-                Assert.fail("deleted root!");
-            } catch(KeeperException.BadArgumentsException e) {
-                // good, expected that
-            }
-            Stat stat = new Stat();
-            // Test basic create, ls, and getData
-            zk.create("/pat", "Pat was here".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            LOG.info("Before create /ben");
-            zk.create("/pat/ben", "Ben was here".getBytes(),
-                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            LOG.info("Before getChildren /pat");
-            List<String> children = zk.getChildren("/pat", false);
-            Assert.assertEquals(1, children.size());
-            Assert.assertEquals("ben", children.get(0));
-            List<String> children2 = zk.getChildren("/pat", false, null);
-            Assert.assertEquals(children, children2);
-            String value = new String(zk.getData("/pat/ben", false, stat));
-            Assert.assertEquals("Ben was here", value);
-            // Test stat and watch of non existent node
-
-            try {
-                if (withWatcherObj) {
-                    Assert.assertEquals(null, zk.exists("/frog", watcher));
-                } else {
-                    Assert.assertEquals(null, zk.exists("/frog", true));
-                }
-                LOG.info("Comment: asseting passed for frog setting /");
-            } catch (KeeperException.NoNodeException e) {
-                // OK, expected that
-            }
-            zk.create("/frog", "hi".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            // the first poll is just a session delivery
-            LOG.info("Comment: checking for events length "
-                     + watcher.events.size());
-            WatchedEvent event = watcher.events.poll(10, TimeUnit.SECONDS);
-            Assert.assertEquals("/frog", event.getPath());
-            Assert.assertEquals(EventType.NodeCreated, event.getType());
-            Assert.assertEquals(KeeperState.SyncConnected, event.getState());
-            // Test child watch and create with sequence
-            zk.getChildren("/pat/ben", true);
-            for (int i = 0; i < 10; i++) {
-                zk.create("/pat/ben/" + i + "-", Integer.toString(i).getBytes(),
-                        Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            }
-            children = zk.getChildren("/pat/ben", false);
-            Collections.sort(children);
-            Assert.assertEquals(10, children.size());
-            for (int i = 0; i < 10; i++) {
-                final String name = children.get(i);
-                Assert.assertTrue("starts with -", name.startsWith(i + "-"));
-                byte b[];
-                if (withWatcherObj) {
-                    b = zk.getData("/pat/ben/" + name, watcher, stat);
-                } else {
-                    b = zk.getData("/pat/ben/" + name, true, stat);
-                }
-                Assert.assertEquals(Integer.toString(i), new String(b));
-                zk.setData("/pat/ben/" + name, "new".getBytes(),
-                        stat.getVersion());
-                if (withWatcherObj) {
-                    stat = zk.exists("/pat/ben/" + name, watcher);
-                } else {
-                stat = zk.exists("/pat/ben/" + name, true);
-                }
-                zk.delete("/pat/ben/" + name, stat.getVersion());
-            }
-            event = watcher.events.poll(10, TimeUnit.SECONDS);
-            Assert.assertEquals("/pat/ben", event.getPath());
-            Assert.assertEquals(EventType.NodeChildrenChanged, event.getType());
-            Assert.assertEquals(KeeperState.SyncConnected, event.getState());
-            for (int i = 0; i < 10; i++) {
-                event = watcher.events.poll(10, TimeUnit.SECONDS);
-                final String name = children.get(i);
-                Assert.assertEquals("/pat/ben/" + name, event.getPath());
-                Assert.assertEquals(EventType.NodeDataChanged, event.getType());
-                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
-                event = watcher.events.poll(10, TimeUnit.SECONDS);
-                Assert.assertEquals("/pat/ben/" + name, event.getPath());
-                Assert.assertEquals(EventType.NodeDeleted, event.getType());
-                Assert.assertEquals(KeeperState.SyncConnected, event.getState());
-            }
-            zk.create("/good\u0040path", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-
-            zk.create("/duplicate", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            try {
-                zk.create("/duplicate", "".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT);
-                Assert.fail("duplicate create allowed");
-            } catch(KeeperException.NodeExistsException e) {
-                // OK, expected that
-            }
-        } finally {
-            if (zk != null) {
-                zk.close();
-            }
-        }
-    }
-    
-    // Test that sequential filenames are being created correctly,
-    // with 0-padding in the filename
-    @Test
-    public void testSequentialNodeNames()
-        throws IOException, InterruptedException, KeeperException
-    {
-        String path = "/SEQUENCE";
-        String file = "TEST";
-        String filepath = path + "/" + file;
-
-        ZooKeeper zk = null;
-        try {
-            zk = createClient();
-            zk.create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            List<String> children = zk.getChildren(path, false);
-            Assert.assertEquals(1, children.size());
-            Assert.assertEquals(file + "0000000000", children.get(0));
-
-            zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            children = zk.getChildren(path, false);
-            Assert.assertEquals(2, children.size());
-            Assert.assertTrue("contains child 1",  children.contains(file + "0000000001"));
-
-            zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            children = zk.getChildren(path, false);
-            Assert.assertEquals(3, children.size());
-            Assert.assertTrue("contains child 2",
-                       children.contains(file + "0000000002"));
-
-            // The pattern is holding so far.  Let's run the counter a bit
-            // to be sure it continues to spit out the correct answer
-            for(int i = children.size(); i < 105; i++)
-               zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-
-            children = zk.getChildren(path, false);
-            Assert.assertTrue("contains child 104",
-                       children.contains(file + "0000000104"));
-
-        }
-        finally {
-            if(zk != null)
-                zk.close();
-        }
-    }
-    
-    // Test that data provided when 
-    // creating sequential nodes is stored properly
-    @Test
-    public void testSequentialNodeData() throws Exception {
-        ZooKeeper zk= null;
-        String queue_handle = "/queue";
-        try {
-            zk = createClient();
-
-            zk.create(queue_handle, new byte[0], Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            zk.create(queue_handle + "/element", "0".getBytes(),
-                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            zk.create(queue_handle + "/element", "1".getBytes(),
-                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
-            List<String> children = zk.getChildren(queue_handle, true);
-            Assert.assertEquals(children.size(), 2);
-            String child1 = children.get(0);
-            String child2 = children.get(1);
-            int compareResult = child1.compareTo(child2);
-            Assert.assertNotSame(compareResult, 0);
-            if (compareResult < 0) {
-            } else {
-                String temp = child1;
-                child1 = child2;
-                child2 = temp;
-            }
-            String child1data = new String(zk.getData(queue_handle
-                    + "/" + child1, false, null));
-            String child2data = new String(zk.getData(queue_handle
-                    + "/" + child2, false, null));
-            Assert.assertEquals(child1data, "0");
-            Assert.assertEquals(child2data, "1");
-        } finally {
-            if (zk != null) {
-                zk.close();
-            }
-        }
-
-    }
-
-    @Test
-    public void testLargeNodeData() throws Exception {
-        ZooKeeper zk= null;
-        String queue_handle = "/large";
-        try {
-            zk = createClient();
-
-            zk.create(queue_handle, new byte[500000], Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        } finally {
-            if (zk != null) {
-                zk.close();
-            }
-        }
-
-    }
-
-    private void verifyCreateFails(String path, ZooKeeper zk) throws Exception {
-        try {
-            zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        } catch (IllegalArgumentException e) {
-            // this is good
-            return;
-        }
-        Assert.fail("bad path \"" + path + "\" not caught");
-    }
-
-    // Test that the path string is validated
-    @Test
-    public void testPathValidation() throws Exception {
-        ZooKeeper zk = createClient();
-
-        verifyCreateFails(null, zk);
-        verifyCreateFails("", zk);
-        verifyCreateFails("//", zk);
-        verifyCreateFails("///", zk);
-        verifyCreateFails("////", zk);
-        verifyCreateFails("/.", zk);
-        verifyCreateFails("/..", zk);
-        verifyCreateFails("/./", zk);
-        verifyCreateFails("/../", zk);
-        verifyCreateFails("/foo/./", zk);
-        verifyCreateFails("/foo/../", zk);
-        verifyCreateFails("/foo/.", zk);
-        verifyCreateFails("/foo/..", zk);
-        verifyCreateFails("/./.", zk);
-        verifyCreateFails("/../..", zk);
-        verifyCreateFails("/\u0001foo", zk);
-        verifyCreateFails("/foo/bar/", zk);
-        verifyCreateFails("/foo//bar", zk);
-        verifyCreateFails("/foo/bar//", zk);
-
-        verifyCreateFails("foo", zk);
-        verifyCreateFails("a", zk);
-
-        zk.create("/createseqpar", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        // next two steps - related to sequential processing
-        // 1) verify that empty child name Assert.fails if not sequential
-        try {
-            zk.create("/createseqpar/", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            Assert.assertTrue(false);
-        } catch(IllegalArgumentException be) {
-            // catch this.
-        }
-
-        // 2) verify that empty child name success if sequential 
-        zk.create("/createseqpar/", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT_SEQUENTIAL);
-        zk.create("/createseqpar/.", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT_SEQUENTIAL);
-        zk.create("/createseqpar/..", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT_SEQUENTIAL);
-        try {
-            zk.create("/createseqpar//", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT_SEQUENTIAL);
-            Assert.assertTrue(false);
-        } catch(IllegalArgumentException be) {
-            // catch this.
-        }
-        try {
-            zk.create("/createseqpar/./", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT_SEQUENTIAL);
-            Assert.assertTrue(false);
-        } catch(IllegalArgumentException be) {
-            // catch this.
-        }
-        try {
-            zk.create("/createseqpar/../", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT_SEQUENTIAL);
-            Assert.assertTrue(false);
-        } catch(IllegalArgumentException be) {
-            // catch this.
-        }
-
-        
-        //check for the code path that throws at server
-        PrepRequestProcessor.setFailCreate(true);
-        try {
-            zk.create("/m", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            Assert.assertTrue(false);
-        } catch(KeeperException.BadArgumentsException be) {
-            // catch this.
-        }
-        PrepRequestProcessor.setFailCreate(false);
-        zk.create("/.foo", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/.f.", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/..f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/..f..", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f.c", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f\u0040f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f/.f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f/f.", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f/..f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f/f..", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f/.f/f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/f/f./f", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-    }
-
-//    private void notestConnections()
-//        throws IOException, InterruptedException, KeeperException
-//    {
-//        ZooKeeper zk;
-//        for(int i = 0; i < 2000; i++) {
-//            if (i % 100 == 0) {
-//                LOG.info("Testing " + i + " connections");
-//            }
-//            // We want to make sure socket descriptors are going away
-//            zk = new ZooKeeper(hostPort, 30000, this);
-//            zk.getData("/", false, new Stat());
-//            zk.close();
-//        }
-//    }
-
-    @Test
-    public void testDeleteWithChildren() throws Exception {
-        ZooKeeper zk = createClient();
-        zk.create("/parent", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/parent/child", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        try {
-            zk.delete("/parent", -1);
-            Assert.fail("Should have received a not equals message");
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NOTEMPTY, e.code());
-        }
-        zk.delete("/parent/child", -1);
-        zk.delete("/parent", -1);
-        zk.close();
-    }
-
-    private class VerifyClientCleanup extends Thread {
-        int count;
-        int current = 0;
-
-        VerifyClientCleanup(String name, int count) {
-            super(name);
-            this.count = count;
-        }
-
-        public void run() {
-            try {
-                for (; current < count; current++) {
-                    TestableZooKeeper zk = createClient();
-                    zk.close();
-                    // we've asked to close, wait for it to finish closing
-                    // all the sub-threads otw the selector may not be
-                    // closed when we check (false positive on test Assert.failure
-                    zk.testableWaitForShutdown(CONNECTION_TIMEOUT);
-                }
-            } catch (Throwable t) {
-                LOG.error("test Assert.failed", t);
-            }
-        }
-    }
-
-    /**
-     * Verify that the client is cleaning up properly. Open/close a large
-     * number of sessions. Essentially looking to see if sockets/selectors
-     * are being cleaned up properly during close.
-     *
-     * @throws Throwable
-     */
-    @Test
-    public void testClientCleanup() throws Throwable {
-        OSMXBean osMbean = new OSMXBean();
-        if (osMbean.getUnix() == false) {
-            LOG.warn("skipping testClientCleanup, only available on Unix");
-            return;
-        }
-
-        final int threadCount = 3;
-        final int clientCount = 10;
-
-        /* Log the number of fds used before and after a test is run. Verifies
-         * we are freeing resources correctly. Unfortunately this only works
-         * on unix systems (the only place sun has implemented as part of the
-         * mgmt bean api).
-         */
-        long initialFdCount = osMbean.getOpenFileDescriptorCount();
-
-        VerifyClientCleanup threads[] = new VerifyClientCleanup[threadCount];
-
-        for (int i = 0; i < threads.length; i++) {
-            threads[i] = new VerifyClientCleanup("VCC" + i, clientCount);
-            threads[i].start();
-        }
-
-        for (int i = 0; i < threads.length; i++) {
-            threads[i].join(CONNECTION_TIMEOUT);
-            Assert.assertTrue(threads[i].current == threads[i].count);
-        }
-
-        // if this Assert.fails it means we are not cleaning up after the closed
-        // sessions.
-        long currentCount = osMbean.getOpenFileDescriptorCount();
-        final String logmsg = "open fds after test ({}) are not significantly higher than before ({})";
-        
-        if (currentCount > initialFdCount + 10) {
-            // consider as error
-        	LOG.error(logmsg,Long.valueOf(currentCount),Long.valueOf(initialFdCount));
-        } else {
-        	LOG.info(logmsg,Long.valueOf(currentCount),Long.valueOf(initialFdCount));
-        }
-    }
-
-
-    /**
-     * We create a perfectly valid 'exists' request, except that the opcode is wrong.
-     * @return
-     * @throws Exception
-     */
-    @Test
-    public void testNonExistingOpCode() throws Exception  {
-        final CountDownLatch clientDisconnected = new CountDownLatch(1);
-        Watcher watcher = new Watcher() {
-            @Override
-            public synchronized void process(WatchedEvent event) {
-                if (event.getState() == KeeperState.Disconnected) {
-                    clientDisconnected.countDown();
-                }
-            }
-        };
-        TestableZooKeeper zk = new TestableZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
-
-        final String path = "/m1";
-
-        RequestHeader h = new RequestHeader();
-        h.setType(888);  // This code does not exists
-        ExistsRequest request = new ExistsRequest();
-        request.setPath(path);
-        request.setWatch(false);
-        ExistsResponse response = new ExistsResponse();
-
-        ReplyHeader r = zk.submitRequest(h, request, response, null);
-
-        Assert.assertEquals(r.getErr(), Code.UNIMPLEMENTED.intValue());
-
-        // Sending a nonexisting opcode should cause the server to disconnect
-        Assert.assertTrue("failed to disconnect",
-                clientDisconnected.await(5000, TimeUnit.MILLISECONDS));
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
deleted file mode 100644
index a169b7b..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ConnectStringParserTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.client.ConnectStringParser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ConnectStringParserTest extends ZKTestCase{
-
-    @Test
-    public void testSingleServerChrootPath(){
-        String chrootPath = "/hallo/welt";
-        String servers = "10.10.10.1";
-        assertChrootPath(chrootPath,
-                new ConnectStringParser(servers+chrootPath));
-    }
-
-    @Test
-    public void testMultipleServersChrootPath(){
-        String chrootPath = "/hallo/welt";
-        String servers = "10.10.10.1,10.10.10.2";
-        assertChrootPath(chrootPath,
-                new ConnectStringParser(servers+chrootPath));
-    }
-
-    @Test
-    public void testParseServersWithoutPort(){
-        String servers = "10.10.10.1,10.10.10.2";
-        ConnectStringParser parser = new ConnectStringParser(servers);
-
-        Assert.assertEquals("10.10.10.1", parser.getServerAddresses().get(0).getHostName());
-        Assert.assertEquals("10.10.10.2", parser.getServerAddresses().get(1).getHostName());
-    }
-
-    @Test
-    public void testParseServersWithPort(){
-        String servers = "10.10.10.1:112,10.10.10.2:110";
-        ConnectStringParser parser = new ConnectStringParser(servers);
-
-        Assert.assertEquals("10.10.10.1", parser.getServerAddresses().get(0).getHostName());
-        Assert.assertEquals("10.10.10.2", parser.getServerAddresses().get(1).getHostName());
-
-        Assert.assertEquals(112, parser.getServerAddresses().get(0).getPort());
-        Assert.assertEquals(110, parser.getServerAddresses().get(1).getPort());
-    }
-
-    private void assertChrootPath(String expected, ConnectStringParser parser){
-        Assert.assertEquals(expected, parser.getChrootPath());
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/CreateModeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/CreateModeTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/CreateModeTest.java
deleted file mode 100644
index a3b838a..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/CreateModeTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.util.EnumSet;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.KeeperException.Code;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class CreateModeTest extends ZKTestCase {
-    
-    @Test
-    public void testBasicCreateMode() {
-        CreateMode cm = CreateMode.PERSISTENT;
-        Assert.assertEquals(cm.toFlag(), 0);
-        Assert.assertFalse(cm.isEphemeral());
-        Assert.assertFalse(cm.isSequential());
-        
-        cm = CreateMode.EPHEMERAL;
-        Assert.assertEquals(cm.toFlag(), 1);
-        Assert.assertTrue(cm.isEphemeral());
-        Assert.assertFalse(cm.isSequential());
-        
-        cm = CreateMode.PERSISTENT_SEQUENTIAL;
-        Assert.assertEquals(cm.toFlag(), 2);
-        Assert.assertFalse(cm.isEphemeral());
-        Assert.assertTrue(cm.isSequential());
-        
-        cm = CreateMode.EPHEMERAL_SEQUENTIAL;
-        Assert.assertEquals(cm.toFlag(), 3);
-        Assert.assertTrue(cm.isEphemeral());
-        Assert.assertTrue(cm.isSequential());
-    }
-    
-    @Test
-    public void testFlagConversion() throws KeeperException {
-        // Ensure we get the same value back after round trip conversion
-        EnumSet<CreateMode> allModes = EnumSet.allOf(CreateMode.class);
-
-        for(CreateMode cm : allModes) {
-            Assert.assertEquals(cm, CreateMode.fromFlag( cm.toFlag() ) );
-        }
-    }
-
-    @Test
-    public void testInvalidFlagConversion() throws KeeperException {
-        try {
-            CreateMode cm = CreateMode.fromFlag(99);
-            Assert.fail("Shouldn't be able to convert 99 to a CreateMode.");
-        } catch(KeeperException ke) {
-            Assert.assertEquals(Code.BADARGUMENTS, ke.code());
-        }
-
-        try {
-            CreateMode cm = CreateMode.fromFlag(-1);
-            Assert.fail("Shouldn't be able to convert -1 to a CreateMode.");
-        } catch(KeeperException ke) {
-            Assert.assertEquals(Code.BADARGUMENTS, ke.code());
-        }
-    }
-}


[21/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/StandaloneTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/StandaloneTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/StandaloneTest.java
deleted file mode 100644
index f305423..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/StandaloneTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Standalone server tests.
- */
-public class StandaloneTest extends QuorumPeerTestBase implements Watcher{
-    protected static final Logger LOG =
-        LoggerFactory.getLogger(StandaloneTest.class);    
-      
-    /**
-     * Ensure that a single standalone server comes up when misconfigured
-     * with a single server.# line in the configuration. This handles the
-     * case of HBase, which configures zoo.cfg in this way. Maintain b/w
-     * compatibility.
-     * TODO remove in a future version (4.0.0 hopefully)
-     */
-    @Test
-    public void testStandaloneQuorum() throws Exception {
-        ClientBase.setupTestEnv();
-        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
-        
-        String quorumCfgSection =
-            "server.1=127.0.0.1:" + (PortAssignment.unique())
-            + ":" + (PortAssignment.unique()) + "\n";
-                    
-        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
-        q1.start();
-        try {
-            Assert.assertTrue("waiting for server 1 being up",
-                    ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1,
-                            CONNECTION_TIMEOUT));
-        } finally {
-            q1.shutdown();
-        }
-    }    
-    
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/StatTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/StatTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/StatTest.java
deleted file mode 100644
index f4c01aa..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/StatTest.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class StatTest extends ClientBase {
-    private ZooKeeper zk;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        zk = createClient();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        zk.close();
-    }
-
-    /**
-     * Create a new Stat, fill in dummy values trying to catch Assert.failure
-     * to copy in client or server code.
-     *
-     * @return a new stat with dummy values
-     */
-    private Stat newStat() {
-        Stat stat = new Stat();
-
-        stat.setAversion(100);
-        stat.setCtime(100);
-        stat.setCversion(100);
-        stat.setCzxid(100);
-        stat.setDataLength(100);
-        stat.setEphemeralOwner(100);
-        stat.setMtime(100);
-        stat.setMzxid(100);
-        stat.setNumChildren(100);
-        stat.setPzxid(100);
-        stat.setVersion(100);
-
-        return stat;
-    }
-
-    @Test
-    public void testBasic()
-        throws IOException, KeeperException, InterruptedException
-    {
-        String name = "/foo";
-        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        Stat stat;
-
-        stat = newStat();
-        zk.getData(name, false, stat);
-
-        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
-        Assert.assertEquals(stat.getCtime(), stat.getMtime());
-        Assert.assertEquals(0, stat.getCversion());
-        Assert.assertEquals(0, stat.getVersion());
-        Assert.assertEquals(0, stat.getAversion());
-        Assert.assertEquals(0, stat.getEphemeralOwner());
-        Assert.assertEquals(name.length(), stat.getDataLength());
-        Assert.assertEquals(0, stat.getNumChildren());
-    }
-
-    @Test
-    public void testChild()
-        throws IOException, KeeperException, InterruptedException
-    {
-        String name = "/foo";
-        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        String childname = name + "/bar";
-        zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.EPHEMERAL);
-
-        Stat stat;
-
-        stat = newStat();
-        zk.getData(name, false, stat);
-
-        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-        Assert.assertEquals(stat.getCzxid() + 1, stat.getPzxid());
-        Assert.assertEquals(stat.getCtime(), stat.getMtime());
-        Assert.assertEquals(1, stat.getCversion());
-        Assert.assertEquals(0, stat.getVersion());
-        Assert.assertEquals(0, stat.getAversion());
-        Assert.assertEquals(0, stat.getEphemeralOwner());
-        Assert.assertEquals(name.length(), stat.getDataLength());
-        Assert.assertEquals(1, stat.getNumChildren());
-
-        stat = newStat();
-        zk.getData(childname, false, stat);
-
-        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
-        Assert.assertEquals(stat.getCtime(), stat.getMtime());
-        Assert.assertEquals(0, stat.getCversion());
-        Assert.assertEquals(0, stat.getVersion());
-        Assert.assertEquals(0, stat.getAversion());
-        Assert.assertEquals(zk.getSessionId(), stat.getEphemeralOwner());
-        Assert.assertEquals(childname.length(), stat.getDataLength());
-        Assert.assertEquals(0, stat.getNumChildren());
-    }
-
-    @Test
-    public void testChildren()
-        throws IOException, KeeperException, InterruptedException
-    {
-        String name = "/foo";
-        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        for(int i = 0; i < 10; i++) {
-            String childname = name + "/bar" + i;
-            zk.create(childname, childname.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.EPHEMERAL);
-
-            Stat stat;
-
-            stat = newStat();
-            zk.getData(name, false, stat);
-
-            Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-            Assert.assertEquals(stat.getCzxid() + i + 1, stat.getPzxid());
-            Assert.assertEquals(stat.getCtime(), stat.getMtime());
-            Assert.assertEquals(i + 1, stat.getCversion());
-            Assert.assertEquals(0, stat.getVersion());
-            Assert.assertEquals(0, stat.getAversion());
-            Assert.assertEquals(0, stat.getEphemeralOwner());
-            Assert.assertEquals(name.length(), stat.getDataLength());
-            Assert.assertEquals(i + 1, stat.getNumChildren());
-        }
-    }
-
-    @Test
-    public void testDataSizeChange()
-        throws IOException, KeeperException, InterruptedException
-    {
-        String name = "/foo";
-        zk.create(name, name.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        Stat stat;
-
-        stat = newStat();
-        zk.getData(name, false, stat);
-
-        Assert.assertEquals(stat.getCzxid(), stat.getMzxid());
-        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
-        Assert.assertEquals(stat.getCtime(), stat.getMtime());
-        Assert.assertEquals(0, stat.getCversion());
-        Assert.assertEquals(0, stat.getVersion());
-        Assert.assertEquals(0, stat.getAversion());
-        Assert.assertEquals(0, stat.getEphemeralOwner());
-        Assert.assertEquals(name.length(), stat.getDataLength());
-        Assert.assertEquals(0, stat.getNumChildren());
-
-        zk.setData(name, (name + name).getBytes(), -1);
-
-        stat = newStat();
-        zk.getData(name, false, stat);
-
-        Assert.assertNotSame(stat.getCzxid(), stat.getMzxid());
-        Assert.assertEquals(stat.getCzxid(), stat.getPzxid());
-        Assert.assertNotSame(stat.getCtime(), stat.getMtime());
-        Assert.assertEquals(0, stat.getCversion());
-        Assert.assertEquals(1, stat.getVersion());
-        Assert.assertEquals(0, stat.getAversion());
-        Assert.assertEquals(0, stat.getEphemeralOwner());
-        Assert.assertEquals(name.length() * 2, stat.getDataLength());
-        Assert.assertEquals(0, stat.getNumChildren());
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java
deleted file mode 100644
index a4107a5..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/StaticHostProviderTest.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.client.HostProvider;
-import org.apache.zookeeper.client.StaticHostProvider;
-import org.apache.zookeeper.common.Time;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.anyOf;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.hasItems;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class StaticHostProviderTest extends ZKTestCase {
-    private static final Logger LOG = LoggerFactory.getLogger(StaticHostProviderTest.class);
-
-    @Test
-    public void testNextGoesRound() {
-        HostProvider hostProvider = getHostProvider((byte) 2);
-        InetSocketAddress first = hostProvider.next(0);
-        assertTrue(first instanceof InetSocketAddress);
-        hostProvider.next(0);
-        assertEquals(first, hostProvider.next(0));
-    }
-
-    @Test
-    public void testNextGoesRoundAndSleeps() {
-        byte size = 2;
-        HostProvider hostProvider = getHostProvider(size);
-        while (size > 0) {
-            hostProvider.next(0);
-            --size;
-        }
-        long start = Time.currentElapsedTime();
-        hostProvider.next(1000);
-        long stop = Time.currentElapsedTime();
-        assertTrue(900 <= stop - start);
-    }
-
-    @Test
-    public void testNextDoesNotSleepForZero() {
-        byte size = 2;
-        HostProvider hostProvider = getHostProvider(size);
-        while (size > 0) {
-            hostProvider.next(0);
-            --size;
-        }
-        long start = Time.currentElapsedTime();
-        hostProvider.next(0);
-        long stop = Time.currentElapsedTime();
-        assertTrue(5 > stop - start);
-    }
-
-    @Test
-    public void testTwoConsequitiveCallsToNextReturnDifferentElement() {
-        HostProvider hostProvider = getHostProvider((byte) 2);
-        assertNotSame(hostProvider.next(0), hostProvider.next(0));
-    }
-
-    @Test
-    public void testOnConnectDoesNotReset() {
-        HostProvider hostProvider = getHostProvider((byte) 2);
-        InetSocketAddress first = hostProvider.next(0);
-        hostProvider.onConnected();
-        InetSocketAddress second = hostProvider.next(0);
-        assertNotSame(first, second);
-    }
-
-    @Test
-    public void testLiteralIPNoReverseNS() {
-        byte size = 30;
-        HostProvider hostProvider = getHostProviderUnresolved(size);
-        for (int i = 0; i < size; i++) {
-            InetSocketAddress next = hostProvider.next(0);
-            assertTrue(next instanceof InetSocketAddress);
-            assertTrue(!next.isUnresolved());
-            assertTrue("InetSocketAddress must not have hostname part " +
-                    next.toString(), next.toString().startsWith("/"));
-            // Do NOT trigger the reverse name service lookup.
-            String hostname = next.getHostName();
-            // In this case, the hostname equals literal IP address.
-            hostname.equals(next.getAddress().getHostAddress());
-        }
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testEmptyServerAddressesList() {
-        HostProvider hp = new StaticHostProvider(new ArrayList<InetSocketAddress>());
-    }
-
-    @Test
-    public void testInvalidHostAddresses() {
-        // Arrange
-        final List<InetSocketAddress> invalidAddresses = new ArrayList<InetSocketAddress>();
-        InetSocketAddress unresolved = InetSocketAddress.createUnresolved("a", 1234);
-        invalidAddresses.add(unresolved);
-        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
-            @Override
-            public InetAddress[] getAllByName(String name) throws UnknownHostException {
-                throw new UnknownHostException();
-            }
-        };
-        StaticHostProvider sp = new StaticHostProvider(invalidAddresses, resolver);
-
-        // Act & Assert
-        InetSocketAddress n1 = sp.next(0);
-        assertTrue("Provider should return unresolved address is host is unresolvable", n1.isUnresolved());
-        assertSame("Provider should return original address is host is unresolvable", unresolved, n1);
-    }
-
-    @Test
-    public void testReResolvingSingle() throws UnknownHostException {
-        // Arrange
-        byte size = 1;
-        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
-
-        // Test a hostname that resolves to a single address
-        list.add(InetSocketAddress.createUnresolved("issues.apache.org", 1234));
-
-        final InetAddress issuesApacheOrg = mock(InetAddress.class);
-        when(issuesApacheOrg.getHostAddress()).thenReturn("192.168.1.1");
-        when(issuesApacheOrg.toString()).thenReturn("issues.apache.org");
-        when(issuesApacheOrg.getHostName()).thenReturn("issues.apache.org");
-
-        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
-            @Override
-            public InetAddress[] getAllByName(String name) {
-                return new InetAddress[] {
-                        issuesApacheOrg
-                };
-            }
-        };
-        StaticHostProvider.Resolver spyResolver = spy(resolver);
-
-        // Act
-        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
-        for (int i = 0; i < 10; i++) {
-            InetSocketAddress next = hostProvider.next(0);
-            assertEquals(issuesApacheOrg, next.getAddress());
-        }
-
-        // Assert
-        // Resolver called 10 times, because we shouldn't cache the resolved addresses
-        verify(spyResolver, times(10)).getAllByName("issues.apache.org"); // resolution occurred
-    }
-
-    @Test
-    public void testReResolvingMultiple() throws UnknownHostException {
-        // Arrange
-        byte size = 1;
-        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
-
-        // Test a hostname that resolves to multiple addresses
-        list.add(InetSocketAddress.createUnresolved("www.apache.org", 1234));
-
-        final InetAddress apacheOrg1 = mock(InetAddress.class);
-        when(apacheOrg1.getHostAddress()).thenReturn("192.168.1.1");
-        when(apacheOrg1.toString()).thenReturn("www.apache.org");
-        when(apacheOrg1.getHostName()).thenReturn("www.apache.org");
-
-        final InetAddress apacheOrg2 = mock(InetAddress.class);
-        when(apacheOrg2.getHostAddress()).thenReturn("192.168.1.2");
-        when(apacheOrg2.toString()).thenReturn("www.apache.org");
-        when(apacheOrg2.getHostName()).thenReturn("www.apache.org");
-
-        final List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>();
-        resolvedAddresses.add(apacheOrg1);
-        resolvedAddresses.add(apacheOrg2);
-        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
-            @Override
-            public InetAddress[] getAllByName(String name) {
-                return resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
-            }
-        };
-        StaticHostProvider.Resolver spyResolver = spy(resolver);
-
-        // Act & Assert
-        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
-        assertEquals(1, hostProvider.size()); // single address not extracted
-
-        for (int i = 0; i < 10; i++) {
-            InetSocketAddress next = hostProvider.next(0);
-            assertThat("Bad IP address returned", next.getAddress().getHostAddress(), anyOf(equalTo(apacheOrg1.getHostAddress()), equalTo(apacheOrg2.getHostAddress())));
-            assertEquals(1, hostProvider.size()); // resolve() call keeps the size of provider
-        }
-        // Resolver called 10 times, because we shouldn't cache the resolved addresses
-        verify(spyResolver, times(10)).getAllByName("www.apache.org"); // resolution occurred
-    }
-
-    @Test
-    public void testReResolveMultipleOneFailing() throws UnknownHostException {
-        // Arrange
-        final List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
-        list.add(InetSocketAddress.createUnresolved("www.apache.org", 1234));
-        final List<String> ipList = new ArrayList<String>();
-        final List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>();
-        for (int i = 0; i < 3; i++) {
-            ipList.add(String.format("192.168.1.%d", i+1));
-            final InetAddress apacheOrg = mock(InetAddress.class);
-            when(apacheOrg.getHostAddress()).thenReturn(String.format("192.168.1.%d", i+1));
-            when(apacheOrg.toString()).thenReturn(String.format("192.168.1.%d", i+1));
-            when(apacheOrg.getHostName()).thenReturn("www.apache.org");
-            resolvedAddresses.add(apacheOrg);
-        }
-
-        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
-            @Override
-            public InetAddress[] getAllByName(String name) {
-                return resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
-            }
-        };
-        StaticHostProvider.Resolver spyResolver = spy(resolver);
-        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
-
-        // Act & Assert
-        InetSocketAddress resolvedFirst = hostProvider.next(0);
-        assertFalse("HostProvider should return resolved addresses", resolvedFirst.isUnresolved());
-        assertThat("Bad IP address returned", ipList, hasItems(resolvedFirst.getAddress().getHostAddress()));
-
-        hostProvider.onConnected(); // first address worked
-
-        InetSocketAddress resolvedSecond = hostProvider.next(0);
-        assertFalse("HostProvider should return resolved addresses", resolvedSecond.isUnresolved());
-        assertThat("Bad IP address returned", ipList, hasItems(resolvedSecond.getAddress().getHostAddress()));
-
-        // Second address doesn't work, so we don't call onConnected() this time
-        // StaticHostProvider should try to re-resolve the address in this case
-
-        InetSocketAddress resolvedThird = hostProvider.next(0);
-        assertFalse("HostProvider should return resolved addresses", resolvedThird.isUnresolved());
-        assertThat("Bad IP address returned", ipList, hasItems(resolvedThird.getAddress().getHostAddress()));
-
-        verify(spyResolver, times(3)).getAllByName("www.apache.org");  // resolution occured every time
-    }
-
-    @Test
-    public void testEmptyResolution() throws UnknownHostException {
-        // Arrange
-        final List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
-        list.add(InetSocketAddress.createUnresolved("www.apache.org", 1234));
-        list.add(InetSocketAddress.createUnresolved("www.google.com", 1234));
-        final List<InetAddress> resolvedAddresses = new ArrayList<InetAddress>();
-
-        final InetAddress apacheOrg1 = mock(InetAddress.class);
-        when(apacheOrg1.getHostAddress()).thenReturn("192.168.1.1");
-        when(apacheOrg1.toString()).thenReturn("www.apache.org");
-        when(apacheOrg1.getHostName()).thenReturn("www.apache.org");
-
-        resolvedAddresses.add(apacheOrg1);
-
-        StaticHostProvider.Resolver resolver = new StaticHostProvider.Resolver() {
-            @Override
-            public InetAddress[] getAllByName(String name) {
-                if ("www.apache.org".equalsIgnoreCase(name)) {
-                    return resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
-                } else {
-                    return new InetAddress[0];
-                }
-            }
-        };
-        StaticHostProvider.Resolver spyResolver = spy(resolver);
-        StaticHostProvider hostProvider = new StaticHostProvider(list, spyResolver);
-
-        // Act & Assert
-        for (int i = 0; i < 10; i++) {
-            InetSocketAddress resolved = hostProvider.next(0);
-            hostProvider.onConnected();
-            if (resolved.getHostName().equals("www.google.com")) {
-                assertTrue("HostProvider should return unresolved address if host is unresolvable", resolved.isUnresolved());
-            } else {
-                assertFalse("HostProvider should return resolved addresses", resolved.isUnresolved());
-                assertEquals("192.168.1.1", resolved.getAddress().getHostAddress());
-            }
-        }
-
-        verify(spyResolver, times(5)).getAllByName("www.apache.org");
-        verify(spyResolver, times(5)).getAllByName("www.google.com");
-    }
-
-    @Test
-    public void testReResolvingLocalhost() {
-        byte size = 2;
-        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
-
-        // Test a hostname that resolves to multiple addresses
-        list.add(InetSocketAddress.createUnresolved("localhost", 1234));
-        list.add(InetSocketAddress.createUnresolved("localhost", 1235));
-        StaticHostProvider hostProvider = new StaticHostProvider(list);
-        int sizeBefore = hostProvider.size();
-        InetSocketAddress next = hostProvider.next(0);
-        next = hostProvider.next(0);
-        assertTrue("Different number of addresses in the list: " + hostProvider.size() +
-                " (after), " + sizeBefore + " (before)", hostProvider.size() == sizeBefore);
-    }
-
-    private StaticHostProvider getHostProviderUnresolved(byte size) {
-        return new StaticHostProvider(getUnresolvedServerAddresses(size));
-    }
-
-    private Collection<InetSocketAddress> getUnresolvedServerAddresses(byte size) {
-        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(size);
-        while (size > 0) {
-            list.add(InetSocketAddress.createUnresolved("192.0.2." + size, 1234 + size));
-            --size;
-        }
-        return list;
-    }
-
-    private StaticHostProvider getHostProvider(byte size) {
-        ArrayList<InetSocketAddress> list = new ArrayList<InetSocketAddress>(
-                size);
-        while (size > 0) {
-            try {
-                list.add(new InetSocketAddress(InetAddress.getByAddress(new byte[]{-64, 0, 2, size}), 1234 + size));
-            } catch (UnknownHostException e) {
-                LOG.error("Exception while resolving address", e);
-                fail("Failed to resolve address");
-            }
-            --size;
-        }
-        return new StaticHostProvider(list);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/SyncCallTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SyncCallTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/SyncCallTest.java
deleted file mode 100644
index 4fb006a..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/SyncCallTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.AsyncCallback.Children2Callback;
-import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
-import org.apache.zookeeper.AsyncCallback.StringCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SyncCallTest extends ClientBase
-    implements ChildrenCallback, Children2Callback, StringCallback, VoidCallback
-{
-    private CountDownLatch opsCount;
-    
-    List<Integer> results = new LinkedList<Integer>();
-    Integer limit = 100 + 1 + 100 + 100;
-    
-    @Test
-    public void testSync() throws Exception {
-        try {
-            LOG.info("Starting ZK:" + (new Date()).toString());
-            opsCount = new CountDownLatch(limit);
-            ZooKeeper zk = createClient();
-            
-            LOG.info("Beginning test:" + (new Date()).toString());
-            for(int i = 0; i < 100; i++)
-                zk.create("/test" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.PERSISTENT, this, results);
-            zk.sync("/test", this, results);
-            for(int i = 0; i < 100; i++)
-                zk.delete("/test" + i, 0, this, results);
-            for(int i = 0; i < 100; i++)
-                zk.getChildren("/", new NullWatcher(), (ChildrenCallback)this,
-                        results);
-            for(int i = 0; i < 100; i++)
-                zk.getChildren("/", new NullWatcher(), (Children2Callback)this,
-                        results);
-            LOG.info("Submitted all operations:" + (new Date()).toString());
-            
-            if(!opsCount.await(10000, TimeUnit.MILLISECONDS))
-                Assert.fail("Haven't received all confirmations" + opsCount.getCount());
-
-            for(int i = 0; i < limit ; i++){
-                Assert.assertEquals(0, (int) results.get(i));
-            }
-            
-        } catch (IOException e) {
-            System.out.println(e.toString());
-        } 
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx,
-            List<String> children) { 
-        ((List<Integer>)ctx).add(rc);
-        opsCount.countDown();
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx,
-            List<String> children, Stat stat) { 
-        ((List<Integer>)ctx).add(rc);
-        opsCount.countDown();
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx, String name){
-        ((List<Integer>) ctx).add(rc);
-        opsCount.countDown();
-    
-    }
-
-    @SuppressWarnings("unchecked")
-    public void processResult(int rc, String path, Object ctx){
-        ((List<Integer>) ctx).add(rc);    
-        opsCount.countDown();
-    
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestHammer.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestHammer.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestHammer.java
deleted file mode 100644
index a73d6df..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestHammer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.common.Time;
-
-public class TestHammer implements VoidCallback {
-
-    /**
-     * @param args
-     */
-    static int REPS = 50000;
-    public static void main(String[] args) {
-            long startTime = Time.currentElapsedTime();
-            ZooKeeper zk = null;
-            try {
-                zk = new ZooKeeper(args[0], 10000, null);
-            } catch (IOException e1) {
-                // TODO Auto-generated catch block
-                e1.printStackTrace();
-                throw new RuntimeException(e1);
-            }
-            for(int i = 0; i < REPS; i++) {
-                try {
-                    String name = zk.create("/testFile-", new byte[16], Ids.OPEN_ACL_UNSAFE,
-                        CreateMode.EPHEMERAL_SEQUENTIAL);
-                    zk.delete(name, -1, new TestHammer(), null);
-                } catch(Exception e) {
-                    i--;
-                    e.printStackTrace();
-                }
-            }
-            System.out.println("creates/sec=" + (REPS*1000/(Time.currentElapsedTime()-startTime)));
-    }
-
-    public void processResult(int rc, String path, Object ctx) {
-        // TODO Auto-generated method stub
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestUtils.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestUtils.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestUtils.java
deleted file mode 100644
index fa08b82..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/TestUtils.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.test;
-
-import java.io.File;
-
-import org.junit.Assert;
-
-/**
- * This class contains test utility methods
- */
-public class TestUtils {
-
-    /**
-     * deletes a folder recursively
-     *
-     * @param file
-     *            folder to be deleted
-     * @param failOnError
-     *            if true file deletion success is ensured
-     */
-    public static boolean deleteFileRecursively(File file,
-            final boolean failOnError) {
-        if (file != null) {
-            if (file.isDirectory()) {
-                File[] files = file.listFiles();
-                int size = files.length;
-                for (int i = 0; i < size; i++) {
-                    File f = files[i];
-                    boolean deleted = deleteFileRecursively(files[i], failOnError);
-                    if(!deleted && failOnError)
-                    {
-                        Assert.fail("file '" + f.getAbsolutePath()+"' deletion failed");
-                    }
-                }
-            }
-            return file.delete();
-        }
-        return true;
-    }
-
-    public static boolean deleteFileRecursively(File file) {
-        return deleteFileRecursively(file, false);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/TruncateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/TruncateTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/TruncateTest.java
deleted file mode 100644
index 66ff63d..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/TruncateTest.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-
-import junit.framework.Assert;
-
-import org.apache.jute.Record;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.Request;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.ZKDatabase;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.apache.zookeeper.server.persistence.FileTxnLog;
-import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
-import org.apache.zookeeper.server.persistence.TxnLog.TxnIterator;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.txn.SetDataTxn;
-import org.apache.zookeeper.txn.TxnHeader;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TruncateTest extends ZKTestCase {
-	private static final Logger LOG = LoggerFactory.getLogger(TruncateTest.class);
-    File dataDir1, dataDir2, dataDir3;
-    final int baseHostPort = PortAssignment.unique();
-    
-    @Before
-    public void setUp() throws IOException {
-        dataDir1 = ClientBase.createTmpDir();
-        dataDir2 = ClientBase.createTmpDir();
-        dataDir3 = ClientBase.createTmpDir();
-    }
-    
-    @After
-    public void tearDown() {
-        ClientBase.recursiveDelete(dataDir1);
-        ClientBase.recursiveDelete(dataDir2);
-        ClientBase.recursiveDelete(dataDir3);
-    }
-    
-    volatile boolean connected;
-    Watcher nullWatcher = new Watcher() {
-        @Override
-        public void process(WatchedEvent event) {
-            connected = event.getState() == Watcher.Event.KeeperState.SyncConnected;
-        }
-    };
-
-    @Test
-    public void testTruncationStreamReset() throws Exception {
-        File tmpdir = ClientBase.createTmpDir();
-        FileTxnSnapLog snaplog = new FileTxnSnapLog(tmpdir, tmpdir);
-        ZKDatabase zkdb = new ZKDatabase(snaplog);
-
-        for (int i = 1; i <= 100; i++) {
-            append(zkdb, i);
-        }
-
-        zkdb.truncateLog(1);
-
-        append(zkdb, 200);
-
-        zkdb.close();
-
-        // verify that the truncation and subsequent append were processed
-        // correctly
-        FileTxnLog txnlog = new FileTxnLog(new File(tmpdir, "version-2"));
-        TxnIterator iter = txnlog.read(1);
-
-        TxnHeader hdr = iter.getHeader();
-        Record txn = iter.getTxn();
-        Assert.assertEquals(1, hdr.getZxid());
-        Assert.assertTrue(txn instanceof SetDataTxn);
-
-        iter.next();
-
-        hdr = iter.getHeader();
-        txn = iter.getTxn();
-        Assert.assertEquals(200, hdr.getZxid());
-        Assert.assertTrue(txn instanceof SetDataTxn);
-        iter.close();
-        ClientBase.recursiveDelete(tmpdir);
-    }
-
-    private void append(ZKDatabase zkdb, int i) throws IOException {
-        TxnHeader hdr = new TxnHeader(1, 1, i, 1, ZooDefs.OpCode.setData);
-        Record txn = new SetDataTxn("/foo" + i, new byte[0], 1);
-        Request req = new Request(null, 0, 0, 0, null, null);
-        req.hdr = hdr;
-        req.txn = txn;
-
-        zkdb.append(req);
-        zkdb.commit();
-    }
-
-    
-    @Test
-    public void testTruncationNullLog() throws Exception {
-        File tmpdir = ClientBase.createTmpDir();
-        FileTxnSnapLog snaplog = new FileTxnSnapLog(tmpdir, tmpdir);
-        ZKDatabase zkdb = new ZKDatabase(snaplog);
-
-        for (int i = 1; i <= 100; i++) {
-            append(zkdb, i);
-        }
-        zkdb.close();
-        File[] logs = snaplog.getDataDir().listFiles();
-        for(int i = 0; i < logs.length; i++) {
-            LOG.debug("Deleting: {}", logs[i].getName());
-            Assert.assertTrue("Failed to delete log file: " + logs[i].getName(), logs[i].delete());
-        }
-        try {
-            zkdb.truncateLog(1);
-            Assert.assertTrue("Should not get here", false);
-        }
-        catch(IOException e) {
-            Assert.assertTrue("Should have received an IOException", true);
-        }
-        catch(NullPointerException npe) {
-            Assert.fail("This should not throw NPE!");
-        }
- 
-        ClientBase.recursiveDelete(tmpdir);
-    }
-    
-    @Test
-    public void testTruncate() throws IOException, InterruptedException, KeeperException {
-        // Prime the server that is going to come in late with 50 txns
-        String hostPort = "127.0.0.1:" + baseHostPort;
-        int maxCnxns = 100;
-        ServerCnxnFactory factory = ClientBase.createNewServerInstance(null,
-                hostPort, maxCnxns);
-        ClientBase.startServerInstance(dataDir1, factory, hostPort);
-        ClientBase.shutdownServerInstance(factory, hostPort);
-
-        // standalone starts with 0 epoch while quorum starts with 1
-        File origfile = new File(new File(dataDir1, "version-2"), "snapshot.0");
-        File newfile = new File(new File(dataDir1, "version-2"), "snapshot.100000000");
-        origfile.renameTo(newfile);
-
-        factory = ClientBase.createNewServerInstance(null, hostPort, maxCnxns);
-        ClientBase.startServerInstance(dataDir1, factory, hostPort);
-
-        ZooKeeper zk = new ZooKeeper(hostPort, 15000, nullWatcher);
-        for(int i = 0; i < 50; i++) {
-            zk.create("/" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        }
-        zk.close();
-        
-        ZKDatabase zkDb;
-        {
-            ZooKeeperServer zs = ClientBase.getServer(factory);
-    
-            zkDb = zs.getZKDatabase();
-        }
-        factory.shutdown();
-        try {
-            zkDb.close();
-        } catch (IOException ie) {
-            LOG.warn("Error closing logs ", ie);
-        }
-        int tickTime = 2000;
-        int initLimit = 3;
-        int syncLimit = 3;
-        int port1 = baseHostPort+1;
-        int port2 = baseHostPort+2;
-        int port3 = baseHostPort+3;
-        
-        // Start up two of the quorum and add 10 txns
-        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>();
-        peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000, 0, null));
-        peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000, 0, null));
-        peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000, 0, null));
-
-        QuorumPeer s2 = new QuorumPeer(peers, dataDir2, dataDir2, port2, 0, 2, tickTime, initLimit, syncLimit);
-        s2.start();
-        QuorumPeer s3 = new QuorumPeer(peers, dataDir3, dataDir3, port3, 0, 3, tickTime, initLimit, syncLimit);
-        s3.start();
-        connected = false;
-        zk = new ZooKeeper("127.0.0.1:" + port2, 15000, nullWatcher);
-        while(!connected) {
-            Thread.sleep(1000);
-        }
-        for(int i = 0; i < 10; i++) {
-            zk.create("/" + i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        }
-        zk.close();
-        
-        final ZooKeeper zk2 = new ZooKeeper("127.0.0.1:" + port2, 15000, nullWatcher);
-        zk2.getData("/9", false, new Stat());
-        try {
-            zk2.getData("/10", false, new Stat());
-            Assert.fail("Should have gotten an error");
-        } catch(KeeperException.NoNodeException e) {
-            // this is what we want
-        }
-        QuorumPeer s1 = new QuorumPeer(peers, dataDir1, dataDir1, port1, 0, 1, tickTime, initLimit, syncLimit);
-        s1.start();
-
-        connected = false;
-        ZooKeeper zk1 = new ZooKeeper("127.0.0.1:" + port1, 15000, nullWatcher);
-        while(!connected) {
-            Thread.sleep(1000);
-        }
-        zk1.getData("/9", false, new Stat());
-        try {
-            // /10 wont work because the session expiration
-            // will match the zxid for /10 and so we wont
-            // actually truncate the zxid for /10 creation
-            // due to an artifact of switching the xid of the standalone
-            // /11 is the last entry in the log for the xid
-            // as a result /12 is the first of the truncated znodes to check for
-            zk1.getData("/12", false, new Stat());
-            Assert.fail("Should have gotten an error");
-        } catch(KeeperException.NoNodeException e) {
-            // this is what we want
-        }
-        zk1.close();
-        QuorumBase.shutdown(s1);
-        QuorumBase.shutdown(s2);
-        QuorumBase.shutdown(s3);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/UpgradeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/UpgradeTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/UpgradeTest.java
deleted file mode 100644
index b8db0da..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/UpgradeTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.SyncRequestProcessor;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.apache.zookeeper.server.upgrade.UpgradeMain;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class UpgradeTest extends ZKTestCase implements Watcher {
-    private final static Logger LOG = LoggerFactory.getLogger(UpgradeTest.class);
-
-    private static String HOSTPORT = "127.0.0.1:" + PortAssignment.unique();
-    private static final File testData = new File(
-            System.getProperty("test.data.dir", "build/test/data"));
-    private CountDownLatch startSignal;
-
-    /**
-     * test the upgrade
-     * @throws Exception
-     */
-    @Test
-    public void testUpgrade() throws Exception {
-        File upgradeDir = new File(testData, "upgrade");
-        UpgradeMain upgrade = new UpgradeMain(upgradeDir, upgradeDir);
-        upgrade.runUpgrade();
-        ZooKeeperServer zks = new ZooKeeperServer(upgradeDir, upgradeDir, 3000);
-        SyncRequestProcessor.setSnapCount(1000);
-        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-        f.startup(zks);
-        LOG.info("starting up the zookeeper server .. waiting");
-        Assert.assertTrue("waiting for server being up",
-                ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
-        ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
-        Stat stat = zk.exists("/", false);
-        List<String> children = zk.getChildren("/", false);
-        Collections.sort(children);
-        for (int i = 0; i < 10; i++) {
-            Assert.assertTrue("data tree sanity check",
-                    ("test-" + i).equals(children.get(i)));
-        }
-        //try creating one node
-        zk.create("/upgrade", "upgrade".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        // check if its there
-        if (zk.exists("/upgrade", false) == null) {
-            Assert.assertTrue(false);
-        }
-
-        zk.close();
-
-        // bring down the server
-        f.shutdown();
-        Assert.assertTrue("waiting for server down",
-                   ClientBase.waitForServerDown(HOSTPORT,
-                           ClientBase.CONNECTION_TIMEOUT));
-
-    }
-
-    public void process(WatchedEvent event) {
-        LOG.info("Event:" + event.getState() + " " + event.getType() + " " + event.getPath());
-        if (event.getState() == KeeperState.SyncConnected
-                && startSignal != null && startSignal.getCount() > 0)
-        {
-            startSignal.countDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java
deleted file mode 100644
index eed02c5..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchEventWhenAutoReset.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
-import org.junit.Assert;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import junit.framework.TestCase;
-
-public class WatchEventWhenAutoReset extends TestCase {
-    protected static final Logger LOG = LoggerFactory
-            .getLogger(WatchEventWhenAutoReset.class);
-
-    // waiting time for expected condition
-    private static final int TIMEOUT = 30000;
-
-    static public class EventsWatcher extends CountdownWatcher {
-        private LinkedBlockingQueue<WatchedEvent> dataEvents = new LinkedBlockingQueue<WatchedEvent>();
-
-        @Override
-        public void process(WatchedEvent event) {
-            super.process(event);
-            try {
-                if (event.getType() != Event.EventType.None) {
-                    dataEvents.put(event);
-                }
-            } catch (InterruptedException e) {
-                LOG.warn("ignoring interrupt during EventsWatcher process");
-            }
-        }
-
-        public void assertEvent(long timeout, EventType eventType) {
-            try {
-                WatchedEvent event = dataEvents.poll(timeout,
-                        TimeUnit.MILLISECONDS);
-                Assert.assertNotNull("do not receive a " + eventType, event);
-                Assert.assertEquals(eventType, event.getType());
-            } catch (InterruptedException e) {
-                LOG.warn("ignoring interrupt during EventsWatcher assertEvent");
-            }
-        }
-    }
-
-    private ZooKeeper createClient(QuorumUtil qu, int id, EventsWatcher watcher)
-            throws IOException {
-        String hostPort = "127.0.0.1:" + qu.getPeer(id).clientPort;
-        ZooKeeper zk = new ZooKeeper(hostPort, TIMEOUT, watcher);
-        try {
-            watcher.waitForConnected(TIMEOUT);
-        } catch (InterruptedException e) {
-            // ignoring the interrupt
-        } catch (TimeoutException e) {
-            fail("can not connect to " + hostPort);
-        }
-        return zk;
-    }
-
-    private ZooKeeper createClient(QuorumUtil qu, int id) throws IOException {
-        return createClient(qu, id, new EventsWatcher());
-    }
-
-    @Test
-    public void testNodeDataChanged() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-
-        EventsWatcher watcher = new EventsWatcher();
-        ZooKeeper zk1 = createClient(qu, 1, watcher);
-        ZooKeeper zk2 = createClient(qu, 2);
-
-        String path = "/test-changed";
-
-        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.getData(path, watcher, null);
-        qu.shutdown(1);
-        zk2.delete(path, -1);
-        zk2.create(path, new byte[2], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        qu.start(1);
-        watcher.waitForConnected(TIMEOUT);
-        watcher.assertEvent(TIMEOUT, EventType.NodeDataChanged);
-
-        zk1.exists(path, watcher);
-        qu.shutdown(1);
-        zk2.delete(path, -1);
-        zk2.create(path, new byte[2], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        qu.start(1);
-        watcher.waitForConnected(TIMEOUT * 1000L);
-        watcher.assertEvent(TIMEOUT, EventType.NodeDataChanged);
-
-        qu.shutdownAll();
-    }
-
-    @Test
-    public void testNodeCreated() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-
-        EventsWatcher watcher = new EventsWatcher();
-        ZooKeeper zk1 = createClient(qu, 1, watcher);
-        ZooKeeper zk2 = createClient(qu, 2);
-
-        String path = "/test1-created";
-
-        zk1.exists(path, watcher);
-        qu.shutdown(1);
-        zk2.create(path, new byte[2], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        qu.start(1);
-        watcher.waitForConnected(TIMEOUT * 1000L);
-        watcher.assertEvent(TIMEOUT, EventType.NodeCreated);
-
-        qu.shutdownAll();
-    }
-
-    @Test
-    public void testNodeDeleted() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-
-        EventsWatcher watcher = new EventsWatcher();
-        ZooKeeper zk1 = createClient(qu, 1, watcher);
-        ZooKeeper zk2 = createClient(qu, 2);
-
-        String path = "/test-deleted";
-
-        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.getData(path, watcher, null);
-        qu.shutdown(1);
-        zk2.delete(path, -1);
-        qu.start(1);
-        watcher.waitForConnected(TIMEOUT * 1000L);
-        watcher.assertEvent(TIMEOUT, EventType.NodeDeleted);
-
-        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.exists(path, watcher);
-        qu.shutdown(1);
-        zk2.delete(path, -1);
-        qu.start(1);
-        watcher.waitForConnected(TIMEOUT * 1000L);
-        watcher.assertEvent(TIMEOUT, EventType.NodeDeleted);
-
-        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.getChildren(path, watcher);
-        qu.shutdown(1);
-        zk2.delete(path, -1);
-        qu.start(1);
-        watcher.waitForConnected(TIMEOUT * 1000L);
-        watcher.assertEvent(TIMEOUT, EventType.NodeDeleted);
-
-        qu.shutdownAll();
-    }
-
-    @Test
-    public void testNodeChildrenChanged() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-
-        EventsWatcher watcher = new EventsWatcher();
-        ZooKeeper zk1 = createClient(qu, 1, watcher);
-        ZooKeeper zk2 = createClient(qu, 2);
-
-        String path = "/test-children-changed";
-
-        zk1.create(path, new byte[1], ZooDefs.Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.getChildren(path, watcher);
-        qu.shutdown(1);
-        zk2.create(path + "/children-1", new byte[2],
-                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        qu.start(1);
-        watcher.waitForConnected(TIMEOUT * 1000L);
-        watcher.assertEvent(TIMEOUT, EventType.NodeChildrenChanged);
-
-        qu.shutdownAll();
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java
deleted file mode 100644
index 0eaea67..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatchedEventTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.util.EnumSet;
-
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.proto.WatcherEvent;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class WatchedEventTest extends ZKTestCase {
-    
-    @Test
-    public void testCreatingWatchedEvent() {
-        // EventWatch is a simple, immutable type, so all we need to do
-       // is make sure we can create all possible combinations of values.
-
-        EnumSet<EventType> allTypes = EnumSet.allOf(EventType.class);
-       EnumSet<KeeperState> allStates = EnumSet.allOf(KeeperState.class);
-       WatchedEvent we;
-
-        for(EventType et : allTypes) {
-           for(KeeperState ks : allStates) {
-               we = new WatchedEvent(et, ks, "blah");
-               Assert.assertEquals(et, we.getType());
-               Assert.assertEquals(ks, we.getState());
-               Assert.assertEquals("blah", we.getPath());
-           }
-            
-        }
-    }
-
-    @Test
-    public void testCreatingWatchedEventFromWrapper() {
-        // Make sure we can handle any type of correct wrapper
-
-        EnumSet<EventType> allTypes = EnumSet.allOf(EventType.class);
-       EnumSet<KeeperState> allStates = EnumSet.allOf(KeeperState.class);
-       WatchedEvent we;
-       WatcherEvent wep;
-
-        for(EventType et : allTypes) {
-           for(KeeperState ks : allStates) {
-               wep = new WatcherEvent(et.getIntValue(), ks.getIntValue(), "blah");
-               we = new WatchedEvent(wep);
-               Assert.assertEquals(et, we.getType());
-               Assert.assertEquals(ks, we.getState());
-               Assert.assertEquals("blah", we.getPath());
-           }
-        }
-    }
-
-    @Test
-    public void testCreatingWatchedEventFromInvalidWrapper() {
-        // Make sure we can't convert from an invalid wrapper
-
-       try {
-           WatcherEvent wep = new WatcherEvent(-2342, -252352, "foo");
-           WatchedEvent we = new WatchedEvent(wep);
-           Assert.fail("Was able to create WatchedEvent from bad wrapper");
-       } catch (RuntimeException re) {
-           // we're good
-       }
-    }
-
-   @Test
-   public void testConvertingToEventWrapper() {
-       WatchedEvent we = new WatchedEvent(EventType.NodeCreated, KeeperState.Expired, "blah");
-       WatcherEvent wew = we.getWrapper();
-       
-       Assert.assertEquals(EventType.NodeCreated.getIntValue(), wew.getType());
-       Assert.assertEquals(KeeperState.Expired.getIntValue(), wew.getState());
-       Assert.assertEquals("blah", wew.getPath());
-   }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java
deleted file mode 100644
index a6c62e4..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/WatcherFuncTest.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-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.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class WatcherFuncTest extends ClientBase {
-    private static class SimpleWatcher implements Watcher {
-        private LinkedBlockingQueue<WatchedEvent> events =
-            new LinkedBlockingQueue<WatchedEvent>();
-        private CountDownLatch latch;
-
-        public SimpleWatcher(CountDownLatch latch) {
-            this.latch = latch;
-        }
-
-        public void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.SyncConnected) {
-                if (latch != null) {
-                    latch.countDown();
-                }
-            }
-
-            if (event.getType() == EventType.None) {
-                return;
-            }
-            try {
-                events.put(event);
-            } catch (InterruptedException e) {
-                Assert.assertTrue("interruption unexpected", false);
-            }
-        }
-        public void verify(List<EventType> expected) throws InterruptedException{
-            WatchedEvent event;
-            int count = 0;
-            while (count < expected.size()
-                    && (event = events.poll(30, TimeUnit.SECONDS)) != null)
-            {
-                Assert.assertEquals(expected.get(count), event.getType());
-                count++;
-            }
-            Assert.assertEquals(expected.size(), count);
-            events.clear();
-        }
-    }
-    private SimpleWatcher client_dwatch;
-    private volatile CountDownLatch client_latch;
-    private ZooKeeper client;
-    private SimpleWatcher lsnr_dwatch;
-    private volatile CountDownLatch lsnr_latch;
-    private ZooKeeper lsnr;
-
-    private List<EventType> expected;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        client_latch = new CountDownLatch(1);
-        client_dwatch = new SimpleWatcher(client_latch);
-        client = createClient(client_dwatch, client_latch);
-
-        lsnr_latch = new CountDownLatch(1);
-        lsnr_dwatch = new SimpleWatcher(lsnr_latch);
-        lsnr = createClient(lsnr_dwatch, lsnr_latch);
-
-        expected = new ArrayList<EventType>();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        client.close();
-        lsnr.close();
-        super.tearDown();
-    }
-
-    protected ZooKeeper createClient(Watcher watcher, CountDownLatch latch)
-        throws IOException, InterruptedException
-    {
-        ZooKeeper zk = new ZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher);
-        if(!latch.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)){
-            Assert.fail("Unable to connect to server");
-        }
-        return zk;
-    }
-
-    private void verify() throws InterruptedException {
-        lsnr_dwatch.verify(expected);
-        expected.clear();
-    }
-
-    @Test
-    public void testExistsSync()
-        throws IOException, InterruptedException, KeeperException
-    {
-        Assert.assertNull(lsnr.exists("/foo", true));
-        Assert.assertNull(lsnr.exists("/foo/bar", true));
-
-        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        expected.add(EventType.NodeCreated);
-        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        expected.add(EventType.NodeCreated);
-
-        verify();
-
-        Assert.assertNotNull(lsnr.exists("/foo", true));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", true));
-
-        try {
-            Assert.assertNull(lsnr.exists("/car", true));
-            client.setData("/car", "missing".getBytes(), -1);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/car", e.getPath());
-        }
-
-        try {
-            Assert.assertNull(lsnr.exists("/foo/car", true));
-            client.setData("/foo/car", "missing".getBytes(), -1);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo/car", e.getPath());
-        }
-
-        client.setData("/foo", "parent".getBytes(), -1);
-        expected.add(EventType.NodeDataChanged);
-        client.setData("/foo/bar", "child".getBytes(), -1);
-        expected.add(EventType.NodeDataChanged);
-
-        verify();
-
-        Assert.assertNotNull(lsnr.exists("/foo", true));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", true));
-
-        client.delete("/foo/bar", -1);
-        expected.add(EventType.NodeDeleted);
-        client.delete("/foo", -1);
-        expected.add(EventType.NodeDeleted);
-
-        verify();
-    }
-
-    @Test
-    public void testGetDataSync()
-        throws IOException, InterruptedException, KeeperException
-    {
-        try {
-            lsnr.getData("/foo", true, null);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo", e.getPath());
-        }
-        try {
-            lsnr.getData("/foo/bar", true, null);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo/bar", e.getPath());
-        }
-
-        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Assert.assertNotNull(lsnr.getData("/foo", true, null));
-        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Assert.assertNotNull(lsnr.getData("/foo/bar", true, null));
-
-        client.setData("/foo", "parent".getBytes(), -1);
-        expected.add(EventType.NodeDataChanged);
-        client.setData("/foo/bar", "child".getBytes(), -1);
-        expected.add(EventType.NodeDataChanged);
-
-        verify();
-
-        Assert.assertNotNull(lsnr.getData("/foo", true, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", true, null));
-
-        client.delete("/foo/bar", -1);
-        expected.add(EventType.NodeDeleted);
-        client.delete("/foo", -1);
-        expected.add(EventType.NodeDeleted);
-
-        verify();
-    }
-
-    @Test
-    public void testGetChildrenSync()
-        throws IOException, InterruptedException, KeeperException
-    {
-        try {
-            lsnr.getChildren("/foo", true);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo", e.getPath());
-        }
-        try {
-            lsnr.getChildren("/foo/bar", true);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo/bar", e.getPath());
-        }
-
-        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Assert.assertNotNull(lsnr.getChildren("/foo", true));
-
-        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        expected.add(EventType.NodeChildrenChanged); // /foo
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", true));
-
-
-        client.setData("/foo", "parent".getBytes(), -1);
-        client.setData("/foo/bar", "child".getBytes(), -1);
-
-
-        Assert.assertNotNull(lsnr.exists("/foo", true));
-
-        Assert.assertNotNull(lsnr.getChildren("/foo", true));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", true));
-
-        client.delete("/foo/bar", -1);
-        expected.add(EventType.NodeDeleted); // /foo/bar childwatch
-        expected.add(EventType.NodeChildrenChanged); // /foo
-        client.delete("/foo", -1);
-        expected.add(EventType.NodeDeleted);
-
-        verify();
-    }
-
-    @Test
-    public void testExistsSyncWObj()
-        throws IOException, InterruptedException, KeeperException
-    {
-        SimpleWatcher w1 = new SimpleWatcher(null);
-        SimpleWatcher w2 = new SimpleWatcher(null);
-        SimpleWatcher w3 = new SimpleWatcher(null);
-        SimpleWatcher w4 = new SimpleWatcher(null);
-
-        List<EventType> e2 = new ArrayList<EventType>();
-
-        Assert.assertNull(lsnr.exists("/foo", true));
-        Assert.assertNull(lsnr.exists("/foo", w1));
-
-        Assert.assertNull(lsnr.exists("/foo/bar", w2));
-        Assert.assertNull(lsnr.exists("/foo/bar", w3));
-        Assert.assertNull(lsnr.exists("/foo/bar", w3));
-        Assert.assertNull(lsnr.exists("/foo/bar", w4));
-
-        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        expected.add(EventType.NodeCreated);
-        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        e2.add(EventType.NodeCreated);
-
-        lsnr_dwatch.verify(expected);
-        w1.verify(expected);
-        w2.verify(e2);
-        w3.verify(e2);
-        w4.verify(e2);
-        expected.clear();
-        e2.clear();
-
-        // default not registered
-        Assert.assertNotNull(lsnr.exists("/foo", w1));
-
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w2));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w3));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w4));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w4));
-
-        client.setData("/foo", "parent".getBytes(), -1);
-        expected.add(EventType.NodeDataChanged);
-        client.setData("/foo/bar", "child".getBytes(), -1);
-        e2.add(EventType.NodeDataChanged);
-
-        lsnr_dwatch.verify(new ArrayList<EventType>()); // not reg so should = 0
-        w1.verify(expected);
-        w2.verify(e2);
-        w3.verify(e2);
-        w4.verify(e2);
-        expected.clear();
-        e2.clear();
-
-        Assert.assertNotNull(lsnr.exists("/foo", true));
-        Assert.assertNotNull(lsnr.exists("/foo", w1));
-        Assert.assertNotNull(lsnr.exists("/foo", w1));
-
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w2));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w2));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w3));
-        Assert.assertNotNull(lsnr.exists("/foo/bar", w4));
-
-        client.delete("/foo/bar", -1);
-        expected.add(EventType.NodeDeleted);
-        client.delete("/foo", -1);
-        e2.add(EventType.NodeDeleted);
-
-        lsnr_dwatch.verify(expected);
-        w1.verify(expected);
-        w2.verify(e2);
-        w3.verify(e2);
-        w4.verify(e2);
-        expected.clear();
-        e2.clear();
-
-    }
-
-    @Test
-    public void testGetDataSyncWObj()
-        throws IOException, InterruptedException, KeeperException
-    {
-        SimpleWatcher w1 = new SimpleWatcher(null);
-        SimpleWatcher w2 = new SimpleWatcher(null);
-        SimpleWatcher w3 = new SimpleWatcher(null);
-        SimpleWatcher w4 = new SimpleWatcher(null);
-
-        List<EventType> e2 = new ArrayList<EventType>();
-
-        try {
-            lsnr.getData("/foo", w1, null);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo", e.getPath());
-        }
-        try {
-            lsnr.getData("/foo/bar", w2, null);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo/bar", e.getPath());
-        }
-
-        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Assert.assertNotNull(lsnr.getData("/foo", true, null));
-        Assert.assertNotNull(lsnr.getData("/foo", w1, null));
-        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w2, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w3, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w4, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w4, null));
-
-        client.setData("/foo", "parent".getBytes(), -1);
-        expected.add(EventType.NodeDataChanged);
-        client.setData("/foo/bar", "child".getBytes(), -1);
-        e2.add(EventType.NodeDataChanged);
-
-        lsnr_dwatch.verify(expected);
-        w1.verify(expected);
-        w2.verify(e2);
-        w3.verify(e2);
-        w4.verify(e2);
-        expected.clear();
-        e2.clear();
-
-        Assert.assertNotNull(lsnr.getData("/foo", true, null));
-        Assert.assertNotNull(lsnr.getData("/foo", w1, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w2, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w3, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w3, null));
-        Assert.assertNotNull(lsnr.getData("/foo/bar", w4, null));
-
-        client.delete("/foo/bar", -1);
-        expected.add(EventType.NodeDeleted);
-        client.delete("/foo", -1);
-        e2.add(EventType.NodeDeleted);
-
-        lsnr_dwatch.verify(expected);
-        w1.verify(expected);
-        w2.verify(e2);
-        w3.verify(e2);
-        w4.verify(e2);
-        expected.clear();
-        e2.clear();
-    }
-
-    @Test
-    public void testGetChildrenSyncWObj()
-        throws IOException, InterruptedException, KeeperException
-    {
-        SimpleWatcher w1 = new SimpleWatcher(null);
-        SimpleWatcher w2 = new SimpleWatcher(null);
-        SimpleWatcher w3 = new SimpleWatcher(null);
-        SimpleWatcher w4 = new SimpleWatcher(null);
-
-        List<EventType> e2 = new ArrayList<EventType>();
-
-        try {
-            lsnr.getChildren("/foo", true);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo", e.getPath());
-        }
-        try {
-            lsnr.getChildren("/foo/bar", true);
-            Assert.fail();
-        } catch (KeeperException e) {
-            Assert.assertEquals(KeeperException.Code.NONODE, e.code());
-            Assert.assertEquals("/foo/bar", e.getPath());
-        }
-
-        client.create("/foo", "parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Assert.assertNotNull(lsnr.getChildren("/foo", true));
-        Assert.assertNotNull(lsnr.getChildren("/foo", w1));
-
-        client.create("/foo/bar", "child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        expected.add(EventType.NodeChildrenChanged); // /foo
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w2));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w2));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w3));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w4));
-
-
-        client.setData("/foo", "parent".getBytes(), -1);
-        client.setData("/foo/bar", "child".getBytes(), -1);
-
-
-        Assert.assertNotNull(lsnr.exists("/foo", true));
-        Assert.assertNotNull(lsnr.exists("/foo", w1));
-        Assert.assertNotNull(lsnr.exists("/foo", true));
-        Assert.assertNotNull(lsnr.exists("/foo", w1));
-
-        Assert.assertNotNull(lsnr.getChildren("/foo", true));
-        Assert.assertNotNull(lsnr.getChildren("/foo", w1));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w2));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w3));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w4));
-        Assert.assertNotNull(lsnr.getChildren("/foo/bar", w4));
-
-        client.delete("/foo/bar", -1);
-        e2.add(EventType.NodeDeleted); // /foo/bar childwatch
-        expected.add(EventType.NodeChildrenChanged); // /foo
-        client.delete("/foo", -1);
-        expected.add(EventType.NodeDeleted);
-
-        lsnr_dwatch.verify(expected);
-        w1.verify(expected);
-        w2.verify(e2);
-        w3.verify(e2);
-        w4.verify(e2);
-        expected.clear();
-        e2.clear();
-    }
-}


[16/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java b/zookeeper-server/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java
new file mode 100644
index 0000000..d6f5549
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/SaslClientCallbackHandler.java
@@ -0,0 +1,104 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.RealmCallback;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is used by the SASL mechanisms to get further information to complete
+ * the authentication. For example, a SASL mechanism might use this callback
+ * handler to do verification operation. The CallbackHandler interface here
+ * refers to javax.security.auth.callback.CallbackHandler. It should not be
+ * confused with ZooKeeper packet callbacks like
+ * org.apache.zookeeper.server.auth.SaslServerCallbackHandler.
+ */
+public class SaslClientCallbackHandler implements CallbackHandler {
+    private String password = null;
+    private static final Logger LOG = LoggerFactory.getLogger(SaslClientCallbackHandler.class);
+    private final String entity;
+    public SaslClientCallbackHandler(String password, String client) {
+        this.password = password;
+        this.entity = client;
+    }
+
+    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
+        for (Callback callback : callbacks) {
+            if (callback instanceof NameCallback) {
+                NameCallback nc = (NameCallback) callback;
+                nc.setName(nc.getDefaultName());
+            }
+            else {
+                if (callback instanceof PasswordCallback) {
+                    PasswordCallback pc = (PasswordCallback)callback;
+                    if (password != null) {
+                        pc.setPassword(this.password.toCharArray());
+                    } else {
+                        LOG.warn("Could not login: the {} is being asked for a password, but the ZooKeeper {}" +
+                          " code does not currently support obtaining a password from the user." +
+                          " Make sure that the {} is configured to use a ticket cache (using" +
+                          " the JAAS configuration setting 'useTicketCache=true)' and restart the {}. If" +
+                          " you still get this message after that, the TGT in the ticket cache has expired and must" +
+                          " be manually refreshed. To do so, first determine if you are using a password or a" +
+                          " keytab. If the former, run kinit in a Unix shell in the environment of the user who" +
+                          " is running this Zookeeper {} using the command" +
+                          " 'kinit <princ>' (where <princ> is the name of the {}'s Kerberos principal)." +
+                          " If the latter, do" +
+                          " 'kinit -k -t <keytab> <princ>' (where <princ> is the name of the Kerberos principal, and" +
+                          " <keytab> is the location of the keytab file). After manually refreshing your cache," +
+                          " restart this {}. If you continue to see this message after manually refreshing" +
+                          " your cache, ensure that your KDC host's clock is in sync with this host's clock.",
+                          new Object[]{entity, entity, entity, entity, entity, entity, entity});
+                    }
+                }
+                else {
+                    if (callback instanceof RealmCallback) {
+                        RealmCallback rc = (RealmCallback) callback;
+                        rc.setText(rc.getDefaultText());
+                    }
+                    else {
+                        if (callback instanceof AuthorizeCallback) {
+                            AuthorizeCallback ac = (AuthorizeCallback) callback;
+                            String authid = ac.getAuthenticationID();
+                            String authzid = ac.getAuthorizationID();
+                            if (authid.equals(authzid)) {
+                                ac.setAuthorized(true);
+                            } else {
+                                ac.setAuthorized(false);
+                            }
+                            if (ac.isAuthorized()) {
+                                ac.setAuthorizedID(authzid);
+                            }
+                        }
+                        else {
+                            throw new UnsupportedCallbackException(callback, "Unrecognized SASL " + entity + "Callback");
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ServerAdminClient.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ServerAdminClient.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ServerAdminClient.java
new file mode 100644
index 0000000..9464f1c
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ServerAdminClient.java
@@ -0,0 +1,316 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.StringTokenizer;
+
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.zookeeper.server.ZooTrace;
+
+@InterfaceAudience.Public
+public class ServerAdminClient {
+    private static final Logger LOG = LoggerFactory.getLogger(ServerAdminClient.class);
+
+    private static long getMask(String mask) {
+        long retv = 0;
+        if (mask.equalsIgnoreCase("CLIENT_REQUEST_TRACE_MASK")) {
+            retv = ZooTrace.CLIENT_REQUEST_TRACE_MASK;
+        } else if (mask.equalsIgnoreCase("CLIENT_DATA_PACKET_TRACE_MASK")) {
+            retv = ZooTrace.CLIENT_DATA_PACKET_TRACE_MASK;
+        } else if (mask.equalsIgnoreCase("CLIENT_PING_TRACE_MASK")) {
+            retv = ZooTrace.CLIENT_PING_TRACE_MASK;
+        } else if (mask.equalsIgnoreCase("SERVER_PACKET_TRACE_MASK")) {
+            retv = ZooTrace.SERVER_PACKET_TRACE_MASK;
+        } else if (mask.equalsIgnoreCase("SESSION_TRACE_MASK")) {
+            retv = ZooTrace.SESSION_TRACE_MASK;
+        } else if (mask.equalsIgnoreCase("EVENT_DELIVERY_TRACE_MASK")) {
+            retv = ZooTrace.EVENT_DELIVERY_TRACE_MASK;
+        } else if (mask.equalsIgnoreCase("SERVER_PING_TRACE_MASK")) {
+            retv = ZooTrace.SERVER_PING_TRACE_MASK;
+        } else if (mask.equalsIgnoreCase("WARNING_TRACE_MASK")) {
+            retv = ZooTrace.WARNING_TRACE_MASK;
+        }
+        return retv;
+    }
+
+    private static long getMasks(String masks) {
+        long retv = 0;
+        StringTokenizer st = new StringTokenizer(masks, "|");
+        while (st.hasMoreTokens()) {
+            String mask = st.nextToken().trim();
+            retv = retv | getMask(mask);
+        }
+        return retv;
+    }
+
+    public static void ruok(String host, int port) {
+        Socket s = null;
+        try {
+            byte[] reqBytes = new byte[4];
+            ByteBuffer req = ByteBuffer.wrap(reqBytes);
+            req.putInt(ByteBuffer.wrap("ruok".getBytes()).getInt());
+            s = new Socket();
+            s.setSoLinger(false, 10);
+            s.setSoTimeout(20000);
+            s.connect(new InetSocketAddress(host, port));
+
+            InputStream is = s.getInputStream();
+            OutputStream os = s.getOutputStream();
+
+            os.write(reqBytes);
+
+            byte[] resBytes = new byte[4];
+
+            int rc = is.read(resBytes);
+            String retv = new String(resBytes);
+            System.out.println("rc=" + rc + " retv=" + retv);
+        } catch (IOException e) {
+            LOG.warn("Unexpected exception", e);
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (IOException e) {
+                    LOG.warn("Unexpected exception", e);
+                }
+            }
+        }
+    }
+
+    public static void dump(String host, int port) {
+        Socket s = null;
+        try {
+            byte[] reqBytes = new byte[4];
+            ByteBuffer req = ByteBuffer.wrap(reqBytes);
+            req.putInt(ByteBuffer.wrap("dump".getBytes()).getInt());
+            s = new Socket();
+            s.setSoLinger(false, 10);
+            s.setSoTimeout(20000);
+            s.connect(new InetSocketAddress(host, port));
+
+            InputStream is = s.getInputStream();
+            OutputStream os = s.getOutputStream();
+
+            os.write(reqBytes);
+
+            byte[] resBytes = new byte[1024];
+
+            int rc = is.read(resBytes);
+            String retv = new String(resBytes);
+            System.out.println("rc=" + rc + " retv=" + retv);
+        } catch (IOException e) {
+            LOG.warn("Unexpected exception", e);
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (IOException e) {
+                    LOG.warn("Unexpected exception", e);
+                }
+            }
+        }
+    }
+
+    public static void stat(String host, int port) {
+        Socket s = null;
+        try {
+            byte[] reqBytes = new byte[4];
+            ByteBuffer req = ByteBuffer.wrap(reqBytes);
+            req.putInt(ByteBuffer.wrap("stat".getBytes()).getInt());
+            s = new Socket();
+            s.setSoLinger(false, 10);
+            s.setSoTimeout(20000);
+            s.connect(new InetSocketAddress(host, port));
+
+            InputStream is = s.getInputStream();
+            OutputStream os = s.getOutputStream();
+
+            os.write(reqBytes);
+
+            byte[] resBytes = new byte[1024];
+
+            int rc = is.read(resBytes);
+            String retv = new String(resBytes);
+            System.out.println("rc=" + rc + " retv=" + retv);
+        } catch (IOException e) {
+            LOG.warn("Unexpected exception", e);
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (IOException e) {
+                    LOG.warn("Unexpected exception", e);
+                }
+            }
+        }
+    }
+
+    public static void kill(String host, int port) {
+        Socket s = null;
+        try {
+            byte[] reqBytes = new byte[4];
+            ByteBuffer req = ByteBuffer.wrap(reqBytes);
+            req.putInt(ByteBuffer.wrap("kill".getBytes()).getInt());
+            s = new Socket();
+            s.setSoLinger(false, 10);
+            s.setSoTimeout(20000);
+            s.connect(new InetSocketAddress(host, port));
+
+            InputStream is = s.getInputStream();
+            OutputStream os = s.getOutputStream();
+
+            os.write(reqBytes);
+            byte[] resBytes = new byte[4];
+
+            int rc = is.read(resBytes);
+            String retv = new String(resBytes);
+            System.out.println("rc=" + rc + " retv=" + retv);
+        } catch (IOException e) {
+            LOG.warn("Unexpected exception", e);
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (IOException e) {
+                    LOG.warn("Unexpected exception", e);
+                }
+            }
+        }
+    }
+
+    public static void setTraceMask(String host, int port, String traceMaskStr) {
+        Socket s = null;
+        try {
+            byte[] reqBytes = new byte[12];
+            ByteBuffer req = ByteBuffer.wrap(reqBytes);
+            long traceMask = Long.parseLong(traceMaskStr, 8);
+            req.putInt(ByteBuffer.wrap("stmk".getBytes()).getInt());
+            req.putLong(traceMask);
+
+            s = new Socket();
+            s.setSoLinger(false, 10);
+            s.setSoTimeout(20000);
+            s.connect(new InetSocketAddress(host, port));
+
+            InputStream is = s.getInputStream();
+            OutputStream os = s.getOutputStream();
+
+            os.write(reqBytes);
+
+            byte[] resBytes = new byte[8];
+
+            int rc = is.read(resBytes);
+            ByteBuffer res = ByteBuffer.wrap(resBytes);
+            long retv = res.getLong();
+            System.out.println("rc=" + rc + " retv=0"
+                    + Long.toOctalString(retv) + " masks=0"
+                    + Long.toOctalString(traceMask));
+            assert (retv == traceMask);
+        } catch (IOException e) {
+            LOG.warn("Unexpected exception", e);
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (IOException e) {
+                    LOG.warn("Unexpected exception", e);
+                }
+            }
+        }
+    }
+
+    public static void getTraceMask(String host, int port) {
+        Socket s = null;
+        try {
+            byte[] reqBytes = new byte[12];
+            ByteBuffer req = ByteBuffer.wrap(reqBytes);
+            req.putInt(ByteBuffer.wrap("gtmk".getBytes()).getInt());
+
+            s = new Socket();
+            s.setSoLinger(false, 10);
+            s.setSoTimeout(20000);
+            s.connect(new InetSocketAddress(host, port));
+
+            InputStream is = s.getInputStream();
+            OutputStream os = s.getOutputStream();
+
+            os.write(reqBytes);
+
+            byte[] resBytes = new byte[8];
+
+            int rc = is.read(resBytes);
+            ByteBuffer res = ByteBuffer.wrap(resBytes);
+            long retv = res.getLong();
+            System.out.println("rc=" + rc + " retv=0"
+                    + Long.toOctalString(retv));
+        } catch (IOException e) {
+            LOG.warn("Unexpected exception", e);
+        } finally {
+            if (s != null) {
+                try {
+                    s.close();
+                } catch (IOException e) {
+                    LOG.warn("Unexpected exception", e);
+                }
+            }
+        }
+    }
+
+    private static void usage() {
+        System.out
+                .println("usage: java [-cp CLASSPATH] org.apache.zookeeper.ServerAdminClient "
+                        + "host port op (ruok|stat|dump|kill|gettracemask|settracemask) [arguments]");
+
+    }
+
+    public static void main(String[] args) {
+        if (args.length < 3) {
+            usage();
+            return;
+        }
+        String host = args[0];
+        int port = Integer.parseInt(args[1]);
+        String op = args[2];
+        if (op.equalsIgnoreCase("gettracemask")) {
+            getTraceMask(host, port);
+        } else if (op.equalsIgnoreCase("settracemask")) {
+            setTraceMask(host, port, args[3]);
+        } else if (op.equalsIgnoreCase("ruok")) {
+            ruok(host, port);
+        } else if (op.equalsIgnoreCase("kill")) {
+            kill(host, port);
+        } else if (op.equalsIgnoreCase("stat")) {
+            stat(host, port);
+        } else if (op.equalsIgnoreCase("dump")) {
+            dump(host, port);
+        } else {
+            System.out.println("Unrecognized op: " + op);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Shell.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Shell.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Shell.java
new file mode 100644
index 0000000..246170e
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Shell.java
@@ -0,0 +1,477 @@
+/**
+ * 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.
+ */
+
+/* This file copied from Hadoop's security branch,
+  * with the following changes:
+  * 1. package changed from org.apache.hadoop.util to
+  *    org.apache.zookeeper.
+  * 2. Usage of Hadoop's Configuration class removed since
+  *    it is not available in Zookeeper: instead, system properties
+  *    are used.
+  * 3. The deprecated getUlimitMemoryCommand() method removed since
+  *    it is not needed.
+  */
+
+
+package org.apache.zookeeper;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.common.Time;
+
+/**
+ * A base class for running a Unix command.
+ * 
+ * <code>Shell</code> can be used to run unix commands like <code>du</code> or
+ * <code>df</code>. It also offers facilities to gate commands by 
+ * time-intervals.
+ */
+abstract public class Shell {
+  
+  Logger LOG = Logger.getLogger(Shell.class);
+  
+  /** a Unix command to get the current user's name */
+  public final static String USER_NAME_COMMAND = "whoami";
+  /** a Unix command to get the current user's groups list */
+  public static String[] getGroupsCommand() {
+    return new String[]{"bash", "-c", "groups"};
+  }
+  /** a Unix command to get a given user's groups list */
+  public static String[] getGroupsForUserCommand(final String user) {
+    //'groups username' command return is non-consistent across different unixes
+    return new String [] {"bash", "-c", "id -Gn " + user};
+  }
+  /** a Unix command to set permission */
+  public static final String SET_PERMISSION_COMMAND = "chmod";
+  /** a Unix command to set owner */
+  public static final String SET_OWNER_COMMAND = "chown";
+  public static final String SET_GROUP_COMMAND = "chgrp";
+  /** Return a Unix command to get permission information. */
+  public static String[] getGET_PERMISSION_COMMAND() {
+    //force /bin/ls, except on windows.
+    return new String[] {(WINDOWS ? "ls" : "/bin/ls"), "-ld"};
+  }
+
+  /**Time after which the executing script would be timedout*/
+  protected long timeOutInterval = 0L;
+  /** If or not script timed out*/
+  private AtomicBoolean timedOut;
+
+  /** a Unix command to get ulimit of a process. */
+  public static final String ULIMIT_COMMAND = "ulimit";
+  
+  /** 
+   * Get the Unix command for setting the maximum virtual memory available
+   * to a given child process. This is only relevant when we are forking a
+   * process from within the Mapper or the Reducer implementations.
+   * Also see Hadoop Pipes and Hadoop Streaming.
+   * 
+   * It also checks to ensure that we are running on a *nix platform else 
+   * (e.g. in Cygwin/Windows) it returns <code>null</code>.
+   * @param memoryLimit virtual memory limit
+   * @return a <code>String[]</code> with the ulimit command arguments or 
+   *         <code>null</code> if we are running on a non *nix platform or
+   *         if the limit is unspecified.
+   */
+  public static String[] getUlimitMemoryCommand(int memoryLimit) {
+    // ulimit isn't supported on Windows
+    if (WINDOWS) {
+      return null;
+    }
+    
+    return new String[] {ULIMIT_COMMAND, "-v", String.valueOf(memoryLimit)};
+  }
+
+  /** Set to true on Windows platforms */
+  public static final boolean WINDOWS /* borrowed from Path.WINDOWS */
+                = System.getProperty("os.name").startsWith("Windows");
+  
+  private long    interval;   // refresh interval in msec
+  private long    lastTime;   // last time the command was performed
+  private Map<String, String> environment; // env for the command execution
+  private File dir;
+  private Process process; // sub process used to execute the command
+  private int exitCode;
+
+  /**If or not script finished executing*/
+  private volatile AtomicBoolean completed;
+  
+  public Shell() {
+    this(0L);
+  }
+  
+  /**
+   * @param interval the minimum duration to wait before re-executing the 
+   *        command.
+   */
+  public Shell( long interval ) {
+    this.interval = interval;
+    this.lastTime = (interval<0) ? 0 : -interval;
+  }
+  
+  /** set the environment for the command 
+   * @param env Mapping of environment variables
+   */
+  protected void setEnvironment(Map<String, String> env) {
+    this.environment = env;
+  }
+
+  /** set the working directory 
+   * @param dir The directory where the command would be executed
+   */
+  protected void setWorkingDirectory(File dir) {
+    this.dir = dir;
+  }
+
+  /** check to see if a command needs to be executed and execute if needed */
+  protected void run() throws IOException {
+    if (lastTime + interval > Time.currentElapsedTime())
+      return;
+    exitCode = 0; // reset for next run
+    runCommand();
+  }
+
+  /** Run a command */
+  private void runCommand() throws IOException { 
+    ProcessBuilder builder = new ProcessBuilder(getExecString());
+    Timer timeOutTimer = null;
+    ShellTimeoutTimerTask timeoutTimerTask = null;
+    timedOut = new AtomicBoolean(false);
+    completed = new AtomicBoolean(false);
+    
+    if (environment != null) {
+      builder.environment().putAll(this.environment);
+    }
+    if (dir != null) {
+      builder.directory(this.dir);
+    }
+    
+    process = builder.start();
+    if (timeOutInterval > 0) {
+      timeOutTimer = new Timer();
+      timeoutTimerTask = new ShellTimeoutTimerTask(
+          this);
+      //One time scheduling.
+      timeOutTimer.schedule(timeoutTimerTask, timeOutInterval);
+    }
+    final BufferedReader errReader = 
+            new BufferedReader(new InputStreamReader(process
+                                                     .getErrorStream()));
+    BufferedReader inReader = 
+            new BufferedReader(new InputStreamReader(process
+                                                     .getInputStream()));
+    final StringBuffer errMsg = new StringBuffer();
+    
+    // read error and input streams as this would free up the buffers
+    // free the error stream buffer
+    Thread errThread = new Thread() {
+      @Override
+      public void run() {
+        try {
+          String line = errReader.readLine();
+          while((line != null) && !isInterrupted()) {
+            errMsg.append(line);
+            errMsg.append(System.getProperty("line.separator"));
+            line = errReader.readLine();
+          }
+        } catch(IOException ioe) {
+          LOG.warn("Error reading the error stream", ioe);
+        }
+      }
+    };
+    try {
+      errThread.start();
+    } catch (IllegalStateException ise) { }
+    try {
+      parseExecResult(inReader); // parse the output
+      // clear the input stream buffer
+      String line = inReader.readLine();
+      while(line != null) { 
+        line = inReader.readLine();
+      }
+      // wait for the process to finish and check the exit code
+      exitCode  = process.waitFor();
+      try {
+        // make sure that the error thread exits
+        errThread.join();
+      } catch (InterruptedException ie) {
+        LOG.warn("Interrupted while reading the error stream", ie);
+      }
+      completed.set(true);
+      //the timeout thread handling
+      //taken care in finally block
+      if (exitCode != 0) {
+        throw new ExitCodeException(exitCode, errMsg.toString());
+      }
+    } catch (InterruptedException ie) {
+      throw new IOException(ie.toString());
+    } finally {
+      if ((timeOutTimer!=null) && !timedOut.get()) {
+        timeOutTimer.cancel();
+      }
+      // close the input stream
+      try {
+        inReader.close();
+      } catch (IOException ioe) {
+        LOG.warn("Error while closing the input stream", ioe);
+      }
+      if (!completed.get()) {
+        errThread.interrupt();
+      }
+      try {
+        errReader.close();
+      } catch (IOException ioe) {
+        LOG.warn("Error while closing the error stream", ioe);
+      }
+      process.destroy();
+      lastTime = Time.currentElapsedTime();
+    }
+  }
+
+  /** return an array containing the command name & its parameters */ 
+  protected abstract String[] getExecString();
+  
+  /** Parse the execution result */
+  protected abstract void parseExecResult(BufferedReader lines)
+  throws IOException;
+
+  /** get the current sub-process executing the given command 
+   * @return process executing the command
+   */
+  public Process getProcess() {
+    return process;
+  }
+
+  /** get the exit code 
+   * @return the exit code of the process
+   */
+  public int getExitCode() {
+    return exitCode;
+  }
+
+  /**
+   * This is an IOException with exit code added.
+   */
+  @SuppressWarnings("serial")
+  public static class ExitCodeException extends IOException {
+    int exitCode;
+    
+    public ExitCodeException(int exitCode, String message) {
+      super(message);
+      this.exitCode = exitCode;
+    }
+    
+    public int getExitCode() {
+      return exitCode;
+    }
+  }
+  
+  /**
+   * A simple shell command executor.
+   * 
+   * <code>ShellCommandExecutor</code>should be used in cases where the output 
+   * of the command needs no explicit parsing and where the command, working 
+   * directory and the environment remains unchanged. The output of the command 
+   * is stored as-is and is expected to be small.
+   */
+  public static class ShellCommandExecutor extends Shell {
+    
+    private String[] command;
+    private StringBuffer output;
+    
+    
+    public ShellCommandExecutor(String[] execString) {
+      this(execString, null);
+    }
+    
+    public ShellCommandExecutor(String[] execString, File dir) {
+      this(execString, dir, null);
+    }
+   
+    public ShellCommandExecutor(String[] execString, File dir, 
+                                 Map<String, String> env) {
+      this(execString, dir, env , 0L);
+    }
+
+    /**
+     * Create a new instance of the ShellCommandExecutor to execute a command.
+     * 
+     * @param execString The command to execute with arguments
+     * @param dir If not-null, specifies the directory which should be set
+     *            as the current working directory for the command.
+     *            If null, the current working directory is not modified.
+     * @param env If not-null, environment of the command will include the
+     *            key-value pairs specified in the map. If null, the current
+     *            environment is not modified.
+     * @param timeout Specifies the time in milliseconds, after which the
+     *                command will be killed and the status marked as timedout.
+     *                If 0, the command will not be timed out. 
+     */
+    public ShellCommandExecutor(String[] execString, File dir, 
+        Map<String, String> env, long timeout) {
+      command = execString.clone();
+      if (dir != null) {
+        setWorkingDirectory(dir);
+      }
+      if (env != null) {
+        setEnvironment(env);
+      }
+      timeOutInterval = timeout;
+    }
+        
+
+    /** Execute the shell command. */
+    public void execute() throws IOException {
+      this.run();    
+    }
+
+    protected String[] getExecString() {
+      return command;
+    }
+
+    protected void parseExecResult(BufferedReader lines) throws IOException {
+      output = new StringBuffer();
+      char[] buf = new char[512];
+      int nRead;
+      while ( (nRead = lines.read(buf, 0, buf.length)) > 0 ) {
+        output.append(buf, 0, nRead);
+      }
+    }
+    
+    /** Get the output of the shell command.*/
+    public String getOutput() {
+      return (output == null) ? "" : output.toString();
+    }
+
+    /**
+     * Returns the commands of this instance.
+     * Arguments with spaces in are presented with quotes round; other
+     * arguments are presented raw
+     *
+     * @return a string representation of the object.
+     */
+    public String toString() {
+      StringBuilder builder = new StringBuilder();
+      String[] args = getExecString();
+      for (String s : args) {
+        if (s.indexOf(' ') >= 0) {
+          builder.append('"').append(s).append('"');
+        } else {
+          builder.append(s);
+        }
+        builder.append(' ');
+      }
+      return builder.toString();
+    }
+  }
+  
+  /**
+   * To check if the passed script to shell command executor timed out or
+   * not.
+   * 
+   * @return if the script timed out.
+   */
+  public boolean isTimedOut() {
+    return timedOut.get();
+  }
+  
+  /**
+   * Set if the command has timed out.
+   * 
+   */
+  private void setTimedOut() {
+    this.timedOut.set(true);
+  }
+  
+  /** 
+   * Static method to execute a shell command. 
+   * Covers most of the simple cases without requiring the user to implement  
+   * the <code>Shell</code> interface.
+   * @param cmd shell command to execute.
+   * @return the output of the executed command.
+   */
+  public static String execCommand(String ... cmd) throws IOException {
+    return execCommand(null, cmd, 0L);
+  }
+  
+  /** 
+   * Static method to execute a shell command. 
+   * Covers most of the simple cases without requiring the user to implement  
+   * the <code>Shell</code> interface.
+   * @param env the map of environment key=value
+   * @param cmd shell command to execute.
+   * @param timeout time in milliseconds after which script should be marked timeout
+   * @return the output of the executed command.o
+   */
+  
+  public static String execCommand(Map<String, String> env, String[] cmd,
+      long timeout) throws IOException {
+    ShellCommandExecutor exec = new ShellCommandExecutor(cmd, null, env, 
+                                                          timeout);
+    exec.execute();
+    return exec.getOutput();
+  }
+
+  /** 
+   * Static method to execute a shell command. 
+   * Covers most of the simple cases without requiring the user to implement  
+   * the <code>Shell</code> interface.
+   * @param env the map of environment key=value
+   * @param cmd shell command to execute.
+   * @return the output of the executed command.
+   */
+  public static String execCommand(Map<String,String> env, String ... cmd) 
+  throws IOException {
+    return execCommand(env, cmd, 0L);
+  }
+  
+  /**
+   * Timer which is used to timeout scripts spawned off by shell.
+   */
+  private static class ShellTimeoutTimerTask extends TimerTask {
+
+    private Shell shell;
+
+    public ShellTimeoutTimerTask(Shell shell) {
+      this.shell = shell;
+    }
+
+    @Override
+    public void run() {
+      Process p = shell.getProcess();
+      try {
+        p.exitValue();
+      } catch (Exception e) {
+        //Process has not terminated.
+        //So check if it has completed 
+        //if not just destroy it.
+        if (p != null && !shell.completed.get()) {
+          shell.setTimedOut();
+          p.destroy();
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/StatsTrack.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/StatsTrack.java b/zookeeper-server/src/main/java/org/apache/zookeeper/StatsTrack.java
new file mode 100644
index 0000000..623c6d4
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/StatsTrack.java
@@ -0,0 +1,101 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+/**
+ * a class that represents the stats associated with quotas
+ */
+public class StatsTrack {
+    private int count;
+    private long bytes;
+    private String countStr = "count";
+    private String byteStr = "bytes";
+
+    /**
+     * a default constructor for
+     * stats
+     */
+    public StatsTrack() {
+        this(null);
+    }
+    /**
+     * the stat string should be of the form count=int,bytes=long
+     * if stats is called with null the count and bytes are initialized
+     * to -1.
+     * @param stats the stat string to be intialized with
+     */
+    public StatsTrack(String stats) {
+        if (stats == null) {
+            stats = "count=-1,bytes=-1";
+        }
+        String[] split = stats.split(",");
+        if (split.length != 2) {
+            throw new IllegalArgumentException("invalid string " + stats);
+        }
+        count = Integer.parseInt(split[0].split("=")[1]);
+        bytes = Long.parseLong(split[1].split("=")[1]);
+    }
+
+
+    /**
+     * get the count of nodes allowed as part of quota
+     *
+     * @return the count as part of this string
+     */
+    public int getCount() {
+        return this.count;
+    }
+
+    /**
+     * set the count for this stat tracker.
+     *
+     * @param count
+     *            the count to set with
+     */
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    /**
+     * get the count of bytes allowed as part of quota
+     *
+     * @return the bytes as part of this string
+     */
+    public long getBytes() {
+        return this.bytes;
+    }
+
+    /**
+     * set teh bytes for this stat tracker.
+     *
+     * @param bytes
+     *            the bytes to set with
+     */
+    public void setBytes(long bytes) {
+        this.bytes = bytes;
+    }
+
+    @Override
+    /*
+     * returns the string that maps to this stat tracking.
+     */
+    public String toString() {
+        return countStr + "=" + count + "," + byteStr + "=" + bytes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Testable.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Testable.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Testable.java
new file mode 100644
index 0000000..b38d2c3
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Testable.java
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+/**
+ * Abstraction that exposes various methods useful for testing ZooKeeper
+ */
+public interface Testable {
+    /**
+     * Cause the ZooKeeper instance to behave as if the session expired
+     */
+    void injectSessionExpiration();
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Transaction.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Transaction.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Transaction.java
new file mode 100644
index 0000000..d8f0e01
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Transaction.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.apache.zookeeper.AsyncCallback.MultiCallback;
+import org.apache.zookeeper.data.ACL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides a builder style interface for doing multiple updates.  This is
+ * really just a thin layer on top of Zookeeper.multi().
+ *
+ * @since 3.4.0
+ *
+ */
+@InterfaceAudience.Public
+public class Transaction {
+    private ZooKeeper zk;
+    private List<Op> ops = new ArrayList<Op>();
+
+    protected Transaction(ZooKeeper zk) {
+        this.zk = zk;
+    }
+
+    public Transaction create(final String path, byte data[], List<ACL> acl,
+                              CreateMode createMode) {
+        ops.add(Op.create(path, data, acl, createMode.toFlag()));
+        return this;
+    }
+
+    public Transaction delete(final String path, int version) {
+        ops.add(Op.delete(path, version));
+        return this;
+    }
+
+    public Transaction check(String path, int version) {
+        ops.add(Op.check(path, version));
+        return this;
+    }
+
+    public Transaction setData(final String path, byte data[], int version) {
+        ops.add(Op.setData(path, data, version));
+        return this;
+    }
+
+    public List<OpResult> commit() throws InterruptedException, KeeperException {
+        return zk.multi(ops);
+    }
+
+    public void commit(MultiCallback cb, Object ctx) {
+        zk.multi(ops, cb, ctx);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java
new file mode 100644
index 0000000..1f5cf1a
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java
@@ -0,0 +1,90 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+public class Version implements org.apache.zookeeper.version.Info {
+
+    /*
+     * Since the SVN to Git port this field doesn't return the revision anymore
+     * TODO: remove this method and associated field declaration in VerGen
+     * @see {@link #getHashRevision()}
+     * @return the default value -1
+     */
+    @Deprecated
+    public static int getRevision() {
+        return REVISION;
+    }
+
+    public static String getRevisionHash() {
+        return REVISION_HASH;
+    }
+
+    public static String getBuildDate() {
+        return BUILD_DATE;
+    }
+
+    public static String getVersion() {
+        return MAJOR + "." + MINOR + "." + MICRO
+            + (QUALIFIER == null ? "" : "-" + QUALIFIER);
+    }
+
+    public static String getVersionRevision() {
+        return getVersion() + "-" + getRevisionHash();
+    }
+
+    public static String getFullVersion() {
+        return getVersionRevision() + ", built on " + getBuildDate();
+    }
+
+    public static void printUsage() {
+        System.out
+                .print("Usage:\tjava -cp ... org.apache.zookeeper.Version "
+                        + "[--full | --short | --revision],\n\tPrints --full version "
+                        + "info if no arg specified.");
+        System.exit(1);
+    }
+
+    /**
+     * Prints the current version, revision and build date to the standard out.
+     * 
+     * @param args
+     *            <ul>
+     *            <li> --short - prints a short version string "1.2.3"
+     *            <li> --revision - prints a short version string with the SVN
+     *            repository revision "1.2.3-94"
+     *            <li> --full - prints the revision and the build date
+     *            </ul>
+     */
+    public static void main(String[] args) {
+        if (args.length > 1) {
+            printUsage();
+        }
+        if (args.length == 0 || (args.length == 1 && args[0].equals("--full"))) {
+            System.out.println(getFullVersion());
+            System.exit(0);
+        }
+        if (args[0].equals("--short"))
+            System.out.println(getVersion());
+        else if (args[0].equals("--revision"))
+            System.out.println(getVersionRevision());
+        else
+            printUsage();
+        System.exit(0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/WatchedEvent.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/WatchedEvent.java b/zookeeper-server/src/main/java/org/apache/zookeeper/WatchedEvent.java
new file mode 100644
index 0000000..851fc6c
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/WatchedEvent.java
@@ -0,0 +1,81 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.apache.zookeeper.proto.WatcherEvent;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+
+/**
+ *  A WatchedEvent represents a change on the ZooKeeper that a Watcher
+ *  is able to respond to.  The WatchedEvent includes exactly what happened,
+ *  the current state of the ZooKeeper, and the path of the znode that
+ *  was involved in the event.
+ */
+@InterfaceAudience.Public
+public class WatchedEvent {
+    final private KeeperState keeperState;
+    final private EventType eventType;
+    private String path;
+    
+    /**
+     * Create a WatchedEvent with specified type, state and path
+     */
+    public WatchedEvent(EventType eventType, KeeperState keeperState, String path) {
+        this.keeperState = keeperState;
+        this.eventType = eventType;
+        this.path = path;
+    }
+    
+    /**
+     * Convert a WatcherEvent sent over the wire into a full-fledged WatcherEvent
+     */
+    public WatchedEvent(WatcherEvent eventMessage) {
+        keeperState = KeeperState.fromInt(eventMessage.getState());
+        eventType = EventType.fromInt(eventMessage.getType());
+        path = eventMessage.getPath();
+    }
+    
+    public KeeperState getState() {
+        return keeperState;
+    }
+    
+    public EventType getType() {
+        return eventType;
+    }
+    
+    public String getPath() {
+        return path;
+    }
+
+    @Override
+    public String toString() {
+        return "WatchedEvent state:" + keeperState
+            + " type:" + eventType + " path:" + path;
+    }
+
+    /**
+     *  Convert WatchedEvent to type that can be sent over network
+     */
+    public WatcherEvent getWrapper() {
+        return new WatcherEvent(eventType.getIntValue(), 
+                                keeperState.getIntValue(), 
+                                path);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/Watcher.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Watcher.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Watcher.java
new file mode 100644
index 0000000..5c21485
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Watcher.java
@@ -0,0 +1,155 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import org.apache.yetus.audience.InterfaceAudience;
+
+/**
+ * This interface specifies the public interface an event handler class must
+ * implement. A ZooKeeper client will get various events from the ZooKeeper
+ * server it connects to. An application using such a client handles these
+ * events by registering a callback object with the client. The callback object
+ * is expected to be an instance of a class that implements Watcher interface.
+ * 
+ */
+@InterfaceAudience.Public
+public interface Watcher {
+
+    /**
+     * This interface defines the possible states an Event may represent
+     */
+    @InterfaceAudience.Public
+    public interface Event {
+        /**
+         * Enumeration of states the ZooKeeper may be at the event
+         */
+        @InterfaceAudience.Public
+        public enum KeeperState {
+            /** Unused, this state is never generated by the server */
+            @Deprecated
+            Unknown (-1),
+
+            /** The client is in the disconnected state - it is not connected
+             * to any server in the ensemble. */
+            Disconnected (0),
+
+            /** Unused, this state is never generated by the server */
+            @Deprecated
+            NoSyncConnected (1),
+
+            /** The client is in the connected state - it is connected
+             * to a server in the ensemble (one of the servers specified
+             * in the host connection parameter during ZooKeeper client
+             * creation). */
+            SyncConnected (3),
+
+            /**
+             * Auth failed state
+             */
+            AuthFailed (4),
+
+            /**
+             * The client is connected to a read-only server, that is the
+             * server which is not currently connected to the majority.
+             * The only operations allowed after receiving this state is
+             * read operations.
+             * This state is generated for read-only clients only since
+             * read/write clients aren't allowed to connect to r/o servers.
+             */
+            ConnectedReadOnly (5),
+
+            /**
+              * SaslAuthenticated: used to notify clients that they are SASL-authenticated,
+              * so that they can perform Zookeeper actions with their SASL-authorized permissions.
+              */
+            SaslAuthenticated(6),
+
+            /** The serving cluster has expired this session. The ZooKeeper
+             * client connection (the session) is no longer valid. You must
+             * create a new client connection (instantiate a new ZooKeeper
+             * instance) if you with to access the ensemble. */
+            Expired (-112);
+
+            private final int intValue;     // Integer representation of value
+                                            // for sending over wire
+
+            KeeperState(int intValue) {
+                this.intValue = intValue;
+            }
+
+            public int getIntValue() {
+                return intValue;
+            }
+
+            public static KeeperState fromInt(int intValue) {
+                switch(intValue) {
+                    case   -1: return KeeperState.Unknown;
+                    case    0: return KeeperState.Disconnected;
+                    case    1: return KeeperState.NoSyncConnected;
+                    case    3: return KeeperState.SyncConnected;
+                    case    4: return KeeperState.AuthFailed;
+                    case    5: return KeeperState.ConnectedReadOnly;
+                    case    6: return KeeperState.SaslAuthenticated;
+                    case -112: return KeeperState.Expired;
+
+                    default:
+                        throw new RuntimeException("Invalid integer value for conversion to KeeperState");
+                }
+            }
+        }
+
+        /**
+         * Enumeration of types of events that may occur on the ZooKeeper
+         */
+        @InterfaceAudience.Public
+        public enum EventType {
+            None (-1),
+            NodeCreated (1),
+            NodeDeleted (2),
+            NodeDataChanged (3),
+            NodeChildrenChanged (4);
+
+            private final int intValue;     // Integer representation of value
+                                            // for sending over wire
+
+            EventType(int intValue) {
+                this.intValue = intValue;
+            }
+
+            public int getIntValue() {
+                return intValue;
+            }
+
+            public static EventType fromInt(int intValue) {
+                switch(intValue) {
+                    case -1: return EventType.None;
+                    case  1: return EventType.NodeCreated;
+                    case  2: return EventType.NodeDeleted;
+                    case  3: return EventType.NodeDataChanged;
+                    case  4: return EventType.NodeChildrenChanged;
+
+                    default:
+                        throw new RuntimeException("Invalid integer value for conversion to EventType");
+                }
+            }           
+        }
+    }
+
+    abstract public void process(WatchedEvent event);
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ZKUtil.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ZKUtil.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ZKUtil.java
new file mode 100644
index 0000000..e901832
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ZKUtil.java
@@ -0,0 +1,124 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper;
+
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.common.PathUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+         
+public class ZKUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(ZKUtil.class);
+    /**
+     * Recursively delete the node with the given path. 
+     * <p>
+     * Important: All versions, of all nodes, under the given node are deleted.
+     * <p>
+     * If there is an error with deleting one of the sub-nodes in the tree, 
+     * this operation would abort and would be the responsibility of the app to handle the same.
+     * 
+     * See {@link #delete(String, int)} for more details.
+     * 
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public static void deleteRecursive(ZooKeeper zk, final String pathRoot)
+        throws InterruptedException, KeeperException
+    {
+        PathUtils.validatePath(pathRoot);
+      
+        List<String> tree = listSubTreeBFS(zk, pathRoot);
+        LOG.debug("Deleting " + tree);
+        LOG.debug("Deleting " + tree.size() + " subnodes ");
+        for (int i = tree.size() - 1; i >= 0 ; --i) {
+            //Delete the leaves first and eventually get rid of the root
+            zk.delete(tree.get(i), -1); //Delete all versions of the node with -1.
+        }
+    }
+    
+
+    /**
+     * Recursively delete the node with the given path. (async version).
+     * 
+     * <p>
+     * Important: All versions, of all nodes, under the given node are deleted.
+     * <p>
+     * If there is an error with deleting one of the sub-nodes in the tree, 
+     * this operation would abort and would be the responsibility of the app to handle the same.
+     * <p>
+     * @param zk the zookeeper handle
+     * @param pathRoot the path to be deleted
+     * @param cb call back method
+     * @param ctx the context the callback method is called with
+     * @throws IllegalArgumentException if an invalid path is specified
+     */
+    public static void deleteRecursive(ZooKeeper zk, final String pathRoot, VoidCallback cb,
+        Object ctx)
+        throws InterruptedException, KeeperException
+    {
+        PathUtils.validatePath(pathRoot);
+      
+        List<String> tree = listSubTreeBFS(zk, pathRoot);
+        LOG.debug("Deleting " + tree);
+        LOG.debug("Deleting " + tree.size() + " subnodes ");
+        for (int i = tree.size() - 1; i >= 0 ; --i) {
+            //Delete the leaves first and eventually get rid of the root
+            zk.delete(tree.get(i), -1, cb, ctx); //Delete all versions of the node with -1.
+        }
+    }
+    
+    /**
+     * BFS Traversal of the system under pathRoot, with the entries in the list, in the 
+     * same order as that of the traversal.
+     * <p>
+     * <b>Important:</b> This is <i>not an atomic snapshot</i> of the tree ever, but the
+     *  state as it exists across multiple RPCs from zkClient to the ensemble.
+     * For practical purposes, it is suggested to bring the clients to the ensemble 
+     * down (i.e. prevent writes to pathRoot) to 'simulate' a snapshot behavior.   
+     * 
+     * @param zk the zookeeper handle
+     * @param pathRoot The znode path, for which the entire subtree needs to be listed.
+     * @throws InterruptedException 
+     * @throws KeeperException 
+     */
+    public static List<String> listSubTreeBFS(ZooKeeper zk, final String pathRoot) throws 
+        KeeperException, InterruptedException {
+        Deque<String> queue = new LinkedList<String>();
+        List<String> tree = new ArrayList<String>();
+        queue.add(pathRoot);
+        tree.add(pathRoot);
+        while (true) {
+            String node = queue.pollFirst();
+            if (node == null) {
+                break;
+            }
+            List<String> children = zk.getChildren(node, false);
+            for (final String child : children) {
+                final String childPath = node + "/" + child;
+                queue.add(childPath);
+                tree.add(childPath);
+            }
+        }
+        return tree;
+    }
+    
+} 

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/main/java/org/apache/zookeeper/ZooDefs.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ZooDefs.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooDefs.java
new file mode 100644
index 0000000..09bc95c
--- /dev/null
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooDefs.java
@@ -0,0 +1,125 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.apache.yetus.audience.InterfaceAudience;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+
+@InterfaceAudience.Public
+public class ZooDefs {
+
+    @InterfaceAudience.Public
+    public interface OpCode {
+        public final int notification = 0;
+
+        public final int create = 1;
+
+        public final int delete = 2;
+
+        public final int exists = 3;
+
+        public final int getData = 4;
+
+        public final int setData = 5;
+
+        public final int getACL = 6;
+
+        public final int setACL = 7;
+
+        public final int getChildren = 8;
+
+        public final int sync = 9;
+
+        public final int ping = 11;
+
+        public final int getChildren2 = 12;
+
+        public final int check = 13;
+
+        public final int multi = 14;
+
+        public final int auth = 100;
+
+        public final int setWatches = 101;
+
+        public final int sasl = 102;
+
+        public final int createSession = -10;
+
+        public final int closeSession = -11;
+
+        public final int error = -1;
+    }
+
+    @InterfaceAudience.Public
+    public interface Perms {
+        int READ = 1 << 0;
+
+        int WRITE = 1 << 1;
+
+        int CREATE = 1 << 2;
+
+        int DELETE = 1 << 3;
+
+        int ADMIN = 1 << 4;
+
+        int ALL = READ | WRITE | CREATE | DELETE | ADMIN;
+    }
+
+    @InterfaceAudience.Public
+    public interface Ids {
+        /**
+         * This Id represents anyone.
+         */
+        public final Id ANYONE_ID_UNSAFE = new Id("world", "anyone");
+
+        /**
+         * This Id is only usable to set ACLs. It will get substituted with the
+         * Id's the client authenticated with.
+         */
+        public final Id AUTH_IDS = new Id("auth", "");
+
+        /**
+         * This is a completely open ACL .
+         */
+        public final ArrayList<ACL> OPEN_ACL_UNSAFE = new ArrayList<ACL>(
+                Collections.singletonList(new ACL(Perms.ALL, ANYONE_ID_UNSAFE)));
+
+        /**
+         * This ACL gives the creators authentication id's all permissions.
+         */
+        public final ArrayList<ACL> CREATOR_ALL_ACL = new ArrayList<ACL>(
+                Collections.singletonList(new ACL(Perms.ALL, AUTH_IDS)));
+
+        /**
+         * This ACL gives the world the ability to read.
+         */
+        public final ArrayList<ACL> READ_ACL_UNSAFE = new ArrayList<ACL>(
+                Collections
+                        .singletonList(new ACL(Perms.READ, ANYONE_ID_UNSAFE)));
+    }
+
+    final public static String[] opNames = { "notification", "create",
+            "delete", "exists", "getData", "setData", "getACL", "setACL",
+            "getChildren", "getChildren2", "getMaxChildren", "setMaxChildren", "ping" };
+}


[23/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java
deleted file mode 100644
index 133d920..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NonRecoverableErrorTest.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.UUID;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.server.ZKDatabase;
-import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
-import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * This class tests the non-recoverable error behavior of quorum server.
- */
-public class NonRecoverableErrorTest extends QuorumPeerTestBase {
-    private static final String NODE_PATH = "/noLeaderIssue";
-
-    /**
-     * Test case for https://issues.apache.org/jira/browse/ZOOKEEPER-2247.
-     * Test to verify that even after non recoverable error (error while
-     * writing transaction log), ZooKeeper is still available.
-     */
-    @Test(timeout = 30000)
-    public void testZooKeeperServiceAvailableOnLeader() throws Exception {
-        int SERVER_COUNT = 3;
-        final int clientPorts[] = new int[SERVER_COUNT];
-        StringBuilder sb = new StringBuilder();
-        String server;
-
-        for (int i = 0; i < SERVER_COUNT; i++) {
-            clientPorts[i] = PortAssignment.unique();
-            server = "server." + i + "=127.0.0.1:" + PortAssignment.unique()
-                    + ":" + PortAssignment.unique();
-            sb.append(server + "\n");
-        }
-        String currentQuorumCfgSection = sb.toString();
-        MainThread mt[] = new MainThread[SERVER_COUNT];
-
-        for (int i = 0; i < SERVER_COUNT; i++) {
-            mt[i] = new MainThread(i, clientPorts[i], currentQuorumCfgSection);
-            mt[i].start();
-        }
-
-        // ensure server started
-        for (int i = 0; i < SERVER_COUNT; i++) {
-            Assert.assertTrue("waiting for server " + i + " being up",
-                    ClientBase.waitForServerUp("127.0.0.1:" + clientPorts[i],
-                            CONNECTION_TIMEOUT));
-        }
-
-        CountdownWatcher watcher = new CountdownWatcher();
-        ZooKeeper zk = new ZooKeeper("127.0.0.1:" + clientPorts[0],
-                ClientBase.CONNECTION_TIMEOUT, watcher);
-        watcher.waitForConnected(ClientBase.CONNECTION_TIMEOUT);
-
-        String data = "originalData";
-        zk.create(NODE_PATH, data.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        // get information of current leader
-        QuorumPeer leader = getLeaderQuorumPeer(mt);
-        assertNotNull("Leader must have been elected by now", leader);
-
-        // inject problem in leader
-        FileTxnSnapLog snapLog = leader.getActiveServer().getTxnLogFactory();
-        FileTxnSnapLog fileTxnSnapLogWithError = new FileTxnSnapLog(
-                snapLog.getDataDir(), snapLog.getSnapDir()) {
-            @Override
-            public void commit() throws IOException {
-                throw new IOException("Input/output error");
-            }
-        };
-        ZKDatabase originalZKDatabase = leader.getActiveServer()
-                .getZKDatabase();
-        long leaderCurrentEpoch = leader.getCurrentEpoch();
-
-        ZKDatabase newDB = new ZKDatabase(fileTxnSnapLogWithError);
-        leader.getActiveServer().setZKDatabase(newDB);
-
-        try {
-            // do create operation, so that injected IOException is thrown
-            zk.create(uniqueZnode(), data.getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-            fail("IOException is expected due to error injected to transaction log commit");
-        } catch (Exception e) {
-            // do nothing
-        }
-
-        // resetting watcher so that this watcher can be again used to ensure
-        // that the zkClient is able to re-establish connection with the
-        // newly elected zookeeper quorum.
-        watcher.reset();
-        waitForNewLeaderElection(leader, leaderCurrentEpoch);
-
-        // ensure server started, give enough time, so that new leader election
-        // takes place
-        for (int i = 0; i < SERVER_COUNT; i++) {
-            Assert.assertTrue("waiting for server " + i + " being up",
-                    ClientBase.waitForServerUp("127.0.0.1:" + clientPorts[i],
-                            CONNECTION_TIMEOUT));
-        }
-
-        // revert back the error
-        leader.getActiveServer().setZKDatabase(originalZKDatabase);
-
-        // verify that now ZooKeeper service is up and running
-        leader = getLeaderQuorumPeer(mt);
-        assertNotNull("New leader must have been elected by now", leader);
-
-        String uniqueNode = uniqueZnode();
-        watcher.waitForConnected(ClientBase.CONNECTION_TIMEOUT);
-        String createNode = zk.create(uniqueNode, data.getBytes(),
-                Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        // if node is created successfully then it means that ZooKeeper service
-        // is available
-        assertEquals("Failed to create znode", uniqueNode, createNode);
-        zk.close();
-        // stop all severs
-        for (int i = 0; i < SERVER_COUNT; i++) {
-            mt[i].shutdown();
-        }
-    }
-
-    private void waitForNewLeaderElection(QuorumPeer peer,
-            long leaderCurrentEpoch) throws IOException, InterruptedException {
-        LOG.info("Waiting for new LE cycle..");
-        int count = 100; // giving a grace period of 10seconds
-        while (count > 0) {
-            if (leaderCurrentEpoch == peer.getCurrentEpoch()) {
-                Thread.sleep(100);
-            }
-            count--;
-        }
-        Assert.assertTrue("New LE cycle must have triggered",
-                leaderCurrentEpoch != peer.getCurrentEpoch());
-    }
-
-    private QuorumPeer getLeaderQuorumPeer(MainThread[] mt) {
-        for (int i = mt.length - 1; i >= 0; i--) {
-            QuorumPeer quorumPeer = mt[i].getQuorumPeer();
-            if (null != quorumPeer
-                    && ServerState.LEADING == quorumPeer.getPeerState()) {
-                return quorumPeer;
-            }
-        }
-        return null;
-    }
-
-    private String uniqueZnode() {
-        UUID randomUUID = UUID.randomUUID();
-        String node = NODE_PATH + "/" + randomUUID.toString();
-        return node;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/NullDataTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NullDataTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/NullDataTest.java
deleted file mode 100644
index 8f1a1bb..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/NullDataTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.AsyncCallback.StatCallback;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class NullDataTest extends ClientBase implements StatCallback {
-    String snapCount;
-    CountDownLatch cn = new CountDownLatch(1);
-    
-    @Override
-    public void setUp() throws Exception {
-        // Change the snapcount to happen more often
-        snapCount = System.getProperty("zookeeper.snapCount", "1024");
-        System.setProperty("zookeeper.snapCount", "10");
-        super.setUp();
-    }
-    
-    @Override
-    public void tearDown() throws Exception {
-        System.setProperty("zookeeper.snapCount", snapCount);
-        super.tearDown();
-    }
-    
-    @Test
-    public void testNullData() throws IOException, 
-        InterruptedException, KeeperException {
-        String path = "/SIZE";
-        ZooKeeper zk = null;
-        zk = createClient();
-        try {
-            zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-            // try sync zk exists 
-            zk.exists(path, false);
-            zk.exists(path, false, this , null);
-            cn.await(10, TimeUnit.SECONDS);
-            Assert.assertSame(0L, cn.getCount());
-        } finally {
-            if(zk != null)
-                zk.close();
-        }
-        
-    }
-
-    public void processResult(int rc, String path, Object ctx, Stat stat) {
-        cn.countDown();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/OOMTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/OOMTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/OOMTest.java
deleted file mode 100644
index 465df98..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/OOMTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.ServerCnxnFactory;
-import org.apache.zookeeper.server.ZooKeeperServer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class OOMTest extends ZKTestCase implements Watcher {
-    @Test
-    public void testOOM() throws IOException, InterruptedException, KeeperException {
-        // This test takes too long tos run!
-        if (true)
-            return;
-        File tmpDir = ClientBase.createTmpDir();
-        // Grab some memory so that it is easier to cause an
-        // OOM condition;
-        ArrayList<byte[]> hog = new ArrayList<byte[]>();
-        while (true) {
-            try {
-                hog.add(new byte[1024 * 1024 * 2]);
-            } catch (OutOfMemoryError e) {
-                hog.remove(0);
-                break;
-            }
-        }
-        ClientBase.setupTestEnv();
-        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
-
-        final int PORT = PortAssignment.unique();
-        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
-        f.startup(zks);
-        Assert.assertTrue("waiting for server up",
-                   ClientBase.waitForServerUp("127.0.0.1:" + PORT,
-                                              CONNECTION_TIMEOUT));
-
-        System.err.println("OOM Stage 0");
-        utestPrep(PORT);
-        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
-                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
-                + Runtime.getRuntime().maxMemory());
-        System.err.println("OOM Stage 1");
-        for (int i = 0; i < 1000; i++) {
-            System.out.println(i);
-            utestExists(PORT);
-        }
-        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
-                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
-                + Runtime.getRuntime().maxMemory());
-        System.err.println("OOM Stage 2");
-        for (int i = 0; i < 1000; i++) {
-            System.out.println(i);
-            utestGet(PORT);
-        }
-        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
-                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
-                + Runtime.getRuntime().maxMemory());
-        System.err.println("OOM Stage 3");
-        for (int i = 0; i < 1000; i++) {
-            System.out.println(i);
-            utestChildren(PORT);
-        }
-        System.out.println("Free = " + Runtime.getRuntime().freeMemory()
-                + " total = " + Runtime.getRuntime().totalMemory() + " max = "
-                + Runtime.getRuntime().maxMemory());
-        hog.get(0)[0] = (byte) 1;
-
-        f.shutdown();
-        zks.shutdown();
-        Assert.assertTrue("waiting for server down",
-                   ClientBase.waitForServerDown("127.0.0.1:" + PORT,
-                                                CONNECTION_TIMEOUT));
-    }
-
-    private void utestExists(int port)
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk =
-            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
-        for (int i = 0; i < 10000; i++) {
-            zk.exists("/this/path/doesnt_exist!", true);
-        }
-        zk.close();
-    }
-
-    private void utestPrep(int port)
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk =
-            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
-        for (int i = 0; i < 10000; i++) {
-            zk.create("/" + i, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        }
-        zk.close();
-    }
-
-    private void utestGet(int port)
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk =
-            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
-        for (int i = 0; i < 10000; i++) {
-            Stat stat = new Stat();
-            zk.getData("/" + i, true, stat);
-        }
-        zk.close();
-    }
-
-    private void utestChildren(int port)
-        throws IOException, InterruptedException, KeeperException
-    {
-        ZooKeeper zk =
-            new ZooKeeper("127.0.0.1:" + port, CONNECTION_TIMEOUT, this);
-        for (int i = 0; i < 10000; i++) {
-            zk.getChildren("/" + i, true);
-        }
-        zk.close();
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.proto.WatcherEvent)
-     */
-    public void process(WatchedEvent event) {
-        System.err.println("Got event " + event.getType() + " "
-                + event.getState() + " " + event.getPath());
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java
deleted file mode 100644
index ce21ab8..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/OSMXBeanTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.Before;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.zookeeper.server.util.OSMXBean;
-
-public class OSMXBeanTest {
-    
-    private OSMXBean osMbean;
-    private Long ofdc = 0L;
-    private Long mfdc = 0L;
-    protected static final Logger LOG = LoggerFactory.getLogger(OSMXBeanTest.class);
-
-    @Before
-    public void initialize() {
-        this.osMbean = new OSMXBean();
-        Assert.assertNotNull("Could not initialize OSMXBean object!", osMbean);
-    }
-    
-    @Test
-    public final void testGetUnix() {
-        boolean isUnix = osMbean.getUnix();
-        if (!isUnix) {
-        	LOG.info("Running in a Windows system! Output won't be printed!");
-        } else {
-        	LOG.info("Running in a Unix or Linux system!");
-        }
-    }
-
-    @Test
-    public final void testGetOpenFileDescriptorCount() {
-        if (osMbean != null && osMbean.getUnix() == true) {
-            ofdc = osMbean.getOpenFileDescriptorCount();
-            LOG.info("open fdcount is: " + ofdc);
-        }   
-        Assert.assertFalse("The number of open file descriptor is negative",(ofdc < 0));
-    }
-
-    @Test
-    public final void testGetMaxFileDescriptorCount() {
-        if (osMbean != null && osMbean.getUnix() == true) {
-            mfdc = osMbean.getMaxFileDescriptorCount();
-            LOG.info("max fdcount is: " + mfdc);
-        }
-        Assert.assertFalse("The max file descriptor number is negative",(mfdc < 0));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java
deleted file mode 100644
index 9d373fc..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverHierarchicalQuorumTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.junit.Test;
-
-public class ObserverHierarchicalQuorumTest extends HierarchicalQuorumTest {
-    private static final Logger LOG = LoggerFactory.getLogger(QuorumBase.class);
-       
-    /**
-     * startServers(true) puts two observers into a 5 peer ensemble
-     */
-    void startServers() throws Exception {
-        startServers(true);
-    }
-           
-    protected void shutdown(QuorumPeer qp) {
-        QuorumBase.shutdown(qp);
-    }
-
-    @Test
-    public void testHierarchicalQuorum() throws Throwable {
-        cht.runHammer(5, 10);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverLETest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverLETest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverLETest.java
deleted file mode 100644
index 123ba0b..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverLETest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.test;
-
-import static org.junit.Assert.*;
-
-import java.util.Arrays;
-
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumStats;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ObserverLETest extends ZKTestCase {
-    final QuorumBase qb = new QuorumBase();
-    final ClientTest ct = new ClientTest();
-
-    @Before
-    public void establishThreeParticipantOneObserverEnsemble() throws Exception {
-        qb.setUp(true);
-        ct.hostPort = qb.hostPort;
-        ct.setUpAll();
-        qb.s5.shutdown();
-    }
-
-    @After
-    public void shutdownQuorum() throws Exception {
-        ct.tearDownAll();
-        qb.tearDown();
-    }
-
-    /**
-     * See ZOOKEEPER-1294. Confirms that an observer will not support the quorum
-     * of a leader by forming a 5-node, 2-observer ensemble (so quorum size is 2).
-     * When all but the leader and one observer are shut down, the leader should
-     * enter the 'looking' state, not stay in the 'leading' state.
-     */
-    @Test
-    public void testLEWithObserver() throws Exception {
-        QuorumPeer leader = null;
-        for (QuorumPeer server : Arrays.asList(qb.s1, qb.s2, qb.s3)) {
-            if (server.getServerState().equals(
-                    QuorumStats.Provider.FOLLOWING_STATE)) {
-                server.shutdown();
-                assertTrue("Waiting for server down", ClientBase
-                        .waitForServerDown("127.0.0.1:"
-                                + server.getClientPort(),
-                                ClientBase.CONNECTION_TIMEOUT));
-            } else {
-                assertNull("More than one leader found", leader);
-                leader = server;
-            }
-        }
-        assertTrue("Leader is not in Looking state", ClientBase
-                .waitForServerState(leader, ClientBase.CONNECTION_TIMEOUT,
-                        QuorumStats.Provider.LOOKING_STATE));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java
deleted file mode 100644
index 03b4000..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverQuorumHammerTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ObserverQuorumHammerTest extends QuorumHammerTest {
-    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
-
-    
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        qb.setUp(true);
-        cht.hostPort = qb.hostPort;
-        cht.setUpAll();
-    }
-   
-    @Test
-    public void testHammerBasic() throws Throwable {
-        cht.testHammerBasic();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverTest.java
deleted file mode 100644
index f7a82c6..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/ObserverTest.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
-
-import java.util.concurrent.CountDownLatch;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException.ConnectionLossException;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooKeeper.States;
-import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ObserverTest extends QuorumPeerTestBase implements Watcher{
-    protected static final Logger LOG =
-        LoggerFactory.getLogger(ObserverTest.class);    
-      
-    CountDownLatch latch;
-    ZooKeeper zk;
-    WatchedEvent lastEvent = null;
-          
-    /**
-     * This test ensures two things:
-     * 1. That Observers can successfully proxy requests to the ensemble.
-     * 2. That Observers don't participate in leader elections.
-     * The second is tested by constructing an ensemble where a leader would
-     * be elected if and only if an Observer voted. 
-     * @throws Exception
-     */
-    @Test
-    public void testObserver() throws Exception {
-        ClientBase.setupTestEnv();
-        // We expect two notifications before we want to continue        
-        latch = new CountDownLatch(2);
-        
-        final int PORT_QP1 = PortAssignment.unique();
-        final int PORT_QP2 = PortAssignment.unique();
-        final int PORT_OBS = PortAssignment.unique();
-        final int PORT_QP_LE1 = PortAssignment.unique();
-        final int PORT_QP_LE2 = PortAssignment.unique();
-        final int PORT_OBS_LE = PortAssignment.unique();
-
-        final int CLIENT_PORT_QP1 = PortAssignment.unique();
-        final int CLIENT_PORT_QP2 = PortAssignment.unique();
-        final int CLIENT_PORT_OBS = PortAssignment.unique();
-
-        
-        String quorumCfgSection =
-            "electionAlg=3\n" + 
-            "server.1=127.0.0.1:" + (PORT_QP1)
-            + ":" + (PORT_QP_LE1)
-            + "\nserver.2=127.0.0.1:" + (PORT_QP2)
-            + ":" + (PORT_QP_LE2)
-            + "\nserver.3=127.0.0.1:" 
-            + (PORT_OBS)+ ":" + (PORT_OBS_LE) + ":observer";
-        String obsCfgSection =  quorumCfgSection + "\npeerType=observer";
-        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
-        MainThread q2 = new MainThread(2, CLIENT_PORT_QP2, quorumCfgSection);
-        MainThread q3 = new MainThread(3, CLIENT_PORT_OBS, obsCfgSection);
-        q1.start();
-        q2.start();
-        q3.start();
-        Assert.assertTrue("waiting for server 1 being up",
-                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1,
-                        CONNECTION_TIMEOUT));
-        Assert.assertTrue("waiting for server 2 being up",
-                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP2,
-                        CONNECTION_TIMEOUT));
-        Assert.assertTrue("waiting for server 3 being up",
-                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_OBS,
-                        CONNECTION_TIMEOUT));        
-        
-        zk = new ZooKeeper("127.0.0.1:" + CLIENT_PORT_OBS,
-                ClientBase.CONNECTION_TIMEOUT, this);
-        zk.create("/obstest", "test".getBytes(),Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        
-        // Assert that commands are getting forwarded correctly
-        Assert.assertEquals(new String(zk.getData("/obstest", null, null)), "test");
-        
-        // Now check that other commands don't blow everything up
-        zk.sync("/", null, null);
-        zk.setData("/obstest", "test2".getBytes(), -1);
-        zk.getChildren("/", false);
-        
-        Assert.assertEquals(zk.getState(), States.CONNECTED);
-        
-        LOG.info("Shutting down server 2");
-        // Now kill one of the other real servers        
-        q2.shutdown();
-                
-        Assert.assertTrue("Waiting for server 2 to shut down",
-                    ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_QP2, 
-                                    ClientBase.CONNECTION_TIMEOUT));
-
-        LOG.info("Server 2 down");
-
-        // Now the resulting ensemble shouldn't be quorate         
-        latch.await();        
-        Assert.assertNotSame("Client is still connected to non-quorate cluster", 
-                KeeperState.SyncConnected,lastEvent.getState());
-
-        LOG.info("Latch returned");
-
-        try {
-            Assert.assertFalse("Shouldn't get a response when cluster not quorate!",
-                    new String(zk.getData("/obstest", null, null)).equals("test"));
-        }
-        catch (ConnectionLossException c) {
-            LOG.info("Connection loss exception caught - ensemble not quorate (this is expected)");
-        }
-        
-        latch = new CountDownLatch(1);
-
-        LOG.info("Restarting server 2");
-
-        // Bring it back
-        q2 = new MainThread(2, CLIENT_PORT_QP2, quorumCfgSection);
-        q2.start();
-        
-        LOG.info("Waiting for server 2 to come up");
-        Assert.assertTrue("waiting for server 2 being up",
-                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP2,
-                        CONNECTION_TIMEOUT));
-        
-        LOG.info("Server 2 started, waiting for latch");
-
-        latch.await();
-        // It's possible our session expired - but this is ok, shows we 
-        // were able to talk to the ensemble
-        Assert.assertTrue("Client didn't reconnect to quorate ensemble (state was" +
-                lastEvent.getState() + ")",
-                (KeeperState.SyncConnected==lastEvent.getState() ||
-                KeeperState.Expired==lastEvent.getState())); 
-
-        LOG.info("Shutting down all servers");
-
-        q1.shutdown();
-        q2.shutdown();
-        q3.shutdown();
-        
-        LOG.info("Closing zk client");
-
-        zk.close();        
-        Assert.assertTrue("Waiting for server 1 to shut down",
-                ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_QP1, 
-                                ClientBase.CONNECTION_TIMEOUT));
-        Assert.assertTrue("Waiting for server 2 to shut down",
-                ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_QP2, 
-                                ClientBase.CONNECTION_TIMEOUT));
-        Assert.assertTrue("Waiting for server 3 to shut down",
-                ClientBase.waitForServerDown("127.0.0.1:"+CLIENT_PORT_OBS, 
-                                ClientBase.CONNECTION_TIMEOUT));
-    
-    }
-    
-    /**
-     * Implementation of watcher interface.
-     */
-    public void process(WatchedEvent event) {
-        lastEvent = event;
-        latch.countDown();
-        LOG.info("Latch got event :: " + event);        
-    }    
-    
-    /**
-     * This test ensures that an Observer does not elect itself as a leader, or
-     * indeed come up properly, if it is the lone member of an ensemble.
-     * @throws Exception
-     */
-    @Test
-    public void testObserverOnly() throws Exception {
-        ClientBase.setupTestEnv();
-        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
-        
-        String quorumCfgSection =
-            "server.1=127.0.0.1:" + (PortAssignment.unique())
-            + ":" + (PortAssignment.unique()) + ":observer\npeerType=observer\n";
-                    
-        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
-        q1.start();
-        q1.join(ClientBase.CONNECTION_TIMEOUT);
-        Assert.assertFalse(q1.isAlive());
-    }    
-    
-    /**
-     * Ensure that observer only comes up when a proper ensemble is configured.
-     * (and will not come up with standalone server).
-     */
-    @Test
-    public void testObserverWithStandlone() throws Exception {
-        ClientBase.setupTestEnv();
-        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
-
-        String quorumCfgSection =
-            "server.1=127.0.0.1:" + (PortAssignment.unique())
-            + ":" + (PortAssignment.unique()) + ":observer\n"
-            + "server.2=127.0.0.1:" + (PortAssignment.unique())
-            + ":" + (PortAssignment.unique()) + "\npeerType=observer\n";
-
-        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
-        q1.start();
-        q1.join(ClientBase.CONNECTION_TIMEOUT);
-        Assert.assertFalse(q1.isAlive());
-    }    
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumBase.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumBase.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumBase.java
deleted file mode 100644
index 49cff35..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumBase.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.server.quorum.Election;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.util.OSMXBean;
-import org.junit.Assert;
-import org.junit.Test;
-
-
-public class QuorumBase extends ClientBase {
-    private static final Logger LOG = LoggerFactory.getLogger(QuorumBase.class);
-
-    File s1dir, s2dir, s3dir, s4dir, s5dir;
-    QuorumPeer s1, s2, s3, s4, s5;
-    protected int port1;
-    protected int port2;
-    protected int port3;
-    protected int port4;
-    protected int port5;
-    
-    protected int portLE1;
-    protected int portLE2;
-    protected int portLE3;
-    protected int portLE4;
-    protected int portLE5;
-
-    @Test
-    // This just avoids complaints by junit
-    public void testNull() {
-    }
-    
-    @Override
-    public void setUp() throws Exception {
-        setUp(false);
-    }
-        
-    protected void setUp(boolean withObservers) throws Exception {
-        LOG.info("QuorumBase.setup " + getTestName());
-        setupTestEnv();
-
-        JMXEnv.setUp();
-
-        setUpAll();
-
-        port1 = PortAssignment.unique();
-        port2 = PortAssignment.unique();
-        port3 = PortAssignment.unique();
-        port4 = PortAssignment.unique();
-        port5 = PortAssignment.unique();
-        
-        portLE1 = PortAssignment.unique();
-        portLE2 = PortAssignment.unique();
-        portLE3 = PortAssignment.unique();
-        portLE4 = PortAssignment.unique();
-        portLE5 = PortAssignment.unique();
-        
-        hostPort = "127.0.0.1:" + port1
-            + ",127.0.0.1:" + port2
-            + ",127.0.0.1:" + port3
-            + ",127.0.0.1:" + port4
-            + ",127.0.0.1:" + port5;
-        LOG.info("Ports are: " + hostPort);
-
-        s1dir = ClientBase.createTmpDir();
-        s2dir = ClientBase.createTmpDir();
-        s3dir = ClientBase.createTmpDir();
-        s4dir = ClientBase.createTmpDir();
-        s5dir = ClientBase.createTmpDir();
-
-        startServers(withObservers);
-
-        OSMXBean osMbean = new OSMXBean();
-        if (osMbean.getUnix() == true) {
-            LOG.info("Initial fdcount is: "
-                    + osMbean.getOpenFileDescriptorCount());
-        }
-
-        LOG.info("Setup finished");
-    }
-    
-    void startServers() throws Exception {
-        startServers(false);        
-    }
-    
-    void startServers(boolean withObservers) throws Exception {
-        int tickTime = 2000;
-        int initLimit = 3;
-        int syncLimit = 3;
-        HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>();
-        peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000,
-                                                    portLE1 + 1000,
-                LearnerType.PARTICIPANT));
-        peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000,
-                                                    portLE2 + 1000,
-                LearnerType.PARTICIPANT));
-        peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000,
-                                                    portLE3 + 1000,
-                LearnerType.PARTICIPANT));
-        peers.put(Long.valueOf(4), new QuorumServer(4, "127.0.0.1", port4 + 1000,
-                                                    portLE4 + 1000,
-                LearnerType.PARTICIPANT));
-        peers.put(Long.valueOf(5), new QuorumServer(5, "127.0.0.1", port5 + 1000,
-                                                    portLE5 + 1000,
-                LearnerType.PARTICIPANT));
-        
-        if (withObservers) {
-            peers.get(Long.valueOf(4)).type = LearnerType.OBSERVER;        
-            peers.get(Long.valueOf(5)).type = LearnerType.OBSERVER;
-        }
-
-        LOG.info("creating QuorumPeer 1 port " + port1);
-        s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit);
-        Assert.assertEquals(port1, s1.getClientPort());
-        LOG.info("creating QuorumPeer 2 port " + port2);
-        s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit);
-        Assert.assertEquals(port2, s2.getClientPort());
-        LOG.info("creating QuorumPeer 3 port " + port3);
-        s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit);
-        Assert.assertEquals(port3, s3.getClientPort());
-        LOG.info("creating QuorumPeer 4 port " + port4);
-        s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit);
-        Assert.assertEquals(port4, s4.getClientPort());
-        LOG.info("creating QuorumPeer 5 port " + port5);
-        s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit);
-        Assert.assertEquals(port5, s5.getClientPort());
-        
-        if (withObservers) {
-            s4.setLearnerType(LearnerType.OBSERVER);
-            s5.setLearnerType(LearnerType.OBSERVER);
-        }
-        
-        LOG.info("QuorumPeer 1 voting view: " + s1.getVotingView());
-        LOG.info("QuorumPeer 2 voting view: " + s2.getVotingView());
-        LOG.info("QuorumPeer 3 voting view: " + s3.getVotingView());
-        LOG.info("QuorumPeer 4 voting view: " + s4.getVotingView());
-        LOG.info("QuorumPeer 5 voting view: " + s5.getVotingView());       
-        
-        LOG.info("start QuorumPeer 1");
-        s1.start();
-        LOG.info("start QuorumPeer 2");
-        s2.start();
-        LOG.info("start QuorumPeer 3");
-        s3.start();
-        LOG.info("start QuorumPeer 4");
-        s4.start();
-        LOG.info("start QuorumPeer 5");
-        s5.start();
-        LOG.info("started QuorumPeer 5");
-
-        LOG.info ("Checking ports " + hostPort);
-        for (String hp : hostPort.split(",")) {
-            Assert.assertTrue("waiting for server up",
-                       ClientBase.waitForServerUp(hp,
-                                    CONNECTION_TIMEOUT));
-            LOG.info(hp + " is accepting client connections");
-        }
-
-        // interesting to see what's there...
-        JMXEnv.dump();
-        // make sure we have these 5 servers listed
-        Set<String> ensureNames = new LinkedHashSet<String>();
-        for (int i = 1; i <= 5; i++) {
-            ensureNames.add("InMemoryDataTree");
-        }
-        for (int i = 1; i <= 5; i++) {
-            ensureNames.add("name0=ReplicatedServer_id" + i
-                 + ",name1=replica." + i + ",name2=");
-        }
-        for (int i = 1; i <= 5; i++) {
-            for (int j = 1; j <= 5; j++) {
-                ensureNames.add("name0=ReplicatedServer_id" + i
-                     + ",name1=replica." + j);
-            }
-        }
-        for (int i = 1; i <= 5; i++) {
-            ensureNames.add("name0=ReplicatedServer_id" + i);
-        }
-        JMXEnv.ensureAll(ensureNames.toArray(new String[ensureNames.size()]));
-    }
-    
-    
-    public void setupServers() throws IOException {        
-        setupServer(1);
-        setupServer(2);
-        setupServer(3);
-        setupServer(4);
-        setupServer(5);
-    }
-
-    HashMap<Long,QuorumServer> peers = null;
-    public void setupServer(int i) throws IOException {
-        int tickTime = 2000;
-        int initLimit = 3;
-        int syncLimit = 3;
-        
-        if(peers == null){
-            peers = new HashMap<Long,QuorumServer>();
-
-            peers.put(Long.valueOf(1), new QuorumServer(1, "127.0.0.1", port1 + 1000,
-                                                        portLE1 + 1000,
-                LearnerType.PARTICIPANT));
-            peers.put(Long.valueOf(2), new QuorumServer(2, "127.0.0.1", port2 + 1000,
-                                                        portLE2 + 1000,
-                LearnerType.PARTICIPANT));
-            peers.put(Long.valueOf(3), new QuorumServer(3, "127.0.0.1", port3 + 1000,
-                                                        portLE3 + 1000,
-                LearnerType.PARTICIPANT));
-            peers.put(Long.valueOf(4), new QuorumServer(4, "127.0.0.1", port4 + 1000,
-                                                        portLE4 + 1000,
-                LearnerType.PARTICIPANT));
-            peers.put(Long.valueOf(5), new QuorumServer(5, "127.0.0.1", port5 + 1000,
-                                                        portLE5 + 1000,
-                LearnerType.PARTICIPANT));
-        }
-        
-        switch(i){
-        case 1:
-            LOG.info("creating QuorumPeer 1 port " + port1);
-            s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit);
-            Assert.assertEquals(port1, s1.getClientPort());
-            break;
-        case 2:
-            LOG.info("creating QuorumPeer 2 port " + port2);
-            s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit);
-            Assert.assertEquals(port2, s2.getClientPort());
-            break;
-        case 3:  
-            LOG.info("creating QuorumPeer 3 port " + port3);
-            s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit);
-            Assert.assertEquals(port3, s3.getClientPort());
-            break;
-        case 4:
-            LOG.info("creating QuorumPeer 4 port " + port4);
-            s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit);
-            Assert.assertEquals(port4, s4.getClientPort());
-            break;
-        case 5:
-            LOG.info("creating QuorumPeer 5 port " + port5);
-            s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit);
-            Assert.assertEquals(port5, s5.getClientPort());
-        }
-    }
-    
-    @Override
-    public void tearDown() throws Exception {
-        LOG.info("TearDown started");
-        
-        OSMXBean osMbean = new OSMXBean();
-        if (osMbean.getUnix() == true) {
-            LOG.info("fdcount after test is: "
-                    + osMbean.getOpenFileDescriptorCount());
-        }
-
-        shutdownServers();
-
-        for (String hp : hostPort.split(",")) {
-            Assert.assertTrue("waiting for server down",
-                       ClientBase.waitForServerDown(hp,
-                                           ClientBase.CONNECTION_TIMEOUT));
-            LOG.info(hp + " is no longer accepting client connections");
-        }
-
-        JMXEnv.tearDown();
-    }
-    public void shutdownServers() {
-        shutdown(s1);
-        shutdown(s2);
-        shutdown(s3);
-        shutdown(s4);
-        shutdown(s5);
-    }
-
-    public static void shutdown(QuorumPeer qp) {
-        try {
-            LOG.info("Shutting down quorum peer " + qp.getName());
-            qp.shutdown();
-            Election e = qp.getElectionAlg();
-            if (e != null) {
-                LOG.info("Shutting down leader election " + qp.getName());
-                e.shutdown();
-            } else {
-                LOG.info("No election available to shutdown " + qp.getName());
-            }
-            LOG.info("Waiting for " + qp.getName() + " to exit thread");
-            long readTimeout = qp.getTickTime() * qp.getInitLimit();
-            long connectTimeout = qp.getTickTime() * qp.getSyncLimit();
-            long maxTimeout = Math.max(readTimeout, connectTimeout);
-            maxTimeout = Math.max(maxTimeout, ClientBase.CONNECTION_TIMEOUT);
-            qp.join(maxTimeout * 2);
-            if (qp.isAlive()) {
-                Assert.fail("QP failed to shutdown in " + (maxTimeout * 2) + " seconds: " + qp.getName());
-            }
-        } catch (InterruptedException e) {
-            LOG.debug("QP interrupted: " + qp.getName(), e);
-        }
-    }
-
-    protected TestableZooKeeper createClient()
-        throws IOException, InterruptedException
-    {
-        return createClient(hostPort);
-    }
-
-    protected TestableZooKeeper createClient(String hp)
-        throws IOException, InterruptedException
-    {
-        CountdownWatcher watcher = new CountdownWatcher();
-        return createClient(watcher, hp);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java
deleted file mode 100644
index e5b377e..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumHammerTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-import org.apache.zookeeper.ZKTestCase;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class QuorumHammerTest extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(QuorumHammerTest.class);
-    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
-
-    protected final QuorumBase qb = new QuorumBase();
-    protected final ClientHammerTest cht = new ClientHammerTest();
-
-    @Before
-    public void setUp() throws Exception {
-        qb.setUp();
-        cht.hostPort = qb.hostPort;
-        cht.setUpAll();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        cht.tearDownAll();
-        qb.tearDown();
-    }
-
-    @Test
-    public void testHammerBasic() throws Throwable {
-        cht.testHammerBasic();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java
deleted file mode 100644
index bef1a33..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumQuotaTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.Quotas;
-import org.apache.zookeeper.StatsTrack;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooKeeperMain;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.data.Stat;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class QuorumQuotaTest extends QuorumBase {
-    private static final Logger LOG =
-        LoggerFactory.getLogger(QuorumQuotaTest.class);
-
-    @Test
-    public void testQuotaWithQuorum() throws Exception {
-        ZooKeeper zk = createClient();
-        zk.setData("/", "some".getBytes(), -1);
-        zk.create("/a", "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        int i = 0;
-        for (i=0; i < 300;i++) {
-            zk.create("/a/" + i, "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        }
-        ZooKeeperMain.createQuota(zk, "/a", 1000L, 5000);
-        String statPath = Quotas.quotaZookeeper + "/a"+ "/" + Quotas.statNode;
-        byte[] data = zk.getData(statPath, false, new Stat());
-        StatsTrack st = new StatsTrack(new String(data));
-        Assert.assertTrue("bytes are set", st.getBytes() == 1204L);
-        Assert.assertTrue("num count is set", st.getCount() == 301);
-        for (i=300; i < 600; i++) {
-            zk.create("/a/" + i, "some".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-        }
-        data = zk.getData(statPath, false, new Stat());
-        st = new StatsTrack(new String(data));
-        Assert.assertTrue("bytes are set", st.getBytes() == 2404L);
-        Assert.assertTrue("num count is set", st.getCount() == 601);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumTest.java
deleted file mode 100644
index 6f827ec..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumTest.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.quorum.Leader;
-import org.apache.zookeeper.server.quorum.LearnerHandler;
-import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class QuorumTest extends ZKTestCase {
-    private static final Logger LOG = LoggerFactory.getLogger(QuorumTest.class);
-    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
-
-    private final QuorumBase qb = new QuorumBase();
-    private final ClientTest ct = new ClientTest();
-
-    @Before
-    public void setUp() throws Exception {
-        qb.setUp();
-        ct.hostPort = qb.hostPort;
-        ct.setUpAll();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        ct.tearDownAll();
-        qb.tearDown();
-    }
-
-    @Test
-    public void testDeleteWithChildren() throws Exception {
-        ct.testDeleteWithChildren();
-    }
-
-    @Test
-    public void testPing() throws Exception {
-        ct.testPing();
-    }
-
-    @Test
-    public void testSequentialNodeNames()
-        throws IOException, InterruptedException, KeeperException
-    {
-        ct.testSequentialNodeNames();
-    }
-
-    @Test
-    public void testACLs() throws Exception {
-        ct.testACLs();
-    }
-
-    @Test
-    public void testClientwithoutWatcherObj() throws IOException,
-            InterruptedException, KeeperException
-    {
-        ct.testClientwithoutWatcherObj();
-    }
-
-    @Test
-    public void testClientWithWatcherObj() throws IOException,
-            InterruptedException, KeeperException
-    {
-        ct.testClientWithWatcherObj();
-    }
-
-    @Test
-    public void testGetView() {
-        Assert.assertEquals(5,qb.s1.getView().size());
-        Assert.assertEquals(5,qb.s2.getView().size());
-        Assert.assertEquals(5,qb.s3.getView().size());
-        Assert.assertEquals(5,qb.s4.getView().size());
-        Assert.assertEquals(5,qb.s5.getView().size());
-    }
-
-    @Test
-    public void testViewContains() {
-        // Test view contains self
-        Assert.assertTrue(qb.s1.viewContains(qb.s1.getId()));
-
-        // Test view contains other servers
-        Assert.assertTrue(qb.s1.viewContains(qb.s2.getId()));
-
-        // Test view does not contain non-existant servers
-        Assert.assertFalse(qb.s1.viewContains(-1L));
-    }
-
-    volatile int counter = 0;
-    volatile int errors = 0;
-    @Test
-    public void testLeaderShutdown() throws IOException, InterruptedException, KeeperException {
-        ZooKeeper zk = new DisconnectableZooKeeper(qb.hostPort, ClientBase.CONNECTION_TIMEOUT, new Watcher() {
-            public void process(WatchedEvent event) {
-        }});
-        zk.create("/blah", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.create("/blah/blah", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Leader leader = qb.s1.leader;
-        if (leader == null) leader = qb.s2.leader;
-        if (leader == null) leader = qb.s3.leader;
-        if (leader == null) leader = qb.s4.leader;
-        if (leader == null) leader = qb.s5.leader;
-        Assert.assertNotNull(leader);
-        for(int i = 0; i < 5000; i++) {
-            zk.setData("/blah/blah", new byte[0], -1, new AsyncCallback.StatCallback() {
-                public void processResult(int rc, String path, Object ctx,
-                        Stat stat) {
-                    counter++;
-                    if (rc != 0) {
-                        errors++;
-                    }
-                }
-            }, null);
-        }
-        for(LearnerHandler f : leader.getForwardingFollowers()) {
-            f.getSocket().shutdownInput();
-        }
-        for(int i = 0; i < 5000; i++) {
-            zk.setData("/blah/blah", new byte[0], -1, new AsyncCallback.StatCallback() {
-                public void processResult(int rc, String path, Object ctx,
-                        Stat stat) {
-                    counter++;
-                    if (rc != 0) {
-                        errors++;
-                    }
-                }
-            }, null);
-        }
-        // check if all the followers are alive
-        Assert.assertTrue(qb.s1.isAlive());
-        Assert.assertTrue(qb.s2.isAlive());
-        Assert.assertTrue(qb.s3.isAlive());
-        Assert.assertTrue(qb.s4.isAlive());
-        Assert.assertTrue(qb.s5.isAlive());
-        zk.close();
-    }
-
-    @Test
-    public void testMultipleWatcherObjs() throws IOException,
-            InterruptedException, KeeperException
-    {
-        ct.testMutipleWatcherObjs();
-    }
-
-    /**
-     * Make sure that we can change sessions
-     *  from follower to leader.
-     *
-     * @throws IOException
-     * @throws InterruptedException
-     * @throws KeeperException
-     */
-    @Test
-    public void testSessionMoved() throws Exception {
-        String hostPorts[] = qb.hostPort.split(",");
-        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(hostPorts[0],
-                ClientBase.CONNECTION_TIMEOUT, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        zk.create("/sessionMoveTest", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-        // we want to loop through the list twice
-        for(int i = 0; i < hostPorts.length*2; i++) {
-            zk.dontReconnect();
-            // This should stomp the zk handle
-            DisconnectableZooKeeper zknew =
-                new DisconnectableZooKeeper(hostPorts[(i+1)%hostPorts.length],
-                    ClientBase.CONNECTION_TIMEOUT,
-                    new Watcher() {public void process(WatchedEvent event) {
-                    }},
-                    zk.getSessionId(),
-                    zk.getSessionPasswd());
-            zknew.setData("/", new byte[1], -1);
-            final int result[] = new int[1];
-            result[0] = Integer.MAX_VALUE;
-            zknew.sync("/", new AsyncCallback.VoidCallback() {
-                    public void processResult(int rc, String path, Object ctx) {
-                        synchronized(result) { result[0] = rc; result.notify(); }
-                    }
-                }, null);
-            synchronized(result) {
-                if(result[0] == Integer.MAX_VALUE) {
-                    result.wait(5000);
-                }
-            }
-            LOG.info(hostPorts[(i+1)%hostPorts.length] + " Sync returned " + result[0]);
-            Assert.assertTrue(result[0] == KeeperException.Code.OK.intValue());
-            try {
-                zk.setData("/", new byte[1], -1);
-                Assert.fail("Should have lost the connection");
-            } catch(KeeperException.ConnectionLossException e) {
-            }
-            zk = zknew;
-        }
-        zk.close();
-    }
-
-    private static class DiscoWatcher implements Watcher {
-        volatile boolean zkDisco = false;
-        public void process(WatchedEvent event) {
-            if (event.getState() == KeeperState.Disconnected) {
-                zkDisco = true;
-            }
-        }
-    }
-
-    /**
-     * Connect to two different servers with two different handles using the same session and
-     * make sure we cannot do any changes.
-     */
-    @Test
-    @Ignore
-    public void testSessionMove() throws Exception {
-        String hps[] = qb.hostPort.split(",");
-        DiscoWatcher oldWatcher = new DiscoWatcher();
-        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(hps[0],
-                ClientBase.CONNECTION_TIMEOUT, oldWatcher);
-        zk.create("/t1", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-        zk.dontReconnect();
-        // This should stomp the zk handle
-        DiscoWatcher watcher = new DiscoWatcher();
-        DisconnectableZooKeeper zknew = new DisconnectableZooKeeper(hps[1],
-                ClientBase.CONNECTION_TIMEOUT, watcher, zk.getSessionId(),
-                zk.getSessionPasswd());
-        zknew.create("/t2", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-        try {
-            zk.create("/t3", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-            Assert.fail("Should have lost the connection");
-        } catch(KeeperException.ConnectionLossException e) {
-            // wait up to 30 seconds for the disco to be delivered
-            for (int i = 0; i < 30; i++) {
-                if (oldWatcher.zkDisco) {
-                    break;
-                }
-                Thread.sleep(1000);
-            }
-            Assert.assertTrue(oldWatcher.zkDisco);
-        }
-
-        ArrayList<ZooKeeper> toClose = new ArrayList<ZooKeeper>();
-        toClose.add(zknew);
-        // Let's just make sure it can still move
-        for(int i = 0; i < 10; i++) {
-            zknew.dontReconnect();
-            zknew = new DisconnectableZooKeeper(hps[1],
-                    ClientBase.CONNECTION_TIMEOUT, new DiscoWatcher(),
-                    zk.getSessionId(), zk.getSessionPasswd());
-            toClose.add(zknew);
-            zknew.create("/t-"+i, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
-        }
-        for (ZooKeeper z: toClose) {
-            z.close();
-        }
-        zk.close();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumUtil.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumUtil.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumUtil.java
deleted file mode 100644
index 1f2dbbc..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumUtil.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.server.quorum.Election;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.util.OSMXBean;
-import org.junit.Assert;
-
-/**
- * Utility for quorum testing. Setups 2n+1 peers and allows to start/stop all
- * peers, particular peer, n peers etc.
- */
-public class QuorumUtil {
-
-    // TODO partitioning of peers and clients
-
-    // TODO refactor QuorumBase to be special case of this
-
-    private static final Logger LOG = LoggerFactory.getLogger(QuorumUtil.class);
-
-    public class PeerStruct {
-        public int id;
-        public QuorumPeer peer;
-        public File dataDir;
-        public int clientPort;
-    }
-
-    private final Map<Long, QuorumServer> peersView = new HashMap<Long, QuorumServer>();
-
-    private final Map<Integer, PeerStruct> peers = new HashMap<Integer, PeerStruct>();
-
-    public final int N;
-
-    public final int ALL;
-
-    private String hostPort;
-
-    private int tickTime;
-
-    private int initLimit;
-
-    private int syncLimit;
-
-    private int electionAlg;
-
-    /**
-     * Initializes 2n+1 quorum peers which will form a ZooKeeper ensemble.
-     *
-     * @param n
-     *            number of peers in the ensemble will be 2n+1
-     */
-    public QuorumUtil(int n, int syncLimit) throws RuntimeException {
-        try {
-            ClientBase.setupTestEnv();
-            JMXEnv.setUp();
-
-            N = n;
-            ALL = 2 * N + 1;
-            tickTime = 2000;
-            initLimit = 3;
-            this.syncLimit = syncLimit;
-            electionAlg = 3;
-            hostPort = "";
-
-            for (int i = 1; i <= ALL; ++i) {
-                PeerStruct ps = new PeerStruct();
-                ps.id = i;
-                ps.dataDir = ClientBase.createTmpDir();
-                ps.clientPort = PortAssignment.unique();
-                peers.put(i, ps);
-
-                peersView.put(Long.valueOf(i),
-                              new QuorumServer(i, "127.0.0.1", ps.clientPort + 1000,
-                                               PortAssignment.unique() + 1000,
-                                               LearnerType.PARTICIPANT));
-                hostPort += "127.0.0.1:" + ps.clientPort + ((i == ALL) ? "" : ",");
-            }
-            for (int i = 1; i <= ALL; ++i) {
-                PeerStruct ps = peers.get(i);
-                LOG.info("Creating QuorumPeer " + i + "; public port " + ps.clientPort);
-                ps.peer = new QuorumPeer(peersView, ps.dataDir, ps.dataDir, ps.clientPort,
-                        electionAlg, ps.id, tickTime, initLimit, syncLimit);
-                Assert.assertEquals(ps.clientPort, ps.peer.getClientPort());
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public QuorumUtil(int n) throws RuntimeException {
-        this(n, 3);
-    }
-
-    public PeerStruct getPeer(int id) {
-        return peers.get(id);
-    }
-
-    public void startAll() throws IOException {
-        shutdownAll();
-        for (int i = 1; i <= ALL; ++i) {
-            start(i);
-            LOG.info("Started QuorumPeer " + i);
-        }
-
-        LOG.info("Checking ports " + hostPort);
-        for (String hp : hostPort.split(",")) {
-            Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(hp,
-                    ClientBase.CONNECTION_TIMEOUT));
-            LOG.info(hp + " is accepting client connections");
-        }
-
-        // interesting to see what's there...
-        try {
-            JMXEnv.dump();
-            // make sure we have all servers listed
-            Set<String> ensureNames = new LinkedHashSet<String>();
-            for (int i = 1; i <= ALL; ++i) {
-                ensureNames.add("InMemoryDataTree");
-            }
-            for (int i = 1; i <= ALL; ++i) {
-                ensureNames
-                        .add("name0=ReplicatedServer_id" + i + ",name1=replica." + i + ",name2=");
-            }
-            for (int i = 1; i <= ALL; ++i) {
-                for (int j = 1; j <= ALL; ++j) {
-                    ensureNames.add("name0=ReplicatedServer_id" + i + ",name1=replica." + j);
-                }
-            }
-            for (int i = 1; i <= ALL; ++i) {
-                ensureNames.add("name0=ReplicatedServer_id" + i);
-            }
-            JMXEnv.ensureAll(ensureNames.toArray(new String[ensureNames.size()]));
-        } catch (IOException e) {
-            LOG.warn("IOException during JMXEnv operation", e);
-        } catch (InterruptedException e) {
-            LOG.warn("InterruptedException during JMXEnv operation", e);
-        }
-    }
-
-    /**
-     * Start first N+1 peers.
-     */
-    public void startQuorum() throws IOException {
-        shutdownAll();
-        for (int i = 1; i <= N + 1; ++i) {
-            start(i);
-        }
-        for (int i = 1; i <= N + 1; ++i) {
-            Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                    + getPeer(i).clientPort, ClientBase.CONNECTION_TIMEOUT));
-        }
-    }
-
-    public void start(int id) throws IOException {
-        PeerStruct ps = getPeer(id);
-        LOG.info("Creating QuorumPeer " + ps.id + "; public port " + ps.clientPort);
-        ps.peer = new QuorumPeer(peersView, ps.dataDir, ps.dataDir, ps.clientPort, electionAlg,
-                ps.id, tickTime, initLimit, syncLimit);
-        Assert.assertEquals(ps.clientPort, ps.peer.getClientPort());
-
-        ps.peer.start();    
-    }
-    
-    public void restart(int id) throws IOException {
-        start(id);
-        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                + getPeer(id).clientPort, ClientBase.CONNECTION_TIMEOUT));
-    }
-    
-    public void startThenShutdown(int id) throws IOException {
-        PeerStruct ps = getPeer(id);
-        LOG.info("Creating QuorumPeer " + ps.id + "; public port " + ps.clientPort);
-        ps.peer = new QuorumPeer(peersView, ps.dataDir, ps.dataDir, ps.clientPort, electionAlg,
-                ps.id, tickTime, initLimit, syncLimit);
-        Assert.assertEquals(ps.clientPort, ps.peer.getClientPort());
-
-        ps.peer.start();
-        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                + getPeer(id).clientPort, ClientBase.CONNECTION_TIMEOUT));
-        shutdown(id);
-    }
-
-    public void shutdownAll() {
-        for (int i = 1; i <= ALL; ++i) {
-            shutdown(i);
-        }
-        for (String hp : hostPort.split(",")) {
-            Assert.assertTrue("Waiting for server down", ClientBase.waitForServerDown(hp,
-                    ClientBase.CONNECTION_TIMEOUT));
-            LOG.info(hp + " is no longer accepting client connections");
-        }
-    }
-
-    public void shutdown(int id) {
-        QuorumPeer qp = getPeer(id).peer;
-        try {
-            LOG.info("Shutting down quorum peer " + qp.getName());
-            qp.shutdown();
-            Election e = qp.getElectionAlg();
-            if (e != null) {
-                LOG.info("Shutting down leader election " + qp.getName());
-                e.shutdown();
-            } else {
-                LOG.info("No election available to shutdown " + qp.getName());
-            }
-            LOG.info("Waiting for " + qp.getName() + " to exit thread");
-            qp.join(30000);
-            if (qp.isAlive()) {
-                Assert.fail("QP failed to shutdown in 30 seconds: " + qp.getName());
-            }
-        } catch (InterruptedException e) {
-            LOG.debug("QP interrupted: " + qp.getName(), e);
-        }
-    }
-
-    public String getConnString() {
-        return hostPort;
-    }
-
-    public void tearDown() throws Exception {
-        LOG.info("TearDown started");
-
-        OSMXBean osMbean = new OSMXBean();
-        if (osMbean.getUnix() == true) {    
-            LOG.info("fdcount after test is: " + osMbean.getOpenFileDescriptorCount());
-        }
-
-        shutdownAll();
-        JMXEnv.tearDown();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java
deleted file mode 100644
index 6e46edc..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/QuorumZxidSyncTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class QuorumZxidSyncTest extends ZKTestCase {
-    QuorumBase qb = new QuorumBase();
-
-    @Before
-    public void setUp() throws Exception {
-        qb.setUp();
-    }
-
-    /**
-     * find out what happens when a follower connects to leader that is behind
-     */
-    @Test
-    public void testBehindLeader() throws Exception {
-        // crank up the epoch numbers
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        ZooKeeper zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        zk.create("/0", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.close();
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        zk.create("/1", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.close();
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        zk.create("/2", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.close();
-        qb.shutdownServers();
-        deleteFiles(qb.s1dir);
-        deleteFiles(qb.s2dir);
-        deleteFiles(qb.s3dir);
-        deleteFiles(qb.s4dir);
-        qb.setupServers();
-        qb.s1.start();
-        qb.s2.start();
-        qb.s3.start();
-        qb.s4.start();
-        Assert.assertTrue("Servers didn't come up", ClientBase.waitForServerUp(qb.hostPort, 10000));
-        qb.s5.start();
-        String hostPort = "127.0.0.1:" + qb.s5.getClientPort();
-        Assert.assertFalse("Servers came up, but shouldn't have since it's ahead of leader",
-                ClientBase.waitForServerUp(hostPort, 10000));
-    }
-
-    private void deleteFiles(File f) {
-        File v = new File(f, "version-2");
-        for(File c: v.listFiles()) {
-            c.delete();
-        }
-    }
-
-    /**
-     * find out what happens when the latest state is in the snapshots not
-     * the logs.
-     */
-    @Test
-    public void testLateLogs() throws Exception {
-        // crank up the epoch numbers
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        ZooKeeper zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        zk.create("/0", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.close();
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        zk.create("/1", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.close();
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        qb.shutdownServers();
-        deleteLogs(qb.s1dir);
-        deleteLogs(qb.s2dir);
-        deleteLogs(qb.s3dir);
-        deleteLogs(qb.s4dir);
-        deleteLogs(qb.s5dir);
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        zk.create("/2", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk.close();
-        qb.shutdownServers();
-        qb.startServers();
-        ClientBase.waitForServerUp(qb.hostPort, 10000);
-        zk = new ZooKeeper(qb.hostPort, 10000, new Watcher() {
-            public void process(WatchedEvent event) {
-            }});
-        boolean saw2 = false;
-        for(String child: zk.getChildren("/", false)) {
-            if (child.equals("2")) {
-                saw2 = true;
-            }
-        }
-        zk.close();
-        Assert.assertTrue("Didn't see /2 (went back in time)", saw2);
-    }
-
-    private void deleteLogs(File f) {
-        File v = new File(f, "version-2");
-        for(File c: v.listFiles()) {
-            if (c.getName().startsWith("log")) {
-                c.delete();
-            }
-        }
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        qb.tearDown();
-    }
-}


[26/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java
deleted file mode 100644
index 619bdc6..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectableZooKeeper.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.IOException;
-
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooKeeper;
-
-public class DisconnectableZooKeeper extends ZooKeeper {
-    public DisconnectableZooKeeper(String host, int sessionTimeout, Watcher watcher)
-        throws IOException
-    {
-        super(host, sessionTimeout, watcher);
-    }
-    
-    public DisconnectableZooKeeper(String host, int sessionTimeout, Watcher watcher,
-        long sessionId, byte[] sessionPasswd)
-        throws IOException
-    {
-        super(host, sessionTimeout, watcher, sessionId, sessionPasswd);
-    }
-
-    /** Testing only!!! Really!!!! This is only here to test when the client
-     * disconnects from the server w/o sending a session disconnect (ie
-     * ending the session cleanly). The server will eventually notice the
-     * client is no longer pinging and will timeout the session.
-     */
-    public void disconnect() throws IOException {
-        cnxn.disconnect();
-    }
-
-    /**
-     * Prevent the client from automatically reconnecting if the connection to the
-     * server is lost
-     */
-    public void dontReconnect() throws Exception {
-        java.lang.reflect.Field f = cnxn.getClass().getDeclaredField("closing");
-        f.setAccessible(true);
-        f.setBoolean(cnxn, true);
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java
deleted file mode 100644
index e81b7f4..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/DisconnectedWatcherTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.junit.Assert;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DisconnectedWatcherTest extends ClientBase {
-    protected static final Logger LOG = LoggerFactory.getLogger(DisconnectedWatcherTest.class);
-    final int TIMEOUT = 5000;
-
-    private class MyWatcher extends CountdownWatcher {
-        LinkedBlockingQueue<WatchedEvent> events =
-            new LinkedBlockingQueue<WatchedEvent>();
-
-        public void process(WatchedEvent event) {
-            super.process(event);
-            if (event.getType() != Event.EventType.None) {
-                try {
-                    events.put(event);
-                } catch (InterruptedException e) {
-                    LOG.warn("ignoring interrupt during event.put");
-                }
-            }
-        }
-    }
-
-    // @see jira issue ZOOKEEPER-961
-    
-    @Test
-    public void testChildWatcherAutoResetWithChroot() throws Exception {
-        ZooKeeper zk1 = createClient();
-
-        zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-
-        MyWatcher watcher = new MyWatcher();
-        ZooKeeper zk2 = createClient(watcher, hostPort + "/ch1");
-        zk2.getChildren("/", true );
-
-        // this call shouldn't trigger any error or watch
-        zk1.create("/youdontmatter1", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        // this should trigger the watch
-        zk1.create("/ch1/youshouldmatter1", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        WatchedEvent e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertNotNull(e);
-        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-        Assert.assertEquals("/", e.getPath());
-
-        MyWatcher childWatcher = new MyWatcher();
-        zk2.getChildren("/", childWatcher);
-        
-        stopServer();
-        watcher.waitForDisconnected(3000);
-        startServer();
-        watcher.waitForConnected(3000);
-
-        // this should trigger the watch
-        zk1.create("/ch1/youshouldmatter2", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertNotNull(e);
-        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-        Assert.assertEquals("/", e.getPath());
-    }
-    
-    @Test
-    public void testDefaultWatcherAutoResetWithChroot() throws Exception {
-        ZooKeeper zk1 = createClient();
-
-        zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-
-        MyWatcher watcher = new MyWatcher();
-        ZooKeeper zk2 = createClient(watcher, hostPort + "/ch1");
-        zk2.getChildren("/", true );
-
-        // this call shouldn't trigger any error or watch
-        zk1.create("/youdontmatter1", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        // this should trigger the watch
-        zk1.create("/ch1/youshouldmatter1", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        WatchedEvent e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertNotNull(e);
-        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-        Assert.assertEquals("/", e.getPath());
-
-        zk2.getChildren("/", true );
-
-        stopServer();
-        watcher.waitForDisconnected(3000);
-        startServer();
-        watcher.waitForConnected(3000);
-
-        // this should trigger the watch
-        zk1.create("/ch1/youshouldmatter2", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertNotNull(e);
-        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-        Assert.assertEquals("/", e.getPath());
-    }
-    
-    @Test
-    public void testDeepChildWatcherAutoResetWithChroot() throws Exception {
-        ZooKeeper zk1 = createClient();
-
-        zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.create("/ch1/here", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.create("/ch1/here/we", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        zk1.create("/ch1/here/we/are", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-
-        MyWatcher watcher = new MyWatcher();
-        ZooKeeper zk2 = createClient(watcher, hostPort + "/ch1/here/we");
-        zk2.getChildren("/are", true );
-
-        // this should trigger the watch
-        zk1.create("/ch1/here/we/are/now", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        WatchedEvent e = watcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertNotNull(e);
-        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-        Assert.assertEquals("/are", e.getPath());
-
-        MyWatcher childWatcher = new MyWatcher();
-        zk2.getChildren("/are", childWatcher);
-        
-        stopServer();
-        watcher.waitForDisconnected(3000);
-        startServer();
-        watcher.waitForConnected(3000);
-
-        // this should trigger the watch
-        zk1.create("/ch1/here/we/are/again", null, Ids.OPEN_ACL_UNSAFE,
-                CreateMode.PERSISTENT);
-        e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-        Assert.assertNotNull(e);
-        Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-        Assert.assertEquals("/are", e.getPath());
-    }
-
-    // @see jira issue ZOOKEEPER-706. Test auto reset of a large number of
-    // watches which require multiple SetWatches calls.
-    @Test(timeout = 840000)
-    public void testManyChildWatchersAutoReset() throws Exception {
-        ZooKeeper zk1 = createClient();
-
-        MyWatcher watcher = new MyWatcher();
-        ZooKeeper zk2 = createClient(watcher);
-
-        // 110 character base path
-        String pathBase = "/long-path-000000000-111111111-222222222-333333333-444444444-"
-                          + "555555555-666666666-777777777-888888888-999999999";
-
-        zk1.create(pathBase, null, Ids.OPEN_ACL_UNSAFE,
-                   CreateMode.PERSISTENT);
-
-        // Create 10,000 nodes. This should ensure the length of our
-        // watches set below exceeds 1MB.
-        List<String> paths = new ArrayList<String>();
-        for (int i = 0; i < 10000; i++) {
-            String path = zk1.create(pathBase + "/ch-", null, Ids.OPEN_ACL_UNSAFE,
-                                     CreateMode.PERSISTENT_SEQUENTIAL);
-            paths.add(path);
-        }
-        LOG.info("Created 10,000 nodes.");
-
-        MyWatcher childWatcher = new MyWatcher();
-
-        // Set a combination of child/exists/data watches
-        int i = 0;
-        for (String path : paths) {
-            if (i % 3 == 0) {
-                zk2.getChildren(path, childWatcher);
-            } else if (i % 3 == 1) {
-                zk2.exists(path + "/foo", childWatcher);
-            } else if (i % 3 == 2) {
-                zk2.getData(path, childWatcher, null);
-            }
-
-            i++;
-        }
-
-        stopServer();
-        watcher.waitForDisconnected(30000);
-        startServer();
-        watcher.waitForConnected(30000);
-
-        // Trigger the watches and ensure they properly propagate to the client
-        i = 0;
-        for (String path : paths) {
-            if (i % 3 == 0) {
-                zk1.create(path + "/ch", null, Ids.OPEN_ACL_UNSAFE,
-                           CreateMode.PERSISTENT);
-
-                WatchedEvent e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-                Assert.assertNotNull(e);
-                Assert.assertEquals(EventType.NodeChildrenChanged, e.getType());
-                Assert.assertEquals(path, e.getPath());
-            } else if (i % 3 == 1) {
-                zk1.create(path + "/foo", null, Ids.OPEN_ACL_UNSAFE,
-                           CreateMode.PERSISTENT);
-
-                WatchedEvent e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-                Assert.assertNotNull(e);
-                Assert.assertEquals(EventType.NodeCreated, e.getType());
-                Assert.assertEquals(path + "/foo", e.getPath());
-            } else if (i % 3 == 2) {
-                zk1.setData(path, new byte[]{1, 2, 3}, -1);
-
-                WatchedEvent e = childWatcher.events.poll(TIMEOUT, TimeUnit.MILLISECONDS);
-                Assert.assertNotNull(e);
-                Assert.assertEquals(EventType.NodeDataChanged, e.getType());
-                Assert.assertEquals(path, e.getPath());
-            }
-
-            i++;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/EventTypeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/EventTypeTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/EventTypeTest.java
deleted file mode 100644
index e6a9826..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/EventTypeTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.util.EnumSet;
-
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class EventTypeTest extends ZKTestCase {
-    
-    @Test
-    public void testIntConversion() {
-        // Ensure that we can convert all valid integers to EventTypes
-        EnumSet<EventType> allTypes = EnumSet.allOf(EventType.class);
-
-        for(EventType et : allTypes) {
-            Assert.assertEquals(et, EventType.fromInt( et.getIntValue() ) );
-        }
-    }
-
-    @Test
-    public void testInvalidIntConversion() {
-        try {
-            EventType et = EventType.fromInt(324242);
-            Assert.fail("Was able to create an invalid EventType via an integer");
-        } catch(RuntimeException re) {
-            // we're good.
-        }
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java
deleted file mode 100644
index 1731e6e..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLENewEpochTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.concurrent.Semaphore;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.server.quorum.FastLeaderElection;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.Vote;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FLENewEpochTest extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(FLENewEpochTest.class);
-
-    int count;
-    HashMap<Long,QuorumServer> peers;
-    ArrayList<LEThread> threads;
-    File tmpdir[];
-    int port[];
-    volatile int [] round;
-
-    Semaphore start0;
-    Semaphore finish3, finish0;
-
-    @Before
-    public void setUp() throws Exception {
-        count = 3;
-
-        peers = new HashMap<Long,QuorumServer>(count);
-        threads = new ArrayList<LEThread>(count);
-        tmpdir = new File[count];
-        port = new int[count];
-
-        round = new int[3];
-        round[0] = 0;
-        round[1] = 0;
-        round[2] = 0;
-
-        start0 = new Semaphore(0);
-        finish0 = new Semaphore(0);
-        finish3 = new Semaphore(0);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        for(int i = 0; i < threads.size(); i++) {
-            ((FastLeaderElection) threads.get(i).peer.getElectionAlg()).shutdown();
-        }
-    }
-
-
-    class LEThread extends Thread {
-        int i;
-        QuorumPeer peer;
-
-        LEThread(QuorumPeer peer, int i) {
-            this.i = i;
-            this.peer = peer;
-            LOG.info("Constructor: " + getName());
-
-        }
-
-        public void run(){
-            boolean flag = true;
-            try{
-                while(flag){
-                    Vote v = null;
-                    peer.setPeerState(ServerState.LOOKING);
-                    LOG.info("Going to call leader election again: " + i);
-                    v = peer.getElectionAlg().lookForLeader();
-
-                    if (v == null){
-                        Assert.fail("Thread " + i + " got a null vote");
-                    }
-
-                    /*
-                     * A real zookeeper would take care of setting the current vote. Here
-                     * we do it manually.
-                     */
-                    peer.setCurrentVote(v);
-
-                    LOG.info("Finished election: " + i + ", " + v.getId());
-                    //votes[i] = v;
-
-                    switch (i) {
-                    case 0:
-                        LOG.info("First peer, do nothing, just join");
-                        if(finish0.tryAcquire(1000, java.util.concurrent.TimeUnit.MILLISECONDS)){
-                        //if(threads.get(0).peer.getPeerState() == ServerState.LEADING ){
-                            LOG.info("Setting flag to false");
-                            flag = false;
-                        }
-                        break;
-                    case 1:
-                        LOG.info("Second entering case");
-                        if(round[1] != 0){
-                            finish0.release();
-                            flag = false;
-                        } else {
-                            finish3.acquire();
-                            start0.release();
-                        }
-                        LOG.info("Second is going to start second round");
-                        round[1]++;
-                        break;
-                    case 2:
-                        LOG.info("Third peer, shutting it down");
-                        QuorumBase.shutdown(peer);
-                        flag = false;
-                        round[2] = 1;
-                        finish3.release();
-                        LOG.info("Third leaving");
-                        break;
-                    }
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-
-      @Test
-      public void testLENewEpoch() throws Exception {
-
-          FastLeaderElection le[] = new FastLeaderElection[count];
-
-          LOG.info("TestLE: " + getTestName()+ ", " + count);
-          for(int i = 0; i < count; i++) {
-              peers.put(Long.valueOf(i),
-                        new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
-                                         PortAssignment.unique(), null));
-              tmpdir[i] = ClientBase.createTmpDir();
-              port[i] = PortAssignment.unique();
-          }
-
-          for(int i = 1; i < le.length; i++) {
-              QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2);
-              peer.startLeaderElection();
-              LEThread thread = new LEThread(peer, i);
-              thread.start();
-              threads.add(thread);
-          }
-          if(!start0.tryAcquire(4000, java.util.concurrent.TimeUnit.MILLISECONDS))
-              Assert.fail("First leader election failed");
-
-          QuorumPeer peer = new QuorumPeer(peers, tmpdir[0], tmpdir[0], port[0], 3, 0, 1000, 2, 2);
-          peer.startLeaderElection();
-          LEThread thread = new LEThread(peer, 0);
-          thread.start();
-          threads.add(thread);
-
-          LOG.info("Started threads " + getTestName());
-
-          for(int i = 0; i < threads.size(); i++) {
-              threads.get(i).join(10000);
-              if (threads.get(i).isAlive()) {
-                  Assert.fail("Threads didn't join");
-              }
-
-          }
-      }
-  }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java
deleted file mode 100644
index 0ecac6e..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEPredicateTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * 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.
- */
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-
-import org.apache.zookeeper.server.quorum.FastLeaderElection;
-import org.apache.zookeeper.server.quorum.QuorumCnxManager;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZKTestCase;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class FLEPredicateTest extends ZKTestCase {
-    
-    protected static final Logger LOG = LoggerFactory.getLogger(FLEPredicateTest.class);
-    
-    class MockFLE extends FastLeaderElection {
-        MockFLE(QuorumPeer peer){
-            super(peer, peer.createCnxnManager());
-        }
-        
-        boolean predicate(long newId, long newZxid, long newEpoch, long curId, long curZxid, long curEpoch){
-            return this.totalOrderPredicate(newId, newZxid, newEpoch, curId, curZxid, curEpoch);
-        }
-    }
-    
-    
-    HashMap<Long,QuorumServer> peers;
-    
-    @Test
-    public void testPredicate() throws IOException {
-        
-        peers = new HashMap<Long,QuorumServer>(3);
-        
-        /*
-         * Creates list of peers.
-         */
-        for(int i = 0; i < 3; i++) {
-            peers.put(Long.valueOf(i),
-                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
-                                       PortAssignment.unique(), null));
-        }
-
-        /*
-         * Creating peer.
-         */
-        try{
-            File tmpDir = ClientBase.createTmpDir();
-            QuorumPeer peer = new QuorumPeer(peers, tmpDir, tmpDir,
-                                        PortAssignment.unique(), 3, 0, 1000, 2, 2);
-        
-            MockFLE mock = new MockFLE(peer);
-            
-            /*
-             * Lower epoch must return false
-             */
-            
-            Assert.assertFalse (mock.predicate(4L, 0L, 0L, 3L, 0L, 2L));
-            
-            /*
-             * Later epoch
-             */
-            Assert.assertTrue (mock.predicate(0L, 0L, 1L, 1L, 0L, 0L));
-        
-            /*
-             * Higher zxid
-             */
-            Assert.assertTrue(mock.predicate(0L, 1L, 0L, 1L, 0L, 0L));
-        
-            /*
-             * Higher id
-             */
-            Assert.assertTrue(mock.predicate(1L, 1L, 0L, 0L, 1L, 0L));
-        } catch (IOException e) {
-            LOG.error("Exception while creating quorum peer", e);
-            Assert.fail("Exception while creating quorum peer");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLERestartTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLERestartTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLERestartTest.java
deleted file mode 100644
index a7cecf6..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLERestartTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Random;
-import java.util.concurrent.Semaphore;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.server.quorum.FastLeaderElection;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.Vote;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FLERestartTest extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(FLETest.class);
-
-    static class TestVote {
-        TestVote(int id, long leader) {
-            this.leader = leader;
-        }
-
-        long leader;
-    }
-
-    int countVotes(HashSet<TestVote> hs, long id) {
-        int counter = 0;
-        for(TestVote v : hs){
-            if(v.leader == id) counter++;
-        }
-
-        return counter;
-    }
-
-    int count;
-    //    int baseport;
-    //    int baseLEport;
-    HashMap<Long,QuorumServer> peers;
-    ArrayList<FLERestartThread> restartThreads;
-    HashMap<Integer, HashSet<TestVote> > voteMap;
-    File tmpdir[];
-    int port[];
-    int successCount;
-    Semaphore finish;
-
-    volatile Vote votes[];
-    volatile boolean leaderDies;
-    volatile long leader = -1;
-    //volatile int round = 1;
-    Random rand = new Random();
-
-    @Before
-    public void setUp() throws Exception {
-        count = 3;
-
-        peers = new HashMap<Long,QuorumServer>(count);
-        restartThreads = new ArrayList<FLERestartThread>(count);
-        voteMap = new HashMap<Integer, HashSet<TestVote> >();
-        votes = new Vote[count];
-        tmpdir = new File[count];
-        port = new int[count];
-        successCount = 0;
-        finish = new Semaphore(0);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        for(int i = 0; i < restartThreads.size(); i++) {
-            ((FastLeaderElection) restartThreads.get(i).peer.getElectionAlg()).shutdown();
-        }
-    }
-
-    class FLERestartThread extends Thread {
-        int i;
-        QuorumPeer peer;
-        int peerRound = 0;
-
-        FLERestartThread(QuorumPeer peer, int i) {
-            this.i = i;
-            this.peer = peer;
-            LOG.info("Constructor: " + getName());
-        }
-        public void run() {
-            try {
-                Vote v = null;
-                while(true) {
-                    peer.setPeerState(ServerState.LOOKING);
-                    LOG.info("Going to call leader election again.");
-                    v = peer.getElectionAlg().lookForLeader();
-                    if(v == null){
-                        LOG.info("Thread " + i + " got a null vote");
-                        break;
-                    }
-
-                    /*
-                     * A real zookeeper would take care of setting the current vote. Here
-                     * we do it manually.
-                     */
-                    peer.setCurrentVote(v);
-
-                    LOG.info("Finished election: " + i + ", " + v.getId());
-                    //votes[i] = v;
-
-                    switch(i){
-                    case 0:
-                        if(peerRound == 0){
-                            LOG.info("First peer, shutting it down");
-                            QuorumBase.shutdown(peer);
-                            ((FastLeaderElection) restartThreads.get(i).peer.getElectionAlg()).shutdown();
-
-                            peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2);
-                            peer.startLeaderElection();
-                            peerRound++;
-                        } else {
-                            finish.release(2);
-                            return;
-                        }
-
-                        break;
-                    case 1:
-                        LOG.info("Second entering case");
-                        finish.acquire();
-                        //if(threads.get(0).peer.getPeerState() == ServerState.LEADING ){
-                        LOG.info("Release");
-
-                        return;
-                    case 2:
-                        LOG.info("First peer, do nothing, just join");
-                        finish.acquire();
-                        //if(threads.get(0).peer.getPeerState() == ServerState.LEADING ){
-                        LOG.info("Release");
-
-                        return;
-                    }
-                }
-            } catch (Exception e){
-                e.printStackTrace();
-            }
-        }
-    }
-
-
-    @Test
-    public void testLERestart() throws Exception {
-
-        FastLeaderElection le[] = new FastLeaderElection[count];
-        leaderDies = true;
-        boolean allowOneBadLeader = leaderDies;
-
-        LOG.info("TestLE: " + getTestName()+ ", " + count);
-        for(int i = 0; i < count; i++) {
-            peers.put(Long.valueOf(i),
-                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
-                                       PortAssignment.unique(), null));
-            tmpdir[i] = ClientBase.createTmpDir();
-            port[i] = PortAssignment.unique();
-        }
-
-        for(int i = 0; i < count; i++) {
-            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2);
-            peer.startLeaderElection();
-            FLERestartThread thread = new FLERestartThread(peer, i);
-            thread.start();
-            restartThreads.add(thread);
-        }
-        LOG.info("Started threads " + getTestName());
-        for(int i = 0; i < restartThreads.size(); i++) {
-            restartThreads.get(i).join(10000);
-            if (restartThreads.get(i).isAlive()) {
-                Assert.fail("Threads didn't join");
-            }
-
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLETest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLETest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLETest.java
deleted file mode 100644
index 6281a57..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLETest.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Random;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.server.quorum.FastLeaderElection;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.Vote;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FLETest extends ZKTestCase {
-    protected static final Logger LOG = LoggerFactory.getLogger(FLETest.class);
-    private FLETest.LEThread leThread;
-
-    static class TestVote {
-        TestVote(int id, long leader) {
-            this.leader = leader;
-        }
-
-        long leader;
-    }
-
-    int countVotes(HashSet<TestVote> hs, long id) {
-        int counter = 0;
-        for(TestVote v : hs){
-            if(v.leader == id) counter++;
-        }
-
-        return counter;
-    }
-
-    int count;
-    HashMap<Long,QuorumServer> peers;
-    ArrayList<LEThread> threads;
-    HashMap<Integer, HashSet<TestVote> > voteMap;
-    File tmpdir[];
-    int port[];
-    int successCount;
-    Object finalObj;
-
-    volatile Vote votes[];
-    volatile boolean leaderDies;
-    volatile long leader = -1;
-    //volatile int round = 1;
-    Random rand = new Random();
-    Set<Long> joinedThreads;
-
-    @Before
-    public void setUp() throws Exception {
-        count = 7;
-
-        peers = new HashMap<Long,QuorumServer>(count);
-        threads = new ArrayList<LEThread>(count);
-        voteMap = new HashMap<Integer, HashSet<TestVote> >();
-        votes = new Vote[count];
-        tmpdir = new File[count];
-        port = new int[count];
-        successCount = 0;
-        finalObj = new Object();
-        joinedThreads = new HashSet<Long>();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        for (int i = 0; i < threads.size(); i++) {
-            leThread = threads.get(i);
-            QuorumBase.shutdown(leThread.peer);
-        }
-    }
-
-    class LEThread extends Thread {
-        int i;
-        QuorumPeer peer;
-        //int peerRound = 1;
-
-        LEThread(QuorumPeer peer, int i) {
-            this.i = i;
-            this.peer = peer;
-            LOG.info("Constructor: " + getName());
-        }
-        public void run() {
-            try {
-                Vote v = null;
-                while(true) {
-                    peer.setPeerState(ServerState.LOOKING);
-                    LOG.info("Going to call leader election again.");
-                    v = peer.getElectionAlg().lookForLeader();
-                    if(v == null){
-                        LOG.info("Thread " + i + " got a null vote");
-                        break;
-                    }
-
-                    /*
-                     * A real zookeeper would take care of setting the current vote. Here
-                     * we do it manually.
-                     */
-                    peer.setCurrentVote(v);
-
-                    LOG.info("Finished election: " + i + ", " + v.getId());
-                    votes[i] = v;
-
-                    /*
-                     * Get the current value of the logical clock for this peer.
-                     */
-                    int lc = (int) ((FastLeaderElection) peer.getElectionAlg()).getLogicalClock();
-
-                    if (v.getId() == i) {
-                        /*
-                         * A leader executes this part of the code. If it is the first leader to be
-                         * elected, then it Assert.fails right after. Otherwise, it waits until it has enough
-                         * followers supporting it.
-                         */
-                        LOG.info("I'm the leader: " + i);
-                        synchronized(FLETest.this) {
-                            if (leaderDies) {
-                                LOG.info("Leader " + i + " dying");
-                                leaderDies = false;
-                                ((FastLeaderElection) peer.getElectionAlg()).shutdown();
-                                leader = -1;
-                                LOG.info("Leader " + i + " dead");
-
-                                //round++;
-                                FLETest.this.notifyAll();
-
-                                break;
-
-                            } else {
-                                synchronized(voteMap){
-                                    if(voteMap.get(lc) == null)
-                                        voteMap.put(lc, new HashSet<TestVote>());
-                                    HashSet<TestVote> hs = voteMap.get(lc);
-                                    hs.add(new TestVote(i, v.getId()));
-
-                                    if(countVotes(hs, v.getId()) > (count/2)){
-                                        leader = i;
-                                        LOG.info("Got majority: " + i);
-                                    } else {
-                                        voteMap.wait(3000);
-                                        LOG.info("Notified or expired: " + i);
-                                        hs = voteMap.get(lc);
-                                        if(countVotes(hs, v.getId()) > (count/2)){
-                                            leader = i;
-                                            LOG.info("Got majority: " + i);
-                                        } else {
-                                            //round++;
-                                        }
-                                    }
-                                }
-                                FLETest.this.notifyAll();
-
-                                if(leader == i){
-                                    synchronized(finalObj){
-                                        successCount++;
-                                        joinedThreads.add((long)i);
-                                        if(successCount > (count/2)) finalObj.notify();
-                                    }
-
-                                    break;
-                                }
-                            }
-                        }
-                    } else {
-                        /*
-                         * Followers execute this part. They first add their vote to voteMap, and then
-                         * they wait for bounded amount of time. A leader notifies followers through the
-                         * FLETest.this object.
-                         *
-                         * Note that I can get FLETest.this, and then voteMap before adding the vote of
-                         * a follower, otherwise a follower would be blocked out until the leader notifies
-                         * or leaves the synchronized block on FLEtest.this.
-                         */
-
-
-                        LOG.info("Logical clock " + ((FastLeaderElection) peer.getElectionAlg()).getLogicalClock());
-                        synchronized(voteMap){
-                            LOG.info("Voting on " + votes[i].getId() + ", round " + ((FastLeaderElection) peer.getElectionAlg()).getLogicalClock());
-                            if(voteMap.get(lc) == null)
-                                voteMap.put(lc, new HashSet<TestVote>());
-                            HashSet<TestVote> hs = voteMap.get(lc);
-                            hs.add(new TestVote(i, votes[i].getId()));
-                            if(countVotes(hs, votes[i].getId()) > (count/2)){
-                                LOG.info("Logical clock: " + lc + ", " + votes[i].getId());
-                                voteMap.notify();
-                            }
-                        }
-
-                        /*
-                         * In this part a follower waits until the leader notifies it, and remove its
-                         * vote if the leader takes too long to respond.
-                         */
-                        synchronized(FLETest.this){
-                            if (leader != votes[i].getId()) FLETest.this.wait(3000);
-
-                            LOG.info("The leader: " + leader + " and my vote " + votes[i].getId());
-                            synchronized(voteMap){
-                                if (leader == votes[i].getId()) {
-                                    synchronized(finalObj){
-                                        successCount++;
-                                        joinedThreads.add((long)i);
-                                        if(successCount > (count/2)) finalObj.notify();
-                                    }
-                                    break;
-                                } else {
-                                    HashSet<TestVote> hs = voteMap.get(lc);
-                                    TestVote toRemove = null;
-                                    for(TestVote tv : hs){
-                                        if(v.getId() == i){
-                                            toRemove = tv;
-                                            break;
-                                        }
-                                    }
-                                    hs.remove(toRemove);
-                                }
-                            }
-                        }
-                    }
-                    /*
-                     * Add some randomness to the execution.
-                     */
-                    Thread.sleep(rand.nextInt(500));
-                    peer.setCurrentVote(new Vote(peer.getId(), 0));
-                }
-                LOG.debug("Thread " + i + " votes " + v);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    @Test
-    public void testLE() throws Exception {
-
-        FastLeaderElection le[] = new FastLeaderElection[count];
-        leaderDies = true;
-        boolean allowOneBadLeader = leaderDies;
-
-        LOG.info("TestLE: " + getTestName()+ ", " + count);
-        for(int i = 0; i < count; i++) {
-            peers.put(Long.valueOf(i),
-                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(),
-                                       PortAssignment.unique(), null));
-            tmpdir[i] = ClientBase.createTmpDir();
-            port[i] = PortAssignment.unique();
-        }
-
-        for(int i = 0; i < le.length; i++) {
-            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i],
-                    port[i], 3, i, 1000, 2, 2);
-            peer.startLeaderElection();
-            LEThread thread = new LEThread(peer, i);
-            thread.start();
-            threads.add(thread);
-        }
-        LOG.info("Started threads " + getTestName());
-
-
-        int waitCounter = 0;
-        synchronized(finalObj){
-            while((successCount <= count/2) && (waitCounter < 50)){
-                finalObj.wait(2000);
-                waitCounter++;
-            }
-        }
-
-        /*
-        * Lists what threads haven-t joined. A thread doesn't join if
-        * it hasn't decided upon a leader yet. It can happen that a
-        * peer is slow or disconnected, and it can take longer to
-        * nominate and connect to the current leader.
-        */
-       for (int i = 0; i < threads.size(); i++) {
-            if (threads.get(i).isAlive()) {
-                LOG.info("Threads didn't join: " + i);
-            }
-        }
-
-       /*
-        * If we have a majority, then we are good to go.
-        */
-       if(successCount <= count/2){
-           Assert.fail("Fewer than a a majority has joined");
-       }
-
-       synchronized(finalObj){
-           if(!joinedThreads.contains(leader)){
-               Assert.fail("Leader hasn't joined: " + leader);
-           }
-       }
-    }
-
-    /*
-     * Class to verify of the thread has become a follower
-     */
-    class VerifyState extends Thread {
-        volatile private boolean success = false;
-        QuorumPeer peer;
-        public VerifyState(QuorumPeer peer) {
-            this.peer = peer;
-        }
-        public void run() {
-            setName("VerifyState-" + peer.getId());
-            while (true) {
-                if(peer.getPeerState() == ServerState.FOLLOWING) {
-                    LOG.info("I am following");
-                    success = true;
-                    break;
-                } else if (peer.getPeerState() == ServerState.LEADING) {
-                    LOG.info("I am leading");
-                    success = false;
-                    break;
-                }
-                try {
-                    Thread.sleep(250);
-                } catch (Exception e) {
-                    LOG.warn("Sleep failed ", e);
-                }
-            }
-        }
-        public boolean isSuccess() {
-            return success;
-        }
-    }
-
-    /*
-     * For ZOOKEEPER-975 verify that a peer joining an established cluster
-     * does not go in LEADING state.
-     */
-    @Test
-    public void testJoin() throws Exception {
-        int sid;
-        QuorumPeer peer;
-        int waitTime = 10 * 1000;
-        ArrayList<QuorumPeer> peerList = new ArrayList<QuorumPeer>();
-        for(sid = 0; sid < 3; sid++) {
-            peers.put(Long.valueOf(sid),
-                      new QuorumServer(sid, "0.0.0.0", PortAssignment.unique(),
-                                       PortAssignment.unique(), null));
-            tmpdir[sid] = ClientBase.createTmpDir();
-            port[sid] = PortAssignment.unique();
-        }
-        // start 2 peers and verify if they form the cluster
-        for (sid = 0; sid < 2; sid++) {
-            peer = new QuorumPeer(peers, tmpdir[sid], tmpdir[sid],
-                                             port[sid], 3, sid, 2000, 2, 2);
-            LOG.info("Starting peer " + peer.getId());
-            peer.start();
-            peerList.add(sid, peer);
-        }
-        peer = peerList.get(0);
-        VerifyState v1 = new VerifyState(peerList.get(0));
-        v1.start();
-        v1.join(waitTime);
-        Assert.assertFalse("Unable to form cluster in " +
-            waitTime + " ms",
-            !v1.isSuccess());
-        // Start 3rd peer and check if it goes in LEADING state
-        peer = new QuorumPeer(peers, tmpdir[sid], tmpdir[sid],
-                 port[sid], 3, sid, 2000, 2, 2);
-        LOG.info("Starting peer " + peer.getId());
-        peer.start();
-        peerList.add(sid, peer);
-        v1 = new VerifyState(peer);
-        v1.start();
-        v1.join(waitTime);
-        if (v1.isAlive()) {
-               Assert.fail("Peer " + peer.getId() + " failed to join the cluster " +
-                "within " + waitTime + " ms");
-        } else if (!v1.isSuccess()) {
-               Assert.fail("Incorrect LEADING state for peer " + peer.getId());
-        }
-        // cleanup
-        for (int id = 0; id < 3; id++) {
-            peer = peerList.get(id);
-            if (peer != null) {
-                peer.shutdown();
-            }
-        }
-    }
-
-    /*
-     * For ZOOKEEPER-1732 verify that it is possible to join an ensemble with
-     * inconsistent election round information.
-     */
-    @Test
-    public void testJoinInconsistentEnsemble() throws Exception {
-        int sid;
-        QuorumPeer peer;
-        int waitTime = 10 * 1000;
-        ArrayList<QuorumPeer> peerList = new ArrayList<QuorumPeer>();
-        for(sid = 0; sid < 3; sid++) {
-            peers.put(Long.valueOf(sid),
-                      new QuorumServer(sid, "0.0.0.0", PortAssignment.unique(),
-                                       PortAssignment.unique(), null));
-            tmpdir[sid] = ClientBase.createTmpDir();
-            port[sid] = PortAssignment.unique();
-        }
-        // start 2 peers and verify if they form the cluster
-        for (sid = 0; sid < 2; sid++) {
-            peer = new QuorumPeer(peers, tmpdir[sid], tmpdir[sid],
-                                             port[sid], 3, sid, 2000, 2, 2);
-            LOG.info("Starting peer " + peer.getId());
-            peer.start();
-            peerList.add(sid, peer);
-        }
-        peer = peerList.get(0);
-        VerifyState v1 = new VerifyState(peerList.get(0));
-        v1.start();
-        v1.join(waitTime);
-        Assert.assertFalse("Unable to form cluster in " +
-            waitTime + " ms",
-            !v1.isSuccess());
-        // Change the election round for one of the members of the ensemble
-        long leaderSid = peer.getCurrentVote().getId();
-        long zxid = peer.getCurrentVote().getZxid();
-        long electionEpoch = peer.getCurrentVote().getElectionEpoch();
-        ServerState state = peer.getCurrentVote().getState();
-        long peerEpoch = peer.getCurrentVote().getPeerEpoch();
-        Vote newVote = new Vote(leaderSid, zxid+100, electionEpoch+100, peerEpoch, state);
-        peer.setCurrentVote(newVote);
-        // Start 3rd peer and check if it joins the quorum
-        peer = new QuorumPeer(peers, tmpdir[2], tmpdir[2],
-                 port[2], 3, 2, 2000, 2, 2);
-        LOG.info("Starting peer " + peer.getId());
-        peer.start();
-        peerList.add(sid, peer);
-        v1 = new VerifyState(peer);
-        v1.start();
-        v1.join(waitTime);
-        if (v1.isAlive()) {
-               Assert.fail("Peer " + peer.getId() + " failed to join the cluster " +
-                "within " + waitTime + " ms");
-        }
-        // cleanup
-        for (int id = 0; id < 3; id++) {
-            peer = peerList.get(id);
-            if (peer != null) {
-                peer.shutdown();
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java
deleted file mode 100644
index e8a8cf7..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FLEZeroWeightTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Properties;
-import java.util.Random;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.zookeeper.PortAssignment;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.server.quorum.FastLeaderElection;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.Vote;
-import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
-import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
-import org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FLEZeroWeightTest extends ZKTestCase {
-    private static final Logger LOG = LoggerFactory.getLogger(HierarchicalQuorumTest.class);
-
-    Properties qp;
-
-    int count;
-    HashMap<Long,QuorumServer> peers;
-    ArrayList<LEThread> threads;
-    File tmpdir[];
-    int port[];
-    Object finalObj;
-
-    volatile Vote votes[];
-    volatile boolean leaderDies;
-    volatile long leader = -1;
-    Random rand = new Random();
-
-
-    @Before
-    public void setUp() throws Exception {
-        count = 9;
-
-        peers = new HashMap<Long,QuorumServer>(count);
-        threads = new ArrayList<LEThread>(count);
-        votes = new Vote[count];
-        tmpdir = new File[count];
-        port = new int[count];
-        finalObj = new Object();
-
-        String config = "group.1=0:1:2\n" +
-        "group.2=3:4:5\n" +
-        "group.3=6:7:8\n" +
-        "weight.0=1\n" +
-        "weight.1=1\n" +
-        "weight.2=1\n" +
-        "weight.3=0\n" +
-        "weight.4=0\n" +
-        "weight.5=0\n" +
-        "weight.6=0\n" +
-        "weight.7=0\n" +
-        "weight.8=0";
-
-        ByteArrayInputStream is = new ByteArrayInputStream(config.getBytes());
-        this.qp = new Properties();
-        qp.load(is);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        for(int i = 0; i < threads.size(); i++) {
-            LEThread leThread = threads.get(i);
-            // shutdown() has to be explicitly called for every thread to
-            // make sure that resources are freed properly and all fixed network ports
-            // are available for other test cases
-            QuorumBase.shutdown(leThread.peer);
-        }
-    }
-
-    class LEThread extends Thread {
-        int i;
-        QuorumPeer peer;
-        boolean fail;
-
-        LEThread(QuorumPeer peer, int i) {
-            this.i = i;
-            this.peer = peer;
-            LOG.info("Constructor: " + getName());
-        }
-
-        public void run() {
-            try {
-                Vote v = null;
-                fail = false;
-                while(true){
-
-                    //while(true) {
-                    peer.setPeerState(ServerState.LOOKING);
-                    LOG.info("Going to call leader election.");
-                    v = peer.getElectionAlg().lookForLeader();
-                    if(v == null){
-                        LOG.info("Thread " + i + " got a null vote");
-                        return;
-                    }
-
-                    /*
-                     * A real zookeeper would take care of setting the current vote. Here
-                     * we do it manually.
-                     */
-                    peer.setCurrentVote(v);
-
-                    LOG.info("Finished election: " + i + ", " + v.getId());
-                    votes[i] = v;
-
-                    if((peer.getPeerState() == ServerState.LEADING) &&
-                            (peer.getId() > 2)) fail = true;
-
-                    if((peer.getPeerState() == ServerState.FOLLOWING) ||
-                            (peer.getPeerState() == ServerState.LEADING)) break;
-                }
-                LOG.debug("Thread " + i + " votes " + v);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    @Test
-    public void testZeroWeightQuorum() throws Exception {
-        FastLeaderElection le[] = new FastLeaderElection[count];
-
-        LOG.info("TestZeroWeightQuorum: " + getTestName()+ ", " + count);
-        for(int i = 0; i < count; i++) {
-            peers.put(Long.valueOf(i),
-                      new QuorumServer(i, "0.0.0.0", PortAssignment.unique(), PortAssignment.unique(), null));
-            tmpdir[i] = ClientBase.createTmpDir();
-            port[i] = PortAssignment.unique();
-        }
-
-        for(int i = 0; i < le.length; i++) {
-            QuorumHierarchical hq = new QuorumHierarchical(qp);
-            QuorumPeer peer = new QuorumPeer(peers, tmpdir[i], tmpdir[i], port[i], 3, i, 1000, 2, 2, hq);
-            peer.startLeaderElection();
-            LEThread thread = new LEThread(peer, i);
-            thread.start();
-            threads.add(thread);
-        }
-        LOG.info("Started threads " + getTestName());
-
-        for(int i = 0; i < threads.size(); i++) {
-            threads.get(i).join(15000);
-            if (threads.get(i).isAlive()) {
-                Assert.fail("Threads didn't join");
-            } else {
-                if(threads.get(i).fail)
-                    Assert.fail("Elected zero-weight server");
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java b/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java
deleted file mode 100644
index acd05d6..0000000
--- a/zookeeper-common/src/test/java/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java
+++ /dev/null
@@ -1,607 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.zookeeper.test;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.TestableZooKeeper;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.ZKTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.server.ZKDatabase;
-import org.apache.zookeeper.server.quorum.Leader;
-import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
-import org.junit.Assert;
-import org.junit.Test;
-
-
-public class FollowerResyncConcurrencyTest extends ZKTestCase {
-    private static final Logger LOG = Logger.getLogger(FollowerResyncConcurrencyTest.class);
-    public static final long CONNECTION_TIMEOUT = ClientTest.CONNECTION_TIMEOUT;
-
-    private volatile int counter = 0;
-    private volatile int errors = 0;
-
-    /**
-     * See ZOOKEEPER-1319 - verify that a lagging follwer resyncs correctly
-     * 
-     * 1) start with down quorum
-     * 2) start leader/follower1, add some data
-     * 3) restart leader/follower1
-     * 4) start follower2
-     * 5) verify data consistency across the ensemble
-     * 
-     * @throws Exception
-     */
-    @Test
-    public void testLaggingFollowerResyncsUnderNewEpoch() throws Exception {
-        CountdownWatcher watcher1 = new CountdownWatcher();
-        CountdownWatcher watcher2 = new CountdownWatcher();
-        CountdownWatcher watcher3 = new CountdownWatcher();
-
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.shutdownAll();
-
-        qu.start(1);
-        qu.start(2);
-        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                + qu.getPeer(1).clientPort, ClientBase.CONNECTION_TIMEOUT));
-        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                + qu.getPeer(2).clientPort, ClientBase.CONNECTION_TIMEOUT));
-
-        ZooKeeper zk1 =
-                createClient(qu.getPeer(1).peer.getClientPort(), watcher1);
-        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
-
-        final String resyncPath = "/resyncundernewepoch";
-        zk1.create(resyncPath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk1.close();
-
-        qu.shutdown(1);
-        qu.shutdown(2);
-        Assert.assertTrue("Waiting for server down", ClientBase.waitForServerDown("127.0.0.1:"
-                + qu.getPeer(1).clientPort, ClientBase.CONNECTION_TIMEOUT));
-        Assert.assertTrue("Waiting for server down", ClientBase.waitForServerDown("127.0.0.1:"
-                + qu.getPeer(2).clientPort, ClientBase.CONNECTION_TIMEOUT));
-        
-        qu.start(1);
-        qu.start(2);
-        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                + qu.getPeer(1).clientPort, ClientBase.CONNECTION_TIMEOUT));
-        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                + qu.getPeer(2).clientPort, ClientBase.CONNECTION_TIMEOUT));
-
-        qu.start(3);
-        Assert.assertTrue("Waiting for server up", ClientBase.waitForServerUp("127.0.0.1:"
-                + qu.getPeer(3).clientPort, ClientBase.CONNECTION_TIMEOUT));
-
-        zk1 = createClient(qu.getPeer(1).peer.getClientPort(), watcher1);
-        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
-        
-        assertNotNull("zk1 has data", zk1.exists(resyncPath, false));
-
-        final ZooKeeper zk2 =
-                createClient(qu.getPeer(2).peer.getClientPort(), watcher2);
-        LOG.info("zk2 has session id 0x" + Long.toHexString(zk2.getSessionId()));
-
-        assertNotNull("zk2 has data", zk2.exists(resyncPath, false));
-
-        final ZooKeeper zk3 =
-            createClient(qu.getPeer(3).peer.getClientPort(), watcher3);
-        LOG.info("zk3 has session id 0x" + Long.toHexString(zk3.getSessionId()));
-
-        assertNotNull("zk3 has data", zk3.exists(resyncPath, false));
-
-        zk1.close();
-        zk2.close();
-        zk3.close();
-        
-        qu.shutdownAll();
-    }      
-
-    /**
-     * See ZOOKEEPER-962. This tests for one of the bugs hit while fixing this,
-     * setting the ZXID of the SNAP packet
-     * Starts up 3 ZKs. Shut down F1, write a node, restart the one that was shut down
-     * The non-leader ZKs are writing to cluster
-     * Shut down F1 again
-     * Restart after sessions are expired, expect to get a snap file
-     * Shut down, run some transactions through.
-     * Restart to a diff while transactions are running in leader
-     * @throws IOException
-     * @throws InterruptedException
-     * @throws KeeperException
-     */
-    @Test
-    public void testResyncBySnapThenDiffAfterFollowerCrashes() 
-        throws IOException, InterruptedException, KeeperException,  Throwable
-    {
-        final Semaphore sem = new Semaphore(0);
-
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-        CountdownWatcher watcher1 = new CountdownWatcher();
-        CountdownWatcher watcher2 = new CountdownWatcher();
-        CountdownWatcher watcher3 = new CountdownWatcher();
-
-        int index = 1;
-        while(qu.getPeer(index).peer.leader == null) {
-            index++;
-        }
-
-        Leader leader = qu.getPeer(index).peer.leader;
-        assertNotNull(leader);    
-
-        /* Reusing the index variable to select a follower to connect to */
-        index = (index == 1) ? 2 : 1;
-        LOG.info("Connecting to follower:" + index);
-
-        qu.shutdown(index);
-
-        final ZooKeeper zk3 =
-            createClient(qu.getPeer(3).peer.getClientPort(), watcher3);
-        LOG.info("zk3 has session id 0x" + Long.toHexString(zk3.getSessionId()));
-
-        zk3.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
-
-        qu.restart(index);
-        final ZooKeeper zk1 =
-            createClient(qu.getPeer(index).peer.getClientPort(), watcher1);
-        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
-
-        final ZooKeeper zk2 =
-            createClient(qu.getPeer(index).peer.getClientPort(), watcher2);
-        LOG.info("zk2 has session id 0x" + Long.toHexString(zk2.getSessionId()));
-        
-        zk1.create("/first", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        Thread mytestfooThread = new Thread(new Runnable() {
-
-            @Override
-            public void run() {
-                for(int i = 0; i < 3000; i++) {
-                    zk3.create("/mytestfoo", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
-
-                        @Override
-                        public void processResult(int rc, String path, Object ctx, String name) {
-                            counter++;
-                            if (rc != 0) {
-                                errors++;
-                            }
-                            if(counter == 16200){
-                                sem.release();
-                            }
-                        }
-                    }, null);
-                    if(i%10==0){
-                        try {
-                            Thread.sleep(100);
-                        } catch (Exception e) {
-
-                        }
-                    }
-                }
-
-            }
-        });
-
-        for(int i = 0; i < 13000; i++) {
-            zk3.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
-
-                @Override
-                public void processResult(int rc, String path, Object ctx, String name) {
-                    counter++;
-                    if (rc != 0) {
-                        errors++;
-                    }
-                    if(counter == 16200){
-                        sem.release();
-                    }
-                }
-            }, null);            
-
-            if(i == 5000){
-                qu.shutdown(index);               
-                LOG.info("Shutting down s1");
-            }
-            if(i == 12000){
-                //Restart off of snap, then get some txns for a log, then shut down
-                mytestfooThread.start();
-                qu.restart(index);       
-                Thread.sleep(300);
-                qu.shutdown(index);               
-                Thread.sleep(300);                
-                qu.restart(index);
-                LOG.info("Setting up server: " + index);
-            }
-            if((i % 1000) == 0){
-                Thread.sleep(1000);
-            }
-
-            if(i%50 == 0) {
-                zk2.create("/newbaz", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
-                    @Override
-                    public void processResult(int rc, String path, Object ctx, String name) {
-                        counter++;
-                        if (rc != 0) {
-                            errors++;
-                        }
-                        if(counter == 16200){
-                            sem.release();
-                        }
-                    }
-                }, null);
-            }
-        }
-
-        // Wait until all updates return
-        if(!sem.tryAcquire(ClientBase.CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)) {
-            LOG.warn("Did not aquire semaphore fast enough");
-        }
-        mytestfooThread.join(ClientBase.CONNECTION_TIMEOUT);
-        if (mytestfooThread.isAlive()) {
-            LOG.error("mytestfooThread is still alive");
-        }
-        Thread.sleep(1000);
-        
-        verifyState(qu, index, leader);
-        
-        zk1.close();
-        zk2.close();
-        zk3.close();
-        
-        qu.shutdownAll();
-    }      
-    
-    /**
-     * This test:
-     * Starts up 3 ZKs. The non-leader ZKs are writing to cluster
-     * Shut down one of the non-leader ZKs. 
-     * Restart after sessions have expired but <500 txns have taken place (get a diff)
-     * Shut down immediately after restarting, start running separate thread with other transactions
-     * Restart to a diff while transactions are running in leader
-     * 
-     * 
-     * Before fixes for ZOOKEEPER-962, restarting off of diff could get an inconsistent view of data missing transactions that
-     * completed during diff syncing. Follower would also be considered "restarted" before all forwarded transactions
-     * were completely processed, so restarting would cause a snap file with a too-high zxid to be written, and transactions
-     * would be missed
-     * 
-     * This test should pretty reliably catch the failure of restarting the server before all diff messages have been processed,
-     * however, due to the transient nature of the system it may not catch failures due to concurrent processing of transactions
-     * during the leader's diff forwarding.
-     * 
-     * @throws IOException
-     * @throws InterruptedException
-     * @throws KeeperException
-     * @throws Throwable
-     */
-
-    @Test
-    public void testResyncByDiffAfterFollowerCrashes() 
-        throws IOException, InterruptedException, KeeperException, Throwable
-    {
-        final Semaphore sem = new Semaphore(0);
-
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-        CountdownWatcher watcher1 = new CountdownWatcher();
-        CountdownWatcher watcher2 = new CountdownWatcher();
-        CountdownWatcher watcher3 = new CountdownWatcher();
-
-        int index = 1;
-        while(qu.getPeer(index).peer.leader == null) {
-            index++;
-        }
-
-        Leader leader = qu.getPeer(index).peer.leader;
-        assertNotNull(leader);
-
-        /* Reusing the index variable to select a follower to connect to */
-        index = (index == 1) ? 2 : 1;
-        LOG.info("Connecting to follower:" + index);
-
-        final ZooKeeper zk1 =
-            createClient(qu.getPeer(index).peer.getClientPort(), watcher1);
-        LOG.info("zk1 has session id 0x" + Long.toHexString(zk1.getSessionId()));
-
-        final ZooKeeper zk2 =
-            createClient(qu.getPeer(index).peer.getClientPort(), watcher2);
-        LOG.info("zk2 has session id 0x" + Long.toHexString(zk2.getSessionId()));
-
-        final ZooKeeper zk3 =
-            createClient(qu.getPeer(3).peer.getClientPort(), watcher3);
-        LOG.info("zk3 has session id 0x" + Long.toHexString(zk3.getSessionId()));
-
-        zk1.create("/first", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
-        zk2.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
-
-        final AtomicBoolean runNow = new AtomicBoolean(false);
-        Thread mytestfooThread = new Thread(new Runnable() {
-            @Override
-            public void run() {                                
-                int inSyncCounter = 0;
-                while(inSyncCounter < 400) {    
-                    if(runNow.get()) {
-                        zk3.create("/mytestfoo", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
-
-                            @Override
-                            public void processResult(int rc, String path, Object ctx, String name) {
-                                counter++;
-                                if (rc != 0) {
-                                    errors++;
-                                }
-                                if(counter > 7300){
-                                    sem.release();
-                                }
-                            }
-                        }, null);
-                        
-                        try {
-                            Thread.sleep(10);
-                        } catch (Exception e) {
-                        }
-                        inSyncCounter++;
-                    } else {
-                        Thread.yield();
-                    }
-                }
-
-            }
-        });
-
-        mytestfooThread.start();
-        for(int i = 0; i < 5000; i++) {
-            zk2.create("/mybar", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
-
-                @Override
-                public void processResult(int rc, String path, Object ctx, String name) {
-                    counter++;
-                    if (rc != 0) {
-                        errors++;
-                    }
-                    if(counter > 7300){
-                        sem.release();
-                    }
-                }
-            }, null);            
-
-            if(i == 1000){
-                qu.shutdown(index);      
-                Thread.sleep(1100);
-                LOG.info("Shutting down s1");
-            }
-            if(i == 1100 || i == 1150 || i == 1200) {
-                Thread.sleep(1000);
-            }
-            
-            if(i == 1200){
-                qu.startThenShutdown(index);                                
-                runNow.set(true);
-                qu.restart(index);
-                LOG.info("Setting up server: " + index);
-            }
-        
-            if(i>=1000 &&  i%2== 0) {
-                zk3.create("/newbaz", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() {
-
-                    @Override
-                    public void processResult(int rc, String path, Object ctx, String name) {
-                        counter++;
-                        if (rc != 0) {
-                            errors++;
-                        }
-                        if(counter > 7300){
-                            sem.release();
-                        }
-                    }
-                }, null);
-            }
-            if(i == 1050 || i == 1100 || i == 1150) {
-                Thread.sleep(1000);
-            }
-        }
-
-        // Wait until all updates return
-        if(!sem.tryAcquire(ClientBase.CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)) {
-            LOG.warn("Did not aquire semaphore fast enough");
-        }
-        mytestfooThread.join(ClientBase.CONNECTION_TIMEOUT);
-        if (mytestfooThread.isAlive()) {
-            LOG.error("mytestfooThread is still alive");
-        }
-
-        Thread.sleep(1000);
-        // Verify that server is following and has the same epoch as the leader
-        
-        verifyState(qu, index, leader);
-        
-        zk1.close();
-        zk2.close();
-        zk3.close();
-        
-        qu.shutdownAll();
-    }
-
-    private static DisconnectableZooKeeper createClient(int port,
-            CountdownWatcher watcher)
-        throws IOException, TimeoutException, InterruptedException
-    {
-        DisconnectableZooKeeper zk = new DisconnectableZooKeeper(
-                "127.0.0.1:" + port, ClientBase.CONNECTION_TIMEOUT, watcher);
-
-        watcher.waitForConnected(CONNECTION_TIMEOUT);
-        return zk;
-    }
-
-    private static TestableZooKeeper createTestableClient(String hp)
-        throws IOException, TimeoutException, InterruptedException
-    {
-        CountdownWatcher watcher = new CountdownWatcher();
-        return createTestableClient(watcher, hp);
-    }
-
-    private static TestableZooKeeper createTestableClient(
-            CountdownWatcher watcher, String hp)
-            throws IOException, TimeoutException, InterruptedException
-        {
-            TestableZooKeeper zk = new TestableZooKeeper(
-                    hp, ClientBase.CONNECTION_TIMEOUT, watcher);
-
-            watcher.waitForConnected(CONNECTION_TIMEOUT);
-            return zk;
-        }
-
-    private void verifyState(QuorumUtil qu, int index, Leader leader) {
-        assertTrue("Not following", qu.getPeer(index).peer.follower != null);
-        long epochF = (qu.getPeer(index).peer.getActiveServer().getZxid() >> 32L);
-        long epochL = (leader.getEpoch() >> 32L);
-        assertTrue("Zxid: " + qu.getPeer(index).peer.getActiveServer().getZKDatabase().getDataTreeLastProcessedZxid() + 
-                "Current epoch: " + epochF, epochF == epochL);
-        int leaderIndex = (index == 1) ? 2 : 1;    
-        Collection<Long> sessionsRestarted = qu.getPeer(index).peer.getActiveServer().getZKDatabase().getSessions();
-        Collection<Long> sessionsNotRestarted = qu.getPeer(leaderIndex).peer.getActiveServer().getZKDatabase().getSessions();
-        
-        for(Long l : sessionsRestarted) {
-            assertTrue("Should have same set of sessions in both servers, did not expect: " + l, sessionsNotRestarted.contains(l));        
-        }      
-        assertEquals("Should have same number of sessions", sessionsNotRestarted.size(), sessionsRestarted.size());
-        ZKDatabase restarted = qu.getPeer(index).peer.getActiveServer().getZKDatabase();
-        ZKDatabase clean =  qu.getPeer(3).peer.getActiveServer().getZKDatabase();
-        ZKDatabase lead = qu.getPeer(leaderIndex).peer.getActiveServer().getZKDatabase();
-        for(Long l : sessionsRestarted) {
-            assertTrue("Should have same set of sessions in both servers, did not expect: " + l, sessionsNotRestarted.contains(l));
-            HashSet ephemerals = restarted.getEphemerals(l);
-            HashSet cleanEphemerals = clean.getEphemerals(l);
-            for(Object o : cleanEphemerals) {
-                if(!ephemerals.contains(o)) {
-                    LOG.info("Restarted follower doesn't contain ephemeral " + o);
-                }
-            }
-            HashSet leadEphemerals = lead.getEphemerals(l);
-            for(Object o : leadEphemerals) {
-                if(!cleanEphemerals.contains(o)) {
-                    LOG.info("Follower doesn't contain ephemeral from leader " + o);
-                }
-            }
-            assertEquals("Should have same number of ephemerals in both followers", ephemerals.size(), cleanEphemerals.size());            
-            assertEquals("Leader should equal follower", lead.getEphemerals(l).size(), cleanEphemerals.size());
-        }
-    }      
-
-    /**
-     * Verify that the server is sending the proper zxid. See ZOOKEEPER-1412.
-     */
-    @Test
-    public void testFollowerSendsLastZxid() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-
-        int index = 1;
-        while(qu.getPeer(index).peer.follower == null) {
-            index++;
-        }
-        LOG.info("Connecting to follower:" + index);
-
-        TestableZooKeeper zk =
-                createTestableClient("localhost:" + qu.getPeer(index).peer.getClientPort());
-
-        assertEquals(0L, zk.testableLastZxid());
-        zk.exists("/", false);
-        long lzxid = zk.testableLastZxid();
-        assertTrue("lzxid:" + lzxid + " > 0", lzxid > 0);
-        zk.close();
-    }
-
-    private class MyWatcher extends CountdownWatcher {
-        LinkedBlockingQueue<WatchedEvent> events =
-            new LinkedBlockingQueue<WatchedEvent>();
-
-        public void process(WatchedEvent event) {
-            super.process(event);
-            if (event.getType() != Event.EventType.None) {
-                try {
-                    events.put(event);
-                } catch (InterruptedException e) {
-                    LOG.warn("ignoring interrupt during event.put");
-                }
-            }
-        }
-    }
-
-    /**
-     * Verify that the server is sending the proper zxid, and as a result
-     * the watch doesn't fire. See ZOOKEEPER-1412.
-     */
-    @Test
-    public void testFollowerWatcherResync() throws Exception {
-        QuorumUtil qu = new QuorumUtil(1);
-        qu.startAll();
-
-        int index = 1;
-        while(qu.getPeer(index).peer.follower == null) {
-            index++;
-        }
-        LOG.info("Connecting to follower:" + index);
-
-        TestableZooKeeper zk1 = createTestableClient(
-                "localhost:" + qu.getPeer(index).peer.getClientPort());
-        zk1.create("/foo", "foo".getBytes(), Ids.OPEN_ACL_UNSAFE,
-                    CreateMode.PERSISTENT);
-
-        MyWatcher watcher = new MyWatcher();
-        TestableZooKeeper zk2 = createTestableClient(watcher,
-                "localhost:" + qu.getPeer(index).peer.getClientPort());
-
-        zk2.exists("/foo", true);
-
-        watcher.reset();
-        zk2.testableConnloss();
-        if (!watcher.clientConnected.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS))
-        {
-            fail("Unable to connect to server");
-        }
-        assertArrayEquals("foo".getBytes(), zk2.getData("/foo", false, null));
-
-        assertNull(watcher.events.poll(5, TimeUnit.SECONDS));
-
-        zk1.close();
-        zk2.close();
-    }
-
-}


[10/36] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.4 - zookeeper-server

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java
new file mode 100644
index 0000000..793265c
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java
@@ -0,0 +1,186 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ACLTest extends ZKTestCase implements Watcher {
+    private static final Logger LOG = LoggerFactory.getLogger(ACLTest.class);
+    private static final String HOSTPORT =
+        "127.0.0.1:" + PortAssignment.unique();
+    private volatile CountDownLatch startSignal;
+
+    @Test
+    public void testDisconnectedAddAuth() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        SyncRequestProcessor.setSnapCount(1000);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        try {
+            LOG.info("starting up the zookeeper server .. waiting");
+            Assert.assertTrue("waiting for server being up",
+                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+            ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+            try {
+                zk.addAuthInfo("digest", "pat:test".getBytes());
+                zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
+            } finally {
+                zk.close();
+            }
+        } finally {
+            f.shutdown();
+            zks.shutdown();
+            Assert.assertTrue("waiting for server down",
+                    ClientBase.waitForServerDown(HOSTPORT,
+                            ClientBase.CONNECTION_TIMEOUT));
+        }
+    }
+
+    /**
+     * Verify that acl optimization of storing just
+     * a few acls and there references in the data
+     * node is actually working.
+     */
+    @Test
+    public void testAcls() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        SyncRequestProcessor.setSnapCount(1000);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        ZooKeeper zk;
+        String path;
+        try {
+            LOG.info("starting up the zookeeper server .. waiting");
+            Assert.assertTrue("waiting for server being up",
+                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+            zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+            LOG.info("starting creating acls");
+            for (int i = 0; i < 100; i++) {
+                path = "/" + i;
+                zk.create(path, path.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+            }
+            Assert.assertTrue("size of the acl map ", (1 == zks.getZKDatabase().getAclSize()));
+            for (int j = 100; j < 200; j++) {
+                path = "/" + j;
+                ACL acl = new ACL();
+                acl.setPerms(0);
+                Id id = new Id();
+                id.setId("1.1.1."+j);
+                id.setScheme("ip");
+                acl.setId(id);
+                ArrayList<ACL> list = new ArrayList<ACL>();
+                list.add(acl);
+                zk.create(path, path.getBytes(), list, CreateMode.PERSISTENT);
+            }
+            Assert.assertTrue("size of the acl map ", (101 == zks.getZKDatabase().getAclSize()));
+        } finally {
+            // now shutdown the server and restart it
+            f.shutdown();
+            zks.shutdown();
+            Assert.assertTrue("waiting for server down",
+                    ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
+        }
+        startSignal = new CountDownLatch(1);
+
+        zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        f = ServerCnxnFactory.createFactory(PORT, -1);
+
+        f.startup(zks);
+        try {
+            Assert.assertTrue("waiting for server up",
+                       ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+    
+            startSignal.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS);
+            Assert.assertTrue("count == 0", startSignal.getCount() == 0);
+    
+            Assert.assertTrue("acl map ", (101 == zks.getZKDatabase().getAclSize()));
+            for (int j = 200; j < 205; j++) {
+                path = "/" + j;
+                ACL acl = new ACL();
+                acl.setPerms(0);
+                Id id = new Id();
+                id.setId("1.1.1."+j);
+                id.setScheme("ip");
+                acl.setId(id);
+                ArrayList<ACL> list = new ArrayList<ACL>();
+                list.add(acl);
+                zk.create(path, path.getBytes(), list, CreateMode.PERSISTENT);
+            }
+            Assert.assertTrue("acl map ", (106 == zks.getZKDatabase().getAclSize()));
+    
+            zk.close();
+        } finally {
+            f.shutdown();
+            zks.shutdown();
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(HOSTPORT,
+                               ClientBase.CONNECTION_TIMEOUT));
+        }
+
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatcherEvent)
+     */
+    public void process(WatchedEvent event) {
+        LOG.info("Event:" + event.getState() + " " + event.getType() + " "
+                 + event.getPath());
+        if (event.getState() == KeeperState.SyncConnected) {
+            if (startSignal != null && startSignal.getCount() > 0) {
+                LOG.info("startsignal.countDown()");
+                startSignal.countDown();
+            } else {
+                LOG.warn("startsignal " + startSignal);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
new file mode 100644
index 0000000..ebfc963
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
@@ -0,0 +1,245 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+import static org.apache.zookeeper.test.ClientBase.verifyThreadTerminated;
+
+import java.util.LinkedList;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AsyncHammerTest extends ZKTestCase
+    implements StringCallback, VoidCallback, DataCallback
+{
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncHammerTest.class);
+
+    private QuorumBase qb = new QuorumBase();
+
+    private volatile boolean bang;
+
+    public void setUp(boolean withObservers) throws Exception {
+        qb.setUp(withObservers);
+    }
+
+    protected void restart() throws Exception {
+        LOG.info("RESTARTING " + getTestName());
+        qb.tearDown();
+
+        // don't call setup - we don't want to reassign ports/dirs, etc...
+        JMXEnv.setUp();
+        qb.startServers();
+    }
+
+    public void tearDown() throws Exception {
+        LOG.info("Test clients shutting down");
+        qb.tearDown();
+    }
+
+    /**
+     * Create /test- sequence nodes asynchronously, max 30 outstanding
+     */
+    class HammerThread extends Thread implements StringCallback, VoidCallback {
+        private static final int MAX_OUTSTANDING = 30;
+
+        private TestableZooKeeper zk;
+        private int outstanding;
+
+        private volatile boolean failed = false;
+
+        public HammerThread(String name) {
+            super(name);
+        }
+
+        public void run() {
+            try {
+                CountdownWatcher watcher = new CountdownWatcher();
+                zk = new TestableZooKeeper(qb.hostPort, CONNECTION_TIMEOUT,
+                        watcher);
+                watcher.waitForConnected(CONNECTION_TIMEOUT);
+                while(bang) {
+                    incOutstanding(); // before create otw race
+                    zk.create("/test-", new byte[0], Ids.OPEN_ACL_UNSAFE,
+                            CreateMode.PERSISTENT_SEQUENTIAL, this, null);
+                }
+            } catch (InterruptedException e) {
+                if (bang) {
+                    LOG.error("sanity check Assert.failed!!!"); // sanity check
+                    return;
+                }
+            } catch (Exception e) {
+                LOG.error("Client create operation Assert.failed", e);
+                return;
+            } finally {
+                if (zk != null) {
+                    try {
+                        zk.close();
+                        if (!zk.testableWaitForShutdown(CONNECTION_TIMEOUT)) {
+                            failed = true;
+                            LOG.error("Client did not shutdown");
+                        }
+                    } catch (InterruptedException e) {
+                        LOG.info("Interrupted", e);
+                    }
+                }
+            }
+        }
+
+        private synchronized void incOutstanding() throws InterruptedException {
+            outstanding++;
+            while(outstanding > MAX_OUTSTANDING) {
+                wait();
+            }
+        }
+
+        private synchronized void decOutstanding() {
+            outstanding--;
+            Assert.assertTrue("outstanding >= 0", outstanding >= 0);
+            notifyAll();
+        }
+
+        public void process(WatchedEvent event) {
+            // ignore for purposes of this test
+        }
+
+        public void processResult(int rc, String path, Object ctx, String name) {
+            if (rc != KeeperException.Code.OK.intValue()) {
+                if (bang) {
+                    failed = true;
+                    LOG.error("Create Assert.failed for 0x"
+                            + Long.toHexString(zk.getSessionId())
+                            + "with rc:" + rc + " path:" + path);
+                }
+                decOutstanding();
+                return;
+            }
+            try {
+                decOutstanding();
+                zk.delete(name, -1, this, null);
+            } catch (Exception e) {
+                if (bang) {
+                    failed = true;
+                    LOG.error("Client delete Assert.failed", e);
+                }
+            }
+        }
+
+        public void processResult(int rc, String path, Object ctx) {
+            if (rc != KeeperException.Code.OK.intValue()) {
+                if (bang) {
+                    failed = true;
+                    LOG.error("Delete Assert.failed for 0x"
+                            + Long.toHexString(zk.getSessionId())
+                            + "with rc:" + rc + " path:" + path);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testHammer() throws Exception {
+        setUp(false);
+        bang = true;
+        LOG.info("Starting hammers");
+        HammerThread[] hammers = new HammerThread[100];
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i] = new HammerThread("HammerThread-" + i);
+            hammers[i].start();
+        }
+        LOG.info("Started hammers");
+        Thread.sleep(5000); // allow the clients to run for max 5sec
+        bang = false;
+        LOG.info("Stopping hammers");
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i].interrupt();
+            verifyThreadTerminated(hammers[i], 60000);
+            Assert.assertFalse(hammers[i].failed);
+        }
+
+        // before restart
+        LOG.info("Hammers stopped, verifying consistency");
+        qb.verifyRootOfAllServersMatch(qb.hostPort);
+
+        restart();
+
+        // after restart
+        LOG.info("Verifying hammers 2");
+        qb.verifyRootOfAllServersMatch(qb.hostPort);
+        tearDown();
+    }
+
+    @Test
+    public void testObserversHammer() throws Exception {
+        setUp(true);
+        bang = true;
+        Thread[] hammers = new Thread[100];
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i] = new HammerThread("HammerThread-" + i);
+            hammers[i].start();
+        }
+        Thread.sleep(5000); // allow the clients to run for max 5sec
+        bang = false;
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i].interrupt();
+            verifyThreadTerminated(hammers[i], 60000);
+        }
+        // before restart
+        qb.verifyRootOfAllServersMatch(qb.hostPort);
+        tearDown();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, String name) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, byte[] data,
+            Stat stat) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java
new file mode 100644
index 0000000..2dbe644
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java
@@ -0,0 +1,655 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.ACLCallback;
+import org.apache.zookeeper.AsyncCallback.Children2Callback;
+import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+
+public class AsyncOps {
+    /**
+     * This is the base class for all of the async callback classes. It will
+     * verify the expected value against the actual value.
+     * 
+     * Basic operation is that the subclasses will generate an "expected" value
+     * which is defined by the "toString" method of the subclass. This is
+     * passed through to the verify clause by specifying it as the ctx object
+     * of each async call (processResult methods get the ctx as part of
+     * the callback). Additionally the callback will also overwrite any
+     * instance fields with matching parameter arguments to the processResult
+     * method. The cb instance can then compare the expected to the
+     * actual value by again calling toString and comparing the two.
+     * 
+     * The format of each expected value differs (is defined) by subclass.
+     * Generally the expected value starts with the result code (rc) and path
+     * of the node being operated on, followed by the fields specific to
+     * each operation type (cb subclass). For example ChildrenCB specifies
+     * a list of the expected children suffixed onto the rc and path. See
+     * the toString() method of each subclass for details of it's format. 
+     */
+    public static abstract class AsyncCB {
+        protected final ZooKeeper zk;
+        protected long defaultTimeoutMillis = 30000;
+        
+        /** the latch is used to await the results from the server */
+        CountDownLatch latch;
+
+        Code rc = Code.OK;
+        String path = "/foo";
+        String expected;
+        
+        public AsyncCB(ZooKeeper zk, CountDownLatch latch) {
+            this.zk = zk;
+            this.latch = latch;
+        }
+        
+        public void setRC(Code rc) {
+            this.rc = rc;
+        }
+        
+        public void setPath(String path) {
+            this.path = path;
+        }
+        
+        public void processResult(Code rc, String path, Object ctx)
+        {
+            this.rc = rc;
+            this.path = path;
+            this.expected = (String)ctx;
+            latch.countDown();
+        }
+        
+        /** String format is rc:path:<suffix> where <suffix> is defined by each
+         * subclass individually. */
+        @Override
+        public String toString() {
+            return rc + ":" + path + ":"; 
+        }
+
+        protected void verify() {
+            try {
+                latch.await(defaultTimeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                Assert.fail("unexpected interrupt");
+            }
+            // on the lookout for timeout
+            Assert.assertSame(0L, latch.getCount());
+            
+            String actual = toString();
+            
+            Assert.assertEquals(expected, actual);
+        }
+    }
+    
+    public static class StringCB extends AsyncCB implements StringCallback {
+        byte[] data = new byte[10];
+        List<ACL> acl = Ids.CREATOR_ALL_ACL;
+        CreateMode flags = CreateMode.PERSISTENT;
+        String name = path;
+        
+        StringCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+        
+        StringCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+        
+        public void setPath(String path) {
+            super.setPath(path);
+            this.name = path;
+        }
+        
+        public String nodeName() {
+            return path.substring(path.lastIndexOf('/') + 1);
+        }
+        
+        public void processResult(int rc, String path, Object ctx, String name)
+        {
+            this.name = name;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+
+        public AsyncCB create() {
+            zk.create(path, data, acl, flags, this, toString());
+            return this;
+        }
+
+        public AsyncCB createEphemeral() {
+            zk.create(path, data, acl, CreateMode.EPHEMERAL, this, toString());
+            return this;
+        }
+        
+        public void verifyCreate() {
+            create();
+            verify();
+        }
+
+        public void verifyCreateEphemeral() {
+            createEphemeral();
+            verify();
+        }
+        
+        public void verifyCreateFailure_NodeExists() {
+            new StringCB(zk).verifyCreate();
+            
+            rc = Code.NODEEXISTS;
+            name = null;
+            zk.create(path, data, acl, flags, this, toString());
+            verify();
+        }
+
+        public void verifyCreateFailure_NoNode() {
+
+            rc = Code.NONODE;
+            name = null;
+            path = path + "/bar";
+            zk.create(path, data, acl, flags, this, toString());
+
+            verify();
+        }
+
+        public void verifyCreateFailure_NoChildForEphemeral() {
+            new StringCB(zk).verifyCreateEphemeral();
+
+            rc = Code.NOCHILDRENFOREPHEMERALS;
+            name = null;
+            path = path + "/bar";
+            zk.create(path, data, acl, flags, this, toString());
+
+            verify();
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + name; 
+        }
+    }
+
+    public static class ACLCB extends AsyncCB implements ACLCallback {
+        List<ACL> acl = Ids.CREATOR_ALL_ACL;
+        int version = 0;
+        Stat stat = new Stat();
+        byte[] data = "testing".getBytes();
+        
+        ACLCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        ACLCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+            stat.setAversion(0);
+            stat.setCversion(0);
+            stat.setEphemeralOwner(0);
+            stat.setVersion(0);
+        }
+
+        public void processResult(int rc, String path, Object ctx,
+                List<ACL> acl, Stat stat)
+        {
+            this.acl = acl;
+            this.stat = stat;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public void verifyGetACL() {
+            new StringCB(zk).verifyCreate();
+
+            zk.getACL(path, stat, this, toString());
+            verify();
+        }
+
+        public void verifyGetACLFailure_NoNode(){
+            rc = Code.NONODE;
+            stat = null;
+            acl = null;
+            zk.getACL(path, stat, this, toString());
+
+            verify();
+        }
+        
+        public String toString(List<ACL> acls) {
+            if (acls == null) {
+                return "";
+            }
+
+            StringBuilder result = new StringBuilder();
+            for(ACL acl : acls) {
+                result.append(acl.getPerms() + "::");
+            }
+            return result.toString();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + toString(acl) + ":" 
+                + ":" + version + ":" + new String(data)
+                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
+                        + stat.getCversion() + ":" + stat.getEphemeralOwner()
+                        + ":" + stat.getVersion()); 
+        }
+    }
+
+    public static class ChildrenCB extends AsyncCB implements ChildrenCallback {
+        List<String> children = new ArrayList<String>();
+        
+        ChildrenCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        ChildrenCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+        
+        public void processResult(int rc, String path, Object ctx,
+                List<String> children)
+        {
+            this.children =
+                (children == null ? new ArrayList<String>() : children);
+            Collections.sort(this.children);
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public StringCB createNode() {
+            StringCB parent = new StringCB(zk);
+            parent.verifyCreate();
+
+            return parent;
+        }
+        
+        public StringCB createNode(StringCB parent) {
+            String childName = "bar";
+
+            return createNode(parent, childName);
+        }
+
+        public StringCB createNode(StringCB parent, String childName) {
+            StringCB child = new StringCB(zk);
+            child.setPath(parent.path + "/" + childName);
+            child.verifyCreate();
+            
+            return child;
+        }
+        
+        public void verifyGetChildrenEmpty() {
+            StringCB parent = createNode();
+            path = parent.path;
+            verify();
+        }
+
+        public void verifyGetChildrenSingle() {
+            StringCB parent = createNode();
+            StringCB child = createNode(parent);
+
+            path = parent.path;
+            children.add(child.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenTwo() {
+            StringCB parent = createNode();
+            StringCB child1 = createNode(parent, "child1");
+            StringCB child2 = createNode(parent, "child2");
+        
+            path = parent.path;
+            children.add(child1.nodeName());
+            children.add(child2.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            verify();
+        }
+        
+        @Override
+        public void verify() {
+            zk.getChildren(path, false, this, toString());
+            super.verify();
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + children.toString();
+        }
+    }
+
+    public static class Children2CB extends AsyncCB implements Children2Callback {
+        List<String> children = new ArrayList<String>();
+
+        Children2CB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        Children2CB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+
+        public void processResult(int rc, String path, Object ctx,
+                List<String> children, Stat stat)
+        {
+            this.children =
+                (children == null ? new ArrayList<String>() : children);
+            Collections.sort(this.children);
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public StringCB createNode() {
+            StringCB parent = new StringCB(zk);
+            parent.verifyCreate();
+
+            return parent;
+        }
+        
+        public StringCB createNode(StringCB parent) {
+            String childName = "bar";
+
+            return createNode(parent, childName);
+        }
+
+        public StringCB createNode(StringCB parent, String childName) {
+            StringCB child = new StringCB(zk);
+            child.setPath(parent.path + "/" + childName);
+            child.verifyCreate();
+            
+            return child;
+        }
+        
+        public void verifyGetChildrenEmpty() {
+            StringCB parent = createNode();
+            path = parent.path;
+            verify();
+        }
+
+        public void verifyGetChildrenSingle() {
+            StringCB parent = createNode();
+            StringCB child = createNode(parent);
+
+            path = parent.path;
+            children.add(child.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenTwo() {
+            StringCB parent = createNode();
+            StringCB child1 = createNode(parent, "child1");
+            StringCB child2 = createNode(parent, "child2");
+        
+            path = parent.path;
+            children.add(child1.nodeName());
+            children.add(child2.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            verify();
+        }
+        
+        @Override
+        public void verify() {
+            zk.getChildren(path, false, this, toString());
+            super.verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + children.toString(); 
+        }
+    }
+
+    public static class DataCB extends AsyncCB implements DataCallback {
+        byte[] data = new byte[10];
+        Stat stat = new Stat();
+        
+        DataCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        DataCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+            stat.setAversion(0);
+            stat.setCversion(0);
+            stat.setEphemeralOwner(0);
+            stat.setVersion(0);
+        }
+        
+        public void processResult(int rc, String path, Object ctx, byte[] data,
+                Stat stat)
+        {
+            this.data = data;
+            this.stat = stat;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public void verifyGetData() {
+            new StringCB(zk).verifyCreate();
+
+            zk.getData(path, false, this, toString());
+            verify();
+        }
+        
+        public void verifyGetDataFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            data = null;
+            stat = null;
+            zk.getData(path, false, this, toString());
+            verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString()
+                + ":" + (data == null ? "null" : new String(data))
+                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
+                    + stat.getCversion() + ":" + stat.getEphemeralOwner()
+                    + ":" + stat.getVersion()); 
+        }
+    }
+
+    public static class StatCB extends AsyncCB implements StatCallback {
+        List<ACL> acl = Ids.CREATOR_ALL_ACL;
+        int version = 0;
+        Stat stat = new Stat();
+        byte[] data = "testing".getBytes();
+        
+        StatCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        StatCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+            stat.setAversion(0);
+            stat.setCversion(0);
+            stat.setEphemeralOwner(0);
+            stat.setVersion(0);
+        }
+        
+        public void processResult(int rc, String path, Object ctx, Stat stat) {
+            this.stat = stat;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public void verifySetACL() {
+            stat.setAversion(1);
+            new StringCB(zk).verifyCreate();
+
+            zk.setACL(path, acl, version, this, toString());
+            verify();
+        }
+        
+        public void verifySetACLFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            stat = null;
+            zk.setACL(path, acl, version, this, toString());
+            verify();
+        }
+
+        public void verifySetACLFailure_BadVersion() {
+            new StringCB(zk).verifyCreate();
+
+            rc = Code.BADVERSION;
+            stat = null;
+            zk.setACL(path, acl, version + 1, this, toString());
+
+            verify();
+        }
+        
+        public void setData() {
+            zk.setData(path, data, version, this, toString());
+        }
+        
+        public void verifySetData() {
+            stat.setVersion(1);
+            new StringCB(zk).verifyCreate();
+
+            setData();
+            verify();
+        }
+        
+        public void verifySetDataFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            stat = null;
+            zk.setData(path, data, version, this, toString());
+            verify();
+        }
+
+        public void verifySetDataFailure_BadVersion() {
+            new StringCB(zk).verifyCreate();
+
+            rc = Code.BADVERSION;
+            stat = null;
+            zk.setData(path, data, version + 1, this, toString());
+
+            verify();
+        }
+        
+        public void verifyExists() {
+            new StringCB(zk).verifyCreate();
+
+            zk.exists(path, false, this, toString());
+            verify();
+        }
+        
+        public void verifyExistsFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            stat = null;
+            zk.exists(path, false, this, toString());
+            verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + version
+                + ":" + new String(data)
+                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
+                        + stat.getCversion() + ":" + stat.getEphemeralOwner()
+                        + ":" + stat.getVersion()); 
+        }
+    }
+
+    public static class VoidCB extends AsyncCB implements VoidCallback {
+        int version = 0;
+        
+        VoidCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+        
+        VoidCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+        
+        public void processResult(int rc, String path, Object ctx) {
+            super.processResult(Code.get(rc), path, ctx);
+        }
+
+        public void delete() {
+            zk.delete(path, version, this, toString());
+        }
+        
+        public void verifyDelete() {
+            new StringCB(zk).verifyCreate();
+
+            delete();
+            verify();
+        }
+        
+        public void verifyDeleteFailure_NoNode() {
+            rc = Code.NONODE;
+            zk.delete(path, version, this, toString());
+            verify();
+        }
+
+        public void verifyDeleteFailure_BadVersion() {
+            new StringCB(zk).verifyCreate();
+            rc = Code.BADVERSION;
+            zk.delete(path, version + 1, this, toString());
+            verify();
+        }
+
+        public void verifyDeleteFailure_NotEmpty() {
+            StringCB scb = new StringCB(zk);
+            scb.create();
+            scb.setPath(path + "/bar");
+            scb.create();
+
+            rc = Code.NOTEMPTY;
+            zk.delete(path, version, this, toString());
+            verify();
+        }
+        
+        public void sync() {
+            zk.sync(path, this, toString());
+        }
+        
+        public void verifySync() {
+            sync();
+            verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + version; 
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
new file mode 100644
index 0000000..c807d72
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
@@ -0,0 +1,227 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.util.concurrent.CountDownLatch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.test.AsyncOps.ACLCB;
+import org.apache.zookeeper.test.AsyncOps.Children2CB;
+import org.apache.zookeeper.test.AsyncOps.ChildrenCB;
+import org.apache.zookeeper.test.AsyncOps.DataCB;
+import org.apache.zookeeper.test.AsyncOps.StatCB;
+import org.apache.zookeeper.test.AsyncOps.StringCB;
+import org.apache.zookeeper.test.AsyncOps.VoidCB;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AsyncOpsTest extends ClientBase {
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncOpsTest.class);
+
+    private ZooKeeper zk;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        LOG.info("Creating client " + getTestName());
+
+        zk = createClient();
+        zk.addAuthInfo("digest", "ben:passwd".getBytes());
+    }
+
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        zk.close();
+
+        super.tearDown();
+
+        LOG.info("Test clients shutting down");
+    }
+
+    @Test
+    public void testAsyncCreate() {
+        new StringCB(zk).verifyCreate();
+    }
+
+    @Test
+    public void testAsyncCreateThree() {
+        CountDownLatch latch = new CountDownLatch(3);
+
+        StringCB op1 = new StringCB(zk, latch);
+        op1.setPath("/op1");
+        StringCB op2 = new StringCB(zk, latch);
+        op2.setPath("/op2");
+        StringCB op3 = new StringCB(zk, latch);
+        op3.setPath("/op3");
+
+        op1.create();
+        op2.create();
+        op3.create();
+
+        op1.verify();
+        op2.verify();
+        op3.verify();
+    }
+
+    @Test
+    public void testAsyncCreateFailure_NodeExists() {
+        new StringCB(zk).verifyCreateFailure_NodeExists();
+    }
+
+    @Test
+    public void testAsyncCreateFailure_NoNode() {
+        new StringCB(zk).verifyCreateFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncCreateFailure_NoChildForEphemeral() {
+        new StringCB(zk).verifyCreateFailure_NoChildForEphemeral();
+    }
+
+    @Test
+    public void testAsyncDelete() {
+        new VoidCB(zk).verifyDelete();
+    }
+
+    @Test
+    public void testAsyncDeleteFailure_NoNode() {
+        new VoidCB(zk).verifyDeleteFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncDeleteFailure_BadVersion() {
+        new VoidCB(zk).verifyDeleteFailure_BadVersion();
+    }
+
+    @Test
+    public void testAsyncDeleteFailure_NotEmpty() {
+        new VoidCB(zk).verifyDeleteFailure_NotEmpty();
+    }
+
+    @Test
+    public void testAsyncSync() {
+        new VoidCB(zk).verifySync();
+    }
+
+    @Test
+    public void testAsyncSetACL() {
+        new StatCB(zk).verifySetACL();
+    }
+
+    @Test
+    public void testAsyncSetACLFailure_NoNode() {
+        new StatCB(zk).verifySetACLFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncSetACLFailure_BadVersion() {
+        new StatCB(zk).verifySetACLFailure_BadVersion();
+    }
+
+    @Test
+    public void testAsyncSetData() {
+        new StatCB(zk).verifySetData();
+    }
+
+    @Test
+    public void testAsyncSetDataFailure_NoNode() {
+        new StatCB(zk).verifySetDataFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncSetDataFailure_BadVersion() {
+        new StatCB(zk).verifySetDataFailure_BadVersion();
+    }
+
+    @Test
+    public void testAsyncExists() {
+        new StatCB(zk).verifyExists();
+    }
+
+    @Test
+    public void testAsyncExistsFailure_NoNode() {
+        new StatCB(zk).verifyExistsFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetACL() {
+        new ACLCB(zk).verifyGetACL();
+    }
+
+    @Test
+    public void testAsyncGetACLFailure_NoNode() {
+        new ACLCB(zk).verifyGetACLFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetChildrenEmpty() {
+        new ChildrenCB(zk).verifyGetChildrenEmpty();
+    }
+
+    @Test
+    public void testAsyncGetChildrenSingle() {
+        new ChildrenCB(zk).verifyGetChildrenSingle();
+    }
+
+    @Test
+    public void testAsyncGetChildrenTwo() {
+        new ChildrenCB(zk).verifyGetChildrenTwo();
+    }
+
+    @Test
+    public void testAsyncGetChildrenFailure_NoNode() {
+        new ChildrenCB(zk).verifyGetChildrenFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Empty() {
+        new Children2CB(zk).verifyGetChildrenEmpty();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Single() {
+        new Children2CB(zk).verifyGetChildrenSingle();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Two() {
+        new Children2CB(zk).verifyGetChildrenTwo();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Failure_NoNode() {
+        new Children2CB(zk).verifyGetChildrenFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetData() {
+        new DataCB(zk).verifyGetData();
+    }
+
+    @Test
+    public void testAsyncGetDataFailure_NoNode() {
+        new DataCB(zk).verifyGetDataFailure_NoNode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java
new file mode 100644
index 0000000..2182032
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java
@@ -0,0 +1,172 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AsyncTest extends ZKTestCase
+    implements StringCallback, VoidCallback, DataCallback
+{
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncTest.class);
+
+    private QuorumBase qb = new QuorumBase();
+
+    @Before
+    public void setUp() throws Exception {
+        qb.setUp();
+    }
+
+    public void restart() throws Exception {
+        JMXEnv.setUp();
+        qb.startServers();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        LOG.info("Test clients shutting down");
+        qb.tearDown();
+    }
+
+    private static class CountdownWatcher implements Watcher {
+        volatile CountDownLatch clientConnected = new CountDownLatch(1);
+
+        public void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.SyncConnected) {
+                clientConnected.countDown();
+            }
+        }
+    }
+
+    private ZooKeeper createClient() throws IOException,InterruptedException {
+        return createClient(qb.hostPort);
+    }
+
+    private ZooKeeper createClient(String hp)
+        throws IOException, InterruptedException
+    {
+        CountdownWatcher watcher = new CountdownWatcher();
+        ZooKeeper zk = new ZooKeeper(hp, CONNECTION_TIMEOUT, watcher);
+        if(!watcher.clientConnected.await(CONNECTION_TIMEOUT,
+                TimeUnit.MILLISECONDS))
+        {
+            Assert.fail("Unable to connect to server");
+        }
+        return zk;
+    }
+
+    LinkedList<Integer> results = new LinkedList<Integer>();
+    @Test
+    public void testAsync()
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk = null;
+        zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "ben:passwd".getBytes());
+            zk.create("/ben", new byte[0], Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT, this, results);
+            zk.create("/ben/2", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT, this, results);
+            zk.delete("/ben", -1, this, results);
+            zk.create("/ben2", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT, this, results);
+            zk.getData("/ben2", false, this, results);
+            synchronized (results) {
+                while (results.size() < 5) {
+                    results.wait();
+                }
+            }
+            Assert.assertEquals(0, (int) results.get(0));
+            Assert.assertEquals(Code.NOAUTH, Code.get(results.get(1)));
+            Assert.assertEquals(0, (int) results.get(2));
+            Assert.assertEquals(0, (int) results.get(3));
+            Assert.assertEquals(0, (int) results.get(4));
+        } finally {
+            zk.close();
+        }
+
+        zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "ben:passwd2".getBytes());
+            try {
+                zk.getData("/ben2", false, new Stat());
+                Assert.fail("Should have received a permission error");
+            } catch (KeeperException e) {
+                Assert.assertEquals(Code.NOAUTH, e.code());
+            }
+        } finally {
+            zk.close();
+        }
+
+        zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "ben:passwd".getBytes());
+            zk.getData("/ben2", false, new Stat());
+        } finally {
+            zk.close();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, String name) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, byte[] data,
+            Stat stat) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
new file mode 100644
index 0000000..cbd2b77
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
@@ -0,0 +1,200 @@
+/**
+ * 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.
+ */
+package org.apache.zookeeper.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.common.AtomicFileOutputStream;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AtomicFileOutputStreamTest extends ZKTestCase {
+    private static final String TEST_STRING = "hello world";
+    private static final String TEST_STRING_2 = "goodbye world";
+
+    private File testDir;
+    private File dstFile;
+
+    @Before
+    public void setupTestDir() throws IOException {
+        testDir = ClientBase.createEmptyTestDir();
+        dstFile = new File(testDir, "test.txt");
+    }
+    @After
+    public void cleanupTestDir() throws IOException {
+        ClientBase.recursiveDelete(testDir);
+    }
+
+    /**
+     * Test case where there is no existing file
+     */
+    @Test
+    public void testWriteNewFile() throws IOException {
+        OutputStream fos = new AtomicFileOutputStream(dstFile);
+        assertFalse(dstFile.exists());
+        fos.write(TEST_STRING.getBytes());
+        fos.flush();
+        assertFalse(dstFile.exists());
+        fos.close();
+        assertTrue(dstFile.exists());
+
+        String readBackData = ClientBase.readFile(dstFile);
+        assertEquals(TEST_STRING, readBackData);
+    }
+
+    /**
+     * Test case where there is no existing file
+     */
+    @Test
+    public void testOverwriteFile() throws IOException {
+        assertTrue("Creating empty dst file", dstFile.createNewFile());
+
+        OutputStream fos = new AtomicFileOutputStream(dstFile);
+
+        assertTrue("Empty file still exists", dstFile.exists());
+        fos.write(TEST_STRING.getBytes());
+        fos.flush();
+
+        // Original contents still in place
+        assertEquals("", ClientBase.readFile(dstFile));
+
+        fos.close();
+
+        // New contents replace original file
+        String readBackData = ClientBase.readFile(dstFile);
+        assertEquals(TEST_STRING, readBackData);
+    }
+
+    /**
+     * Test case where the flush() fails at close time - make sure that we clean
+     * up after ourselves and don't touch any existing file at the destination
+     */
+    @Test
+    public void testFailToFlush() throws IOException {
+        // Create a file at destination
+        FileOutputStream fos = new FileOutputStream(dstFile);
+        fos.write(TEST_STRING_2.getBytes());
+        fos.close();
+
+        OutputStream failingStream = createFailingStream();
+        failingStream.write(TEST_STRING.getBytes());
+        try {
+            failingStream.close();
+            fail("Close didn't throw exception");
+        } catch (IOException ioe) {
+            // expected
+        }
+
+        // Should not have touched original file
+        assertEquals(TEST_STRING_2, ClientBase.readFile(dstFile));
+
+        assertEquals("Temporary file should have been cleaned up",
+                dstFile.getName(), ClientBase.join(",", testDir.list()));
+    }
+
+    /**
+     * Create a stream that fails to flush at close time
+     */
+    private OutputStream createFailingStream() throws FileNotFoundException {
+        return new AtomicFileOutputStream(dstFile) {
+            @Override
+            public void flush() throws IOException {
+                throw new IOException("injected failure");
+            }
+        };
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is not created when
+     * aborting a new file.
+     */
+    @Test
+    public void testAbortNewFile() throws IOException {
+        AtomicFileOutputStream fos = new AtomicFileOutputStream(dstFile);
+
+        fos.abort();
+
+        assertEquals(0, testDir.list().length);
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is not created when
+     * aborting a new file.
+     */
+    @Test
+    public void testAbortNewFileAfterFlush() throws IOException {
+        AtomicFileOutputStream fos = new AtomicFileOutputStream(dstFile);
+        fos.write(TEST_STRING.getBytes());
+        fos.flush();
+
+        fos.abort();
+
+        assertEquals(0, testDir.list().length);
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is untouched when
+     * aborting an existing file overwrite.
+     */
+    @Test
+    public void testAbortExistingFile() throws IOException {
+        FileOutputStream fos1 = new FileOutputStream(dstFile);
+        fos1.write(TEST_STRING.getBytes());
+        fos1.close();
+
+        AtomicFileOutputStream fos2 = new AtomicFileOutputStream(dstFile);
+
+        fos2.abort();
+
+        // Should not have touched original file
+        assertEquals(TEST_STRING, ClientBase.readFile(dstFile));
+        assertEquals(1, testDir.list().length);
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is untouched when
+     * aborting an existing file overwrite.
+     */
+    @Test
+    public void testAbortExistingFileAfterFlush() throws IOException {
+        FileOutputStream fos1 = new FileOutputStream(dstFile);
+        fos1.write(TEST_STRING.getBytes());
+        fos1.close();
+
+        AtomicFileOutputStream fos2 = new AtomicFileOutputStream(dstFile);
+        fos2.write(TEST_STRING_2.getBytes());
+        fos2.flush();
+
+        fos2.abort();
+
+        // Should not have touched original file
+        assertEquals(TEST_STRING, ClientBase.readFile(dstFile));
+        assertEquals(1, testDir.list().length);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java
new file mode 100644
index 0000000..60e3453
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java
@@ -0,0 +1,174 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AuthTest extends ClientBase {
+    static {
+        // password is test
+        System.setProperty("zookeeper.DigestAuthenticationProvider.superDigest",
+                "super:D/InIHSb7yEEbrWz8b9l71RjZJU=");    
+        System.setProperty("zookeeper.authProvider.1", "org.apache.zookeeper.test.InvalidAuthProvider");
+    }
+
+    private final CountDownLatch authFailed = new CountDownLatch(1);
+
+    @Override
+    protected TestableZooKeeper createClient(String hp)
+    throws IOException, InterruptedException
+    {
+        MyWatcher watcher = new MyWatcher();
+        return createClient(watcher, hp);
+    }
+
+    private class MyWatcher extends CountdownWatcher {
+        @Override
+        public synchronized void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.AuthFailed) {
+                authFailed.countDown();
+            }
+            else {
+                super.process(event);
+            }
+        }
+    }
+
+    @Test
+    public void testBadAuthNotifiesWatch() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.addAuthInfo("FOO", "BAR".getBytes());
+            zk.getData("/path1", false, null);
+            Assert.fail("Should get auth state error");
+        } catch(KeeperException.AuthFailedException e) {
+            if(!authFailed.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS))
+            {
+                Assert.fail("Should have called my watcher");
+            }
+        }
+        finally {
+            zk.close();
+        }
+    }
+    
+    @Test
+    public void testBadAuthThenSendOtherCommands() throws Exception {
+        ZooKeeper zk = createClient();     
+        try {        
+            zk.addAuthInfo("INVALID", "BAR".getBytes());
+            zk.exists("/foobar", false);             
+            zk.getData("/path1", false, null);
+            Assert.fail("Should get auth state error");
+        } catch(KeeperException.AuthFailedException e) {
+            if(!authFailed.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS))
+            {
+                Assert.fail("Should have called my watcher");
+            }
+        }
+        finally {
+            zk.close();          
+        }
+    }
+
+    
+    @Test
+    public void testSuper() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "pat:pass".getBytes());
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL,
+                    CreateMode.PERSISTENT);
+            zk.close();
+            // verify no auth
+            zk = createClient();
+            try {
+                zk.getData("/path1", false, null);
+                Assert.fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify bad pass Assert.fails
+            zk = createClient();
+            zk.addAuthInfo("digest", "pat:pass2".getBytes());
+            try {
+                zk.getData("/path1", false, null);
+                Assert.fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify super with bad pass Assert.fails
+            zk = createClient();
+            zk.addAuthInfo("digest", "super:test2".getBytes());
+            try {
+                zk.getData("/path1", false, null);
+                Assert.fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify super with correct pass success
+            zk = createClient();
+            zk.addAuthInfo("digest", "super:test".getBytes());
+            zk.getData("/path1", false, null);
+        } finally {
+            zk.close();
+        }
+    }
+    
+    @Test
+    public void testSuperACL() throws Exception {
+    	 ZooKeeper zk = createClient();
+         try {
+             zk.addAuthInfo("digest", "pat:pass".getBytes());
+             zk.create("/path1", null, Ids.CREATOR_ALL_ACL,
+                     CreateMode.PERSISTENT);
+             zk.close();
+             // verify super can do anything and ignores ACLs
+             zk = createClient();
+             zk.addAuthInfo("digest", "super:test".getBytes());
+             zk.getData("/path1", false, null);
+             
+             zk.setACL("/path1", Ids.READ_ACL_UNSAFE, -1);
+             zk.create("/path1/foo", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+           
+             
+             zk.setACL("/path1", Ids.OPEN_ACL_UNSAFE, -1);
+        	 
+         } finally {
+             zk.close();
+         }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
new file mode 100644
index 0000000..6d74e54
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
@@ -0,0 +1,132 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.jute.BinaryInputArchive;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BufferSizeTest extends ClientBase {
+    public static final int TEST_MAXBUFFER = 100;
+    private static final File TEST_DATA = new File(
+            System.getProperty("test.data.dir", "build/test/data"),
+            "buffersize");
+    
+    private ZooKeeper zk;
+
+    @Before
+    public void setMaxBuffer() throws IOException, InterruptedException {
+        System.setProperty("jute.maxbuffer", "" + TEST_MAXBUFFER);
+        assertEquals("Can't set jute.maxbuffer!", TEST_MAXBUFFER, BinaryInputArchive.maxBuffer);
+        zk = createClient();
+    }
+    
+    @Test
+    public void testCreatesReqs() throws Exception {
+        testRequests(new ClientOp() {
+            @Override
+            public void execute(byte[] data) throws Exception {
+                zk.create("/create_test", data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            }
+        });
+    }
+    
+    @Test
+    public void testSetReqs() throws Exception {
+        final String path = "/set_test";
+        zk.create(path, new byte[1], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        testRequests(new ClientOp() {
+            @Override
+            public void execute(byte[] data) throws Exception {
+                zk.setData(path, data, -1);
+            }
+        });
+    }
+    
+    /** Issues requests containing data smaller, equal, and greater than TEST_MAXBUFFER. */
+    private void testRequests(ClientOp clientOp) throws Exception {
+        clientOp.execute(new byte[TEST_MAXBUFFER - 60]);
+        try {
+            // This should fail since the buffer size > the data size due to extra fields
+            clientOp.execute(new byte[TEST_MAXBUFFER]);
+            fail("Request exceeding jute.maxbuffer succeeded!");
+        } catch (KeeperException.ConnectionLossException e) {}
+        try {
+            clientOp.execute(new byte[TEST_MAXBUFFER + 10]);
+            fail("Request exceeding jute.maxbuffer succeeded!");
+        } catch (KeeperException.ConnectionLossException e) {}
+    }
+
+    private interface ClientOp {
+        void execute(byte[] data) throws Exception;
+    }
+
+    @Test
+    public void testStartup() throws Exception {
+        final String path = "/test_node";
+        zk.create(path, new byte[TEST_MAXBUFFER - 60], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.setData(path, new byte[TEST_MAXBUFFER - 50], -1);
+
+        stopServer();
+        startServer();
+    }
+    
+    @Test
+    public void testStartupFailureCreate() throws Exception {
+        // Empty snapshot and logfile containing a 5000-byte create
+        testStartupFailure(new File(TEST_DATA, "create"),
+                "Server started despite create exceeding jute.maxbuffer!");
+    }
+    
+    @Test
+    public void testStartupFailureSet() throws Exception {
+        // Empty snapshot and logfile containing a 1-byte create and 5000-byte set
+        testStartupFailure(new File(TEST_DATA, "set"),
+                "Server started despite set exceeding jute.maxbuffer!");
+    }
+    
+    @Test
+    public void testStartupFailureSnapshot() throws Exception {
+        // Snapshot containing 5000-byte znode and logfile containing create txn
+        testStartupFailure(new File(TEST_DATA, "snapshot"),
+                "Server started despite znode exceeding jute.maxbuffer!");
+    }
+    
+    private void testStartupFailure(File testDir, String failureMsg) throws Exception {
+        stopServer();
+        // Point server at testDir
+        tmpDir = testDir;
+        try {
+            startServer();
+            fail(failureMsg);
+        } catch (IOException e) {
+            LOG.info("Successfully caught IOException: " + e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
new file mode 100644
index 0000000..e60ea04
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+
+public class ChrootAsyncTest extends AsyncOpsTest {
+    private static final Logger LOG = LoggerFactory.getLogger(ChrootAsyncTest.class);
+
+    @Override
+    public void setUp() throws Exception {
+        String hp = hostPort;
+        hostPort = hostPort + "/chrootasynctest";
+
+        super.setUp();
+
+        LOG.info("Creating client " + getTestName());
+
+        ZooKeeper zk = createClient(hp);
+        try {
+            zk.create("/chrootasynctest", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        } finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
new file mode 100644
index 0000000..e0286e1
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Test;
+
+public class ChrootClientTest extends ClientTest {
+    private static final Logger LOG = LoggerFactory.getLogger(ChrootClientTest.class);
+
+    @Override
+    public void setUp() throws Exception {
+        String hp = hostPort;
+        hostPort = hostPort + "/chrootclienttest";
+
+        System.out.println(hostPort);
+        super.setUp();
+
+        LOG.info("STARTING " + getTestName());
+
+        ZooKeeper zk = createClient(hp);
+        try {
+            zk.create("/chrootclienttest", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        } finally {
+            zk.close();
+        }
+    }
+    
+    @Test
+    public void testPing() throws Exception {
+        // not necessary to repeat this, expensive and not chroot related
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootTest.java
new file mode 100644
index 0000000..3df068b
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootTest.java
@@ -0,0 +1,136 @@
+/**
+ * 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.
+ */
+
+package org.apache.zookeeper.test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+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.junit.Assert;
+import org.junit.Test;
+
+public class ChrootTest extends ClientBase {
+    private class MyWatcher implements Watcher {
+        private final String path;
+        private String eventPath;
+        private CountDownLatch latch = new CountDownLatch(1);
+
+        public MyWatcher(String path) {
+            this.path = path;
+        }
+        public void process(WatchedEvent event) {
+            System.out.println("latch:" + path + " " + event.getPath());
+            this.eventPath = event.getPath();
+            latch.countDown();
+        }
+        public boolean matches() throws InterruptedException {
+            if (!latch.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)) {
+                Assert.fail("No watch received within timeout period " + path);
+            }
+            return path.equals(eventPath);
+        }
+    }
+
+    @Test
+    public void testChrootSynchronous()
+        throws IOException, InterruptedException, KeeperException
+    {
+        ZooKeeper zk1 = createClient();
+        try {
+            zk1.create("/ch1", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        } finally {
+            if(zk1 != null)
+                zk1.close();
+        }
+        ZooKeeper zk2 = createClient(hostPort + "/ch1");
+        try {
+            Assert.assertEquals("/ch2",
+                    zk2.create("/ch2", null, Ids.OPEN_ACL_UNSAFE,
+                            CreateMode.PERSISTENT));
+        } finally {
+            if(zk2 != null)
+                zk2.close();
+        }
+
+        zk1 = createClient();
+        zk2 = createClient(hostPort + "/ch1");
+        try {
+            // check get
+            MyWatcher w1 = new MyWatcher("/ch1");
+            Assert.assertNotNull(zk1.exists("/ch1", w1));
+            MyWatcher w2 = new MyWatcher("/ch1/ch2");
+            Assert.assertNotNull(zk1.exists("/ch1/ch2", w2));
+
+            MyWatcher w3 = new MyWatcher("/ch2");
+            Assert.assertNotNull(zk2.exists("/ch2", w3));
+            
+            // set watches on child
+            MyWatcher w4 = new MyWatcher("/ch1");
+            zk1.getChildren("/ch1",w4);
+            MyWatcher w5 = new MyWatcher("/");
+            zk2.getChildren("/",w5);
+
+            // check set
+            zk1.setData("/ch1", "1".getBytes(), -1);
+            zk2.setData("/ch2", "2".getBytes(), -1);
+
+            // check watches
+            Assert.assertTrue(w1.matches());
+            Assert.assertTrue(w2.matches());
+            Assert.assertTrue(w3.matches());
+
+            // check exceptions
+            try {
+                zk2.setData("/ch3", "3".getBytes(), -1);
+            } catch (KeeperException.NoNodeException e) {
+                Assert.assertEquals("/ch3", e.getPath());
+            }
+
+            Assert.assertTrue(Arrays.equals("1".getBytes(),
+                    zk1.getData("/ch1", false, null)));
+            Assert.assertTrue(Arrays.equals("2".getBytes(),
+                    zk1.getData("/ch1/ch2", false, null)));
+            Assert.assertTrue(Arrays.equals("2".getBytes(),
+                    zk2.getData("/ch2", false, null)));
+
+            // check delete
+            zk2.delete("/ch2", -1);
+            Assert.assertTrue(w4.matches());
+            Assert.assertTrue(w5.matches());
+            
+            zk1.delete("/ch1", -1);
+            Assert.assertNull(zk1.exists("/ch1", false));
+            Assert.assertNull(zk1.exists("/ch1/ch2", false));
+            Assert.assertNull(zk2.exists("/ch2", false));
+        } finally {
+            if(zk1 != null)
+                zk1.close();
+            if(zk2 != null)
+                zk2.close();
+        }
+    }
+}