当前位置:   article > 正文

Apache Zookeeper zkCli.sh命令及Java客户端连接测试_java执行zkcli.sh

java执行zkcli.sh

如题:Apache Zookeeper zkCli.sh命令及Java客户端连接测试,本文分两部分进行说明,第一部分是zkCli.sh命令行的使用,第二部分是Java客户端测试连接Zookeeper服务端。本文开始的前提是已安装Apache Zookeeper。

zkCli.sh命令使用

Linux的shell环境窗口操作:

zkCli.sh -server 127.0.0.1:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。

注:如果是本地单机情况,只需要输入 zkCli.sh 即可进入。

命令行工具的一些简单操作如下:

  • 1. 显示根目录下、文件: ls /      使用 ls 命令来查看当前 ZooKeeper 中所包含的内容

  • 2. 显示根目录下、文件: ls2 /    查看当前节点数据并能看到更新次数等数据

  • 3. 创建文件,并设置初始内容: create /zk    "test"     创建一个新的 znode节点“ zk ”以及与它关联的字符串

  • 4. 获取文件内容: get /zk     确认 znode 是否包含我们所创建的字符串

  • 5. 修改文件内容: set /zk "zkbak"     对 zk 所关联的字符串进行设置

  • 6. 删除文件: delete /zk      将刚才创建的 znode 删除

  • 7. 退出客户端: quit

  • 8. 帮助命令: help


Java客户端连接测试

首先添加maven依赖配置

pom.xml

  1. <dependency>
  2. <groupId>org.apache.zookeeper</groupId>
  3. <artifactId>zookeeper</artifactId>
  4. <version>3.4.9</version>
  5. </dependency>

ZkWatcher.java

  1. package com.github.boonya.zookeeper;
  2. import java.io.IOException;
  3. import java.util.Date;
  4. import java.util.concurrent.CountDownLatch;
  5. import org.apache.zookeeper.KeeperException;
  6. import org.apache.zookeeper.WatchedEvent;
  7. import org.apache.zookeeper.Watcher;
  8. import org.apache.zookeeper.ZooKeeper;
  9. import org.apache.zookeeper.data.Stat;
  10. /**
  11. * 测试Zookeeper基本连接
  12. *
  13. * @package com.github.boonya.zookeeper.ZkWatcher
  14. * @date 2017年3月28日 上午9:22:16
  15. * @author pengjunlin
  16. * @comment
  17. * @update
  18. */
  19. public class ZkWatcher implements Watcher{
  20. private static CountDownLatch countDownLatch = new CountDownLatch(1);
  21. /**
  22. * 处理同步连接
  23. */
  24. public void process(WatchedEvent event) {
  25. System.out.println("Receive watcher event:" + event);
  26. if(Event.KeeperState.SyncConnected == event.getState()){
  27. countDownLatch.countDown();
  28. }
  29. }
  30. /**
  31. * 主函数入口
  32. *
  33. * @MethodName: main
  34. * @Description:
  35. * @param args
  36. * @throws IOException
  37. * @throws KeeperException
  38. * @throws InterruptedException
  39. * @throws
  40. */
  41. public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
  42. Long startTime = new Date().getTime();
  43. ZooKeeper zooKeeper = new ZooKeeper("192.168.234.128:2181",5000,new ZkWatcher());
  44. try {
  45. countDownLatch.await();
  46. } catch (InterruptedException e) {
  47. e.printStackTrace();
  48. }
  49. System.out.println("创建连接花费时间:" + (new Date().getTime() - startTime) + "ms");
  50. System.out.println("连接状态:" + zooKeeper.getState());
  51. System.out.println("sessionId:" + zooKeeper.getSessionId());
  52. System.out.println("sessionPasswd:" + new String(zooKeeper.getSessionPasswd()));
  53. // 此时需要使用到zkCli.sh命令窗口 ,Zookeeper默认节点路径为/zookeeper
  54. //查看path: ls \
  55. //创建path数据情况: create /zookeeper '默认内容'
  56. //查看path数据情况: get /zookeeper
  57. //version以节点的dataVersion = 2一致才能成功,否则抛出 KeeperErrorCode = BadVersion for /zookeeper
  58. zooKeeper.setData("/zookeeper", "Hello world! Hello Zookeeper!".getBytes(), 2);
  59. byte [] data=zooKeeper.getData("/zookeeper", new ZkWatcher(), new Stat());
  60. System.out.println("/zookeeper data:"+new String(data));
  61. }
  62. /* [zk: localhost:2181(CONNECTED) 4] get /zookeeper
  63. Hello world!Hello Zookeeper!
  64. cZxid = 0x0
  65. ctime = Wed Dec 31 16:00:00 PST 1969
  66. mZxid = 0xc
  67. mtime = Mon Mar 27 18:41:45 PDT 2017
  68. pZxid = 0x0
  69. cversion = -1
  70. dataVersion = 1
  71. aclVersion = 0
  72. ephemeralOwner = 0x0
  73. dataLength = 28
  74. numChildren = 1
  75. [zk: localhost:2181(CONNECTED) 5] get /zookeeper
  76. Hello world! Hello Zookeeper!
  77. cZxid = 0x0
  78. ctime = Wed Dec 31 16:00:00 PST 1969
  79. mZxid = 0x15
  80. mtime = Mon Mar 27 18:44:50 PDT 2017
  81. pZxid = 0x0
  82. cversion = -1
  83. dataVersion = 2
  84. aclVersion = 0
  85. ephemeralOwner = 0x0
  86. dataLength = 29
  87. numChildren = 1*/
  88. }

测试运行输出:

创建连接花费时间:227ms
连接状态:CONNECTED
sessionId:97692145141547018
sessionPasswd:��W�DlRʼ�p��*09:45:14.301 [main-SendThread(192.168.234.128:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x15b127d0882000a, packet:: clientPath:null serverPath:null finished:false header:: 1,5  replyHeader:: 1,28,0  request:: '/zookeeper,#48656c6c6f20776f726c64212048656c6c6f205a6f6f6b656570657221,2  response:: s{0,28,0,1490665711525,3,-1,0,0,29,1,0} 
09:45:14.304 [main-SendThread(192.168.234.128:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x15b127d0882000a, packet:: clientPath:null serverPath:null finished:false header:: 2,4  replyHeader:: 2,28,0  request:: '/zookeeper,T  response:: #48656c6c6f20776f726c64212048656c6c6f205a6f6f6b656570657221,s{0,28,0,1490665711525,3,-1,0,0,29,1,0} 
/zookeeper data:Hello world! Hello Zookeeper!

Zookeeper源代码工具类

  1. * Licensed to the Apache Software Foundation (ASF) under one
  2. package org.apache.zookeeper;
  3. import org.apache.zookeeper.AsyncCallback.*;
  4. import org.apache.zookeeper.OpResult.ErrorResult;
  5. import org.apache.zookeeper.client.ConnectStringParser;
  6. import org.apache.zookeeper.client.HostProvider;
  7. import org.apache.zookeeper.client.StaticHostProvider;
  8. import org.apache.zookeeper.client.ZooKeeperSaslClient;
  9. import org.apache.zookeeper.common.PathUtils;
  10. import org.apache.zookeeper.data.ACL;
  11. import org.apache.zookeeper.data.Stat;
  12. import org.apache.zookeeper.proto.*;
  13. import org.apache.zookeeper.server.DataTree;
  14. import org.slf4j.Logger;
  15. import org.slf4j.LoggerFactory;
  16. import java.io.IOException;
  17. import java.net.SocketAddress;
  18. import java.util.*;
  19. /**
  20. * This is the main class of ZooKeeper client library. To use a ZooKeeper
  21. * service, an application must first instantiate an object of ZooKeeper class.
  22. * All the iterations will be done by calling the methods of ZooKeeper class.
  23. * The methods of this class are thread-safe unless otherwise noted.
  24. * <p>
  25. * Once a connection to a server is established, a session ID is assigned to the
  26. * client. The client will send heart beats to the server periodically to keep
  27. * the session valid.
  28. * <p>
  29. * The application can call ZooKeeper APIs through a client as long as the
  30. * session ID of the client remains valid.
  31. * <p>
  32. * If for some reason, the client fails to send heart beats to the server for a
  33. * prolonged period of time (exceeding the sessionTimeout value, for instance),
  34. * the server will expire the session, and the session ID will become invalid.
  35. * The client object will no longer be usable. To make ZooKeeper API calls, the
  36. * application must create a new client object.
  37. * <p>
  38. * If the ZooKeeper server the client currently connects to fails or otherwise
  39. * does not respond, the client will automatically try to connect to another
  40. * server before its session ID expires. If successful, the application can
  41. * continue to use the client.
  42. * <p>
  43. * The ZooKeeper API methods are either synchronous or asynchronous. Synchronous
  44. * methods blocks until the server has responded. Asynchronous methods just queue
  45. * the request for sending and return immediately. They take a callback object that
  46. * will be executed either on successful execution of the request or on error with
  47. * an appropriate return code (rc) indicating the error.
  48. * <p>
  49. * Some successful ZooKeeper API calls can leave watches on the "data nodes" in
  50. * the ZooKeeper server. Other successful ZooKeeper API calls can trigger those
  51. * watches. Once a watch is triggered, an event will be delivered to the client
  52. * which left the watch at the first place. Each watch can be triggered only
  53. * once. Thus, up to one event will be delivered to a client for every watch it
  54. * leaves.
  55. * <p>
  56. * A client needs an object of a class implementing Watcher interface for
  57. * processing the events delivered to the client.
  58. *
  59. * When a client drops current connection and re-connects to a server, all the
  60. * existing watches are considered as being triggered but the undelivered events
  61. * are lost. To emulate this, the client will generate a special event to tell
  62. * the event handler a connection has been dropped. This special event has type
  63. * EventNone and state sKeeperStateDisconnected.
  64. *
  65. */
  66. public class ZooKeeper {
  67. public static final String ZOOKEEPER_CLIENT_CNXN_SOCKET = "zookeeper.clientCnxnSocket";
  68. protected final ClientCnxn cnxn;
  69. private static final Logger LOG;
  70. static {
  71. //Keep these two lines together to keep the initialization order explicit
  72. LOG = LoggerFactory.getLogger(ZooKeeper.class);
  73. Environment.logEnv("Client environment:", LOG);
  74. }
  75. public ZooKeeperSaslClient getSaslClient() {
  76. return cnxn.zooKeeperSaslClient;
  77. }
  78. private final ZKWatchManager watchManager = new ZKWatchManager();
  79. List<String> getDataWatches() {
  80. synchronized(watchManager.dataWatches) {
  81. List<String> rc = new ArrayList<String>(watchManager.dataWatches.keySet());
  82. return rc;
  83. }
  84. }
  85. List<String> getExistWatches() {
  86. synchronized(watchManager.existWatches) {
  87. List<String> rc = new ArrayList<String>(watchManager.existWatches.keySet());
  88. return rc;
  89. }
  90. }
  91. List<String> getChildWatches() {
  92. synchronized(watchManager.childWatches) {
  93. List<String> rc = new ArrayList<String>(watchManager.childWatches.keySet());
  94. return rc;
  95. }
  96. }
  97. /**
  98. * Manage watchers & handle events generated by the ClientCnxn object.
  99. *
  100. * We are implementing this as a nested class of ZooKeeper so that
  101. * the public methods will not be exposed as part of the ZooKeeper client
  102. * API.
  103. */
  104. private static class ZKWatchManager implements ClientWatchManager {
  105. private final Map<String, Set<Watcher>> dataWatches =
  106. new HashMap<String, Set<Watcher>>();
  107. private final Map<String, Set<Watcher>> existWatches =
  108. new HashMap<String, Set<Watcher>>();
  109. private final Map<String, Set<Watcher>> childWatches =
  110. new HashMap<String, Set<Watcher>>();
  111. private volatile Watcher defaultWatcher;
  112. final private void addTo(Set<Watcher> from, Set<Watcher> to) {
  113. if (from != null) {
  114. to.addAll(from);
  115. }
  116. }
  117. /* (non-Javadoc)
  118. * @see org.apache.zookeeper.ClientWatchManager#materialize(Event.KeeperState,
  119. * Event.EventType, java.lang.String)
  120. */
  121. @Override
  122. public Set<Watcher> materialize(Watcher.Event.KeeperState state,
  123. Watcher.Event.EventType type,
  124. String clientPath)
  125. {
  126. Set<Watcher> result = new HashSet<Watcher>();
  127. switch (type) {
  128. case None:
  129. result.add(defaultWatcher);
  130. boolean clear = ClientCnxn.getDisableAutoResetWatch() &&
  131. state != Watcher.Event.KeeperState.SyncConnected;
  132. synchronized(dataWatches) {
  133. for(Set<Watcher> ws: dataWatches.values()) {
  134. result.addAll(ws);
  135. }
  136. if (clear) {
  137. dataWatches.clear();
  138. }
  139. }
  140. synchronized(existWatches) {
  141. for(Set<Watcher> ws: existWatches.values()) {
  142. result.addAll(ws);
  143. }
  144. if (clear) {
  145. existWatches.clear();
  146. }
  147. }
  148. synchronized(childWatches) {
  149. for(Set<Watcher> ws: childWatches.values()) {
  150. result.addAll(ws);
  151. }
  152. if (clear) {
  153. childWatches.clear();
  154. }
  155. }
  156. return result;
  157. case NodeDataChanged:
  158. case NodeCreated:
  159. synchronized (dataWatches) {
  160. addTo(dataWatches.remove(clientPath), result);
  161. }
  162. synchronized (existWatches) {
  163. addTo(existWatches.remove(clientPath), result);
  164. }
  165. break;
  166. case NodeChildrenChanged:
  167. synchronized (childWatches) {
  168. addTo(childWatches.remove(clientPath), result);
  169. }
  170. break;
  171. case NodeDeleted:
  172. synchronized (dataWatches) {
  173. addTo(dataWatches.remove(clientPath), result);
  174. }
  175. // XXX This shouldn't be needed, but just in case
  176. synchronized (existWatches) {
  177. Set<Watcher> list = existWatches.remove(clientPath);
  178. if (list != null) {
  179. addTo(existWatches.remove(clientPath), result);
  180. LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!");
  181. }
  182. }
  183. synchronized (childWatches) {
  184. addTo(childWatches.remove(clientPath), result);
  185. }
  186. break;
  187. default:
  188. String msg = "Unhandled watch event type " + type
  189. + " with state " + state + " on path " + clientPath;
  190. LOG.error(msg);
  191. throw new RuntimeException(msg);
  192. }
  193. return result;
  194. }
  195. }
  196. /**
  197. * Register a watcher for a particular path.
  198. */
  199. abstract class WatchRegistration {
  200. private Watcher watcher;
  201. private String clientPath;
  202. public WatchRegistration(Watcher watcher, String clientPath)
  203. {
  204. this.watcher = watcher;
  205. this.clientPath = clientPath;
  206. }
  207. abstract protected Map<String, Set<Watcher>> getWatches(int rc);
  208. /**
  209. * Register the watcher with the set of watches on path.
  210. * @param rc the result code of the operation that attempted to
  211. * add the watch on the path.
  212. */
  213. public void register(int rc) {
  214. if (shouldAddWatch(rc)) {
  215. Map<String, Set<Watcher>> watches = getWatches(rc);
  216. synchronized(watches) {
  217. Set<Watcher> watchers = watches.get(clientPath);
  218. if (watchers == null) {
  219. watchers = new HashSet<Watcher>();
  220. watches.put(clientPath, watchers);
  221. }
  222. watchers.add(watcher);
  223. }
  224. }
  225. }
  226. /**
  227. * Determine whether the watch should be added based on return code.
  228. * @param rc the result code of the operation that attempted to add the
  229. * watch on the node
  230. * @return true if the watch should be added, otw false
  231. */
  232. protected boolean shouldAddWatch(int rc) {
  233. return rc == 0;
  234. }
  235. }
  236. /** Handle the special case of exists watches - they add a watcher
  237. * even in the case where NONODE result code is returned.
  238. */
  239. class ExistsWatchRegistration extends WatchRegistration {
  240. public ExistsWatchRegistration(Watcher watcher, String clientPath) {
  241. super(watcher, clientPath);
  242. }
  243. @Override
  244. protected Map<String, Set<Watcher>> getWatches(int rc) {
  245. return rc == 0 ? watchManager.dataWatches : watchManager.existWatches;
  246. }
  247. @Override
  248. protected boolean shouldAddWatch(int rc) {
  249. return rc == 0 || rc == KeeperException.Code.NONODE.intValue();
  250. }
  251. }
  252. class DataWatchRegistration extends WatchRegistration {
  253. public DataWatchRegistration(Watcher watcher, String clientPath) {
  254. super(watcher, clientPath);
  255. }
  256. @Override
  257. protected Map<String, Set<Watcher>> getWatches(int rc) {
  258. return watchManager.dataWatches;
  259. }
  260. }
  261. class ChildWatchRegistration extends WatchRegistration {
  262. public ChildWatchRegistration(Watcher watcher, String clientPath) {
  263. super(watcher, clientPath);
  264. }
  265. @Override
  266. protected Map<String, Set<Watcher>> getWatches(int rc) {
  267. return watchManager.childWatches;
  268. }
  269. }
  270. public enum States {
  271. CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY,
  272. CLOSED, AUTH_FAILED, NOT_CONNECTED;
  273. public boolean isAlive() {
  274. return this != CLOSED && this != AUTH_FAILED;
  275. }
  276. /**
  277. * Returns whether we are connected to a server (which
  278. * could possibly be read-only, if this client is allowed
  279. * to go to read-only mode)
  280. * */
  281. public boolean isConnected() {
  282. return this == CONNECTED || this == CONNECTEDREADONLY;
  283. }
  284. }
  285. /**
  286. * To create a ZooKeeper client object, the application needs to pass a
  287. * connection string containing a comma separated list of host:port pairs,
  288. * each corresponding to a ZooKeeper server.
  289. * <p>
  290. * Session establishment is asynchronous. This constructor will initiate
  291. * connection to the server and return immediately - potentially (usually)
  292. * before the session is fully established. The watcher argument specifies
  293. * the watcher that will be notified of any changes in state. This
  294. * notification can come at any point before or after the constructor call
  295. * has returned.
  296. * <p>
  297. * The instantiated ZooKeeper client object will pick an arbitrary server
  298. * from the connectString and attempt to connect to it. If establishment of
  299. * the connection fails, another server in the connect string will be tried
  300. * (the order is non-deterministic, as we random shuffle the list), until a
  301. * connection is established. The client will continue attempts until the
  302. * session is explicitly closed.
  303. * <p>
  304. * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
  305. * connection string. This will run the client commands while interpreting
  306. * all paths relative to this root (similar to the unix chroot command).
  307. *
  308. * @param connectString
  309. * comma separated host:port pairs, each corresponding to a zk
  310. * server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If
  311. * the optional chroot suffix is used the example would look
  312. * like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
  313. * where the client would be rooted at "/app/a" and all paths
  314. * would be relative to this root - ie getting/setting/etc...
  315. * "/foo/bar" would result in operations being run on
  316. * "/app/a/foo/bar" (from the server perspective).
  317. * @param sessionTimeout
  318. * session timeout in milliseconds
  319. * @param watcher
  320. * a watcher object which will be notified of state changes, may
  321. * also be notified for node events
  322. *
  323. * @throws IOException
  324. * in cases of network failure
  325. * @throws IllegalArgumentException
  326. * if an invalid chroot path is specified
  327. */
  328. public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
  329. throws IOException
  330. {
  331. this(connectString, sessionTimeout, watcher, false);
  332. }
  333. /**
  334. * To create a ZooKeeper client object, the application needs to pass a
  335. * connection string containing a comma separated list of host:port pairs,
  336. * each corresponding to a ZooKeeper server.
  337. * <p>
  338. * Session establishment is asynchronous. This constructor will initiate
  339. * connection to the server and return immediately - potentially (usually)
  340. * before the session is fully established. The watcher argument specifies
  341. * the watcher that will be notified of any changes in state. This
  342. * notification can come at any point before or after the constructor call
  343. * has returned.
  344. * <p>
  345. * The instantiated ZooKeeper client object will pick an arbitrary server
  346. * from the connectString and attempt to connect to it. If establishment of
  347. * the connection fails, another server in the connect string will be tried
  348. * (the order is non-deterministic, as we random shuffle the list), until a
  349. * connection is established. The client will continue attempts until the
  350. * session is explicitly closed.
  351. * <p>
  352. * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
  353. * connection string. This will run the client commands while interpreting
  354. * all paths relative to this root (similar to the unix chroot command).
  355. *
  356. * @param connectString
  357. * comma separated host:port pairs, each corresponding to a zk
  358. * server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If
  359. * the optional chroot suffix is used the example would look
  360. * like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
  361. * where the client would be rooted at "/app/a" and all paths
  362. * would be relative to this root - ie getting/setting/etc...
  363. * "/foo/bar" would result in operations being run on
  364. * "/app/a/foo/bar" (from the server perspective).
  365. * @param sessionTimeout
  366. * session timeout in milliseconds
  367. * @param watcher
  368. * a watcher object which will be notified of state changes, may
  369. * also be notified for node events
  370. * @param canBeReadOnly
  371. * (added in 3.4) whether the created client is allowed to go to
  372. * read-only mode in case of partitioning. Read-only mode
  373. * basically means that if the client can't find any majority
  374. * servers but there's partitioned server it could reach, it
  375. * connects to one in read-only mode, i.e. read requests are
  376. * allowed while write requests are not. It continues seeking for
  377. * majority in the background.
  378. *
  379. * @throws IOException
  380. * in cases of network failure
  381. * @throws IllegalArgumentException
  382. * if an invalid chroot path is specified
  383. */
  384. public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
  385. boolean canBeReadOnly)
  386. throws IOException
  387. {
  388. LOG.info("Initiating client connection, connectString=" + connectString
  389. + " sessionTimeout=" + sessionTimeout + " watcher=" + watcher);
  390. watchManager.defaultWatcher = watcher;
  391. ConnectStringParser connectStringParser = new ConnectStringParser(
  392. connectString);
  393. HostProvider hostProvider = new StaticHostProvider(
  394. connectStringParser.getServerAddresses());
  395. cnxn = new ClientCnxn(connectStringParser.getChrootPath(),
  396. hostProvider, sessionTimeout, this, watchManager,
  397. getClientCnxnSocket(), canBeReadOnly);
  398. cnxn.start();
  399. }
  400. /**
  401. * To create a ZooKeeper client object, the application needs to pass a
  402. * connection string containing a comma separated list of host:port pairs,
  403. * each corresponding to a ZooKeeper server.
  404. * <p>
  405. * Session establishment is asynchronous. This constructor will initiate
  406. * connection to the server and return immediately - potentially (usually)
  407. * before the session is fully established. The watcher argument specifies
  408. * the watcher that will be notified of any changes in state. This
  409. * notification can come at any point before or after the constructor call
  410. * has returned.
  411. * <p>
  412. * The instantiated ZooKeeper client object will pick an arbitrary server
  413. * from the connectString and attempt to connect to it. If establishment of
  414. * the connection fails, another server in the connect string will be tried
  415. * (the order is non-deterministic, as we random shuffle the list), until a
  416. * connection is established. The client will continue attempts until the
  417. * session is explicitly closed (or the session is expired by the server).
  418. * <p>
  419. * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
  420. * connection string. This will run the client commands while interpreting
  421. * all paths relative to this root (similar to the unix chroot command).
  422. * <p>
  423. * Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
  424. * client connection, these values must be passed as sessionId and
  425. * sessionPasswd respectively if reconnecting. Otherwise, if not
  426. * reconnecting, use the other constructor which does not require these
  427. * parameters.
  428. *
  429. * @param connectString
  430. * comma separated host:port pairs, each corresponding to a zk
  431. * server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
  432. * If the optional chroot suffix is used the example would look
  433. * like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
  434. * where the client would be rooted at "/app/a" and all paths
  435. * would be relative to this root - ie getting/setting/etc...
  436. * "/foo/bar" would result in operations being run on
  437. * "/app/a/foo/bar" (from the server perspective).
  438. * @param sessionTimeout
  439. * session timeout in milliseconds
  440. * @param watcher
  441. * a watcher object which will be notified of state changes, may
  442. * also be notified for node events
  443. * @param sessionId
  444. * specific session id to use if reconnecting
  445. * @param sessionPasswd
  446. * password for this session
  447. *
  448. * @throws IOException in cases of network failure
  449. * @throws IllegalArgumentException if an invalid chroot path is specified
  450. * @throws IllegalArgumentException for an invalid list of ZooKeeper hosts
  451. */
  452. public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
  453. long sessionId, byte[] sessionPasswd)
  454. throws IOException
  455. {
  456. this(connectString, sessionTimeout, watcher, sessionId, sessionPasswd, false);
  457. }
  458. /**
  459. * To create a ZooKeeper client object, the application needs to pass a
  460. * connection string containing a comma separated list of host:port pairs,
  461. * each corresponding to a ZooKeeper server.
  462. * <p>
  463. * Session establishment is asynchronous. This constructor will initiate
  464. * connection to the server and return immediately - potentially (usually)
  465. * before the session is fully established. The watcher argument specifies
  466. * the watcher that will be notified of any changes in state. This
  467. * notification can come at any point before or after the constructor call
  468. * has returned.
  469. * <p>
  470. * The instantiated ZooKeeper client object will pick an arbitrary server
  471. * from the connectString and attempt to connect to it. If establishment of
  472. * the connection fails, another server in the connect string will be tried
  473. * (the order is non-deterministic, as we random shuffle the list), until a
  474. * connection is established. The client will continue attempts until the
  475. * session is explicitly closed (or the session is expired by the server).
  476. * <p>
  477. * Added in 3.2.0: An optional "chroot" suffix may also be appended to the
  478. * connection string. This will run the client commands while interpreting
  479. * all paths relative to this root (similar to the unix chroot command).
  480. * <p>
  481. * Use {@link #getSessionId} and {@link #getSessionPasswd} on an established
  482. * client connection, these values must be passed as sessionId and
  483. * sessionPasswd respectively if reconnecting. Otherwise, if not
  484. * reconnecting, use the other constructor which does not require these
  485. * parameters.
  486. *
  487. * @param connectString
  488. * comma separated host:port pairs, each corresponding to a zk
  489. * server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
  490. * If the optional chroot suffix is used the example would look
  491. * like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"
  492. * where the client would be rooted at "/app/a" and all paths
  493. * would be relative to this root - ie getting/setting/etc...
  494. * "/foo/bar" would result in operations being run on
  495. * "/app/a/foo/bar" (from the server perspective).
  496. * @param sessionTimeout
  497. * session timeout in milliseconds
  498. * @param watcher
  499. * a watcher object which will be notified of state changes, may
  500. * also be notified for node events
  501. * @param sessionId
  502. * specific session id to use if reconnecting
  503. * @param sessionPasswd
  504. * password for this session
  505. * @param canBeReadOnly
  506. * (added in 3.4) whether the created client is allowed to go to
  507. * read-only mode in case of partitioning. Read-only mode
  508. * basically means that if the client can't find any majority
  509. * servers but there's partitioned server it could reach, it
  510. * connects to one in read-only mode, i.e. read requests are
  511. * allowed while write requests are not. It continues seeking for
  512. * majority in the background.
  513. *
  514. * @throws IOException in cases of network failure
  515. * @throws IllegalArgumentException if an invalid chroot path is specified
  516. */
  517. public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
  518. long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
  519. throws IOException
  520. {
  521. LOG.info("Initiating client connection, connectString=" + connectString
  522. + " sessionTimeout=" + sessionTimeout
  523. + " watcher=" + watcher
  524. + " sessionId=" + Long.toHexString(sessionId)
  525. + " sessionPasswd="
  526. + (sessionPasswd == null ? "<null>" : "<hidden>"));
  527. watchManager.defaultWatcher = watcher;
  528. ConnectStringParser connectStringParser = new ConnectStringParser(
  529. connectString);
  530. HostProvider hostProvider = new StaticHostProvider(
  531. connectStringParser.getServerAddresses());
  532. cnxn = new ClientCnxn(connectStringParser.getChrootPath(),
  533. hostProvider, sessionTimeout, this, watchManager,
  534. getClientCnxnSocket(), sessionId, sessionPasswd, canBeReadOnly);
  535. cnxn.seenRwServerBefore = true; // since user has provided sessionId
  536. cnxn.start();
  537. }
  538. /**
  539. * The session id for this ZooKeeper client instance. The value returned is
  540. * not valid until the client connects to a server and may change after a
  541. * re-connect.
  542. *
  543. * This method is NOT thread safe
  544. *
  545. * @return current session id
  546. */
  547. public long getSessionId() {
  548. return cnxn.getSessionId();
  549. }
  550. /**
  551. * The session password for this ZooKeeper client instance. The value
  552. * returned is not valid until the client connects to a server and may
  553. * change after a re-connect.
  554. *
  555. * This method is NOT thread safe
  556. *
  557. * @return current session password
  558. */
  559. public byte[] getSessionPasswd() {
  560. return cnxn.getSessionPasswd();
  561. }
  562. /**
  563. * The negotiated session timeout for this ZooKeeper client instance. The
  564. * value returned is not valid until the client connects to a server and
  565. * may change after a re-connect.
  566. *
  567. * This method is NOT thread safe
  568. *
  569. * @return current session timeout
  570. */
  571. public int getSessionTimeout() {
  572. return cnxn.getSessionTimeout();
  573. }
  574. /**
  575. * Add the specified scheme:auth information to this connection.
  576. *
  577. * This method is NOT thread safe
  578. *
  579. * @param scheme
  580. * @param auth
  581. */
  582. public void addAuthInfo(String scheme, byte auth[]) {
  583. cnxn.addAuthInfo(scheme, auth);
  584. }
  585. /**
  586. * Specify the default watcher for the connection (overrides the one
  587. * specified during construction).
  588. *
  589. * @param watcher
  590. */
  591. public synchronized void register(Watcher watcher) {
  592. watchManager.defaultWatcher = watcher;
  593. }
  594. /**
  595. * Close this client object. Once the client is closed, its session becomes
  596. * invalid. All the ephemeral nodes in the ZooKeeper server associated with
  597. * the session will be removed. The watches left on those nodes (and on
  598. * their parents) will be triggered.
  599. *
  600. * @throws InterruptedException
  601. */
  602. public synchronized void close() throws InterruptedException {
  603. if (!cnxn.getState().isAlive()) {
  604. if (LOG.isDebugEnabled()) {
  605. LOG.debug("Close called on already closed client");
  606. }
  607. return;
  608. }
  609. if (LOG.isDebugEnabled()) {
  610. LOG.debug("Closing session: 0x" + Long.toHexString(getSessionId()));
  611. }
  612. try {
  613. cnxn.close();
  614. } catch (IOException e) {
  615. if (LOG.isDebugEnabled()) {
  616. LOG.debug("Ignoring unexpected exception during close", e);
  617. }
  618. }
  619. LOG.info("Session: 0x" + Long.toHexString(getSessionId()) + " closed");
  620. }
  621. /**
  622. * Prepend the chroot to the client path (if present). The expectation of
  623. * this function is that the client path has been validated before this
  624. * function is called
  625. * @param clientPath path to the node
  626. * @return server view of the path (chroot prepended to client path)
  627. */
  628. private String prependChroot(String clientPath) {
  629. if (cnxn.chrootPath != null) {
  630. // handle clientPath = "/"
  631. if (clientPath.length() == 1) {
  632. return cnxn.chrootPath;
  633. }
  634. return cnxn.chrootPath + clientPath;
  635. } else {
  636. return clientPath;
  637. }
  638. }
  639. /**
  640. * Create a node with the given path. The node data will be the given data,
  641. * and node acl will be the given acl.
  642. * <p>
  643. * The flags argument specifies whether the created node will be ephemeral
  644. * or not.
  645. * <p>
  646. * An ephemeral node will be removed by the ZooKeeper automatically when the
  647. * session associated with the creation of the node expires.
  648. * <p>
  649. * The flags argument can also specify to create a sequential node. The
  650. * actual path name of a sequential node will be the given path plus a
  651. * suffix "i" where i is the current sequential number of the node. The sequence
  652. * number is always fixed length of 10 digits, 0 padded. Once
  653. * such a node is created, the sequential number will be incremented by one.
  654. * <p>
  655. * If a node with the same actual path already exists in the ZooKeeper, a
  656. * KeeperException with error code KeeperException.NodeExists will be
  657. * thrown. Note that since a different actual path is used for each
  658. * invocation of creating sequential node with the same path argument, the
  659. * call will never throw "file exists" KeeperException.
  660. * <p>
  661. * If the parent node does not exist in the ZooKeeper, a KeeperException
  662. * with error code KeeperException.NoNode will be thrown.
  663. * <p>
  664. * An ephemeral node cannot have children. If the parent node of the given
  665. * path is ephemeral, a KeeperException with error code
  666. * KeeperException.NoChildrenForEphemerals will be thrown.
  667. * <p>
  668. * This operation, if successful, will trigger all the watches left on the
  669. * node of the given path by exists and getData API calls, and the watches
  670. * left on the parent node by getChildren API calls.
  671. * <p>
  672. * If a node is created successfully, the ZooKeeper server will trigger the
  673. * watches on the path left by exists calls, and the watches on the parent
  674. * of the node by getChildren calls.
  675. * <p>
  676. * The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
  677. * Arrays larger than this will cause a KeeperExecption to be thrown.
  678. *
  679. * @param path
  680. * the path for the node
  681. * @param data
  682. * the initial data for the node
  683. * @param acl
  684. * the acl for the node
  685. * @param createMode
  686. * specifying whether the node to be created is ephemeral
  687. * and/or sequential
  688. * @return the actual path of the created node
  689. * @throws KeeperException if the server returns a non-zero error code
  690. * @throws KeeperException.InvalidACLException if the ACL is invalid, null, or empty
  691. * @throws InterruptedException if the transaction is interrupted
  692. * @throws IllegalArgumentException if an invalid path is specified
  693. */
  694. public String create(final String path, byte data[], List<ACL> acl,
  695. CreateMode createMode)
  696. throws KeeperException, InterruptedException
  697. {
  698. final String clientPath = path;
  699. PathUtils.validatePath(clientPath, createMode.isSequential());
  700. final String serverPath = prependChroot(clientPath);
  701. RequestHeader h = new RequestHeader();
  702. h.setType(ZooDefs.OpCode.create);
  703. CreateRequest request = new CreateRequest();
  704. CreateResponse response = new CreateResponse();
  705. request.setData(data);
  706. request.setFlags(createMode.toFlag());
  707. request.setPath(serverPath);
  708. if (acl != null && acl.size() == 0) {
  709. throw new KeeperException.InvalidACLException();
  710. }
  711. request.setAcl(acl);
  712. ReplyHeader r = cnxn.submitRequest(h, request, response, null);
  713. if (r.getErr() != 0) {
  714. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  715. clientPath);
  716. }
  717. if (cnxn.chrootPath == null) {
  718. return response.getPath();
  719. } else {
  720. return response.getPath().substring(cnxn.chrootPath.length());
  721. }
  722. }
  723. /**
  724. * The asynchronous version of create.
  725. *
  726. * @see #create(String, byte[], List, CreateMode)
  727. */
  728. public void create(final String path, byte data[], List<ACL> acl,
  729. CreateMode createMode, StringCallback cb, Object ctx)
  730. {
  731. final String clientPath = path;
  732. PathUtils.validatePath(clientPath, createMode.isSequential());
  733. final String serverPath = prependChroot(clientPath);
  734. RequestHeader h = new RequestHeader();
  735. h.setType(ZooDefs.OpCode.create);
  736. CreateRequest request = new CreateRequest();
  737. CreateResponse response = new CreateResponse();
  738. ReplyHeader r = new ReplyHeader();
  739. request.setData(data);
  740. request.setFlags(createMode.toFlag());
  741. request.setPath(serverPath);
  742. request.setAcl(acl);
  743. cnxn.queuePacket(h, r, request, response, cb, clientPath,
  744. serverPath, ctx, null);
  745. }
  746. /**
  747. * Delete the node with the given path. The call will succeed if such a node
  748. * exists, and the given version matches the node's version (if the given
  749. * version is -1, it matches any node's versions).
  750. * <p>
  751. * A KeeperException with error code KeeperException.NoNode will be thrown
  752. * if the nodes does not exist.
  753. * <p>
  754. * A KeeperException with error code KeeperException.BadVersion will be
  755. * thrown if the given version does not match the node's version.
  756. * <p>
  757. * A KeeperException with error code KeeperException.NotEmpty will be thrown
  758. * if the node has children.
  759. * <p>
  760. * This operation, if successful, will trigger all the watches on the node
  761. * of the given path left by exists API calls, and the watches on the parent
  762. * node left by getChildren API calls.
  763. *
  764. * @param path
  765. * the path of the node to be deleted.
  766. * @param version
  767. * the expected node version.
  768. * @throws InterruptedException IF the server transaction is interrupted
  769. * @throws KeeperException If the server signals an error with a non-zero
  770. * return code.
  771. * @throws IllegalArgumentException if an invalid path is specified
  772. */
  773. public void delete(final String path, int version)
  774. throws InterruptedException, KeeperException
  775. {
  776. final String clientPath = path;
  777. PathUtils.validatePath(clientPath);
  778. final String serverPath;
  779. // maintain semantics even in chroot case
  780. // specifically - root cannot be deleted
  781. // I think this makes sense even in chroot case.
  782. if (clientPath.equals("/")) {
  783. // a bit of a hack, but delete(/) will never succeed and ensures
  784. // that the same semantics are maintained
  785. serverPath = clientPath;
  786. } else {
  787. serverPath = prependChroot(clientPath);
  788. }
  789. RequestHeader h = new RequestHeader();
  790. h.setType(ZooDefs.OpCode.delete);
  791. DeleteRequest request = new DeleteRequest();
  792. request.setPath(serverPath);
  793. request.setVersion(version);
  794. ReplyHeader r = cnxn.submitRequest(h, request, null, null);
  795. if (r.getErr() != 0) {
  796. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  797. clientPath);
  798. }
  799. }
  800. /**
  801. * Executes multiple ZooKeeper operations or none of them.
  802. * <p>
  803. * On success, a list of results is returned.
  804. * On failure, an exception is raised which contains partial results and
  805. * error details, see {@link KeeperException#getResults}
  806. * <p>
  807. * Note: The maximum allowable size of all of the data arrays in all of
  808. * the setData operations in this single request is typically 1 MB
  809. * (1,048,576 bytes). This limit is specified on the server via
  810. * <a href="http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#Unsafe+Options">jute.maxbuffer</a>.
  811. * Requests larger than this will cause a KeeperException to be
  812. * thrown.
  813. *
  814. * @param ops An iterable that contains the operations to be done.
  815. * These should be created using the factory methods on {@link Op}.
  816. * @return A list of results, one for each input Op, the order of
  817. * which exactly matches the order of the <code>ops</code> input
  818. * operations.
  819. * @throws InterruptedException If the operation was interrupted.
  820. * The operation may or may not have succeeded, but will not have
  821. * partially succeeded if this exception is thrown.
  822. * @throws KeeperException If the operation could not be completed
  823. * due to some error in doing one of the specified ops.
  824. * @throws IllegalArgumentException if an invalid path is specified
  825. *
  826. * @since 3.4.0
  827. */
  828. public List<OpResult> multi(Iterable<Op> ops) throws InterruptedException, KeeperException {
  829. for (Op op : ops) {
  830. op.validate();
  831. }
  832. return multiInternal(generateMultiTransaction(ops));
  833. }
  834. /**
  835. * The asynchronous version of multi.
  836. *
  837. * @see #multi(Iterable)
  838. * @since 3.4.7
  839. */
  840. public void multi(Iterable<Op> ops, MultiCallback cb, Object ctx) {
  841. List<OpResult> results = validatePath(ops);
  842. if (results.size() > 0) {
  843. cb.processResult(KeeperException.Code.BADARGUMENTS.intValue(),
  844. null, ctx, results);
  845. return;
  846. }
  847. multiInternal(generateMultiTransaction(ops), cb, ctx);
  848. }
  849. private List<OpResult> validatePath(Iterable<Op> ops) {
  850. List<OpResult> results = new ArrayList<OpResult>();
  851. boolean error = false;
  852. for (Op op : ops) {
  853. try {
  854. op.validate();
  855. } catch (IllegalArgumentException iae) {
  856. LOG.error("IllegalArgumentException: " + iae.getMessage());
  857. ErrorResult err = new ErrorResult(
  858. KeeperException.Code.BADARGUMENTS.intValue());
  859. results.add(err);
  860. error = true;
  861. continue;
  862. } catch (KeeperException ke) {
  863. LOG.error("KeeperException: " + ke.getMessage());
  864. ErrorResult err = new ErrorResult(ke.code().intValue());
  865. results.add(err);
  866. error = true;
  867. continue;
  868. }
  869. ErrorResult err = new ErrorResult(
  870. KeeperException.Code.RUNTIMEINCONSISTENCY.intValue());
  871. results.add(err);
  872. }
  873. if (false == error) {
  874. results.clear();
  875. }
  876. return results;
  877. }
  878. private MultiTransactionRecord generateMultiTransaction(Iterable<Op> ops) {
  879. List<Op> transaction = new ArrayList<Op>();
  880. for (Op op : ops) {
  881. transaction.add(withRootPrefix(op));
  882. }
  883. return new MultiTransactionRecord(transaction);
  884. }
  885. private Op withRootPrefix(Op op) {
  886. if (null != op.getPath()) {
  887. final String serverPath = prependChroot(op.getPath());
  888. if (!op.getPath().equals(serverPath)) {
  889. return op.withChroot(serverPath);
  890. }
  891. }
  892. return op;
  893. }
  894. protected void multiInternal(MultiTransactionRecord request, MultiCallback cb, Object ctx) {
  895. RequestHeader h = new RequestHeader();
  896. h.setType(ZooDefs.OpCode.multi);
  897. MultiResponse response = new MultiResponse();
  898. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, null, null, ctx, null);
  899. }
  900. protected List<OpResult> multiInternal(MultiTransactionRecord request)
  901. throws InterruptedException, KeeperException {
  902. RequestHeader h = new RequestHeader();
  903. h.setType(ZooDefs.OpCode.multi);
  904. MultiResponse response = new MultiResponse();
  905. ReplyHeader r = cnxn.submitRequest(h, request, response, null);
  906. if (r.getErr() != 0) {
  907. throw KeeperException.create(KeeperException.Code.get(r.getErr()));
  908. }
  909. List<OpResult> results = response.getResultList();
  910. ErrorResult fatalError = null;
  911. for (OpResult result : results) {
  912. if (result instanceof ErrorResult && ((ErrorResult)result).getErr() != KeeperException.Code.OK.intValue()) {
  913. fatalError = (ErrorResult) result;
  914. break;
  915. }
  916. }
  917. if (fatalError != null) {
  918. KeeperException ex = KeeperException.create(KeeperException.Code.get(fatalError.getErr()));
  919. ex.setMultiResults(results);
  920. throw ex;
  921. }
  922. return results;
  923. }
  924. /**
  925. * A Transaction is a thin wrapper on the {@link #multi} method
  926. * which provides a builder object that can be used to construct
  927. * and commit an atomic set of operations.
  928. *
  929. * @since 3.4.0
  930. *
  931. * @return a Transaction builder object
  932. */
  933. public Transaction transaction() {
  934. return new Transaction(this);
  935. }
  936. /**
  937. * The asynchronous version of delete.
  938. *
  939. * @see #delete(String, int)
  940. */
  941. public void delete(final String path, int version, VoidCallback cb,
  942. Object ctx)
  943. {
  944. final String clientPath = path;
  945. PathUtils.validatePath(clientPath);
  946. final String serverPath;
  947. // maintain semantics even in chroot case
  948. // specifically - root cannot be deleted
  949. // I think this makes sense even in chroot case.
  950. if (clientPath.equals("/")) {
  951. // a bit of a hack, but delete(/) will never succeed and ensures
  952. // that the same semantics are maintained
  953. serverPath = clientPath;
  954. } else {
  955. serverPath = prependChroot(clientPath);
  956. }
  957. RequestHeader h = new RequestHeader();
  958. h.setType(ZooDefs.OpCode.delete);
  959. DeleteRequest request = new DeleteRequest();
  960. request.setPath(serverPath);
  961. request.setVersion(version);
  962. cnxn.queuePacket(h, new ReplyHeader(), request, null, cb, clientPath,
  963. serverPath, ctx, null);
  964. }
  965. /**
  966. * Return the stat of the node of the given path. Return null if no such a
  967. * node exists.
  968. * <p>
  969. * If the watch is non-null and the call is successful (no exception is thrown),
  970. * a watch will be left on the node with the given path. The watch will be
  971. * triggered by a successful operation that creates/delete the node or sets
  972. * the data on the node.
  973. *
  974. * @param path the node path
  975. * @param watcher explicit watcher
  976. * @return the stat of the node of the given path; return null if no such a
  977. * node exists.
  978. * @throws KeeperException If the server signals an error
  979. * @throws InterruptedException If the server transaction is interrupted.
  980. * @throws IllegalArgumentException if an invalid path is specified
  981. */
  982. public Stat exists(final String path, Watcher watcher)
  983. throws KeeperException, InterruptedException
  984. {
  985. final String clientPath = path;
  986. PathUtils.validatePath(clientPath);
  987. // the watch contains the un-chroot path
  988. WatchRegistration wcb = null;
  989. if (watcher != null) {
  990. wcb = new ExistsWatchRegistration(watcher, clientPath);
  991. }
  992. final String serverPath = prependChroot(clientPath);
  993. RequestHeader h = new RequestHeader();
  994. h.setType(ZooDefs.OpCode.exists);
  995. ExistsRequest request = new ExistsRequest();
  996. request.setPath(serverPath);
  997. request.setWatch(watcher != null);
  998. SetDataResponse response = new SetDataResponse();
  999. ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
  1000. if (r.getErr() != 0) {
  1001. if (r.getErr() == KeeperException.Code.NONODE.intValue()) {
  1002. return null;
  1003. }
  1004. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  1005. clientPath);
  1006. }
  1007. return response.getStat().getCzxid() == -1 ? null : response.getStat();
  1008. }
  1009. /**
  1010. * Return the stat of the node of the given path. Return null if no such a
  1011. * node exists.
  1012. * <p>
  1013. * If the watch is true and the call is successful (no exception is thrown),
  1014. * a watch will be left on the node with the given path. The watch will be
  1015. * triggered by a successful operation that creates/delete the node or sets
  1016. * the data on the node.
  1017. *
  1018. * @param path
  1019. * the node path
  1020. * @param watch
  1021. * whether need to watch this node
  1022. * @return the stat of the node of the given path; return null if no such a
  1023. * node exists.
  1024. * @throws KeeperException If the server signals an error
  1025. * @throws InterruptedException If the server transaction is interrupted.
  1026. */
  1027. public Stat exists(String path, boolean watch) throws KeeperException,
  1028. InterruptedException
  1029. {
  1030. return exists(path, watch ? watchManager.defaultWatcher : null);
  1031. }
  1032. /**
  1033. * The asynchronous version of exists.
  1034. *
  1035. * @see #exists(String, Watcher)
  1036. */
  1037. public void exists(final String path, Watcher watcher,
  1038. StatCallback cb, Object ctx)
  1039. {
  1040. final String clientPath = path;
  1041. PathUtils.validatePath(clientPath);
  1042. // the watch contains the un-chroot path
  1043. WatchRegistration wcb = null;
  1044. if (watcher != null) {
  1045. wcb = new ExistsWatchRegistration(watcher, clientPath);
  1046. }
  1047. final String serverPath = prependChroot(clientPath);
  1048. RequestHeader h = new RequestHeader();
  1049. h.setType(ZooDefs.OpCode.exists);
  1050. ExistsRequest request = new ExistsRequest();
  1051. request.setPath(serverPath);
  1052. request.setWatch(watcher != null);
  1053. SetDataResponse response = new SetDataResponse();
  1054. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1055. clientPath, serverPath, ctx, wcb);
  1056. }
  1057. /**
  1058. * The asynchronous version of exists.
  1059. *
  1060. * @see #exists(String, boolean)
  1061. */
  1062. public void exists(String path, boolean watch, StatCallback cb, Object ctx) {
  1063. exists(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
  1064. }
  1065. /**
  1066. * Return the data and the stat of the node of the given path.
  1067. * <p>
  1068. * If the watch is non-null and the call is successful (no exception is
  1069. * thrown), a watch will be left on the node with the given path. The watch
  1070. * will be triggered by a successful operation that sets data on the node, or
  1071. * deletes the node.
  1072. * <p>
  1073. * A KeeperException with error code KeeperException.NoNode will be thrown
  1074. * if no node with the given path exists.
  1075. *
  1076. * @param path the given path
  1077. * @param watcher explicit watcher
  1078. * @param stat the stat of the node
  1079. * @return the data of the node
  1080. * @throws KeeperException If the server signals an error with a non-zero error code
  1081. * @throws InterruptedException If the server transaction is interrupted.
  1082. * @throws IllegalArgumentException if an invalid path is specified
  1083. */
  1084. public byte[] getData(final String path, Watcher watcher, Stat stat)
  1085. throws KeeperException, InterruptedException
  1086. {
  1087. final String clientPath = path;
  1088. PathUtils.validatePath(clientPath);
  1089. // the watch contains the un-chroot path
  1090. WatchRegistration wcb = null;
  1091. if (watcher != null) {
  1092. wcb = new DataWatchRegistration(watcher, clientPath);
  1093. }
  1094. final String serverPath = prependChroot(clientPath);
  1095. RequestHeader h = new RequestHeader();
  1096. h.setType(ZooDefs.OpCode.getData);
  1097. GetDataRequest request = new GetDataRequest();
  1098. request.setPath(serverPath);
  1099. request.setWatch(watcher != null);
  1100. GetDataResponse response = new GetDataResponse();
  1101. ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
  1102. if (r.getErr() != 0) {
  1103. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  1104. clientPath);
  1105. }
  1106. if (stat != null) {
  1107. DataTree.copyStat(response.getStat(), stat);
  1108. }
  1109. return response.getData();
  1110. }
  1111. /**
  1112. * Return the data and the stat of the node of the given path.
  1113. * <p>
  1114. * If the watch is true and the call is successful (no exception is
  1115. * thrown), a watch will be left on the node with the given path. The watch
  1116. * will be triggered by a successful operation that sets data on the node, or
  1117. * deletes the node.
  1118. * <p>
  1119. * A KeeperException with error code KeeperException.NoNode will be thrown
  1120. * if no node with the given path exists.
  1121. *
  1122. * @param path the given path
  1123. * @param watch whether need to watch this node
  1124. * @param stat the stat of the node
  1125. * @return the data of the node
  1126. * @throws KeeperException If the server signals an error with a non-zero error code
  1127. * @throws InterruptedException If the server transaction is interrupted.
  1128. */
  1129. public byte[] getData(String path, boolean watch, Stat stat)
  1130. throws KeeperException, InterruptedException {
  1131. return getData(path, watch ? watchManager.defaultWatcher : null, stat);
  1132. }
  1133. /**
  1134. * The asynchronous version of getData.
  1135. *
  1136. * @see #getData(String, Watcher, Stat)
  1137. */
  1138. public void getData(final String path, Watcher watcher,
  1139. DataCallback cb, Object ctx)
  1140. {
  1141. final String clientPath = path;
  1142. PathUtils.validatePath(clientPath);
  1143. // the watch contains the un-chroot path
  1144. WatchRegistration wcb = null;
  1145. if (watcher != null) {
  1146. wcb = new DataWatchRegistration(watcher, clientPath);
  1147. }
  1148. final String serverPath = prependChroot(clientPath);
  1149. RequestHeader h = new RequestHeader();
  1150. h.setType(ZooDefs.OpCode.getData);
  1151. GetDataRequest request = new GetDataRequest();
  1152. request.setPath(serverPath);
  1153. request.setWatch(watcher != null);
  1154. GetDataResponse response = new GetDataResponse();
  1155. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1156. clientPath, serverPath, ctx, wcb);
  1157. }
  1158. /**
  1159. * The asynchronous version of getData.
  1160. *
  1161. * @see #getData(String, boolean, Stat)
  1162. */
  1163. public void getData(String path, boolean watch, DataCallback cb, Object ctx) {
  1164. getData(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
  1165. }
  1166. /**
  1167. * Set the data for the node of the given path if such a node exists and the
  1168. * given version matches the version of the node (if the given version is
  1169. * -1, it matches any node's versions). Return the stat of the node.
  1170. * <p>
  1171. * This operation, if successful, will trigger all the watches on the node
  1172. * of the given path left by getData calls.
  1173. * <p>
  1174. * A KeeperException with error code KeeperException.NoNode will be thrown
  1175. * if no node with the given path exists.
  1176. * <p>
  1177. * A KeeperException with error code KeeperException.BadVersion will be
  1178. * thrown if the given version does not match the node's version.
  1179. * <p>
  1180. * The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
  1181. * Arrays larger than this will cause a KeeperException to be thrown.
  1182. *
  1183. * @param path
  1184. * the path of the node
  1185. * @param data
  1186. * the data to set
  1187. * @param version
  1188. * the expected matching version
  1189. * @return the state of the node
  1190. * @throws InterruptedException If the server transaction is interrupted.
  1191. * @throws KeeperException If the server signals an error with a non-zero error code.
  1192. * @throws IllegalArgumentException if an invalid path is specified
  1193. */
  1194. public Stat setData(final String path, byte data[], int version)
  1195. throws KeeperException, InterruptedException
  1196. {
  1197. final String clientPath = path;
  1198. PathUtils.validatePath(clientPath);
  1199. final String serverPath = prependChroot(clientPath);
  1200. RequestHeader h = new RequestHeader();
  1201. h.setType(ZooDefs.OpCode.setData);
  1202. SetDataRequest request = new SetDataRequest();
  1203. request.setPath(serverPath);
  1204. request.setData(data);
  1205. request.setVersion(version);
  1206. SetDataResponse response = new SetDataResponse();
  1207. ReplyHeader r = cnxn.submitRequest(h, request, response, null);
  1208. if (r.getErr() != 0) {
  1209. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  1210. clientPath);
  1211. }
  1212. return response.getStat();
  1213. }
  1214. /**
  1215. * The asynchronous version of setData.
  1216. *
  1217. * @see #setData(String, byte[], int)
  1218. */
  1219. public void setData(final String path, byte data[], int version,
  1220. StatCallback cb, Object ctx)
  1221. {
  1222. final String clientPath = path;
  1223. PathUtils.validatePath(clientPath);
  1224. final String serverPath = prependChroot(clientPath);
  1225. RequestHeader h = new RequestHeader();
  1226. h.setType(ZooDefs.OpCode.setData);
  1227. SetDataRequest request = new SetDataRequest();
  1228. request.setPath(serverPath);
  1229. request.setData(data);
  1230. request.setVersion(version);
  1231. SetDataResponse response = new SetDataResponse();
  1232. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1233. clientPath, serverPath, ctx, null);
  1234. }
  1235. /**
  1236. * Return the ACL and stat of the node of the given path.
  1237. * <p>
  1238. * A KeeperException with error code KeeperException.NoNode will be thrown
  1239. * if no node with the given path exists.
  1240. *
  1241. * @param path
  1242. * the given path for the node
  1243. * @param stat
  1244. * the stat of the node will be copied to this parameter if
  1245. * not null.
  1246. * @return the ACL array of the given node.
  1247. * @throws InterruptedException If the server transaction is interrupted.
  1248. * @throws KeeperException If the server signals an error with a non-zero error code.
  1249. * @throws IllegalArgumentException if an invalid path is specified
  1250. */
  1251. public List<ACL> getACL(final String path, Stat stat)
  1252. throws KeeperException, InterruptedException
  1253. {
  1254. final String clientPath = path;
  1255. PathUtils.validatePath(clientPath);
  1256. final String serverPath = prependChroot(clientPath);
  1257. RequestHeader h = new RequestHeader();
  1258. h.setType(ZooDefs.OpCode.getACL);
  1259. GetACLRequest request = new GetACLRequest();
  1260. request.setPath(serverPath);
  1261. GetACLResponse response = new GetACLResponse();
  1262. ReplyHeader r = cnxn.submitRequest(h, request, response, null);
  1263. if (r.getErr() != 0) {
  1264. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  1265. clientPath);
  1266. }
  1267. if (stat != null) {
  1268. DataTree.copyStat(response.getStat(), stat);
  1269. }
  1270. return response.getAcl();
  1271. }
  1272. /**
  1273. * The asynchronous version of getACL.
  1274. *
  1275. * @see #getACL(String, Stat)
  1276. */
  1277. public void getACL(final String path, Stat stat, ACLCallback cb,
  1278. Object ctx)
  1279. {
  1280. final String clientPath = path;
  1281. PathUtils.validatePath(clientPath);
  1282. final String serverPath = prependChroot(clientPath);
  1283. RequestHeader h = new RequestHeader();
  1284. h.setType(ZooDefs.OpCode.getACL);
  1285. GetACLRequest request = new GetACLRequest();
  1286. request.setPath(serverPath);
  1287. GetACLResponse response = new GetACLResponse();
  1288. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1289. clientPath, serverPath, ctx, null);
  1290. }
  1291. /**
  1292. * Set the ACL for the node of the given path if such a node exists and the
  1293. * given version matches the version of the node. Return the stat of the
  1294. * node.
  1295. * <p>
  1296. * A KeeperException with error code KeeperException.NoNode will be thrown
  1297. * if no node with the given path exists.
  1298. * <p>
  1299. * A KeeperException with error code KeeperException.BadVersion will be
  1300. * thrown if the given version does not match the node's version.
  1301. *
  1302. * @param path
  1303. * @param acl
  1304. * @param version
  1305. * @return the stat of the node.
  1306. * @throws InterruptedException If the server transaction is interrupted.
  1307. * @throws KeeperException If the server signals an error with a non-zero error code.
  1308. * @throws org.apache.zookeeper.KeeperException.InvalidACLException If the acl is invalide.
  1309. * @throws IllegalArgumentException if an invalid path is specified
  1310. */
  1311. public Stat setACL(final String path, List<ACL> acl, int version)
  1312. throws KeeperException, InterruptedException
  1313. {
  1314. final String clientPath = path;
  1315. PathUtils.validatePath(clientPath);
  1316. final String serverPath = prependChroot(clientPath);
  1317. RequestHeader h = new RequestHeader();
  1318. h.setType(ZooDefs.OpCode.setACL);
  1319. SetACLRequest request = new SetACLRequest();
  1320. request.setPath(serverPath);
  1321. if (acl != null && acl.size() == 0) {
  1322. throw new KeeperException.InvalidACLException(clientPath);
  1323. }
  1324. request.setAcl(acl);
  1325. request.setVersion(version);
  1326. SetACLResponse response = new SetACLResponse();
  1327. ReplyHeader r = cnxn.submitRequest(h, request, response, null);
  1328. if (r.getErr() != 0) {
  1329. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  1330. clientPath);
  1331. }
  1332. return response.getStat();
  1333. }
  1334. /**
  1335. * The asynchronous version of setACL.
  1336. *
  1337. * @see #setACL(String, List, int)
  1338. */
  1339. public void setACL(final String path, List<ACL> acl, int version,
  1340. StatCallback cb, Object ctx)
  1341. {
  1342. final String clientPath = path;
  1343. PathUtils.validatePath(clientPath);
  1344. final String serverPath = prependChroot(clientPath);
  1345. RequestHeader h = new RequestHeader();
  1346. h.setType(ZooDefs.OpCode.setACL);
  1347. SetACLRequest request = new SetACLRequest();
  1348. request.setPath(serverPath);
  1349. request.setAcl(acl);
  1350. request.setVersion(version);
  1351. SetACLResponse response = new SetACLResponse();
  1352. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1353. clientPath, serverPath, ctx, null);
  1354. }
  1355. /**
  1356. * Return the list of the children of the node of the given path.
  1357. * <p>
  1358. * If the watch is non-null and the call is successful (no exception is thrown),
  1359. * a watch will be left on the node with the given path. The watch willbe
  1360. * triggered by a successful operation that deletes the node of the given
  1361. * path or creates/delete a child under the node.
  1362. * <p>
  1363. * The list of children returned is not sorted and no guarantee is provided
  1364. * as to its natural or lexical order.
  1365. * <p>
  1366. * A KeeperException with error code KeeperException.NoNode will be thrown
  1367. * if no node with the given path exists.
  1368. *
  1369. * @param path
  1370. * @param watcher explicit watcher
  1371. * @return an unordered array of children of the node with the given path
  1372. * @throws InterruptedException If the server transaction is interrupted.
  1373. * @throws KeeperException If the server signals an error with a non-zero error code.
  1374. * @throws IllegalArgumentException if an invalid path is specified
  1375. */
  1376. public List<String> getChildren(final String path, Watcher watcher)
  1377. throws KeeperException, InterruptedException
  1378. {
  1379. final String clientPath = path;
  1380. PathUtils.validatePath(clientPath);
  1381. // the watch contains the un-chroot path
  1382. WatchRegistration wcb = null;
  1383. if (watcher != null) {
  1384. wcb = new ChildWatchRegistration(watcher, clientPath);
  1385. }
  1386. final String serverPath = prependChroot(clientPath);
  1387. RequestHeader h = new RequestHeader();
  1388. h.setType(ZooDefs.OpCode.getChildren);
  1389. GetChildrenRequest request = new GetChildrenRequest();
  1390. request.setPath(serverPath);
  1391. request.setWatch(watcher != null);
  1392. GetChildrenResponse response = new GetChildrenResponse();
  1393. ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
  1394. if (r.getErr() != 0) {
  1395. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  1396. clientPath);
  1397. }
  1398. return response.getChildren();
  1399. }
  1400. /**
  1401. * Return the list of the children of the node of the given path.
  1402. * <p>
  1403. * If the watch is true and the call is successful (no exception is thrown),
  1404. * a watch will be left on the node with the given path. The watch willbe
  1405. * triggered by a successful operation that deletes the node of the given
  1406. * path or creates/delete a child under the node.
  1407. * <p>
  1408. * The list of children returned is not sorted and no guarantee is provided
  1409. * as to its natural or lexical order.
  1410. * <p>
  1411. * A KeeperException with error code KeeperException.NoNode will be thrown
  1412. * if no node with the given path exists.
  1413. *
  1414. * @param path
  1415. * @param watch
  1416. * @return an unordered array of children of the node with the given path
  1417. * @throws InterruptedException If the server transaction is interrupted.
  1418. * @throws KeeperException If the server signals an error with a non-zero error code.
  1419. */
  1420. public List<String> getChildren(String path, boolean watch)
  1421. throws KeeperException, InterruptedException {
  1422. return getChildren(path, watch ? watchManager.defaultWatcher : null);
  1423. }
  1424. /**
  1425. * The asynchronous version of getChildren.
  1426. *
  1427. * @see #getChildren(String, Watcher)
  1428. */
  1429. public void getChildren(final String path, Watcher watcher,
  1430. ChildrenCallback cb, Object ctx)
  1431. {
  1432. final String clientPath = path;
  1433. PathUtils.validatePath(clientPath);
  1434. // the watch contains the un-chroot path
  1435. WatchRegistration wcb = null;
  1436. if (watcher != null) {
  1437. wcb = new ChildWatchRegistration(watcher, clientPath);
  1438. }
  1439. final String serverPath = prependChroot(clientPath);
  1440. RequestHeader h = new RequestHeader();
  1441. h.setType(ZooDefs.OpCode.getChildren);
  1442. GetChildrenRequest request = new GetChildrenRequest();
  1443. request.setPath(serverPath);
  1444. request.setWatch(watcher != null);
  1445. GetChildrenResponse response = new GetChildrenResponse();
  1446. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1447. clientPath, serverPath, ctx, wcb);
  1448. }
  1449. /**
  1450. * The asynchronous version of getChildren.
  1451. *
  1452. * @see #getChildren(String, boolean)
  1453. */
  1454. public void getChildren(String path, boolean watch, ChildrenCallback cb,
  1455. Object ctx)
  1456. {
  1457. getChildren(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
  1458. }
  1459. /**
  1460. * For the given znode path return the stat and children list.
  1461. * <p>
  1462. * If the watch is non-null and the call is successful (no exception is thrown),
  1463. * a watch will be left on the node with the given path. The watch willbe
  1464. * triggered by a successful operation that deletes the node of the given
  1465. * path or creates/delete a child under the node.
  1466. * <p>
  1467. * The list of children returned is not sorted and no guarantee is provided
  1468. * as to its natural or lexical order.
  1469. * <p>
  1470. * A KeeperException with error code KeeperException.NoNode will be thrown
  1471. * if no node with the given path exists.
  1472. *
  1473. * @since 3.3.0
  1474. *
  1475. * @param path
  1476. * @param watcher explicit watcher
  1477. * @param stat stat of the znode designated by path
  1478. * @return an unordered array of children of the node with the given path
  1479. * @throws InterruptedException If the server transaction is interrupted.
  1480. * @throws KeeperException If the server signals an error with a non-zero error code.
  1481. * @throws IllegalArgumentException if an invalid path is specified
  1482. */
  1483. public List<String> getChildren(final String path, Watcher watcher,
  1484. Stat stat)
  1485. throws KeeperException, InterruptedException
  1486. {
  1487. final String clientPath = path;
  1488. PathUtils.validatePath(clientPath);
  1489. // the watch contains the un-chroot path
  1490. WatchRegistration wcb = null;
  1491. if (watcher != null) {
  1492. wcb = new ChildWatchRegistration(watcher, clientPath);
  1493. }
  1494. final String serverPath = prependChroot(clientPath);
  1495. RequestHeader h = new RequestHeader();
  1496. h.setType(ZooDefs.OpCode.getChildren2);
  1497. GetChildren2Request request = new GetChildren2Request();
  1498. request.setPath(serverPath);
  1499. request.setWatch(watcher != null);
  1500. GetChildren2Response response = new GetChildren2Response();
  1501. ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
  1502. if (r.getErr() != 0) {
  1503. throw KeeperException.create(KeeperException.Code.get(r.getErr()),
  1504. clientPath);
  1505. }
  1506. if (stat != null) {
  1507. DataTree.copyStat(response.getStat(), stat);
  1508. }
  1509. return response.getChildren();
  1510. }
  1511. /**
  1512. * For the given znode path return the stat and children list.
  1513. * <p>
  1514. * If the watch is true and the call is successful (no exception is thrown),
  1515. * a watch will be left on the node with the given path. The watch willbe
  1516. * triggered by a successful operation that deletes the node of the given
  1517. * path or creates/delete a child under the node.
  1518. * <p>
  1519. * The list of children returned is not sorted and no guarantee is provided
  1520. * as to its natural or lexical order.
  1521. * <p>
  1522. * A KeeperException with error code KeeperException.NoNode will be thrown
  1523. * if no node with the given path exists.
  1524. *
  1525. * @since 3.3.0
  1526. *
  1527. * @param path
  1528. * @param watch
  1529. * @param stat stat of the znode designated by path
  1530. * @return an unordered array of children of the node with the given path
  1531. * @throws InterruptedException If the server transaction is interrupted.
  1532. * @throws KeeperException If the server signals an error with a non-zero
  1533. * error code.
  1534. */
  1535. public List<String> getChildren(String path, boolean watch, Stat stat)
  1536. throws KeeperException, InterruptedException {
  1537. return getChildren(path, watch ? watchManager.defaultWatcher : null,
  1538. stat);
  1539. }
  1540. /**
  1541. * The asynchronous version of getChildren.
  1542. *
  1543. * @since 3.3.0
  1544. *
  1545. * @see #getChildren(String, Watcher, Stat)
  1546. */
  1547. public void getChildren(final String path, Watcher watcher,
  1548. Children2Callback cb, Object ctx)
  1549. {
  1550. final String clientPath = path;
  1551. PathUtils.validatePath(clientPath);
  1552. // the watch contains the un-chroot path
  1553. WatchRegistration wcb = null;
  1554. if (watcher != null) {
  1555. wcb = new ChildWatchRegistration(watcher, clientPath);
  1556. }
  1557. final String serverPath = prependChroot(clientPath);
  1558. RequestHeader h = new RequestHeader();
  1559. h.setType(ZooDefs.OpCode.getChildren2);
  1560. GetChildren2Request request = new GetChildren2Request();
  1561. request.setPath(serverPath);
  1562. request.setWatch(watcher != null);
  1563. GetChildren2Response response = new GetChildren2Response();
  1564. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1565. clientPath, serverPath, ctx, wcb);
  1566. }
  1567. /**
  1568. * The asynchronous version of getChildren.
  1569. *
  1570. * @since 3.3.0
  1571. *
  1572. * @see #getChildren(String, boolean, Stat)
  1573. */
  1574. public void getChildren(String path, boolean watch, Children2Callback cb,
  1575. Object ctx)
  1576. {
  1577. getChildren(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
  1578. }
  1579. /**
  1580. * Asynchronous sync. Flushes channel between process and leader.
  1581. * @param path
  1582. * @param cb a handler for the callback
  1583. * @param ctx context to be provided to the callback
  1584. * @throws IllegalArgumentException if an invalid path is specified
  1585. */
  1586. public void sync(final String path, VoidCallback cb, Object ctx){
  1587. final String clientPath = path;
  1588. PathUtils.validatePath(clientPath);
  1589. final String serverPath = prependChroot(clientPath);
  1590. RequestHeader h = new RequestHeader();
  1591. h.setType(ZooDefs.OpCode.sync);
  1592. SyncRequest request = new SyncRequest();
  1593. SyncResponse response = new SyncResponse();
  1594. request.setPath(serverPath);
  1595. cnxn.queuePacket(h, new ReplyHeader(), request, response, cb,
  1596. clientPath, serverPath, ctx, null);
  1597. }
  1598. public States getState() {
  1599. return cnxn.getState();
  1600. }
  1601. /**
  1602. * String representation of this ZooKeeper client. Suitable for things
  1603. * like logging.
  1604. *
  1605. * Do NOT count on the format of this string, it may change without
  1606. * warning.
  1607. *
  1608. * @since 3.3.0
  1609. */
  1610. @Override
  1611. public String toString() {
  1612. States state = getState();
  1613. return ("State:" + state.toString()
  1614. + (state.isConnected() ?
  1615. " Timeout:" + getSessionTimeout() + " " :
  1616. " ")
  1617. + cnxn);
  1618. }
  1619. /*
  1620. * Methods to aid in testing follow.
  1621. *
  1622. * THESE METHODS ARE EXPECTED TO BE USED FOR TESTING ONLY!!!
  1623. */
  1624. /**
  1625. * Wait up to wait milliseconds for the underlying threads to shutdown.
  1626. * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
  1627. *
  1628. * @since 3.3.0
  1629. *
  1630. * @param wait max wait in milliseconds
  1631. * @return true iff all threads are shutdown, otw false
  1632. */
  1633. protected boolean testableWaitForShutdown(int wait)
  1634. throws InterruptedException
  1635. {
  1636. cnxn.sendThread.join(wait);
  1637. if (cnxn.sendThread.isAlive()) return false;
  1638. cnxn.eventThread.join(wait);
  1639. if (cnxn.eventThread.isAlive()) return false;
  1640. return true;
  1641. }
  1642. /**
  1643. * Returns the address to which the socket is connected. Useful for testing
  1644. * against an ensemble - test client may need to know which server
  1645. * to shutdown if interested in verifying that the code handles
  1646. * disconnection/reconnection correctly.
  1647. * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
  1648. *
  1649. * @since 3.3.0
  1650. *
  1651. * @return ip address of the remote side of the connection or null if
  1652. * not connected
  1653. */
  1654. protected SocketAddress testableRemoteSocketAddress() {
  1655. return cnxn.sendThread.getClientCnxnSocket().getRemoteSocketAddress();
  1656. }
  1657. /**
  1658. * Returns the local address to which the socket is bound.
  1659. * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
  1660. *
  1661. * @since 3.3.0
  1662. *
  1663. * @return ip address of the remote side of the connection or null if
  1664. * not connected
  1665. */
  1666. protected SocketAddress testableLocalSocketAddress() {
  1667. return cnxn.sendThread.getClientCnxnSocket().getLocalSocketAddress();
  1668. }
  1669. private static ClientCnxnSocket getClientCnxnSocket() throws IOException {
  1670. String clientCnxnSocketName = System
  1671. .getProperty(ZOOKEEPER_CLIENT_CNXN_SOCKET);
  1672. if (clientCnxnSocketName == null) {
  1673. clientCnxnSocketName = ClientCnxnSocketNIO.class.getName();
  1674. }
  1675. try {
  1676. return (ClientCnxnSocket) Class.forName(clientCnxnSocketName)
  1677. .newInstance();
  1678. } catch (Exception e) {
  1679. IOException ioe = new IOException("Couldn't instantiate "
  1680. + clientCnxnSocketName);
  1681. ioe.initCause(e);
  1682. throw ioe;
  1683. }
  1684. }
  1685. }

注:Zookeeper的用法基本上都可以在这个类里面找到。

Zookeeper构造函数实例

  1. package com.github.boonya.zookeeper;
  2. import java.io.IOException;
  3. import org.apache.zookeeper.Watcher;
  4. import org.apache.zookeeper.ZooKeeper;
  5. /**
  6. * Zookeeper构造参数类
  7. *
  8. * @package com.github.boonya.zookeeper.ZkZookeeper
  9. * @date 2017年3月28日 上午10:48:24
  10. * @author pengjunlin
  11. * @comment
  12. * @update
  13. */
  14. public class ZkZookeeper extends ZooKeeper {
  15. /**
  16. *
  17. * @param connectString
  18. * ip:port
  19. * @param sessionTimeout
  20. * @param watcher
  21. * @param sessionId
  22. * @param sessionPasswd
  23. * @param canBeReadOnly
  24. * @throws IOException
  25. */
  26. public ZkZookeeper(String connectString, int sessionTimeout,
  27. Watcher watcher, long sessionId, byte[] sessionPasswd,
  28. boolean canBeReadOnly) throws IOException {
  29. super(connectString, sessionTimeout, watcher, sessionId, sessionPasswd,
  30. canBeReadOnly);
  31. // TODO Auto-generated constructor stub
  32. }
  33. /**
  34. *
  35. * @param connectString
  36. * ip:port
  37. * @param sessionTimeout
  38. * @param watcher
  39. * @param sessionId
  40. * @param sessionPasswd
  41. * @throws IOException
  42. */
  43. public ZkZookeeper(String connectString, int sessionTimeout,
  44. Watcher watcher, long sessionId, byte[] sessionPasswd)
  45. throws IOException {
  46. super(connectString, sessionTimeout, watcher, sessionId, sessionPasswd);
  47. // TODO Auto-generated constructor stub
  48. }
  49. /**
  50. *
  51. * @param connectString
  52. * ip:port
  53. * @param sessionTimeout
  54. * @param watcher
  55. * @param canBeReadOnly
  56. * @throws IOException
  57. */
  58. public ZkZookeeper(String connectString, int sessionTimeout,
  59. Watcher watcher, boolean canBeReadOnly) throws IOException {
  60. super(connectString, sessionTimeout, watcher, canBeReadOnly);
  61. // TODO Auto-generated constructor stub
  62. }
  63. /**
  64. *
  65. * @param connectString
  66. * ip:port
  67. * @param sessionTimeout
  68. * @param watcher
  69. * @throws IOException
  70. */
  71. public ZkZookeeper(String connectString, int sessionTimeout, Watcher watcher)
  72. throws IOException {
  73. super(connectString, sessionTimeout, watcher);
  74. // TODO Auto-generated constructor stub
  75. }
  76. }

Zookeeper支持四种构造实现。

参考资料

Zookeeper系列之二Zookeeper常用命令:https://my.oschina.net/u/347386/blog/313037


Zookeeper客户端API之会话创建:http://blog.csdn.net/wo541075754/article/details/61190967


声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号