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();
+ }
+ }
+}