Search in sources :

Example 1 with ZKException

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);
}
Also used : Versioned(org.apache.bookkeeper.versioning.Versioned) LedgerHandle(org.apache.bookkeeper.client.LedgerHandle) ZKTransaction(com.twitter.distributedlog.zk.ZKTransaction) ZKException(com.twitter.distributedlog.exceptions.ZKException) Stat(org.apache.zookeeper.data.Stat) LedgerEntry(org.apache.bookkeeper.client.LedgerEntry) BKException(org.apache.bookkeeper.client.BKException) ZkVersion(org.apache.bookkeeper.meta.ZkVersion) Test(org.junit.Test)

Example 2 with ZKException

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);
}
Also used : Op(org.apache.zookeeper.Op) LogExistsException(com.twitter.distributedlog.exceptions.LogExistsException) Versioned(org.apache.bookkeeper.versioning.Versioned) AsyncCallback(org.apache.zookeeper.AsyncCallback) ZKException(com.twitter.distributedlog.exceptions.ZKException) CreateMode(org.apache.zookeeper.CreateMode) OpResult(org.apache.zookeeper.OpResult) List(java.util.List) LogNotFoundException(com.twitter.distributedlog.exceptions.LogNotFoundException) File(java.io.File) ZkVersion(org.apache.bookkeeper.meta.ZkVersion)

Example 3 with ZKException

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;
}
Also used : AsyncCallback(org.apache.zookeeper.AsyncCallback) Promise(com.twitter.util.Promise) ZKException(com.twitter.distributedlog.exceptions.ZKException) ZooKeeper(org.apache.zookeeper.ZooKeeper) Stat(org.apache.zookeeper.data.Stat) ZooKeeperClient(com.twitter.distributedlog.ZooKeeperClient) Iterator(java.util.Iterator) List(java.util.List)

Example 4 with ZKException

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);
    }
}
Also used : ZKException(com.twitter.distributedlog.exceptions.ZKException) LogExistsException(com.twitter.distributedlog.exceptions.LogExistsException) Transaction(org.apache.zookeeper.Transaction) OpResult(org.apache.zookeeper.OpResult) List(java.util.List) KeeperException(org.apache.zookeeper.KeeperException)

Example 5 with ZKException

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);
}
Also used : Versioned(org.apache.bookkeeper.versioning.Versioned) Promise(com.twitter.util.Promise) ZKException(com.twitter.distributedlog.exceptions.ZKException) Stat(org.apache.zookeeper.data.Stat) Transaction(com.twitter.distributedlog.util.Transaction) ZkVersion(org.apache.bookkeeper.meta.ZkVersion) Version(org.apache.bookkeeper.versioning.Version) ZkVersion(org.apache.bookkeeper.meta.ZkVersion) KeeperException(org.apache.zookeeper.KeeperException) Test(org.junit.Test)

Aggregations

ZKException (com.twitter.distributedlog.exceptions.ZKException)23 Test (org.junit.Test)13 KeeperException (org.apache.zookeeper.KeeperException)9 Stat (org.apache.zookeeper.data.Stat)9 Promise (com.twitter.util.Promise)7 ZkVersion (org.apache.bookkeeper.meta.ZkVersion)7 Versioned (org.apache.bookkeeper.versioning.Versioned)7 DLInterruptedException (com.twitter.distributedlog.exceptions.DLInterruptedException)6 List (java.util.List)6 AsyncCallback (org.apache.zookeeper.AsyncCallback)5 LogSegmentMetadata (com.twitter.distributedlog.LogSegmentMetadata)4 Transaction (com.twitter.distributedlog.util.Transaction)4 ZKTransaction (com.twitter.distributedlog.zk.ZKTransaction)4 LedgerHandle (org.apache.bookkeeper.client.LedgerHandle)4 Version (org.apache.bookkeeper.versioning.Version)4 LogNotFoundException (com.twitter.distributedlog.exceptions.LogNotFoundException)3 ArrayList (java.util.ArrayList)3 ZooKeeper (org.apache.zookeeper.ZooKeeper)3 LogExistsException (com.twitter.distributedlog.exceptions.LogExistsException)2 IOException (java.io.IOException)2