public static String buildPath(String parent, String firstPart, String... restOfParts) { PathUtils.validatePath(parent); if (firstPart.contains("/")) throw new IllegalArgumentException("only parent may contain / character"); String path = (parent.equals("/") ? parent : parent + "/") + firstPart; for (String part : restOfParts) { if (part.contains("/")) throw new IllegalArgumentException("only parent may contain / character"); path = path + "/" + part; } PathUtils.validatePath(path); return path; }
/** * 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(); }
/** * 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()); } }
/** * 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(); }
/** * 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(); }
public static String getName(String path) { PathUtils.validatePath(path); if (path.equals("/")) { throw new IllegalArgumentException("name of / is undefined"); } final int index = path.lastIndexOf('/'); return path.substring(index + 1); }
public static String getParent(String path) { PathUtils.validatePath(path); if (path.equals("/")) { throw new IllegalArgumentException("parent of / is undefined"); } final int index = path.lastIndexOf('/'); if (index == 0) { return "/"; } return path.substring(0, index); }
/** * Asynchronous sync. Flushes channel between process and leader. * * @param path * @param cb a handler for the callback * @param ctx context to be provided to the callback * @throws IllegalArgumentException if an invalid path is specified */ public void sync(final String path, VoidCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.sync); SyncRequest request = new SyncRequest(); SyncResponse response = new SyncResponse(); request.setPath(serverPath); cnxn.queuePacket( h, new ReplyHeader(), request, response, cb, clientPath, serverPath, ctx, null); }
/** * The Asynchronous version of setData. The request doesn't actually until the asynchronous * callback is called. * * @see #setData(String, byte[], int) */ public void setData(final String path, byte data[], int version, StatCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.setData); SetDataRequest request = new SetDataRequest(); request.setPath(serverPath); request.setData(data); request.setVersion(version); SetDataResponse response = new SetDataResponse(); cnxn.queuePacket( h, new ReplyHeader(), request, response, cb, clientPath, serverPath, ctx, null); }
LockInternals( CuratorFramework client, LockInternalsDriver driver, String path, String lockName, int maxLeases) { this.driver = driver; this.lockName = lockName; this.maxLeases = maxLeases; PathUtils.validatePath(path); this.client = client; this.basePath = path; this.path = ZKPaths.makePath(path, lockName); ensurePath = client.newNamespaceAwareEnsurePath(basePath); }
/** * 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(); }
/** * The Asynchronous version of getData. The request doesn't actually until the asynchronous * callback is called. * * @see #getData(String, Watcher, Stat) */ public void getData(final String path, Watcher watcher, DataCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new DataWatchRegistration(watcher, clientPath); } final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getData); GetDataRequest request = new GetDataRequest(); request.setPath(serverPath); request.setWatch(watcher != null); GetDataResponse response = new GetDataResponse(); cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, clientPath, serverPath, ctx, wcb); }
/** * 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(); }
/** * The Asynchronous version of create. The request doesn't actually until the asynchronous * callback is called. * * @see #create(String, byte[], List, CreateMode) */ public void create( final String path, byte data[], List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath, createMode.isSequential()); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.create); CreateRequest request = new CreateRequest(); CreateResponse response = new CreateResponse(); ReplyHeader r = new ReplyHeader(); request.setData(data); request.setFlags(createMode.toFlag()); request.setPath(serverPath); request.setAcl(acl); cnxn.queuePacket(h, r, request, response, cb, clientPath, serverPath, ctx, null); }
/** * The Asynchronous version of delete. The request doesn't actually until the asynchronous * callback is called. * * @see #delete(String, int) */ public void delete(final String path, int version, VoidCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath; // maintain semantics even in chroot case // specifically - root cannot be deleted // I think this makes sense even in chroot case. if (clientPath.equals("/")) { // a bit of a hack, but delete(/) will never succeed and ensures // that the same semantics are maintained serverPath = clientPath; } else { serverPath = prependChroot(clientPath); } RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.delete); DeleteRequest request = new DeleteRequest(); request.setPath(serverPath); request.setVersion(version); cnxn.queuePacket(h, new ReplyHeader(), request, null, cb, clientPath, serverPath, ctx, null); }
/** * This method will be called inside the ProcessRequestThread, which is a singleton, so there will * be a single thread calling this code. * * @param request */ @SuppressWarnings("unchecked") protected void pRequest(Request request) throws RequestProcessorException { // LOG.info("Prep>>> cxid = " + request.cxid + " type = " + // request.type + " id = 0x" + Long.toHexString(request.sessionId)); TxnHeader txnHeader = null; Record txn = null; try { switch (request.type) { case OpCode.create: txnHeader = new TxnHeader( request.sessionId, request.cxid, zks.getNextZxid(), zks.getTime(), OpCode.create); zks.sessionTracker.checkSession(request.sessionId, request.getOwner()); CreateRequest createRequest = new CreateRequest(); ZooKeeperServer.byteBuffer2Record(request.request, createRequest); String path = createRequest.getPath(); int lastSlash = path.lastIndexOf('/'); if (lastSlash == -1 || path.indexOf('\0') != -1 || failCreate) { LOG.info( "Invalid path " + path + " with session 0x" + Long.toHexString(request.sessionId)); throw new KeeperException.BadArgumentsException(path); } if (!fixupACL(request.authInfo, createRequest.getAcl())) { throw new KeeperException.InvalidACLException(path); } String parentPath = path.substring(0, lastSlash); ChangeRecord parentRecord = getRecordForPath(parentPath); checkACL(zks, parentRecord.acl, ZooDefs.Perms.CREATE, request.authInfo); int parentCVersion = parentRecord.stat.getCversion(); CreateMode createMode = CreateMode.fromFlag(createRequest.getFlags()); if (createMode.isSequential()) { path = path + String.format(Locale.ENGLISH, "%010d", parentCVersion); } try { PathUtils.validatePath(path); } catch (IllegalArgumentException ie) { LOG.info( "Invalid path " + path + " with session 0x" + Long.toHexString(request.sessionId)); throw new KeeperException.BadArgumentsException(path); } try { if (getRecordForPath(path) != null) { throw new KeeperException.NodeExistsException(path); } } catch (KeeperException.NoNodeException e) { // ignore this one } boolean ephemeralParent = parentRecord.stat.getEphemeralOwner() != 0; if (ephemeralParent) { throw new KeeperException.NoChildrenForEphemeralsException(path); } txn = new CreateTxn( path, createRequest.getData(), createRequest.getAcl(), createMode.isEphemeral()); StatPersisted s = new StatPersisted(); if (createMode.isEphemeral()) { s.setEphemeralOwner(request.sessionId); } parentRecord = parentRecord.duplicate(txnHeader.getZxid()); parentRecord.childCount++; parentRecord.stat.setCversion(parentRecord.stat.getCversion() + 1); addChangeRecord(parentRecord); addChangeRecord( new ChangeRecord(txnHeader.getZxid(), path, s, 0, createRequest.getAcl())); break; case OpCode.delete: txnHeader = new TxnHeader( request.sessionId, request.cxid, zks.getNextZxid(), zks.getTime(), OpCode.delete); zks.sessionTracker.checkSession(request.sessionId, request.getOwner()); DeleteRequest deleteRequest = new DeleteRequest(); ZooKeeperServer.byteBuffer2Record(request.request, deleteRequest); path = deleteRequest.getPath(); lastSlash = path.lastIndexOf('/'); if (lastSlash == -1 || path.indexOf('\0') != -1 || zks.getZKDatabase().isSpecialPath(path)) { throw new KeeperException.BadArgumentsException(path); } parentPath = path.substring(0, lastSlash); parentRecord = getRecordForPath(parentPath); ChangeRecord nodeRecord = getRecordForPath(path); checkACL(zks, parentRecord.acl, ZooDefs.Perms.DELETE, request.authInfo); int version = deleteRequest.getVersion(); if (version != -1 && nodeRecord.stat.getVersion() != version) { throw new KeeperException.BadVersionException(path); } if (nodeRecord.childCount > 0) { throw new KeeperException.NotEmptyException(path); } txn = new DeleteTxn(path); parentRecord = parentRecord.duplicate(txnHeader.getZxid()); parentRecord.childCount--; parentRecord.stat.setCversion(parentRecord.stat.getCversion() + 1); addChangeRecord(parentRecord); addChangeRecord(new ChangeRecord(txnHeader.getZxid(), path, null, -1, null)); break; case OpCode.setData: txnHeader = new TxnHeader( request.sessionId, request.cxid, zks.getNextZxid(), zks.getTime(), OpCode.setData); zks.sessionTracker.checkSession(request.sessionId, request.getOwner()); SetDataRequest setDataRequest = new SetDataRequest(); ZooKeeperServer.byteBuffer2Record(request.request, setDataRequest); path = setDataRequest.getPath(); nodeRecord = getRecordForPath(path); checkACL(zks, nodeRecord.acl, ZooDefs.Perms.WRITE, request.authInfo); version = setDataRequest.getVersion(); int currentVersion = nodeRecord.stat.getVersion(); if (version != -1 && version != currentVersion) { throw new KeeperException.BadVersionException(path); } version = currentVersion + 1; txn = new SetDataTxn(path, setDataRequest.getData(), version); nodeRecord = nodeRecord.duplicate(txnHeader.getZxid()); nodeRecord.stat.setVersion(version); addChangeRecord(nodeRecord); break; case OpCode.setACL: txnHeader = new TxnHeader( request.sessionId, request.cxid, zks.getNextZxid(), zks.getTime(), OpCode.setACL); zks.sessionTracker.checkSession(request.sessionId, request.getOwner()); SetACLRequest setAclRequest = new SetACLRequest(); ZooKeeperServer.byteBuffer2Record(request.request, setAclRequest); path = setAclRequest.getPath(); if (!fixupACL(request.authInfo, setAclRequest.getAcl())) { throw new KeeperException.InvalidACLException(path); } nodeRecord = getRecordForPath(path); checkACL(zks, nodeRecord.acl, ZooDefs.Perms.ADMIN, request.authInfo); version = setAclRequest.getVersion(); currentVersion = nodeRecord.stat.getAversion(); if (version != -1 && version != currentVersion) { throw new KeeperException.BadVersionException(path); } version = currentVersion + 1; txn = new SetACLTxn(path, setAclRequest.getAcl(), version); nodeRecord = nodeRecord.duplicate(txnHeader.getZxid()); nodeRecord.stat.setAversion(version); addChangeRecord(nodeRecord); break; case OpCode.createSession: txnHeader = new TxnHeader( request.sessionId, request.cxid, zks.getNextZxid(), zks.getTime(), OpCode.createSession); request.request.rewind(); int to = request.request.getInt(); txn = new CreateSessionTxn(to); request.request.rewind(); zks.sessionTracker.addSession(request.sessionId, to); zks.setOwner(request.sessionId, request.getOwner()); break; case OpCode.closeSession: txnHeader = new TxnHeader( request.sessionId, request.cxid, zks.getNextZxid(), zks.getTime(), OpCode.closeSession); // We don't want to do this check since the session expiration thread // queues up this operation without being the session owner. // this request is the last of the session so it should be ok // zks.sessionTracker.checkSession(request.sessionId, request.getOwner()); HashSet<String> es = zks.getZKDatabase().getEphemerals(request.sessionId); synchronized (zks.outstandingChanges) { for (ChangeRecord c : zks.outstandingChanges) { if (c.stat == null) { // Doing a delete es.remove(c.path); } else if (c.stat.getEphemeralOwner() == request.sessionId) { es.add(c.path); } } for (String path2Delete : es) { addChangeRecord(new ChangeRecord(txnHeader.getZxid(), path2Delete, null, 0, null)); } zks.sessionTracker.setSessionClosing(request.sessionId); } LOG.info( "Processed session termination for sessionid: 0x" + Long.toHexString(request.sessionId)); break; case OpCode.sync: case OpCode.exists: case OpCode.getData: case OpCode.getACL: case OpCode.getChildren: case OpCode.getChildren2: case OpCode.ping: case OpCode.setWatches: zks.sessionTracker.checkSession(request.sessionId, request.getOwner()); break; } } catch (KeeperException e) { if (txnHeader != null) { txnHeader.setType(OpCode.error); txn = new ErrorTxn(e.code().intValue()); } LOG.info( "Got user-level KeeperException when processing " + request.toString() + " Error Path:" + e.getPath() + " Error:" + e.getMessage()); request.setException(e); } catch (Exception e) { // log at error level as we are returning a marshalling // error to the user LOG.error("Failed to process " + request, e); StringBuilder sb = new StringBuilder(); ByteBuffer bb = request.request; if (bb != null) { bb.rewind(); while (bb.hasRemaining()) { sb.append(Integer.toHexString(bb.get() & 0xff)); } } else { sb.append("request buffer is null"); } LOG.error("Dumping request buffer: 0x" + sb.toString()); if (txnHeader != null) { txnHeader.setType(OpCode.error); txn = new ErrorTxn(Code.MARSHALLINGERROR.intValue()); } } request.hdr = txnHeader; request.txn = txn; request.zxid = zks.getZxid(); nextProcessor.processRequest(request); }