public byte[] getData(String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException { RetryCounter retryCounter = retryCounterFactory.create(); while (true) { try { // 120227 by DaeJin Choi - What about Metadata of data ( ex: Magic // number and so on ) return zk.getData(path, watcher, stat); } catch (KeeperException e) { switch (e.code()) { case CONNECTIONLOSS: case OPERATIONTIMEOUT: LOG.warn("Possibly transient ZooKeeper exception: " + e); if (!retryCounter.shouldRetry()) { LOG.error( "ZooKeeper getData failed after " + retryCounter.getMaxRetries() + " retries"); throw e; } break; default: throw e; } } retryCounter.sleepUntilNextRetry(); retryCounter.useRetry(); } }
public List<String> getChildren(String path) throws KeeperException, InterruptedException { RetryCounter retryCounter = retryCounterFactory.create(); while (true) { try { return zk.getChildren(path, true); } catch (KeeperException e) { switch (e.code()) { case CONNECTIONLOSS: case OPERATIONTIMEOUT: LOG.warn("Possibly transient ZooKeeper exception: " + e); if (!retryCounter.shouldRetry()) { LOG.error( "ZooKeeper getChildren failed after " + retryCounter.getMaxRetries() + " retries"); throw e; } break; default: throw e; } } retryCounter.sleepUntilNextRetry(); retryCounter.useRetry(); } }
public String createEphemeralSequential(final String path, final byte[] data) throws Exception { RetryCounter retryCounter = retryCounterFactory.create(); while (true) { try { return zk.create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); } catch (KeeperException e) { switch (e.code()) { case CONNECTIONLOSS: case OPERATIONTIMEOUT: LOG.warn("Possibly transient ZooKeeper exception: " + e); if (!retryCounter.shouldRetry()) { LOG.error( "ZooKeeper create failed after " + retryCounter.getMaxRetries() + " retries"); throw e; } break; default: throw e; } } retryCounter.sleepUntilNextRetry(); retryCounter.useRetry(); } }
/** * Creates the serialized value of the object and stores this in ZooKeeper under the path. It * updates the lastStatusVersion. It does not set a watcher for the path. */ private void updateCoordinateData() throws CoordinateMissingException, CloudnameException { if (!started.get()) { throw new IllegalStateException("Not started."); } if (!zkClient.isConnected()) { throw new CloudnameException("No proper connection with zookeeper."); } synchronized (lastStatusVersionMonitor) { try { Stat stat = zkClient .getZookeeper() .setData( path, zkCoordinateData.snapshot().serialize().getBytes(Util.CHARSET_NAME), lastStatusVersion); LOG.fine("Updated coordinate, latest version is " + stat.getVersion()); lastStatusVersion = stat.getVersion(); } catch (KeeperException.NoNodeException e) { throw new CoordinateMissingException("Coordinate does not exist " + path); } catch (KeeperException e) { throw new CloudnameException( "ZooKeeper errror in updateCoordinateData: " + e.getMessage(), e); } catch (UnsupportedEncodingException e) { throw new CloudnameException(e); } catch (InterruptedException e) { throw new CloudnameException(e); } catch (IOException e) { throw new CloudnameException(e); } } }
@Override public void run() { if (isSynchronizedWithZooKeeper.get() || !zkClient.isConnected() || !started.get()) { return; } if (checkVersion.getAndSet(false)) { try { synchronized (lastStatusVersionMonitor) { final Stat stat = zkClient.getZookeeper().exists(path, null); if (stat != null && zkClient.getZookeeper().getSessionId() == stat.getEphemeralOwner()) { zkClient.getZookeeper().delete(path, lastStatusVersion); } } } catch (InterruptedException e) { LOG.info("Interrupted"); checkVersion.set(true); } catch (KeeperException e) { LOG.info("exception " + e.getMessage()); checkVersion.set(true); } } LOG.info( "We are out-of-sync, have a zookeeper connection, and are started, trying reclaim: " + path + this); tryClaim(); }
public void createPersistent(final String path, final byte[] data) throws KeeperException, InterruptedException { RetryCounter retryCounter = retryCounterFactory.create(); while (true) { try { zk.create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); return; } catch (KeeperException e) { switch (e.code()) { case CONNECTIONLOSS: case OPERATIONTIMEOUT: LOG.warn("Possibly transient ZooKeeper exception: " + e); if (!retryCounter.shouldRetry()) { LOG.error( "ZooKeeper create failed after " + retryCounter.getMaxRetries() + " retries"); throw e; } break; default: throw e; } } retryCounter.sleepUntilNextRetry(); retryCounter.useRetry(); } }
/** * Removes the lock or associated znode if you no longer require the lock. this also removes your * request in the queue for locking in case you do not already hold the lock. * * @throws RuntimeException throws a runtime exception if it cannot connect to zookeeper. */ public synchronized void unlock() throws RuntimeException { if (!isClosed() && id != null) { // we don't need to retry this operation in the case of failure // as ZK will remove ephemeral files and we don't wanna hang // this process when closing if we cannot reconnect to ZK try { ZooKeeperOperation zopdel = new ZooKeeperOperation() { public boolean execute() throws KeeperException, InterruptedException { zookeeper.delete(id, -1); return Boolean.TRUE; } }; zopdel.execute(); } catch (InterruptedException e) { LOG.warn("Caught: " + e, e); // set that we have been interrupted. Thread.currentThread().interrupt(); } catch (KeeperException.NoNodeException e) { // do nothing } catch (KeeperException e) { LOG.warn("Caught: " + e, e); throw (RuntimeException) new RuntimeException(e.getMessage()).initCause(e); } finally { if (callback != null) { callback.lockReleased(); } id = null; } } }
/** * Return the list of the children of the node of the given path. * * <p>If the watch is non-null and the call is successful (no exception is thrown), a watch will * be left on the node with the given path. The watch willbe triggered by a successful operation * that deletes the node of the given path or creates/delete a child under the node. * * <p>The list of children returned is not sorted and no guarantee is provided as to its natural * or lexical order. * * <p>A KeeperException with error code KeeperException.NoNode will be thrown if no node with the * given path exists. * * @param path * @param watcher explicit watcher * @return an unordered array of children of the node with the given path * @throws InterruptedException If the server transaction is interrupted. * @throws KeeperException If the server signals an error with a non-zero error code. * @throws IllegalArgumentException if an invalid path is specified */ public List<String> getChildren(final String path, Watcher watcher) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new ChildWatchRegistration(watcher, clientPath); } final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getChildren); GetChildrenRequest request = new GetChildrenRequest(); request.setPath(serverPath); request.setWatch(watcher != null); GetChildrenResponse response = new GetChildrenResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, wcb); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } return response.getChildren(); }
/** * Return the data and the stat of the node of the given path. * * <p>If the watch is non-null and the call is successful (no exception is thrown), a watch will * be left on the node with the given path. The watch will be triggered by a successful operation * that sets data on the node, or deletes the node. * * <p>A KeeperException with error code KeeperException.NoNode will be thrown if no node with the * given path exists. * * @param path the given path * @param watcher explicit watcher * @param stat the stat of the node * @return the data of the node * @throws KeeperException If the server signals an error with a non-zero error code * @throws InterruptedException If the server transaction is interrupted. * @throws IllegalArgumentException if an invalid path is specified */ public byte[] getData(final String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new DataWatchRegistration(watcher, clientPath); } final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getData); GetDataRequest request = new GetDataRequest(); request.setPath(serverPath); request.setWatch(watcher != null); GetDataResponse response = new GetDataResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, wcb); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } if (stat != null) { DataTree.copyStat(response.getStat(), stat); } return response.getData(); }
/** * Delete the node with the given path. The call will succeed if such a node exists, and the given * version matches the node's version (if the given version is -1, it matches any node's * versions). * * <p>A KeeperException with error code KeeperException.NoNode will be thrown if the nodes does * not exist. * * <p>A KeeperException with error code KeeperException.BadVersion will be thrown if the given * version does not match the node's version. * * <p>A KeeperException with error code KeeperException.NotEmpty will be thrown if the node has * children. * * <p>This operation, if successful, will trigger all the watches on the node of the given path * left by exists API calls, and the watches on the parent node left by getChildren API calls. * * @param path the path of the node to be deleted. * @param version the expected node version. * @throws InterruptedException IF the server transaction is interrupted * @throws KeeperException If the server signals an error with a non-zero return code. * @throws IllegalArgumentException if an invalid path is specified */ public void delete(final String path, int version) throws InterruptedException, KeeperException { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath; // maintain semantics even in chroot case // specifically - root cannot be deleted // I think this makes sense even in chroot case. if (clientPath.equals("/")) { // a bit of a hack, but delete(/) will never succeed and ensures // that the same semantics are maintained serverPath = clientPath; } else { serverPath = prependChroot(clientPath); } RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.delete); DeleteRequest request = new DeleteRequest(); request.setPath(serverPath); request.setVersion(version); ReplyHeader r = cnxn.submitRequest(h, request, null, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } }
/** * Return the stat of the node of the given path. Return null if no such a node exists. * * <p>If the watch is non-null and the call is successful (no exception is thrown), a watch will * be left on the node with the given path. The watch will be triggered by a successful operation * that creates/delete the node or sets the data on the node. * * @param path the node path * @param watcher explicit watcher * @return the stat of the node of the given path; return null if no such a node exists. * @throws KeeperException If the server signals an error * @throws InterruptedException If the server transaction is interrupted. * @throws IllegalArgumentException if an invalid path is specified */ public Stat exists(final String path, Watcher watcher) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new ExistsWatchRegistration(watcher, clientPath); } final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.exists); ExistsRequest request = new ExistsRequest(); request.setPath(serverPath); request.setWatch(watcher != null); SetDataResponse response = new SetDataResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, wcb); if (r.getErr() != 0) { if (r.getErr() == KeeperException.Code.NONODE.intValue()) { return null; } throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } return response.getStat().getCzxid() == -1 ? null : response.getStat(); }
/** * Create a node with the given path. The node data will be the given data, and node acl will be * the given acl. * * <p>The flags argument specifies whether the created node will be ephemeral or not. * * <p>An ephemeral node will be removed by the ZooKeeper automatically when the session associated * with the creation of the node expires. * * <p>The flags argument can also specify to create a sequential node. The actual path name of a * sequential node will be the given path plus a suffix "_i" where i is the current sequential * number of the node. Once such a node is created, the sequential number will be incremented by * one. * * <p>If a node with the same actual path already exists in the ZooKeeper, a KeeperException with * error code KeeperException.NodeExists will be thrown. Note that since a different actual path * is used for each invocation of creating sequential node with the same path argument, the call * will never throw "file exists" KeeperException. * * <p>If the parent node does not exist in the ZooKeeper, a KeeperException with error code * KeeperException.NoNode will be thrown. * * <p>An ephemeral node cannot have children. If the parent node of the given path is ephemeral, a * KeeperException with error code KeeperException.NoChildrenForEphemerals will be thrown. * * <p>This operation, if successful, will trigger all the watches left on the node of the given * path by exists and getData API calls, and the watches left on the parent node by getChildren * API calls. * * <p>If a node is created successfully, the ZooKeeper server will trigger the watches on the path * left by exists calls, and the watches on the parent of the node by getChildren calls. * * <p>The maximum allowable size of the data array is 1 MB (1,048,576 bytes). Arrays larger than * this will cause a KeeperExecption to be thrown. * * @param path the path for the node * @param data the initial data for the node * @param acl the acl for the node * @param createMode specifying whether the node to be created is ephemeral and/or sequential * @return the actual path of the created node * @throws KeeperException if the server returns a non-zero error code * @throws KeeperException.InvalidACLException if the ACL is invalid * @throws InterruptedException if the transaction is interrupted * @throws IllegalArgumentException if an invalid path is specified */ public String create(final String path, byte data[], List<ACL> acl, CreateMode createMode) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath, createMode.isSequential()); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.create); CreateRequest request = new CreateRequest(); CreateResponse response = new CreateResponse(); request.setData(data); request.setFlags(createMode.toFlag()); request.setPath(serverPath); if (acl != null && acl.size() == 0) { throw new KeeperException.InvalidACLException(); } request.setAcl(acl); ReplyHeader r = cnxn.submitRequest(h, request, response, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } if (cnxn.chrootPath == null) { return response.getPath(); } else { return response.getPath().substring(cnxn.chrootPath.length()); } }
public void leaveServer(String host) throws InterruptedException, KeeperException { RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.leave); LeaveRequest request = new LeaveRequest(); request.setHost(host); ReplyHeader r = cnxn.submitRequest(h, request, null, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), null); } }
public void joinServer(String host, int port, int election_port) throws InterruptedException, KeeperException { RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.join); JoinRequest request = new JoinRequest(); request.setPort(port); request.setElectionPort(election_port); request.setHost(host); ReplyHeader r = cnxn.submitRequest(h, request, null, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), null); } }
/** * Return the ACL and stat of the node of the given path. * * <p>A KeeperException with error code KeeperException.NoNode will be thrown if no node with the * given path exists. * * @param path the given path for the node * @param stat the stat of the node will be copied to this parameter. * @return the ACL array of the given node. * @throws InterruptedException If the server transaction is interrupted. * @throws KeeperException If the server signals an error with a non-zero error code. * @throws IllegalArgumentException if an invalid path is specified */ public List<ACL> getACL(final String path, Stat stat) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getACL); GetACLRequest request = new GetACLRequest(); request.setPath(serverPath); GetACLResponse response = new GetACLResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } DataTree.copyStat(response.getStat(), stat); return response.getAcl(); }
/** * Set the data for the node of the given path if such a node exists and the given version matches * the version of the node (if the given version is -1, it matches any node's versions). Return * the stat of the node. * * <p>This operation, if successful, will trigger all the watches on the node of the given path * left by getData calls. * * <p>A KeeperException with error code KeeperException.NoNode will be thrown if no node with the * given path exists. * * <p>A KeeperException with error code KeeperException.BadVersion will be thrown if the given * version does not match the node's version. * * <p>The maximum allowable size of the data array is 1 MB (1,048,576 bytes). Arrays larger than * this will cause a KeeperExecption to be thrown. * * @param path the path of the node * @param data the data to set * @param version the expected matching version * @return the state of the node * @throws InterruptedException If the server transaction is interrupted. * @throws KeeperException If the server signals an error with a non-zero error code. * @throws IllegalArgumentException if an invalid path is specified */ public Stat setData(final String path, byte data[], int version) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.setData); SetDataRequest request = new SetDataRequest(); request.setPath(serverPath); request.setData(data); request.setVersion(version); SetDataResponse response = new SetDataResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } return response.getStat(); }
/** * Set the ACL for the node of the given path if such a node exists and the given version matches * the version of the node. Return the stat of the node. * * <p>A KeeperException with error code KeeperException.NoNode will be thrown if no node with the * given path exists. * * <p>A KeeperException with error code KeeperException.BadVersion will be thrown if the given * version does not match the node's version. * * @param path * @param acl * @param version * @return the stat of the node. * @throws InterruptedException If the server transaction is interrupted. * @throws KeeperException If the server signals an error with a non-zero error code. * @throws org.apache.zookeeper.KeeperException.InvalidACLException If the acl is invalide. * @throws IllegalArgumentException if an invalid path is specified */ public Stat setACL(final String path, List<ACL> acl, int version) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.setACL); SetACLRequest request = new SetACLRequest(); request.setPath(serverPath); if (acl != null && acl.size() == 0) { throw new KeeperException.InvalidACLException(); } request.setAcl(acl); request.setVersion(version); SetACLResponse response = new SetACLResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } return response.getStat(); }
/** * Handles event from ZooKeeper for this coordinate. * * @param event */ @Override public void process(WatchedEvent event) { LOG.info("Got an event from ZooKeeper " + event.toString()); synchronized (lastStatusVersionMonitor) { switch (event.getType()) { case None: switch (event.getState()) { case SyncConnected: break; case Disconnected: case AuthFailed: case Expired: default: // If we lost connection, we don't attempt to register another watcher as // this might be blocking forever. Parent will try to reconnect (reclaim) // later. isSynchronizedWithZooKeeper.set(false); sendEventToCoordinateListener( CoordinateListener.Event.NO_CONNECTION_TO_STORAGE, event.toString()); return; } return; case NodeDeleted: // If node is deleted, we have no node to place a new watcher so we stop watching. isSynchronizedWithZooKeeper.set(false); sendEventToCoordinateListener(CoordinateListener.Event.NOT_OWNER, event.toString()); return; case NodeDataChanged: LOG.fine("Node data changed, check versions."); boolean verifiedSynchronized = false; try { final Stat stat = zkClient.getZookeeper().exists(path, this); if (stat == null) { LOG.info("Could not stat path, setting out of synch, will retry claim"); } else { LOG.fine("Previous version is " + lastStatusVersion + " now is " + stat.getVersion()); if (stat.getVersion() != lastStatusVersion) { LOG.fine("Version mismatch, sending out of sync."); } else { verifiedSynchronized = true; } } } catch (KeeperException e) { LOG.fine( "Problems with zookeeper, sending consistencyState out of sync: " + e.getMessage()); } catch (InterruptedException e) { LOG.fine("Got interrupted: " + e.getMessage()); return; } finally { isSynchronizedWithZooKeeper.set(verifiedSynchronized); } if (verifiedSynchronized) { sendEventToCoordinateListener( CoordinateListener.Event.COORDINATE_OUT_OF_SYNC, event.toString()); } return; case NodeChildrenChanged: case NodeCreated: // This should not happen.. isSynchronizedWithZooKeeper.set(false); sendEventToCoordinateListener( CoordinateListener.Event.COORDINATE_OUT_OF_SYNC, event.toString()); return; } } }