}
ServerCnxn cnxn = request.cnxn;
String lastOp = "NA";
decInProcess();
Code err = Code.OK;
Record rsp = null;
boolean closeSession = false;
try {
if (request.hdr != null && request.hdr.getType() == OpCode.error) {
throw KeeperException.create(KeeperException.Code
.get(((ErrorTxn) request.txn).getErr()));
}
KeeperException ke = request.getException();
if (ke != null) {
throw ke;
}
if (LOG.isDebugEnabled()) {
LOG.debug(request);
}
switch (request.type) {
case OpCode.ping: {
serverStats().updateLatency(request.createTime);
lastOp = "PING";
((CnxnStats) cnxn.getStats()).updateForResponse(request.cxid,
request.zxid, lastOp, request.createTime,
System.currentTimeMillis());
cnxn.sendResponse(new ReplyHeader(-2, getZKDatabase()
.getDataTreeLastProcessedZxid(), 0), null, "response");
return;
}
case OpCode.createSession: {
serverStats().updateLatency(request.createTime);
lastOp = "SESS";
((CnxnStats) cnxn.getStats()).updateForResponse(request.cxid,
request.zxid, lastOp, request.createTime,
System.currentTimeMillis());
cnxn.finishSessionInit(true);
return;
}
case OpCode.create: {
lastOp = "CREA";
rsp = new CreateResponse(rc.path);
err = Code.get(rc.err);
break;
}
case OpCode.delete: {
lastOp = "DELE";
err = Code.get(rc.err);
break;
}
case OpCode.setData: {
lastOp = "SETD";
rsp = new SetDataResponse(rc.stat);
err = Code.get(rc.err);
break;
}
case OpCode.setACL: {
lastOp = "SETA";
rsp = new SetACLResponse(rc.stat);
err = Code.get(rc.err);
break;
}
case OpCode.closeSession: {
lastOp = "CLOS";
closeSession = true;
err = Code.get(rc.err);
break;
}
case OpCode.sync: {
lastOp = "SYNC";
SyncRequest syncRequest = new SyncRequest();
ZooKeeperServer.byteBuffer2Record(request.request, syncRequest);
rsp = new SyncResponse(syncRequest.getPath());
break;
}
case OpCode.exists: {
lastOp = "EXIS";
// TODO we need to figure out the security requirement for this!
ExistsRequest existsRequest = new ExistsRequest();
ZooKeeperServer.byteBuffer2Record(request.request,
existsRequest);
String path = existsRequest.getPath();
if (path.indexOf('\0') != -1) {
throw new KeeperException.BadArgumentsException();
}
Stat stat = getZKDatabase().statNode(path,
existsRequest.getWatch() ? cnxn : null);
rsp = new ExistsResponse(stat);
break;
}
case OpCode.getData: {
lastOp = "GETD";
GetDataRequest getDataRequest = new GetDataRequest();
ZooKeeperServer.byteBuffer2Record(request.request,
getDataRequest);
DataNode n = getZKDatabase().getNode(getDataRequest.getPath());
if (n == null) {
throw new KeeperException.NoNodeException();
}
Long aclL;
synchronized (n) {
aclL = n.acl;
}
checkACL(getZKDatabase().convertLong(aclL), ZooDefs.Perms.READ,
request.authInfo);
Stat stat = new Stat();
byte b[] = getZKDatabase().getData(getDataRequest.getPath(),
stat, getDataRequest.getWatch() ? cnxn : null);
rsp = new GetDataResponse(b, stat);
break;
}
case OpCode.setWatches: {
lastOp = "SETW";
SetWatches setWatches = new SetWatches();
// XXX We really should NOT need this!!!!
request.request.rewind();
ZooKeeperServer.byteBuffer2Record(request.request, setWatches);
long relativeZxid = setWatches.getRelativeZxid();
getZKDatabase().setWatches(relativeZxid,
setWatches.getDataWatches(),
setWatches.getExistWatches(),
setWatches.getChildWatches(), cnxn);
break;
}
case OpCode.getACL: {
lastOp = "GETA";
GetACLRequest getACLRequest = new GetACLRequest();
ZooKeeperServer.byteBuffer2Record(request.request,
getACLRequest);
Stat stat = new Stat();
List<ACL> acl = getZKDatabase().getACL(getACLRequest.getPath(),
stat);
rsp = new GetACLResponse(acl, stat);
break;
}
case OpCode.getChildren: {
lastOp = "GETC";
GetChildrenRequest getChildrenRequest = new GetChildrenRequest();
ZooKeeperServer.byteBuffer2Record(request.request,
getChildrenRequest);
DataNode n = getZKDatabase().getNode(
getChildrenRequest.getPath());
if (n == null) {
throw new KeeperException.NoNodeException();
}
Long aclG;
synchronized (n) {
aclG = n.acl;
}
checkACL(getZKDatabase().convertLong(aclG), ZooDefs.Perms.READ,
request.authInfo);
List<String> children = getZKDatabase().getChildren(
getChildrenRequest.getPath(), null,
getChildrenRequest.getWatch() ? cnxn : null);
rsp = new GetChildrenResponse(children);
break;
}
case OpCode.getChildren2: {
lastOp = "GETC";
GetChildren2Request getChildren2Request = new GetChildren2Request();
ZooKeeperServer.byteBuffer2Record(request.request,
getChildren2Request);
Stat stat = new Stat();
DataNode n = getZKDatabase().getNode(
getChildren2Request.getPath());
if (n == null) {
throw new KeeperException.NoNodeException();
}
Long aclG;
synchronized (n) {
aclG = n.acl;
}
checkACL(getZKDatabase().convertLong(aclG), ZooDefs.Perms.READ,
request.authInfo);
List<String> children = getZKDatabase().getChildren(
getChildren2Request.getPath(), stat,
getChildren2Request.getWatch() ? cnxn : null);
rsp = new GetChildren2Response(children, stat);
break;
}
}
} catch (SessionMovedException e) {
// session moved is a connection level error, we need to tear
// down the connection otw ZOOKEEPER-710 might happen
// ie client on slow follower starts to renew session, fails
// before this completes, then tries the fast follower (leader)
// and is successful, however the initial renew is then
// successfully fwd/processed by the leader and as a result
// the client and leader disagree on where the client is most
// recently attached (and therefore invalid SESSION MOVED generated)
cnxn.sendCloseSession();
return;
} catch (KeeperException e) {
err = e.code();
} 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;
bb.rewind();
while (bb.hasRemaining()) {
sb.append(Integer.toHexString(bb.get() & 0xff));
}
LOG.error("Dumping request buffer: 0x" + sb.toString());
err = Code.MARSHALLINGERROR;
}
ReplyHeader hdr = new ReplyHeader(request.cxid, request.zxid,
err.intValue());
serverStats().updateLatency(request.createTime);
((CnxnStats) cnxn.getStats()).updateForResponse(request.cxid,
request.zxid, lastOp, request.createTime,
System.currentTimeMillis());