*/
@SuppressWarnings("unchecked")
protected void pRequest(Request request) {
// 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);
CreateRequest createRequest = new CreateRequest();
ZooKeeperServer.byteBuffer2Record(request.request,
createRequest);
String path = createRequest.getPath();
int lastSlash = path.lastIndexOf('/');
if (lastSlash == -1 || path.indexOf('\0') != -1) {
throw new KeeperException.BadArgumentsException();
}
if (!fixupACL(request.authInfo, createRequest.getAcl())) {
throw new KeeperException.InvalidACLException();
}
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("%010d", parentCVersion);
}
try {
if (getRecordForPath(path) != null) {
throw new KeeperException.NodeExistsException();
}
} catch (KeeperException.NoNodeException e) {
// ignore this one
}
boolean ephemeralParent = parentRecord.stat.getEphemeralOwner() != 0;
if (ephemeralParent) {
throw new KeeperException.NoChildrenForEphemeralsException();
}
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);
DeleteRequest deleteRequest = new DeleteRequest();
ZooKeeperServer.byteBuffer2Record(request.request,
deleteRequest);
path = deleteRequest.getPath();
lastSlash = path.lastIndexOf('/');
if (lastSlash == -1 || path.indexOf('\0') != -1
|| path.equals("/")) {
throw new KeeperException.BadArgumentsException();
}
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();
}
if (nodeRecord.childCount > 0) {
throw new KeeperException.NotEmptyException();
}
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);
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();
}
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);
SetACLRequest setAclRequest = new SetACLRequest();
ZooKeeperServer.byteBuffer2Record(request.request,
setAclRequest);
if (!fixupACL(request.authInfo, setAclRequest.getAcl())) {
throw new KeeperException.InvalidACLException();
}
path = setAclRequest.getPath();
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();
}
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);
break;
case OpCode.closeSession:
txnHeader = new TxnHeader(request.sessionId, request.cxid, zks
.getNextZxid(), zks.getTime(), OpCode.closeSession);
HashSet<String> es = zks.dataTree
.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));
}
}
LOG.info("Processed session termination request for id: 0x"
+ Long.toHexString(request.sessionId));
break;
case OpCode.sync:
case OpCode.exists:
case OpCode.getData:
case OpCode.getACL:
case OpCode.getChildren:
case OpCode.ping:
case OpCode.setWatches:
break;
}
} catch (KeeperException e) {
if (txnHeader != null) {
txnHeader.setType(OpCode.error);
txn = new ErrorTxn(e.getCode());
}
} catch (Exception e) {
LOG.error("*********************************" + request);
StringBuffer sb = new StringBuffer();
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(sb.toString());
LOG.error("Unexpected exception", e);
if (txnHeader != null) {
txnHeader.setType(OpCode.error);
txn = new ErrorTxn(Code.MarshallingError);
}
}
request.hdr = txnHeader;
request.txn = txn;