try {
Assert.assertEquals(0, o.self.getAcceptedEpoch());
Assert.assertEquals(0, o.self.getCurrentEpoch());
// Setup a database with a single /foo node
ZKDatabase zkDb = new ZKDatabase(new FileTxnSnapLog(tmpDir, tmpDir));
final long foo1Zxid = ZxidUtils.makeZxid(1, 1);
final long foo2Zxid = ZxidUtils.makeZxid(1, 2);
zkDb.processTxn(new TxnHeader(13, 1313, foo1Zxid, 33,
ZooDefs.OpCode.create), new CreateTxn("/foo1",
"data1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
false, 1));
zkDb.processTxn(new TxnHeader(13, 1313, foo2Zxid, 33,
ZooDefs.OpCode.create), new CreateTxn("/foo2",
"data1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
false, 1));
Stat stat = new Stat();
Assert.assertEquals("data1",
new String(zkDb.getData("/foo1", stat, null)));
Assert.assertEquals("data1",
new String(zkDb.getData("/foo2", stat, null)));
QuorumPacket qp = new QuorumPacket();
readPacketSkippingPing(ia, qp);
Assert.assertEquals(Leader.OBSERVERINFO, qp.getType());
Assert.assertEquals(qp.getZxid(), 0);
LearnerInfo learnInfo = new LearnerInfo();
ByteBufferInputStream.byteBuffer2Record(
ByteBuffer.wrap(qp.getData()), learnInfo);
Assert.assertEquals(learnInfo.getProtocolVersion(), 0x10000);
Assert.assertEquals(learnInfo.getServerid(), 0);
// We are simulating an established leader, so the epoch is 1
qp.setType(Leader.LEADERINFO);
qp.setZxid(ZxidUtils.makeZxid(1, 0));
byte protoBytes[] = new byte[4];
ByteBuffer.wrap(protoBytes).putInt(0x10000);
qp.setData(protoBytes);
oa.writeRecord(qp, null);
readPacketSkippingPing(ia, qp);
Assert.assertEquals(Leader.ACKEPOCH, qp.getType());
Assert.assertEquals(0, qp.getZxid());
Assert.assertEquals(ZxidUtils.makeZxid(0, 0), ByteBuffer
.wrap(qp.getData()).getInt());
Assert.assertEquals(1, o.self.getAcceptedEpoch());
Assert.assertEquals(0, o.self.getCurrentEpoch());
// Send the snapshot we created earlier
qp.setType(Leader.SNAP);
qp.setData(new byte[0]);
qp.setZxid(zkDb.getDataTreeLastProcessedZxid());
oa.writeRecord(qp, null);
zkDb.serializeSnapshot(oa);
oa.writeString("BenWasHere", null);
qp.setType(Leader.NEWLEADER);
qp.setZxid(ZxidUtils.makeZxid(1, 0));
oa.writeRecord(qp, null);
// Get the ack of the new leader
readPacketSkippingPing(ia, qp);
Assert.assertEquals(Leader.ACK, qp.getType());
Assert.assertEquals(ZxidUtils.makeZxid(1, 0), qp.getZxid());
Assert.assertEquals(1, o.self.getAcceptedEpoch());
Assert.assertEquals(1, o.self.getCurrentEpoch());
Assert.assertEquals(foo2Zxid, o.zk.getLastProcessedZxid());
// Make sure the data was recorded in the filesystem ok
ZKDatabase zkDb2 = new ZKDatabase(new FileTxnSnapLog(
logDir, snapDir));
long lastZxid = zkDb2.loadDataBase();
Assert.assertEquals("data1",
new String(zkDb2.getData("/foo1", stat, null)));
Assert.assertEquals(foo2Zxid, lastZxid);
// Register watch
TrackerWatcher watcher = new TrackerWatcher();
Assert.assertEquals("data1", new String(o.zk
.getZKDatabase().getData("/foo2", stat, watcher)));
// Propose /foo1 update
long proposalZxid = ZxidUtils.makeZxid(1, 1000);
proposeSetData(qp, "/foo1", proposalZxid, "data2", 2);
oa.writeRecord(qp, null);
// Commit /foo1 update
qp.setType(Leader.COMMIT);
qp.setZxid(proposalZxid);
oa.writeRecord(qp, null);
// Inform /foo2 update
long informZxid = ZxidUtils.makeZxid(1, 1001);
proposeSetData(qp, "/foo2", informZxid, "data2", 2);
qp.setType(Leader.INFORM);
oa.writeRecord(qp, null);
qp.setType(Leader.UPTODATE);
qp.setZxid(0);
oa.writeRecord(qp, null);
// Read the uptodate ack
readPacketSkippingPing(ia, qp);
Assert.assertEquals(Leader.ACK, qp.getType());
Assert.assertEquals(ZxidUtils.makeZxid(1, 0), qp.getZxid());
// Data should get updated
watcher.waitForChange();
Assert.assertEquals("data2", new String(o.zk
.getZKDatabase().getData("/foo1", stat, null)));
Assert.assertEquals("data2", new String(o.zk
.getZKDatabase().getData("/foo2", stat, null)));
// Shutdown sequence guarantee that all pending requests
// in sync request processor get flush to disk
o.zk.shutdown();
zkDb2 = new ZKDatabase(new FileTxnSnapLog(logDir, snapDir));
lastZxid = zkDb2.loadDataBase();
Assert.assertEquals("data2", new String(zkDb2.getData("/foo1", stat, null)));
Assert.assertEquals("data2", new String(zkDb2.getData("/foo2", stat, null)));
Assert.assertEquals(informZxid, lastZxid);
} finally {