use of com.twitter.distributedlog.exceptions.ZKException in project distributedlog by twitter.
the class TestLedgerAllocator method testSuccessAllocatorShouldDeleteUnusedledger.
@Test(timeout = 60000)
public void testSuccessAllocatorShouldDeleteUnusedledger() throws Exception {
String allocationPath = "/allocation-delete-unused-ledger";
zkc.get().create(allocationPath, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
Stat stat = new Stat();
byte[] data = zkc.get().getData(allocationPath, false, stat);
Versioned<byte[]> allocationData = new Versioned<byte[]>(data, new ZkVersion(stat.getVersion()));
SimpleLedgerAllocator allocator1 = new SimpleLedgerAllocator(allocationPath, allocationData, newQuorumConfigProvider(dlConf), zkc, bkc);
allocator1.allocate();
// wait until allocated
ZKTransaction txn1 = newTxn();
LedgerHandle lh1 = FutureUtils.result(allocator1.tryObtain(txn1, NULL_LISTENER));
// Second allocator kicks in
stat = new Stat();
data = zkc.get().getData(allocationPath, false, stat);
allocationData = new Versioned<byte[]>(data, new ZkVersion(stat.getVersion()));
SimpleLedgerAllocator allocator2 = new SimpleLedgerAllocator(allocationPath, allocationData, newQuorumConfigProvider(dlConf), zkc, bkc);
allocator2.allocate();
// wait until allocated
ZKTransaction txn2 = newTxn();
LedgerHandle lh2 = FutureUtils.result(allocator2.tryObtain(txn2, NULL_LISTENER));
// should fail to commit txn1 as version is changed by second allocator
try {
FutureUtils.result(txn1.execute());
fail("Should fail commit obtaining ledger handle from first allocator as allocator is modified by second allocator.");
} catch (ZKException ke) {
// as expected
}
FutureUtils.result(txn2.execute());
Utils.close(allocator1);
Utils.close(allocator2);
// ledger handle should be deleted
try {
lh1.close();
fail("LedgerHandle allocated by allocator1 should be deleted.");
} catch (BKException bke) {
// as expected
}
try {
bkc.get().openLedger(lh1.getId(), BookKeeper.DigestType.CRC32, dlConf.getBKDigestPW().getBytes());
fail("LedgerHandle allocated by allocator1 should be deleted.");
} catch (BKException.BKNoSuchLedgerExistsException nslee) {
// as expected
}
long eid = lh2.addEntry("hello world".getBytes());
lh2.close();
LedgerHandle readLh = bkc.get().openLedger(lh2.getId(), BookKeeper.DigestType.CRC32, dlConf.getBKDigestPW().getBytes());
Enumeration<LedgerEntry> entries = readLh.readEntries(eid, eid);
int i = 0;
while (entries.hasMoreElements()) {
LedgerEntry entry = entries.nextElement();
assertEquals("hello world", new String(entry.getEntry(), UTF_8));
++i;
}
assertEquals(1, i);
}
use of com.twitter.distributedlog.exceptions.ZKException in project distributedlog by twitter.
the class ZKLogMetadataForWriter method createMissingMetadata.
static void createMissingMetadata(final ZooKeeper zk, final String logRootPath, final List<Versioned<byte[]>> metadatas, final List<ACL> acl, final boolean ownAllocator, final boolean createIfNotExists, final Promise<List<Versioned<byte[]>>> promise) {
final List<byte[]> pathsToCreate = Lists.newArrayListWithExpectedSize(metadatas.size());
final List<Op> zkOps = Lists.newArrayListWithExpectedSize(metadatas.size());
CreateMode createMode = CreateMode.PERSISTENT;
// log root parent path
if (pathExists(metadatas.get(MetadataIndex.LOG_ROOT_PARENT))) {
pathsToCreate.add(null);
} else {
String logRootParentPath = new File(logRootPath).getParent();
pathsToCreate.add(DistributedLogConstants.EMPTY_BYTES);
zkOps.add(Op.create(logRootParentPath, DistributedLogConstants.EMPTY_BYTES, acl, createMode));
}
// log root path
if (pathExists(metadatas.get(MetadataIndex.LOG_ROOT))) {
pathsToCreate.add(null);
} else {
pathsToCreate.add(DistributedLogConstants.EMPTY_BYTES);
zkOps.add(Op.create(logRootPath, DistributedLogConstants.EMPTY_BYTES, acl, createMode));
}
// max id
if (pathExists(metadatas.get(MetadataIndex.MAX_TXID))) {
pathsToCreate.add(null);
} else {
byte[] zeroTxnIdData = DLUtils.serializeTransactionId(0L);
pathsToCreate.add(zeroTxnIdData);
zkOps.add(Op.create(logRootPath + MAX_TXID_PATH, zeroTxnIdData, acl, createMode));
}
// version
if (pathExists(metadatas.get(MetadataIndex.VERSION))) {
pathsToCreate.add(null);
} else {
byte[] versionData = intToBytes(LAYOUT_VERSION);
pathsToCreate.add(versionData);
zkOps.add(Op.create(logRootPath + VERSION_PATH, versionData, acl, createMode));
}
// lock path
if (pathExists(metadatas.get(MetadataIndex.LOCK))) {
pathsToCreate.add(null);
} else {
pathsToCreate.add(DistributedLogConstants.EMPTY_BYTES);
zkOps.add(Op.create(logRootPath + LOCK_PATH, DistributedLogConstants.EMPTY_BYTES, acl, createMode));
}
// read lock path
if (pathExists(metadatas.get(MetadataIndex.READ_LOCK))) {
pathsToCreate.add(null);
} else {
pathsToCreate.add(DistributedLogConstants.EMPTY_BYTES);
zkOps.add(Op.create(logRootPath + READ_LOCK_PATH, DistributedLogConstants.EMPTY_BYTES, acl, createMode));
}
// log segments path
if (pathExists(metadatas.get(MetadataIndex.LOGSEGMENTS))) {
pathsToCreate.add(null);
} else {
byte[] logSegmentsData = DLUtils.serializeLogSegmentSequenceNumber(DistributedLogConstants.UNASSIGNED_LOGSEGMENT_SEQNO);
pathsToCreate.add(logSegmentsData);
zkOps.add(Op.create(logRootPath + LOGSEGMENTS_PATH, logSegmentsData, acl, createMode));
}
// allocation path
if (ownAllocator) {
if (pathExists(metadatas.get(MetadataIndex.ALLOCATION))) {
pathsToCreate.add(null);
} else {
pathsToCreate.add(DistributedLogConstants.EMPTY_BYTES);
zkOps.add(Op.create(logRootPath + ALLOCATION_PATH, DistributedLogConstants.EMPTY_BYTES, acl, createMode));
}
}
if (zkOps.isEmpty()) {
// nothing missed
promise.setValue(metadatas);
return;
}
if (!createIfNotExists) {
promise.setException(new LogNotFoundException("Log " + logRootPath + " not found"));
return;
}
zk.multi(zkOps, new AsyncCallback.MultiCallback() {
@Override
public void processResult(int rc, String path, Object ctx, List<OpResult> resultList) {
if (KeeperException.Code.OK.intValue() == rc) {
List<Versioned<byte[]>> finalMetadatas = Lists.newArrayListWithExpectedSize(metadatas.size());
for (int i = 0; i < pathsToCreate.size(); i++) {
byte[] dataCreated = pathsToCreate.get(i);
if (null == dataCreated) {
finalMetadatas.add(metadatas.get(i));
} else {
finalMetadatas.add(new Versioned<byte[]>(dataCreated, new ZkVersion(0)));
}
}
promise.setValue(finalMetadatas);
} else if (KeeperException.Code.NODEEXISTS.intValue() == rc) {
promise.setException(new LogExistsException("Someone just created log " + logRootPath));
} else {
if (LOG.isDebugEnabled()) {
StringBuilder builder = new StringBuilder();
for (OpResult result : resultList) {
if (result instanceof OpResult.ErrorResult) {
OpResult.ErrorResult errorResult = (OpResult.ErrorResult) result;
builder.append(errorResult.getErr()).append(",");
} else {
builder.append(0).append(",");
}
}
String resultCodeList = builder.substring(0, builder.length() - 1);
LOG.debug("Failed to create log, full rc list = {}", resultCodeList);
}
promise.setException(new ZKException("Failed to create log " + logRootPath, KeeperException.Code.get(rc)));
}
}
}, null);
}
use of com.twitter.distributedlog.exceptions.ZKException in project distributedlog by twitter.
the class ZKLogMetadataStore method getLogs.
@Override
public Future<Iterator<String>> getLogs() {
final Promise<Iterator<String>> promise = new Promise<Iterator<String>>();
final String nsRootPath = namespace.getPath();
try {
final ZooKeeper zk = zkc.get();
zk.sync(nsRootPath, new AsyncCallback.VoidCallback() {
@Override
public void processResult(int syncRc, String syncPath, Object ctx) {
if (KeeperException.Code.OK.intValue() == syncRc) {
zk.getChildren(nsRootPath, false, new AsyncCallback.Children2Callback() {
@Override
public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
if (KeeperException.Code.OK.intValue() == rc) {
List<String> results = Lists.newArrayListWithExpectedSize(children.size());
for (String child : children) {
if (!isReservedStreamName(child)) {
results.add(child);
}
}
promise.setValue(results.iterator());
} else if (KeeperException.Code.NONODE.intValue() == rc) {
List<String> streams = Lists.newLinkedList();
promise.setValue(streams.iterator());
} else {
promise.setException(new ZKException("Error reading namespace " + nsRootPath, KeeperException.Code.get(rc)));
}
}
}, null);
} else if (KeeperException.Code.NONODE.intValue() == syncRc) {
List<String> streams = Lists.newLinkedList();
promise.setValue(streams.iterator());
} else {
promise.setException(new ZKException("Error reading namespace " + nsRootPath, KeeperException.Code.get(syncRc)));
}
}
}, null);
zkc.get();
} catch (ZooKeeperClient.ZooKeeperConnectionException e) {
promise.setException(e);
} catch (InterruptedException e) {
promise.setException(e);
}
return promise;
}
use of com.twitter.distributedlog.exceptions.ZKException in project distributedlog by twitter.
the class FederatedZKLogMetadataStore method createLogInNamespaceSync.
void createLogInNamespaceSync(URI uri, String logName) throws InterruptedException, IOException, KeeperException {
Transaction txn = zkc.get().transaction();
// we don't have the zk version yet. set it to 0 instead of -1, to prevent non CAS operation.
int zkVersion = null == zkSubnamespacesVersion.get() ? 0 : zkSubnamespacesVersion.get();
txn.setData(zkSubnamespacesPath, uri.getPath().getBytes(UTF_8), zkVersion);
String logPath = uri.getPath() + "/" + logName;
txn.create(logPath, new byte[0], zkc.getDefaultACL(), CreateMode.PERSISTENT);
try {
txn.commit();
// if the transaction succeed, the zk version is advanced
setZkSubnamespacesVersion(zkVersion + 1);
} catch (KeeperException ke) {
List<OpResult> opResults = ke.getResults();
OpResult createResult = opResults.get(1);
if (createResult instanceof OpResult.ErrorResult) {
OpResult.ErrorResult errorResult = (OpResult.ErrorResult) createResult;
if (Code.NODEEXISTS.intValue() == errorResult.getErr()) {
throw new LogExistsException("Log " + logName + " already exists");
}
}
OpResult setResult = opResults.get(0);
if (setResult instanceof OpResult.ErrorResult) {
OpResult.ErrorResult errorResult = (OpResult.ErrorResult) setResult;
if (Code.BADVERSION.intValue() == errorResult.getErr()) {
throw KeeperException.create(Code.BADVERSION);
}
}
throw new ZKException("ZK exception in creating log " + logName + " in " + uri, ke);
}
}
use of com.twitter.distributedlog.exceptions.ZKException in project distributedlog by twitter.
the class TestZKLogSegmentMetadataStore method testStoreMaxTxnIdBadVersion.
@Test(timeout = 60000)
public void testStoreMaxTxnIdBadVersion() throws Exception {
Transaction<Object> updateTxn = lsmStore.transaction();
Versioned<Long> value = new Versioned<Long>(999L, new ZkVersion(10));
final Promise<Version> result = new Promise<Version>();
lsmStore.storeMaxTxnId(updateTxn, rootZkPath, value, new Transaction.OpListener<Version>() {
@Override
public void onCommit(Version r) {
result.setValue(r);
}
@Override
public void onAbort(Throwable t) {
result.setException(t);
}
});
try {
FutureUtils.result(updateTxn.execute());
fail("Should fail on storing log record transaction id if providing bad version");
} catch (ZKException zke) {
assertEquals(KeeperException.Code.BADVERSION, zke.getKeeperExceptionCode());
}
try {
Await.result(result);
fail("Should fail on storing log record transaction id if providing bad version");
} catch (KeeperException ke) {
assertEquals(KeeperException.Code.BADVERSION, ke.code());
}
Stat stat = new Stat();
byte[] data = zkc.get().getData(rootZkPath, false, stat);
assertEquals(0, stat.getVersion());
assertEquals(0, data.length);
}
Aggregations