You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ha...@apache.org on 2018/07/16 04:30:36 UTC
[37/51] [partial] zookeeper git commit: Website update for release
3.4.13.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/connection_test.py
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/connection_test.py b/content/build/contrib/zkpython/src/test/connection_test.py
new file mode 100644
index 0000000..3913fe3
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/connection_test.py
@@ -0,0 +1,131 @@
+#!/usr/bin/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.
+
+import unittest, threading, re, sys
+if sys.version_info < (3,):
+ range = xrange
+
+import zookeeper, zktestbase
+ZOO_OPEN_ACL_UNSAFE = {"perms":0x1f, "scheme":"world", "id" :"anyone"}
+
+class ConnectionTest(zktestbase.TestBase):
+ """Test whether we can make a connection"""
+ def setUp(self):
+ pass
+
+ def testconnection(self):
+ cv = threading.Condition()
+ self.connected = False
+ def connection_watcher(handle, type, state, path):
+ cv.acquire()
+ self.connected = True
+ self.assertEqual(zookeeper.CONNECTED_STATE, state)
+ self.handle = handle
+ cv.notify()
+ cv.release()
+
+ cv.acquire()
+ ret = zookeeper.init(self.host, connection_watcher)
+ cv.wait(15.0)
+ cv.release()
+ self.assertEqual(self.connected, True, "Connection timed out to " + self.host)
+ self.assertEqual(zookeeper.CONNECTED_STATE, zookeeper.state(self.handle))
+
+ self.assertEqual(zookeeper.close(self.handle), zookeeper.OK)
+ # Trying to close the same handle twice is an error, and the C library will segfault on it
+ # so make sure this is caught at the Python module layer
+ self.assertRaises(zookeeper.ZooKeeperException,
+ zookeeper.close,
+ self.handle)
+
+ self.assertRaises(zookeeper.ZooKeeperException,
+ zookeeper.get,
+ self.handle,
+ "/")
+
+ def testhandlereuse(self):
+ """
+ Test a) multiple concurrent connections b) reuse of closed handles
+ """
+ cv = threading.Condition()
+ self.connected = False
+ def connection_watcher(handle, type, state, path):
+ cv.acquire()
+ self.connected = True
+ self.assertEqual(zookeeper.CONNECTED_STATE, state)
+ self.handle = handle
+ cv.notify()
+ cv.release()
+
+ cv.acquire()
+ handles = [ zookeeper.init(self.host) for i in range(10) ]
+ ret = zookeeper.init(self.host, connection_watcher)
+ cv.wait(15.0)
+ cv.release()
+ self.assertEqual(self.connected, True, "Connection timed out to " + self.host)
+ self.assertEqual(True, self.all( [ zookeeper.state(handle) == zookeeper.CONNECTED_STATE for handle in handles ] ),
+ "Not all connections succeeded")
+ oldhandle = handles[3]
+ zookeeper.close(oldhandle)
+ newhandle = zookeeper.init(self.host)
+
+ # This assertion tests *internal* behaviour; i.e. that the module
+ # correctly reuses closed handles. This is therefore implementation
+ # dependent.
+ self.assertEqual(newhandle, oldhandle, "Didn't get reused handle")
+
+ def testmanyhandles(self):
+ """
+ Test the ability of the module to support many handles.
+ """
+ # We'd like to do more, but currently the C client doesn't
+ # work with > 83 handles (fails to create a pipe) on MacOS 10.5.8
+ handles = [ zookeeper.init(self.host) for i in range(9) ]
+
+ cv = threading.Condition()
+ self.connected = False
+ def connection_watcher(handle, type, state, path):
+ cv.acquire()
+ self.connected = True
+ self.assertEqual(zookeeper.CONNECTED_STATE, state)
+ self.handle = handle
+ cv.notify()
+ cv.release()
+
+ cv.acquire()
+ ret = zookeeper.init(self.host, connection_watcher)
+ cv.wait(15.0)
+ cv.release()
+ self.assertEqual(self.connected, True, "Connection timed out to " + self.host)
+
+ for i,h in enumerate(handles):
+ path = "/zkpython-test-handles-%s" % str(i)
+ self.assertEqual(path, zookeeper.create(h, path, "", [ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL))
+
+ self.assertEqual(True, self.all( zookeeper.close(h) == zookeeper.OK for h in handles ))
+
+ def testversionstringexists(self):
+ self.assertTrue(hasattr(zookeeper, '__version__'))
+ self.assertTrue(re.match("\d.\d.\d", zookeeper.__version__))
+
+
+ def tearDown(self):
+ pass
+
+if __name__ == '__main__':
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/create_test.py
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/create_test.py b/content/build/contrib/zkpython/src/test/create_test.py
new file mode 100644
index 0000000..8ab80f9
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/create_test.py
@@ -0,0 +1,104 @@
+#!/usr/bin/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.
+
+import zookeeper, zktestbase, unittest, threading
+
+ZOO_OPEN_ACL_UNSAFE = {"perms":0x1f, "scheme":"world", "id" :"anyone"}
+
+class CreationTest(zktestbase.TestBase):
+ """Test whether we can create znodes"""
+ # to do: startup and teardown via scripts?
+ def setUp(self):
+ zktestbase.TestBase.setUp(self)
+ try:
+ zookeeper.delete(self.handle, "/zk-python-createtest")
+ zookeeper.delete(self.handle, "/zk-python-acreatetest")
+ except:
+ pass
+
+ def test_sync_create(self):
+ self.assertEqual(self.connected, True)
+ ret = zookeeper.create(self.handle, "/zk-python-createtest", "nodecontents", [ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL)
+ self.assertEqual(ret, "/zk-python-createtest")
+ self.assertRaises(zookeeper.NoChildrenForEphemeralsException,
+ zookeeper.create,
+ self.handle,
+ "/zk-python-createtest/invalid-child",
+ "",
+ [ZOO_OPEN_ACL_UNSAFE],
+ zookeeper.EPHEMERAL)
+
+ def test_sync_create_existing(self):
+ self.assertEqual(self.connected, True)
+ ret = zookeeper.create(self.handle, "/zk-python-createtest-existing", "nodecontents", [ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL)
+ self.assertEqual(ret, "/zk-python-createtest-existing")
+
+ self.assertRaises(zookeeper.NodeExistsException,
+ zookeeper.create,
+ self.handle,
+ "/zk-python-createtest-existing",
+ "nodecontents",
+ [ZOO_OPEN_ACL_UNSAFE],
+ zookeeper.EPHEMERAL)
+
+
+ def test_exception_paths(self):
+ """
+ Make sure common exceptions due to API misuse are correctly propogated
+ """
+ self.assertRaises(zookeeper.BadArgumentsException,
+ zookeeper.create,
+ self.handle,
+ "/zk-python-badargs-test",
+ "",
+ [ZOO_OPEN_ACL_UNSAFE],
+ -1)
+ self.assertRaises(zookeeper.InvalidACLException,
+ zookeeper.create,
+ self.handle,
+ "/zk-python-invalidacl-test",
+ "",
+ ZOO_OPEN_ACL_UNSAFE) # Error - not a list
+
+
+ def test_async_create(self):
+ self.cv = threading.Condition()
+ def callback(handle, rc, value):
+ self.cv.acquire()
+ self.callback_flag = True
+ self.rc = rc
+ self.cv.notify()
+ self.cv.release()
+
+ self.assertEqual(self.connected, True, "Not connected!")
+ self.cv.acquire()
+
+ ret = zookeeper.acreate(self.handle, "/zk-python-acreatetest", "nodecontents",
+ [ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL,
+ callback )
+ self.assertEqual(ret, zookeeper.OK, "acreate failed")
+ while not self.callback_flag:
+ self.cv.wait(15)
+ self.cv.release()
+
+ self.assertEqual(self.callback_flag, True, "acreate timed out")
+ self.assertEqual(self.rc, zookeeper.OK)
+
+
+if __name__ == '__main__':
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/delete_test.py
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/delete_test.py b/content/build/contrib/zkpython/src/test/delete_test.py
new file mode 100644
index 0000000..913b6a9
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/delete_test.py
@@ -0,0 +1,68 @@
+#!/usr/bin/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.
+
+import zookeeper, zktestbase, unittest, threading
+
+class DeletionTest(zktestbase.TestBase):
+ """Test whether we can delete znodes"""
+
+ def test_sync_delete(self):
+ ZOO_OPEN_ACL_UNSAFE = {"perms":0x1f, "scheme":"world", "id" :"anyone"}
+ self.assertEqual(self.connected, True)
+ ret = zookeeper.create(self.handle, "/zk-python-deletetest", "nodecontents", [ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL)
+ self.assertEqual(ret, "/zk-python-deletetest")
+ ret = zookeeper.delete(self.handle,"/zk-python-deletetest")
+ self.assertEqual(ret, zookeeper.OK)
+ children = zookeeper.get_children(self.handle, "/")
+ self.assertEqual(False, "zk-python-deletetest" in children)
+
+ # test exception
+ self.assertRaises(zookeeper.NoNodeException,
+ zookeeper.delete,
+ self.handle,
+ "/zk-python-deletetest")
+
+ def test_async_delete(self):
+ ZOO_OPEN_ACL_UNSAFE = {"perms":0x1f, "scheme":"world", "id" :"anyone"}
+ self.assertEqual(self.connected, True)
+ ret = zookeeper.create(self.handle, "/zk-python-adeletetest", "nodecontents", [ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL)
+ self.assertEqual(ret, "/zk-python-adeletetest")
+
+ self.cv = threading.Condition()
+ self.callback_flag = False
+ self.rc = -1
+ def callback(handle, rc):
+ self.cv.acquire()
+ self.callback_flag = True
+ self.cv.notify()
+ self.rc = rc # don't assert this here, as if the assertion fails, the test will block
+ self.cv.release()
+
+ self.cv.acquire()
+ ret = zookeeper.adelete(self.handle,"/zk-python-adeletetest",-1,callback)
+ self.assertEqual(ret, zookeeper.OK, "adelete failed")
+ while not self.callback_flag:
+ self.cv.wait(15)
+ self.cv.release()
+
+ self.assertEqual(self.callback_flag, True, "adelete timed out")
+ self.assertEqual(self.rc, zookeeper.OK)
+
+
+if __name__ == '__main__':
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/exists_test.py
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/exists_test.py b/content/build/contrib/zkpython/src/test/exists_test.py
new file mode 100644
index 0000000..ddc6ef3
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/exists_test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/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.
+
+import zookeeper, zktestbase, unittest, threading
+
+ZOO_OPEN_ACL_UNSAFE = {"perms":0x1f, "scheme":"world", "id" :"anyone"}
+class ExistsTest(zktestbase.TestBase):
+ def setUp( self ):
+ zktestbase.TestBase.setUp(self)
+ try:
+ zookeeper.create(self.handle, "/zk-python-existstest","existstest", [ZOO_OPEN_ACL_UNSAFE],zookeeper.EPHEMERAL)
+ zookeeper.create(self.handle, "/zk-python-aexiststest","existstest",[ZOO_OPEN_ACL_UNSAFE],zookeeper.EPHEMERAL)
+ except:
+ pass
+
+ def test_sync_exists(self):
+ self.assertEqual(self.connected, True)
+ ret = zookeeper.exists(self.handle, "/zk-python-existstest", None)
+ self.assertNotEqual(ret, None, "/zk-python-existstest does not exist (possibly means creation failure)")
+
+ def test_sync_nexists(self):
+ self.assertEqual(None, zookeeper.exists(self.handle, "/i-dont-exist", None))
+
+
+ def test_async_exists(self):
+ self.cv = threading.Condition()
+ def callback(handle, rc, stat):
+ self.cv.acquire()
+ self.callback_flag = True
+ self.cv.notify()
+ self.cv.release()
+ self.rc = rc
+
+ self.assertEqual(self.connected, True)
+
+ self.cv.acquire()
+ ret = zookeeper.aexists(self.handle, "/zk-python-aexiststest", None,
+ callback )
+ self.assertEqual(ret, zookeeper.OK)
+ while not self.callback_flag:
+ self.cv.wait(15)
+ self.cv.release()
+
+ self.assertEqual(self.callback_flag, True, "aexists timed out")
+ self.assertEqual(self.rc, zookeeper.OK, "Return code not ok:" + zookeeper.zerror(self.rc))
+
+
+if __name__ == '__main__':
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/get_set_test.py
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/get_set_test.py b/content/build/contrib/zkpython/src/test/get_set_test.py
new file mode 100644
index 0000000..b77b3b2
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/get_set_test.py
@@ -0,0 +1,211 @@
+#!/usr/bin/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.
+
+import zookeeper, zktestbase, unittest, threading, sys
+if sys.version_info < (3,):
+ range = xrange
+
+ZOO_OPEN_ACL_UNSAFE = {"perms":0x1f, "scheme":"world", "id" :"anyone"}
+
+class GetSetTest(zktestbase.TestBase):
+ def setUp( self ):
+ zktestbase.TestBase.setUp(self)
+ try:
+ zookeeper.create(self.handle, "/zk-python-getsettest", "on",[ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL)
+ zookeeper.create(self.handle, "/zk-python-agetsettest",
+ "on",[ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL)
+ except:
+ pass
+
+ def test_empty_node(self):
+ """
+ Test for a bug when instead of empty string we can get
+ random data from buffer malloc'ed to hold node contents.
+ See ZOOKEEPER-1906 for details
+ """
+ NODE_PATH = "/zk-python-test-empty-node"
+ self.ensureDeleted(NODE_PATH)
+ zookeeper.create(self.handle, NODE_PATH, "",
+ [{"perms":0x1f, "scheme":"world", "id" :"anyone"}])
+ (data,stat) = zookeeper.get(self.handle, NODE_PATH, None)
+ self.assertEqual(data, "", "Data is not empty as expected: " + data)
+
+ def test_sync_getset(self):
+ self.assertEqual(self.connected, True, "Not connected!")
+ (data,stat) = zookeeper.get(self.handle, "/zk-python-getsettest", None)
+ self.assertEqual(data, "on", "Data is not 'on' as expected: " + data)
+ ret = zookeeper.set(self.handle, "/zk-python-getsettest",
+ "off", stat["version"])
+ (data,stat) = zookeeper.get(self.handle, "/zk-python-getsettest", None)
+ self.assertEqual(data, "off", "Data is not 'off' as expected: " + data)
+ self.assertRaises(zookeeper.BadVersionException,
+ zookeeper.set,
+ self.handle,
+ "/zk-python-getsettest",
+ "test",
+ stat["version"]+1)
+ stat2 = zookeeper.set2(self.handle, "/zk-python-getsettest",
+ "set2", stat["version"])
+ self.assertNotEqual(stat2, None, "set2 call failed, return should not be None")
+ self.assertEqual(stat2["numChildren"], 0,
+ "set2 call failed, numChildren not 0 in set2 call")
+ (data,stat) = zookeeper.get(self.handle, "/zk-python-getsettest", None)
+ self.assertEqual(data, "set2", "Data is not 'set2' as expected: " + data)
+
+ def test_stat_deleted_node(self):
+ """
+ Test for a bug that surfaced when trying to build a
+ stat object from a non-existant node.
+
+ """
+ self.ensureDeleted("/zk-python-test-deleteme")
+ self.assertRaises(zookeeper.NoNodeException,
+ zookeeper.get,
+ self.handle,
+ "/zk-python-test-deleteme")
+ self.cv = threading.Condition()
+ def callback(handle, rc, value, stat):
+ self.cv.acquire()
+ self.stat = stat
+ self.rc = rc
+ self.value = value
+ self.callback_flag = True
+ self.cv.notify()
+ self.cv.release()
+ self.cv.acquire()
+ zookeeper.aget(self.handle, "/zk-python-test-deleteme", None, callback)
+ self.cv.wait(15)
+ self.assertEqual(self.callback_flag, True, "aget timed out!")
+ self.assertEqual(self.stat, None, "Stat should be none!")
+ self.assertEqual(self.value, None, "Value should be none!")
+
+ def test_sync_get_large_datanode(self):
+ """
+ Test that we can retrieve datanode sizes up to
+ 1Mb with default parameters (depends on ZooKeeper server).
+ """
+
+ data = ''.join(["A" for x in range(1024*1023)])
+ self.ensureDeleted("/zk-python-test-large-datanode")
+ zookeeper.create(self.handle, "/zk-python-test-large-datanode", data,
+ [{"perms":0x1f, "scheme":"world", "id" :"anyone"}])
+ (ret,stat) = zookeeper.get(self.handle, "/zk-python-test-large-datanode")
+ self.assertEqual(len(ret), 1024*1023,
+ "Should have got 1Mb returned, instead got %s" % len(ret))
+ (ret,stat) = zookeeper.get(self.handle, "/zk-python-test-large-datanode",None,500)
+ self.assertEqual(len(ret), 500,
+ "Should have got 500 bytes returned, instead got %s" % len(ret))
+
+
+
+ def test_async_getset(self):
+ self.cv = threading.Condition()
+ def get_callback(handle, rc, value, stat):
+ self.cv.acquire()
+ self.callback_flag = True
+ self.rc = rc
+ self.value = (value,stat)
+ self.cv.notify()
+ self.cv.release()
+
+ def set_callback(handle, rc, stat):
+ self.cv.acquire()
+ self.callback_flag = True
+ self.rc = rc
+ self.value = stat
+ self.cv.notify()
+ self.cv.release()
+
+ self.assertEqual(self.connected, True, "Not connected!")
+
+ self.cv.acquire()
+ self.callback_flag = False
+ ret = zookeeper.aset(self.handle, "/zk-python-agetsettest", "off", -1, set_callback)
+ self.assertEqual(ret, zookeeper.OK, "aset failed")
+ while not self.callback_flag:
+ self.cv.wait(15)
+ self.cv.release()
+ self.assertEqual(self.callback_flag, True, "aset timed out")
+
+ self.cv.acquire()
+ self.callback_flag = False
+ ret = zookeeper.aget(self.handle, "/zk-python-agetsettest", None, get_callback)
+ self.assertEqual(ret, zookeeper.OK, "aget failed")
+ self.cv.wait(15)
+ self.cv.release()
+ self.assertEqual(self.callback_flag, True, "aget timed out")
+ self.assertEqual(self.value[0], "off", "Data is not 'off' as expected: " + self.value[0])
+
+ def test_sync_getchildren(self):
+ self.ensureCreated("/zk-python-getchildrentest", flags=0)
+ self.ensureCreated("/zk-python-getchildrentest/child")
+ children = zookeeper.get_children(self.handle, "/zk-python-getchildrentest")
+ self.assertEqual(len(children), 1, "Expected to find 1 child, got " + str(len(children)))
+
+ def test_async_getchildren(self):
+ self.ensureCreated("/zk-python-getchildrentest", flags=0)
+ self.ensureCreated("/zk-python-getchildrentest/child")
+
+ def gc_callback(handle, rc, children):
+ self.cv.acquire()
+ self.rc = rc
+ self.children = children
+ self.callback_flag = True
+ self.cv.notify()
+ self.cv.release()
+
+ self.cv.acquire()
+ self.callback_flag = False
+ zookeeper.aget_children(self.handle, "/zk-python-getchildrentest", None, gc_callback)
+ self.cv.wait(15)
+ self.assertEqual(self.callback_flag, True, "aget_children timed out")
+ self.assertEqual(self.rc, zookeeper.OK, "Return code for aget_children was not OK - %s" % zookeeper.zerror(self.rc))
+ self.assertEqual(len(self.children), 1, "Expected to find 1 child, got " + str(len(self.children)))
+
+
+ def test_async_getchildren_with_watcher(self):
+ self.ensureCreated("/zk-python-getchildrentest", flags=0)
+ self.ensureCreated("/zk-python-getchildrentest/child")
+
+ watched = []
+
+ def watcher(*args):
+ self.cv.acquire()
+ watched.append(args)
+ self.cv.notify()
+ self.cv.release()
+
+ def children_callback(*args):
+ self.cv.acquire()
+ self.cv.notify()
+ self.cv.release()
+
+ zookeeper.aget_children(
+ self.handle, "/zk-python-getchildrentest", watcher, children_callback)
+
+ self.cv.acquire()
+ self.cv.wait()
+ self.cv.release()
+
+ self.cv.acquire()
+ self.ensureCreated("/zk-python-getchildrentest/child2")
+ self.cv.wait(15)
+ self.assertTrue(watched)
+
+if __name__ == '__main__':
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/run_tests.sh
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/run_tests.sh b/content/build/contrib/zkpython/src/test/run_tests.sh
new file mode 100644
index 0000000..18d9240
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/run_tests.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Usage: run_tests.sh testdir [logdir]
+# logdir is optional, defaults to cwd
+
+# get the number of command-line arguments given
+ARGC=$#
+
+# check to make sure enough arguments were given or exit
+if [ $ARGC -lt 2 ]; then
+ export ZKPY_LOG_DIR="."
+else
+ export ZKPY_LOG_DIR=$2
+fi
+
+# Find the build directory containing zookeeper.so
+SO_PATH=`find ../../../build/ -name "zookeeper.so" | head -1`
+PYTHONPATH=`dirname $SO_PATH`
+LIB_PATH=../../c/.libs/:../../../build/test/test-cppunit/.libs
+for test in `ls $1/*_test.py`;
+do
+ echo "Running $test"
+ LD_LIBRARY_PATH=$LIB_PATH:$LD_LIBRARY_PATH DYLD_LIBRARY_PATH=$LIB_PATH:$DYLD_LIBRARY_PATH PYTHONPATH=$PYTHONPATH python $test
+done
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/zkServer.sh
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/zkServer.sh b/content/build/contrib/zkpython/src/test/zkServer.sh
new file mode 100644
index 0000000..51d508f
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/zkServer.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [ "x$1" == "x" ]
+then
+ echo "USAGE: $0 startClean|start|stop hostPorts"
+ exit 2
+fi
+
+if [ "x$1" == "xstartClean" ]
+then
+ if [ "x${base_dir}" == "x" ]
+ then
+ rm -rf /tmp/zkdata
+ else
+ rm -rf ${base_dir}/build/tmp
+ fi
+fi
+
+if [ "x${base_dir}" == "x" ]
+then
+zk_base="../../../"
+else
+zk_base="${base_dir}"
+fi
+
+CLASSPATH="$CLASSPATH:${zk_base}/build/classes"
+CLASSPATH="$CLASSPATH:${zk_base}/conf"
+
+for i in "${zk_base}"/build/lib/*.jar
+do
+ CLASSPATH="$CLASSPATH:$i"
+done
+
+for i in "${zk_base}"/src/java/lib/*.jar
+do
+ CLASSPATH="$CLASSPATH:$i"
+done
+
+# Make sure nothing is left over from before
+#fuser -skn tcp 22182/tcp
+
+case $1 in
+start|startClean)
+ if [ "x${base_dir}" == "x" ]
+ then
+ mkdir -p /tmp/zkdata
+ java -cp $CLASSPATH org.apache.zookeeper.server.ZooKeeperServerMain 22182 /tmp/zkdata &> /tmp/zk.log &
+ else
+ mkdir -p ${base_dir}/build/tmp/zkdata
+ java -cp $CLASSPATH org.apache.zookeeper.server.ZooKeeperServerMain 22182 ${base_dir}/build/tmp/zkdata &> ${base_dir}/build/tmp/zk.log &
+ fi
+ sleep 5
+ ;;
+stop)
+ # Already killed above
+ ;;
+*)
+ echo "Unknown command " + $1
+ exit 2
+esac
+
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zkpython/src/test/zktestbase.py
----------------------------------------------------------------------
diff --git a/content/build/contrib/zkpython/src/test/zktestbase.py b/content/build/contrib/zkpython/src/test/zktestbase.py
new file mode 100644
index 0000000..8229418
--- /dev/null
+++ b/content/build/contrib/zkpython/src/test/zktestbase.py
@@ -0,0 +1,101 @@
+#!/usr/bin/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.
+
+import os
+import unittest, threading, zookeeper
+ZOO_OPEN_ACL_UNSAFE = {"perms":0x1f, "scheme":"world", "id" :"anyone"}
+
+class TestBase(unittest.TestCase):
+ SERVER_PORT = 22182
+
+ def __init__(self,methodName='runTest'):
+ unittest.TestCase.__init__(self,methodName)
+ self.host = "localhost:%d" % self.SERVER_PORT
+ self.connected = False
+ self.handle = -1
+ logdir = os.environ.get("ZKPY_LOG_DIR")
+ logfile = os.path.join(logdir, self.__class__.__name__ + ".log")
+ try:
+ f = open(logfile,"w")
+ zookeeper.set_log_stream(f)
+ except IOError:
+ print("Couldn't open " + logfile + " for writing")
+
+
+ def setUp(self):
+ self.callback_flag = False
+ self.cv = threading.Condition()
+ self.connected = False
+ def connection_watcher(handle, type, state, path):
+ self.cv.acquire()
+ self.connected = True
+ self.cv.notify()
+ self.cv.release()
+
+ self.cv.acquire()
+ self.handle = zookeeper.init(self.host, connection_watcher)
+ self.cv.wait(15.0)
+ self.cv.release()
+
+ if not self.connected:
+ raise Exception("Couldn't connect to host -", self.host)
+
+ def newConnection(self):
+ cv = threading.Condition()
+ self.pending_connection = False
+ def connection_watcher(handle, type, state, path):
+ cv.acquire()
+ self.pending_connection = True
+ cv.notify()
+ cv.release()
+
+ cv.acquire()
+ handle = zookeeper.init(self.host, connection_watcher)
+ cv.wait(15.0)
+ cv.release()
+
+ if not self.pending_connection:
+ raise Exception("Couldn't connect to host -", self.host)
+ return handle
+
+ def ensureDeleted(self,path):
+ self.assertEqual(zookeeper.CONNECTED_STATE, zookeeper.state(self.handle), "Not connected!")
+ try:
+ self.assertEqual(zookeeper.OK, zookeeper.delete(self.handle, path))
+ except zookeeper.NoNodeException:
+ pass
+
+ def ensureCreated(self,path,data="",flags=zookeeper.EPHEMERAL):
+ """
+ It's possible not to get the flags you want here if the node already exists
+ """
+ self.assertEqual(zookeeper.CONNECTED_STATE, zookeeper.state(self.handle), "Not connected!")
+ try:
+ self.assertEqual(path, zookeeper.create(self.handle, path, data, [ZOO_OPEN_ACL_UNSAFE], flags))
+ except zookeeper.NodeExistsException:
+ pass
+
+ def tearDown(self):
+ if self.connected:
+ zookeeper.close(self.handle)
+
+ def all(self, iterable):
+ for element in iterable:
+ if not element:
+ return False
+ return True
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/Makefile.am
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/Makefile.am b/content/build/contrib/zktreeutil/Makefile.am
new file mode 100644
index 0000000..36da1a5
--- /dev/null
+++ b/content/build/contrib/zktreeutil/Makefile.am
@@ -0,0 +1,4 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = src
+
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/README.txt
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/README.txt b/content/build/contrib/zktreeutil/README.txt
new file mode 100644
index 0000000..43b06fa
--- /dev/null
+++ b/content/build/contrib/zktreeutil/README.txt
@@ -0,0 +1,74 @@
+==========================================
+zktreeutil - Zookeeper Tree Data Utility
+Author: Anirban Roy
+Organization: Yahoo Inc.
+==========================================
+
+zktreeutil program is intended to manage and manipulate zk-tree data quickly, effi-
+ciently and with ease. The utility operates on free-form ZK-tree and hence can be used
+for any cluster managed by Zookeeper. Here are the basic functionalities -
+
+EXPORT: The whole/partial ZK-tree is exported into a XML file. This helps in
+capturing a current snapshot of the data for backup/analysis. For a subtree
+export, one need to specify the path to the ZK-subtree with proper option.
+
+IMPORT: The ZK-tree can be imported from XML into ZK cluster. This helps in priming
+the new ZK cluster with static configuration. The import can be non-intrusive by
+making only the additions in the existing data. The import of subtree is also
+possible by optionally providing the path to the ZK-subtree.
+
+DIFF: Creates a diff between live ZK data vs data saved in XML file. Diff can ignore
+some ZK-tree branches (possibly dynamic data) on reading the optional ignore flag
+from XML file. Diffing on a ZK-subtree achieved by providing path to ZK-subtree with
+diff command.
+
+UPDATE: Make the incremental changes into the live ZK-tree from saved XML, essentia-
+lly after running the diff.
+
+DUMP: Dumps the ZK-tree on the standard output device reading either from live ZK
+server or XML file. Like export, ZK-subtree can be dumped with optionaly
+providing the path to the ZK-subtree, and till a certain depth of the (sub)tree.
+
+The exported ZK data into XML file can be shortened by only keeping the static ZK
+nodes which are required to prime a cluster. The dynamic zk nodes (created on-the-
+fly) can be ignored by setting a 'ignore' attribute at the root node of the dynamic
+subtree (see tests/zk_sample.xml), possibly deleting all inner ZK nodes under that.
+Once ignored, the whole subtree is ignored during DIFF, UPDATE and WRITE.
+
+Pre-requisites
+--------------
+1. Linux system with 2.6.X kernel.
+2. Zookeeper C client library (locally built at ../../c/.libs) >= 3.X.X
+3. Development build libraries (rpm packages):
+ a. boost-devel >= 1.32.0
+ b. libxml2-devel >= 2.7.3
+ c. log4cxx0100-devel >= 0.10.0
+
+Build instructions
+------------------
+1. cd into this directory
+2. autoreconf -if
+3. ./configure
+4. make
+5. 'zktreeutil' binary created under src directory
+
+Limitations
+-----------
+Current version works with text data only, binary data will be supported in future
+versions.
+
+Testing and usage of zktreeutil
+--------------------------------
+1. Run Zookeeper server locally on port 2181
+2. export LD_LIBRARY_PATH=../../c/.libs/:/usr/local/lib/
+3. ./src/zktreeutil --help # show help
+4. ./src/zktreeutil --zookeeper=localhost:2181 --import --xmlfile=tests/zk_sample.xml 2>/dev/null # import sample ZK tree
+5. ./src/zktreeutil --zookeeper=localhost:2181 --dump --path=/myapp/version-1.0 2>/dev/null # dump Zk subtree
+5. ./src/zktreeutil --zookeeper=localhost:2181 --dump --depth=3 2>/dev/null # dump Zk tree till certain depth
+6. ./src/zktreeutil --xmlfile=zk_sample.xml -D 2>/dev/null # dump the xml data
+7. Change zk_sample.xml with adding/deleting/chaging some nodes
+8. ./src/zktreeutil -z localhost:2181 -F -x zk_sample.xml -p /myapp/version-1.0/configuration 2>/dev/null # take a diff of changes
+9. ./src/zktreeutil -z localhost:2181 -E 2>/dev/null > zk_sample2.xml # export the mofied ZK tree
+10. ./src/zktreeutil -z localhost:2181 -U -x zk_sample.xml -p /myapp/version-1.0/distributions 2>/dev/null # update with incr. changes
+11. ./src/zktreeutil --zookeeper=localhost:2181 --import --force --xmlfile=zk_sample2.xml 2>/dev/null # re-prime the ZK tree
+
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/VERSION
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/VERSION b/content/build/contrib/zktreeutil/VERSION
new file mode 100644
index 0000000..618659f
--- /dev/null
+++ b/content/build/contrib/zktreeutil/VERSION
@@ -0,0 +1 @@
+3.4.13
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/build.xml
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/build.xml b/content/build/contrib/zktreeutil/build.xml
new file mode 100644
index 0000000..809d134
--- /dev/null
+++ b/content/build/contrib/zktreeutil/build.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="zktreeutil" default="compile">
+ <import file="../build-contrib.xml"/>
+
+ <target name="init" depends="check-contrib" unless="skip.contrib">
+ <echo message="contrib: ${name}"/>
+ <mkdir dir="${build.dir}"/>
+ <antcall target="init-contrib"/>
+ </target>
+
+ <target name="compile" depends="init" unless="skip.contrib">
+ <echo message="contrib: ${name}"/>
+
+ <mkdir dir="${build.dir}"/>
+ <copy todir="${build.dir}">
+ <fileset dir="${basedir}">
+ <exclude name="**/VERSION"/>
+ </fileset>
+ </copy>
+ <exec executable="echo" output="${build.dir}/VERSION">
+ <arg line="${version}" />
+ </exec>
+ </target>
+
+ <target name="jar" depends="compile" >
+ <echo message="No jar target defined for this package"/>
+ </target>
+
+ <target name="test">
+ <echo message="No test target defined for this package" />
+ </target>
+
+
+ <target name="package" depends="compile" unless="skip.contrib">
+ <echo message="contrib: ${name}"/>
+
+ <mkdir dir="${dist.dir}/contrib/${name}"/>
+ <copy todir="${dist.dir}/contrib/${name}">
+ <fileset dir="${build.dir}"/>
+ </copy>
+ </target>
+
+</project>
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/configure.ac
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/configure.ac b/content/build/contrib/zktreeutil/configure.ac
new file mode 100644
index 0000000..b4a82a7
--- /dev/null
+++ b/content/build/contrib/zktreeutil/configure.ac
@@ -0,0 +1,66 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+
+AC_INIT([zktreeutil], [1.0.0])
+AM_INIT_AUTOMAKE(foreign)
+
+AC_CONFIG_SRCDIR([src])
+AM_CONFIG_HEADER([config.h])
+
+PACKAGE=zktreeutil
+VERSION=1.0.0
+
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+BUILD_PATH="`pwd`"
+
+# Checks for programs.
+AC_LANG_CPLUSPLUS
+AC_PROG_CXX
+
+# Checks for libxm2.
+AM_PATH_XML2(2.7.3)
+XML2_INCLUDE="/usr/include/libxml2"
+AC_SUBST(XML2_INCLUDE)
+
+# Zookeeper C client
+ZOOKEEPER_PATH=${BUILD_PATH}/../../c
+AC_CHECK_LIB(zookeeper_mt, main, [ZOOKEEPER="-L${ZOOKEEPER_PATH}/.libs -lzookeeper_mt"],,["-L${ZOOKEEPER_PATH}/.libs"])
+if test -z "${ZOOKEEPER}"; then
+ AC_ERROR("... zookeeper C client not found!")
+fi
+
+AC_SUBST(ZOOKEEPER)
+AC_SUBST(ZOOKEEPER_PATH)
+
+### log4cxx ###
+
+LOG4CXX_VERSION="0.10.0"
+LOG4CXX_INCLUDE="/usr/local/include"
+LOG4CXX_LIB_PATH="/usr/local/lib"
+AC_CHECK_LIB(log4cxx, main, [LOG4CXX="-L${LOG4CXX_LIB_PATH} -llog4cxx"],,["-L${LOG4CXX_LIB_PATH}"])
+if test -z "${LOG4CXX}"; then
+ AC_ERROR("... log4cxx not found!")
+fi
+
+AC_SUBST(LOG4CXX)
+AC_SUBST(LOG4CXX_VERSION)
+AC_SUBST(LOG4CXX_INCLUDE)
+
+# Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h string.h stdio.h unistd.h boost/shared_ptr.hpp boost/algorithm/string.hpp boost/algorithm/string/split.hpp])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_C_VOLATILE
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([src/Makefile])
+AC_OUTPUT
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/src/Makefile.am
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/src/Makefile.am b/content/build/contrib/zktreeutil/src/Makefile.am
new file mode 100644
index 0000000..641077a
--- /dev/null
+++ b/content/build/contrib/zktreeutil/src/Makefile.am
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+AM_CXXFLAGS = -I${ZOOKEEPER_PATH}/include -I${ZOOKEEPER_PATH}/generated \
+ -I$(top_srcdir)/include -I${LOG4CXX_INCLUDE} -I/usr/include \
+ -I${XML2_INCLUDE}
+
+bin_PROGRAMS = zktreeutil
+
+zktreeutil_SOURCES = ZkAdaptor.cc ZkTreeUtil.cc ZkTreeUtilMain.cc
+zktreeutil_LDADD = ${ZOOKEEPER} ${XML_LIBS} ${LOG4CXX}
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/src/SimpleTree.h
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/src/SimpleTree.h b/content/build/contrib/zktreeutil/src/SimpleTree.h
new file mode 100644
index 0000000..8226f05
--- /dev/null
+++ b/content/build/contrib/zktreeutil/src/SimpleTree.h
@@ -0,0 +1,150 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SIMPLE_TREE_H__
+#define __SIMPLE_TREE_H__
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+namespace zktreeutil
+{
+ using std::vector;
+
+ /**
+ * \brief A simple tree data-structure template.
+ */
+ template < class KeyType, class DataType > class SimpleTreeNode
+ {
+ private:
+ /**
+ * \brief The type representing simple-tree node smart-pointer.
+ */
+ typedef boost::shared_ptr< SimpleTreeNode< KeyType, DataType > > SimpleTreeNodeSptr;
+
+ public:
+ /**
+ * \brief Constructor.
+ *
+ * @param isRoot the flag indicating whether the node is root.
+ */
+ SimpleTreeNode (bool isRoot=false) : isRoot_(isRoot)
+ {
+ }
+
+ /**
+ * \brief Constructor.
+ *
+ * @param key the key stored at the tree node
+ * @param isRoot the flag indicating whether the node is root
+ */
+ SimpleTreeNode (const KeyType& key, bool isRoot=false) :
+ isRoot_(isRoot), key_(key)
+ {
+ }
+
+ /**
+ * \brief Constructor.
+ *
+ * @param key the key stored at the tree node
+ * @param val the value stored at the tree node
+ * @param isRoot the flag indicating whether the node is root
+ */
+ SimpleTreeNode (const KeyType& key, const DataType& val, bool isRoot=false) :
+ isRoot_(isRoot), key_(key), val_(val)
+ {
+ }
+
+ /**
+ * \brief Destructor.
+ */
+ ~SimpleTreeNode () throw() {}
+
+ /**
+ * \brief Add a child node to this node.
+ *
+ * @param node the child node to be added
+ */
+ void addChild (const SimpleTreeNodeSptr node) { children_.push_back (node); }
+
+ /**
+ * \brief Sets the key of this node.
+ *
+ * @param key the key to be set
+ */
+ void setKey (const KeyType& key) { key_ = key; }
+
+ /**
+ * \brief Sets the data of this node.
+ *
+ * @param val the value to be set
+ */
+ void setData (const DataType& val) { val_ = val; }
+
+ /**
+ * \brief Gets the key of this node.
+ *
+ * @return the key of this node
+ */
+ KeyType getKey () const { return key_; }
+
+ /**
+ * \brief Gets the data of this node.
+ *
+ * @return the value of this node
+ */
+ DataType getData () const { return val_; }
+
+ /**
+ * \brief Gets the i'th of this node.
+ *
+ * @param idx the index of the child node
+ * @return the child node
+ */
+ SimpleTreeNodeSptr getChild (unsigned idx) const { return children_[idx]; }
+
+ /**
+ * \brief Gets the number of children of this node.
+ *
+ * @return the number of children
+ */
+ unsigned numChildren () const { return children_.size(); }
+
+ /**
+ * \brief Indicates whether this node is root.
+ *
+ * @return 'true' if this node is root, 'false' otherwise
+ */
+ bool isRoot () const { return isRoot_; }
+
+ /**
+ * \brief Indicates whether this node is leaf node.
+ *
+ * @return 'true' if this node is leaf node, 'false' otherwise
+ */
+ bool isLeaf () const { return !numChildren(); }
+
+ private:
+ bool isRoot_; // Flag indicates if the node is root
+ KeyType key_; // Key of this node
+ DataType val_; // Value of this node
+ vector< SimpleTreeNodeSptr > children_; // List of children of this node
+ };
+}
+
+#endif // __SIMPLE_TREE_H__
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/src/ZkAdaptor.cc
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/src/ZkAdaptor.cc b/content/build/contrib/zktreeutil/src/ZkAdaptor.cc
new file mode 100644
index 0000000..1df175a
--- /dev/null
+++ b/content/build/contrib/zktreeutil/src/ZkAdaptor.cc
@@ -0,0 +1,513 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ZkAdaptor.h"
+#include <string.h>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+#include <log4cxx/logger.h>
+
+// Logger
+static log4cxx::LoggerPtr zkLoggerPtr = log4cxx::Logger::getLogger ("zookeeper.core");
+
+namespace zktreeutil
+{
+ /**
+ * \brief This class provides logic for checking if a request can be retried.
+ */
+ class RetryHandler
+ {
+ public:
+ RetryHandler(const ZooKeeperConfig &zkConfig) : m_zkConfig(zkConfig)
+ {
+ if (zkConfig.getAutoReconnect())
+ retries = 2;
+ else
+ retries = 0;
+ }
+
+ /**
+ * \brief Attempts to fix a side effect of the given RC.
+ *
+ * @param rc the ZK error code
+ * @return whether the error code has been handled and the caller should
+ * retry an operation the caused this error
+ */
+ bool handleRC(int rc)
+ {
+ //check if the given error code is recoverable
+ if (!retryOnError(rc))
+ return false;
+
+ std::cerr << "[zktreeuti] Number of retries left: " << retries << std::endl;
+ if (retries-- > 0)
+ return true;
+ else
+ return false;
+ }
+
+ private:
+ /**
+ * The ZK config.
+ */
+ const ZooKeeperConfig &m_zkConfig;
+
+ /**
+ * The number of outstanding retries.
+ */
+ int retries;
+
+ /**
+ * Checks whether the given error entitles this adapter
+ * to retry the previous operation.
+ *
+ * @param zkErrorCode one of the ZK error code
+ */
+ static bool retryOnError(int zkErrorCode)
+ {
+ return (zkErrorCode == ZCONNECTIONLOSS || zkErrorCode == ZOPERATIONTIMEOUT);
+ }
+ };
+
+
+ // =======================================================================
+
+ ZooKeeperAdapter::ZooKeeperAdapter(ZooKeeperConfig config) throw(ZooKeeperException) :
+ m_zkConfig(config),
+ mp_zkHandle(NULL)
+ {
+ // Enforce setting up appropriate ZK log level
+ if (zkLoggerPtr->isDebugEnabled()
+#ifdef LOG4CXX_TRACE
+ || zkLoggerPtr->isTraceEnabled()
+#endif
+ )
+ {
+ zoo_set_debug_level( ZOO_LOG_LEVEL_DEBUG );
+ } else if (zkLoggerPtr->isInfoEnabled()) {
+ zoo_set_debug_level( ZOO_LOG_LEVEL_INFO );
+ } else if (zkLoggerPtr->isWarnEnabled()) {
+ zoo_set_debug_level( ZOO_LOG_LEVEL_WARN );
+ } else {
+ zoo_set_debug_level( ZOO_LOG_LEVEL_ERROR );
+ }
+
+ // Establish the connection
+ reconnect();
+ }
+
+ ZooKeeperAdapter::~ZooKeeperAdapter()
+ {
+ try
+ {
+ disconnect();
+ }
+ catch (std::exception &e)
+ {
+ std::cerr << "[zktreeutil] An exception while disconnecting from ZK: "
+ << e.what()
+ << std::endl;
+ }
+ }
+
+ void ZooKeeperAdapter::validatePath(const string &path) throw(ZooKeeperException)
+ {
+ if (path.find ("/") != 0)
+ {
+ std::ostringstream oss;
+ oss << "Node path must start with '/' but" "it was '"
+ << path
+ << "'";
+ throw ZooKeeperException (oss.str());
+ }
+ if (path.length() > 1)
+ {
+ if (path.rfind ("/") == path.length() - 1)
+ {
+ std::ostringstream oss;
+ oss << "Node path must not end with '/' but it was '"
+ << path
+ << "'";
+ throw ZooKeeperException (oss.str());
+ }
+ if (path.find( "//" ) != string::npos)
+ {
+ std::ostringstream oss;
+ oss << "Node path must not contain '//' but it was '"
+ << path
+ << "'";
+ throw ZooKeeperException (oss.str());
+ }
+ }
+ }
+
+ void ZooKeeperAdapter::disconnect()
+ {
+ if (mp_zkHandle != NULL)
+ {
+ zookeeper_close (mp_zkHandle);
+ mp_zkHandle = NULL;
+ }
+ }
+
+ void ZooKeeperAdapter::reconnect() throw(ZooKeeperException)
+ {
+ // Clear the connection state
+ disconnect();
+
+ // Establish a new connection to ZooKeeper
+ mp_zkHandle = zookeeper_init( m_zkConfig.getHosts().c_str(),
+ NULL,
+ m_zkConfig.getLeaseTimeout(),
+ 0,
+ NULL,
+ 0);
+ if (mp_zkHandle == NULL)
+ {
+ // Invalid handle returned
+ std::ostringstream oss;
+ oss << "Unable to connect to ZK running at '"
+ << m_zkConfig.getHosts()
+ << "'";
+ throw ZooKeeperException (oss.str());
+ }
+
+ // Enter into connect loop
+ int64_t connWaitTime = m_zkConfig.getConnectTimeout();
+ while (1)
+ {
+ int state = zoo_state (mp_zkHandle);
+ if (state == ZOO_CONNECTED_STATE)
+ {
+ // connected
+ std::cerr << "[zktreeutil] Connected! mp_zkHandle: "
+ << mp_zkHandle
+ << std::endl;
+ return;
+ }
+ else if ( state && state != ZOO_CONNECTING_STATE)
+ {
+ // Not connecting any more... some other issue
+ std::ostringstream oss;
+ oss << "Unable to connect to ZK running at '"
+ << m_zkConfig.getHosts()
+ << "'; state="
+ << state;
+ throw ZooKeeperException (oss.str());
+ }
+
+ // Still connecting, wait and come back
+ struct timeval now;
+ gettimeofday( &now, NULL );
+ int64_t milliSecs = -(now.tv_sec * 1000LL + now.tv_usec / 1000);
+ std::cerr << "[zktreeutil] About to wait 1 sec" << std::endl;
+ sleep (1);
+ gettimeofday( &now, NULL );
+ milliSecs += now.tv_sec * 1000LL + now.tv_usec / 1000;
+ connWaitTime -= milliSecs;
+ // Timed out !!!
+ if (connWaitTime <= 0)
+ break;
+ }
+
+ // Timed out while connecting
+ std::ostringstream oss;
+ oss << "Timed out while connecting to ZK running at '"
+ << m_zkConfig.getHosts()
+ << "'";
+ throw ZooKeeperException (oss.str());
+ }
+
+ void ZooKeeperAdapter::verifyConnection() throw(ZooKeeperException)
+ {
+ // Check connection state
+ int state = zoo_state (mp_zkHandle);
+ if (state != ZOO_CONNECTED_STATE)
+ {
+ if (m_zkConfig.getAutoReconnect())
+ {
+ // Trying to reconnect
+ std::cerr << "[zktreeutil] Trying to reconnect..." << std::endl;
+ reconnect();
+ }
+ else
+ {
+ std::ostringstream oss;
+ oss << "Disconnected from ZK running at '"
+ << m_zkConfig.getHosts()
+ << "'; state="
+ << state;
+ throw ZooKeeperException (oss.str());
+ }
+ }
+ }
+
+ bool ZooKeeperAdapter::createNode(const string &path,
+ const string &value,
+ int flags,
+ bool createAncestors) throw(ZooKeeperException)
+ {
+ const int MAX_PATH_LENGTH = 1024;
+ char realPath[MAX_PATH_LENGTH];
+ realPath[0] = 0;
+
+ int rc;
+ RetryHandler rh(m_zkConfig);
+ do
+ {
+ verifyConnection();
+ rc = zoo_create( mp_zkHandle,
+ path.c_str(),
+ value.c_str(),
+ value.length(),
+ &ZOO_OPEN_ACL_UNSAFE,
+ flags,
+ realPath,
+ MAX_PATH_LENGTH );
+ } while (rc != ZOK && rh.handleRC(rc));
+ if (rc != ZOK) // check return status
+ {
+ if (rc == ZNODEEXISTS)
+ {
+ //the node already exists
+ std::cerr << "[zktreeutil] ZK node " << path << " already exists" << std::endl;
+ return false;
+ }
+ else if (rc == ZNONODE && createAncestors)
+ {
+ std::cerr << "[zktreeutil] Intermediate ZK node missing in path " << path << std::endl;
+ //one of the ancestors doesn't exist so lets start from the root
+ //and make sure the whole path exists, creating missing nodes if
+ //necessary
+ for (string::size_type pos = 1; pos != string::npos; )
+ {
+ pos = path.find( "/", pos );
+ if (pos != string::npos)
+ {
+ try
+ {
+ createNode( path.substr( 0, pos ), "", 0, true );
+ }
+ catch (ZooKeeperException &e)
+ {
+ throw ZooKeeperException( string("Unable to create " "node ") + path, rc );
+ }
+ pos++;
+ }
+ else
+ {
+ // No more path components
+ return createNode( path, value, flags, false );
+ }
+ }
+ }
+
+ // Unexpected error during create
+ std::cerr << "[zktreeutil] Error in creating ZK node " << path << std::endl;
+ throw ZooKeeperException( string("Unable to create node ") + path, rc );
+ }
+
+ // Success
+ std::cerr << "[zktreeutil] " << realPath << " has been created" << std::endl;
+ return true;
+ }
+
+ bool ZooKeeperAdapter::deleteNode(const string &path,
+ bool recursive,
+ int version) throw(ZooKeeperException)
+ {
+ // Validate the zk path
+ validatePath( path );
+
+ int rc;
+ RetryHandler rh(m_zkConfig);
+ do
+ {
+ verifyConnection();
+ rc = zoo_delete( mp_zkHandle, path.c_str(), version );
+ } while (rc != ZOK && rh.handleRC(rc));
+ if (rc != ZOK) //check return status
+ {
+ if (rc == ZNONODE)
+ {
+ std::cerr << "[zktreeutil] ZK Node "
+ << path
+ << " does not exist"
+ << std::endl;
+ return false;
+ }
+ if (rc == ZNOTEMPTY && recursive)
+ {
+ std::cerr << "[zktreeutil] ZK Node "
+ << path
+ << " not empty; deleting..."
+ << std::endl;
+ //get all children and delete them recursively...
+ vector<string> nodeList = getNodeChildren (path);
+ for (vector<string>::const_iterator i = nodeList.begin();
+ i != nodeList.end();
+ ++i) {
+ deleteNode( *i, true );
+ }
+ //...and finally attempt to delete the node again
+ return deleteNode( path, false );
+ }
+
+ // Unexpected return without success
+ std::cerr << "[zktreeutil] Unable to delete ZK node " << path << std::endl;
+ throw ZooKeeperException( string("Unable to delete node ") + path, rc );
+ }
+
+ // success
+ std::cerr << "[zktreeutil] " << path << " has been deleted" << std::endl;
+ return true;
+ }
+
+ vector< string > ZooKeeperAdapter::getNodeChildren (const string &path) throw (ZooKeeperException)
+ {
+ // Validate the zk path
+ validatePath( path );
+
+ String_vector children;
+ memset( &children, 0, sizeof(children) );
+ int rc;
+ RetryHandler rh(m_zkConfig);
+ do
+ {
+ verifyConnection();
+ rc = zoo_get_children( mp_zkHandle,
+ path.c_str(),
+ 0,
+ &children );
+ } while (rc != ZOK && rh.handleRC(rc));
+ if (rc != ZOK) // check return code
+ {
+ std::cerr << "[zktreeutil] Error in fetching children of " << path << std::endl;
+ throw ZooKeeperException( string("Unable to get children of node ") + path, rc );
+ }
+ else
+ {
+ vector< string > nodeList;
+ for (int i = 0; i < children.count; ++i)
+ {
+ //convert each child's path from relative to absolute
+ string absPath(path);
+ if (path != "/")
+ {
+ absPath.append( "/" );
+ }
+ absPath.append( children.data[i] );
+ nodeList.push_back( absPath );
+ }
+
+ //make sure the order is always deterministic
+ sort( nodeList.begin(), nodeList.end() );
+ return nodeList;
+ }
+ }
+
+ bool ZooKeeperAdapter::nodeExists(const string &path) throw(ZooKeeperException)
+ {
+ // Validate the zk path
+ validatePath( path );
+
+ struct Stat tmpStat;
+ struct Stat* stat = &tmpStat;
+ memset( stat, 0, sizeof(Stat) );
+
+ int rc;
+ RetryHandler rh(m_zkConfig);
+ do {
+ verifyConnection();
+ rc = zoo_exists( mp_zkHandle,
+ path.c_str(),
+ 0,
+ stat );
+ } while (rc != ZOK && rh.handleRC(rc));
+ if (rc != ZOK)
+ {
+ if (rc == ZNONODE)
+ return false;
+ // Some error
+ std::cerr << "[zktreeutil] Error in checking existence of " << path << std::endl;
+ throw ZooKeeperException( string("Unable to check existence of node ") + path, rc );
+ } else {
+ return true;
+ }
+ }
+
+ string ZooKeeperAdapter::getNodeData(const string &path) throw(ZooKeeperException)
+ {
+ // Validate the zk path
+ validatePath( path );
+
+ const int MAX_DATA_LENGTH = 128 * 1024;
+ char buffer[MAX_DATA_LENGTH];
+ memset( buffer, 0, MAX_DATA_LENGTH );
+ struct Stat tmpStat;
+ struct Stat* stat = &tmpStat;
+ memset( stat, 0, sizeof(Stat) );
+
+ int rc;
+ int len;
+ RetryHandler rh(m_zkConfig);
+ do {
+ verifyConnection();
+ len = MAX_DATA_LENGTH - 1;
+ rc = zoo_get( mp_zkHandle,
+ path.c_str(),
+ 0,
+ buffer, &len, stat );
+ } while (rc != ZOK && rh.handleRC(rc));
+ if (rc != ZOK) // checl return code
+ {
+ std::cerr << "[zktreeutil] Error in fetching value of " << path << std::endl;
+ throw ZooKeeperException( string("Unable to get data of node ") + path, rc );
+ }
+
+ // return data
+ return string( buffer, buffer + len );
+ }
+
+ void ZooKeeperAdapter::setNodeData(const string &path,
+ const string &value,
+ int version) throw(ZooKeeperException)
+ {
+ // Validate the zk path
+ validatePath( path );
+
+ int rc;
+ RetryHandler rh(m_zkConfig);
+ do {
+ verifyConnection();
+ rc = zoo_set( mp_zkHandle,
+ path.c_str(),
+ value.c_str(),
+ value.length(),
+ version);
+ } while (rc != ZOK && rh.handleRC(rc));
+ if (rc != ZOK) // check return code
+ {
+ std::cerr << "[zktreeutil] Error in setting value of " << path << std::endl;
+ throw ZooKeeperException( string("Unable to set data for node ") + path, rc );
+ }
+ // success
+ }
+
+} /* end of 'namespace zktreeutil' */
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c9914857/content/build/contrib/zktreeutil/src/ZkAdaptor.h
----------------------------------------------------------------------
diff --git a/content/build/contrib/zktreeutil/src/ZkAdaptor.h b/content/build/contrib/zktreeutil/src/ZkAdaptor.h
new file mode 100644
index 0000000..4b68e28
--- /dev/null
+++ b/content/build/contrib/zktreeutil/src/ZkAdaptor.h
@@ -0,0 +1,327 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ZK_ADAPTER_H__
+#define __ZK_ADAPTER_H__
+
+#include <string>
+#include <vector>
+
+extern "C" {
+#include "zookeeper.h"
+}
+
+namespace zktreeutil
+{
+ using std::string;
+ using std::vector;
+
+ /**
+ * \brief A cluster related exception.
+ */
+ class ZooKeeperException : public std::exception
+ {
+ public:
+
+ /**
+ * \brief Constructor.
+ *
+ * @param msg the detailed message associated with this exception
+ */
+ ZooKeeperException(const string& msg) :
+ m_message(msg),
+ m_zkErrorCode(0) {}
+
+ /**
+ * \brief Constructor.
+ *
+ * @param msg the detailed message associated with this exception
+ * @param errorCode the ZK error code associated with this exception
+ */
+ ZooKeeperException(const string &msg, int errorCode) :
+ m_zkErrorCode(errorCode)
+ {
+ char tmp[100];
+ sprintf( tmp, " (ZK error code: %d)", errorCode );
+ m_message = msg + tmp;
+ }
+
+ /**
+ * \brief Destructor.
+ */
+ ~ZooKeeperException() throw() {}
+
+ /**
+ * \brief Returns detailed description of the exception.
+ */
+ const char *what() const throw()
+ {
+ return m_message.c_str();
+ }
+
+ /**
+ * \brief Returns the ZK error code.
+ */
+ int getZKErrorCode() const
+ {
+ return m_zkErrorCode;
+ }
+
+ private:
+
+ /**
+ * The detailed message associated with this exception.
+ */
+ string m_message;
+
+ /**
+ * The optional error code received from ZK.
+ */
+ int m_zkErrorCode;
+
+ };
+
+ /**
+ * \brief This class encapsulates configuration of a ZK client.
+ */
+ class ZooKeeperConfig
+ {
+ public:
+
+ /**
+ * \brief Constructor.
+ *
+ * @param hosts the comma separated list of host and port pairs of ZK nodes
+ * @param leaseTimeout the lease timeout (heartbeat)
+ * @param autoReconnect whether to allow for auto-reconnect
+ * @param connectTimeout the connect timeout, in milliseconds;
+ */
+ ZooKeeperConfig(const string &hosts,
+ int leaseTimeout,
+ bool autoReconnect = true,
+ long long int connectTimeout = 15000)
+ : m_hosts(hosts),
+ m_leaseTimeout(leaseTimeout),
+ m_autoReconnect(autoReconnect),
+ m_connectTimeout(connectTimeout) {}
+
+ /**
+ * \brief Returns the list of ZK hosts to connect to.
+ */
+ string getHosts() const { return m_hosts; }
+
+ /**
+ * \brief Returns the lease timeout.
+ */
+ int getLeaseTimeout() const { return m_leaseTimeout; }
+
+ /**
+ * \brief Returns whether {@link ZooKeeperAdapter} should attempt
+ * \brief to automatically reconnect in case of a connection failure.
+ */
+ bool getAutoReconnect() const { return m_autoReconnect; }
+
+ /**
+ * \brief Gets the connect timeout.
+ *
+ * @return the connect timeout
+ */
+ long long int getConnectTimeout() const { return m_connectTimeout; }
+
+ private:
+
+ /**
+ * The host addresses of ZK nodes.
+ */
+ const string m_hosts;
+
+ /**
+ * The ZK lease timeout.
+ */
+ const int m_leaseTimeout;
+
+ /**
+ * True if this adapater should attempt to autoreconnect in case
+ * the current session has been dropped.
+ */
+ const bool m_autoReconnect;
+
+ /**
+ * How long to wait, in milliseconds, before a connection
+ * is established to ZK.
+ */
+ const long long int m_connectTimeout;
+ };
+
+ /**
+ * \brief This is a wrapper around ZK C synchrounous API.
+ */
+ class ZooKeeperAdapter
+ {
+ public:
+ /**
+ * \brief Constructor.
+ * Attempts to create a ZK adapter, optionally connecting
+ * to the ZK. Note, that if the connection is to be established
+ * and the given listener is NULL, some events may be lost,
+ * as they may arrive asynchronously before this method finishes.
+ *
+ * @param config the ZK configuration
+ * @throw ZooKeeperException if cannot establish connection to the given ZK
+ */
+ ZooKeeperAdapter(ZooKeeperConfig config) throw(ZooKeeperException);
+
+ /**
+ * \brief Destructor.
+ */
+ ~ZooKeeperAdapter();
+
+ /**
+ * \brief Returns the current config.
+ */
+ const ZooKeeperConfig &getZooKeeperConfig() const { return m_zkConfig; }
+
+ /**
+ * \brief Restablishes connection to the ZK.
+ * If this adapter is already connected, the current connection
+ * will be dropped and a new connection will be established.
+ *
+ * @throw ZooKeeperException if cannot establish connection to the ZK
+ */
+ void reconnect() throw(ZooKeeperException);
+
+ /**
+ * \brief Disconnects from the ZK and unregisters {@link #mp_zkHandle}.
+ */
+ void disconnect();
+
+ /**
+ * \brief Creates a new node identified by the given path.
+ * This method will optionally attempt to create all missing ancestors.
+ *
+ * @param path the absolute path name of the node to be created
+ * @param value the initial value to be associated with the node
+ * @param flags the ZK flags of the node to be created
+ * @param createAncestors if true and there are some missing ancestor nodes,
+ * this method will attempt to create them
+ *
+ * @return true if the node has been successfully created; false otherwise
+ * @throw ZooKeeperException if the operation has failed
+ */
+ bool createNode(const string &path,
+ const string &value = "",
+ int flags = 0,
+ bool createAncestors = true) throw(ZooKeeperException);
+
+ /**
+ * \brief Deletes a node identified by the given path.
+ *
+ * @param path the absolute path name of the node to be deleted
+ * @param recursive if true this method will attempt to remove
+ * all children of the given node if any exist
+ * @param version the expected version of the node. The function will
+ * fail if the actual version of the node does not match
+ * the expected version
+ *
+ * @return true if the node has been deleted; false otherwise
+ * @throw ZooKeeperException if the operation has failed
+ */
+ bool deleteNode(const string &path,
+ bool recursive = false,
+ int version = -1) throw(ZooKeeperException);
+
+ /**
+ * \brief Retrieves list of all children of the given node.
+ *
+ * @param path the absolute path name of the node for which to get children
+ * @return the list of absolute paths of child nodes, possibly empty
+ * @throw ZooKeeperException if the operation has failed
+ */
+ vector<string> getNodeChildren( const string &path) throw(ZooKeeperException);
+
+ /**
+ * \brief Check the existence of path to a znode.
+ *
+ * @param path the absolute path name of the znode
+ * @return TRUE if the znode exists; FALSE otherwise
+ * @throw ZooKeeperException if the operation has failed
+ */
+ bool nodeExists(const string &path) throw(ZooKeeperException);
+
+ /**
+ * \brief Gets the given node's data.
+ *
+ * @param path the absolute path name of the node to get data from
+ *
+ * @return the node's data
+ * @throw ZooKeeperException if the operation has failed
+ */
+ string getNodeData(const string &path) throw(ZooKeeperException);
+
+ /**
+ * \brief Sets the given node's data.
+ *
+ * @param path the absolute path name of the node to get data from
+ * @param value the node's data to be set
+ * @param version the expected version of the node. The function will
+ * fail if the actual version of the node does not match
+ * the expected version
+ *
+ * @throw ZooKeeperException if the operation has failed
+ */
+ void setNodeData(const string &path,
+ const string &value,
+ int version = -1) throw(ZooKeeperException);
+
+ /**
+ * \brief Validates the given path to a node in ZK.
+ *
+ * @param the path to be validated
+ *
+ * @throw ZooKeeperException if the given path is not valid
+ * (for instance it doesn't start with "/")
+ */
+ static void validatePath(const string &path) throw(ZooKeeperException);
+
+ private:
+
+ /**
+ * Verifies whether the connection is established,
+ * optionally auto reconnecting.
+ *
+ * @throw ZooKeeperConnection if this client is disconnected
+ * and auto-reconnect failed or was not allowed
+ */
+ void verifyConnection() throw(ZooKeeperException);
+
+ private:
+
+ /**
+ * The current ZK configuration.
+ */
+ const ZooKeeperConfig m_zkConfig;
+
+ /**
+ * The current ZK session.
+ */
+ zhandle_t *mp_zkHandle;
+ };
+
+} /* end of 'namespace zktreeutil' */
+
+#endif /* __ZK_ADAPTER_H__ */