System.exit(ExitCode.SERVER_EXCEPTION);
}
}
public void processPacket(ByteBuffer packet, Cnxn src) {
PacketHeader h = PacketHeader.fromInt(packet.getInt());
boolean success = false;
int statType = BKStats.STATS_UNKNOWN;
long startTime = 0;
if (isStatsEnabled) {
startTime = System.currentTimeMillis();
}
// packet format is different between ADDENTRY and READENTRY
long ledgerId = -1;
long entryId = BookieProtocol.INVALID_ENTRY_ID;
byte[] masterKey = null;
switch (h.getOpCode()) {
case BookieProtocol.ADDENTRY:
// first read master key
masterKey = new byte[BookieProtocol.MASTER_KEY_LENGTH];
packet.get(masterKey, 0, BookieProtocol.MASTER_KEY_LENGTH);
ByteBuffer bb = packet.duplicate();
ledgerId = bb.getLong();
entryId = bb.getLong();
break;
case BookieProtocol.READENTRY:
ledgerId = packet.getLong();
entryId = packet.getLong();
break;
}
if (h.getVersion() < BookieProtocol.LOWEST_COMPAT_PROTOCOL_VERSION
|| h.getVersion() > BookieProtocol.CURRENT_PROTOCOL_VERSION) {
LOG.error("Invalid protocol version, expected something between "
+ BookieProtocol.LOWEST_COMPAT_PROTOCOL_VERSION
+ " & " + BookieProtocol.CURRENT_PROTOCOL_VERSION
+ ". got " + h.getVersion());
src.sendResponse(buildResponse(BookieProtocol.EBADVERSION,
h.getVersion(), h.getOpCode(), ledgerId, entryId));
return;
}
short flags = h.getFlags();
switch (h.getOpCode()) {
case BookieProtocol.ADDENTRY:
statType = BKStats.STATS_ADD;
try {
TimedCnxn tsrc = new TimedCnxn(src, startTime);
// LOG.debug("Master key: " + new String(masterKey));
if ((flags & BookieProtocol.FLAG_RECOVERY_ADD) == BookieProtocol.FLAG_RECOVERY_ADD) {
bookie.recoveryAddEntry(packet.slice(), this, tsrc, masterKey);
} else {
bookie.addEntry(packet.slice(), this, tsrc, masterKey);
}
success = true;
} catch (IOException e) {
LOG.error("Error writing " + entryId + "@" + ledgerId, e);
src.sendResponse(buildResponse(BookieProtocol.EIO, h.getVersion(), h.getOpCode(), ledgerId, entryId));
} catch (BookieException.LedgerFencedException lfe) {
LOG.error("Attempt to write to fenced ledger", lfe);
src.sendResponse(buildResponse(BookieProtocol.EFENCED, h.getVersion(), h.getOpCode(), ledgerId, entryId));
} catch (BookieException e) {
LOG.error("Unauthorized access to ledger " + ledgerId, e);
src.sendResponse(buildResponse(BookieProtocol.EUA, h.getVersion(), h.getOpCode(), ledgerId, entryId));
}
break;
case BookieProtocol.READENTRY:
statType = BKStats.STATS_READ;
ByteBuffer[] rsp = new ByteBuffer[2];
LOG.debug("Received new read request: " + ledgerId + ", " + entryId);
int errorCode = BookieProtocol.EIO;
try {
if ((flags & BookieProtocol.FLAG_DO_FENCING) == BookieProtocol.FLAG_DO_FENCING) {
LOG.warn("Ledger " + ledgerId + " fenced by " + src.getPeerName());
if (h.getVersion() >= 2) {
masterKey = new byte[BookieProtocol.MASTER_KEY_LENGTH];
packet.get(masterKey, 0, BookieProtocol.MASTER_KEY_LENGTH);
bookie.fenceLedger(ledgerId, masterKey);
} else {
LOG.error("Password not provided, Not safe to fence {}", ledgerId);
throw BookieException.create(BookieException.Code.UnauthorizedAccessException);
}
}
rsp[1] = bookie.readEntry(ledgerId, entryId);
LOG.debug("##### Read entry ##### " + rsp[1].remaining());
errorCode = BookieProtocol.EOK;
success = true;
} catch (Bookie.NoLedgerException e) {
if (LOG.isTraceEnabled()) {
LOG.error("Error reading " + entryId + "@" + ledgerId, e);
}
errorCode = BookieProtocol.ENOLEDGER;
} catch (Bookie.NoEntryException e) {
if (LOG.isTraceEnabled()) {
LOG.error("Error reading " + entryId + "@" + ledgerId, e);
}
errorCode = BookieProtocol.ENOENTRY;
} catch (IOException e) {
if (LOG.isTraceEnabled()) {
LOG.error("Error reading " + entryId + "@" + ledgerId, e);
}
errorCode = BookieProtocol.EIO;
} catch (BookieException e) {
LOG.error("Unauthorized access to ledger " + ledgerId, e);
errorCode = BookieProtocol.EUA;
}
rsp[0] = buildResponse(errorCode, h.getVersion(), h.getOpCode(), ledgerId, entryId);
if (LOG.isTraceEnabled()) {
LOG.trace("Read entry rc = " + errorCode + " for " + entryId + "@" + ledgerId);
}
if (rsp[1] == null) {
// We haven't filled in entry data, so we have to send back
// the ledger and entry ids here
rsp[1] = ByteBuffer.allocate(16);
rsp[1].putLong(ledgerId);
rsp[1].putLong(entryId);
rsp[1].flip();
}
LOG.debug("Sending response for: " + entryId + ", " + new String(rsp[1].array()));
src.sendResponse(rsp);
break;
default:
src.sendResponse(buildResponse(BookieProtocol.EBADREQ, h.getVersion(), h.getOpCode(), ledgerId, entryId));
}
if (isStatsEnabled) {
if (success) {
// for add operations, we compute latency in writeComplete callbacks.
if (statType != BKStats.STATS_ADD) {