Search in sources :

Example 11 with UnexpectedException

use of org.apache.distributedlog.exceptions.UnexpectedException in project bookkeeper by apache.

the class TestLogSegmentsZK method testCreateLogSegmentMissingMaxSequenceNumber.

/**
 * Create Log Segment when no max sequence number recorded in /ledgers. e.g. old version.
 */
@Test(timeout = 60000)
public void testCreateLogSegmentMissingMaxSequenceNumber() throws Exception {
    URI uri = createURI();
    String streamName = testName.getMethodName();
    DistributedLogConfiguration conf = new DistributedLogConfiguration().setLockTimeout(99999).setOutputBufferSize(0).setImmediateFlushEnabled(true).setEnableLedgerAllocatorPool(true).setLedgerAllocatorPoolName("test");
    Namespace namespace = NamespaceBuilder.newBuilder().conf(conf).uri(uri).build();
    namespace.createLog(streamName);
    MaxLogSegmentSequenceNo max1 = getMaxLogSegmentSequenceNo(getZooKeeperClient(namespace), uri, streamName, conf);
    assertEquals(DistributedLogConstants.UNASSIGNED_LOGSEGMENT_SEQNO, max1.getSequenceNumber());
    DistributedLogManager dlm = namespace.openLog(streamName);
    final int numSegments = 3;
    for (int i = 0; i < numSegments; i++) {
        BKSyncLogWriter out = (BKSyncLogWriter) dlm.startLogSegmentNonPartitioned();
        out.write(DLMTestUtil.getLogRecordInstance(i));
        out.closeAndComplete();
    }
    MaxLogSegmentSequenceNo max2 = getMaxLogSegmentSequenceNo(getZooKeeperClient(namespace), uri, streamName, conf);
    assertEquals(3, max2.getSequenceNumber());
    // nuke the max ledger sequence number
    updateMaxLogSegmentSequenceNo(getZooKeeperClient(namespace), uri, streamName, conf, new byte[0]);
    DistributedLogManager dlm1 = namespace.openLog(streamName);
    try {
        dlm1.startLogSegmentNonPartitioned();
        fail("Should fail with unexpected exceptions");
    } catch (UnexpectedException ue) {
    // expected
    } finally {
        dlm1.close();
    }
    // invalid max ledger sequence number
    updateMaxLogSegmentSequenceNo(getZooKeeperClient(namespace), uri, streamName, conf, "invalid-max".getBytes(UTF_8));
    DistributedLogManager dlm2 = namespace.openLog(streamName);
    try {
        dlm2.startLogSegmentNonPartitioned();
        fail("Should fail with unexpected exceptions");
    } catch (UnexpectedException ue) {
    // expected
    } finally {
        dlm2.close();
    }
    dlm.close();
    namespace.close();
}
Also used : UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) DistributedLogManager(org.apache.distributedlog.api.DistributedLogManager) URI(java.net.URI) Namespace(org.apache.distributedlog.api.namespace.Namespace) Test(org.junit.Test)

Example 12 with UnexpectedException

use of org.apache.distributedlog.exceptions.UnexpectedException in project bookkeeper by apache.

the class ZKLogStreamMetadataStore method processLogMetadatas.

static LogMetadataForWriter processLogMetadatas(URI uri, String logName, String logIdentifier, List<Versioned<byte[]>> metadatas, boolean ownAllocator) throws UnexpectedException {
    try {
        // max id
        Versioned<byte[]> maxTxnIdData = metadatas.get(MetadataIndex.MAX_TXID);
        ensureMetadataExist(maxTxnIdData);
        // version
        Versioned<byte[]> versionData = metadatas.get(MetadataIndex.VERSION);
        ensureMetadataExist(maxTxnIdData);
        checkArgument(LAYOUT_VERSION == bytesToInt(versionData.getValue()));
        // lock path
        ensureMetadataExist(metadatas.get(MetadataIndex.LOCK));
        // read lock path
        ensureMetadataExist(metadatas.get(MetadataIndex.READ_LOCK));
        // max lssn
        Versioned<byte[]> maxLSSNData = metadatas.get(MetadataIndex.LOGSEGMENTS);
        ensureMetadataExist(maxLSSNData);
        try {
            DLUtils.deserializeLogSegmentSequenceNumber(maxLSSNData.getValue());
        } catch (NumberFormatException nfe) {
            throw new UnexpectedException("Invalid max sequence number found in log " + logName, nfe);
        }
        // allocation path
        Versioned<byte[]> allocationData;
        if (ownAllocator) {
            allocationData = metadatas.get(MetadataIndex.ALLOCATION);
            ensureMetadataExist(allocationData);
        } else {
            allocationData = new Versioned<byte[]>(null, null);
        }
        return new LogMetadataForWriter(uri, logName, logIdentifier, maxLSSNData, maxTxnIdData, allocationData);
    } catch (IllegalArgumentException iae) {
        throw new UnexpectedException("Invalid log " + logName, iae);
    } catch (NullPointerException npe) {
        throw new UnexpectedException("Invalid log " + logName, npe);
    }
}
Also used : UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) LogMetadataForWriter(org.apache.distributedlog.metadata.LogMetadataForWriter)

Example 13 with UnexpectedException

use of org.apache.distributedlog.exceptions.UnexpectedException in project bookkeeper by apache.

the class BKDistributedLogManager method getAsyncLogReaderWithLock.

protected CompletableFuture<AsyncLogReader> getAsyncLogReaderWithLock(final Optional<DLSN> fromDLSN, final Optional<String> subscriberId) {
    if (!fromDLSN.isPresent() && !subscriberId.isPresent()) {
        return FutureUtils.exception(new UnexpectedException("Neither from dlsn nor subscriber id is provided."));
    }
    final BKAsyncLogReader reader = new BKAsyncLogReader(BKDistributedLogManager.this, scheduler, fromDLSN.isPresent() ? fromDLSN.get() : DLSN.InitialDLSN, subscriberId, false, statsLogger);
    pendingReaders.add(reader);
    final CompletableFuture<Void> lockFuture = reader.lockStream();
    final CompletableFuture<AsyncLogReader> createPromise = FutureUtils.createFuture();
    createPromise.whenComplete((value, cause) -> {
        if (cause instanceof CancellationException) {
            // cancel the lock when the creation future is cancelled
            lockFuture.cancel(true);
        }
    });
    // lock the stream - fetch the last commit position on success
    lockFuture.thenCompose(new Function<Void, CompletableFuture<AsyncLogReader>>() {

        @Override
        public CompletableFuture<AsyncLogReader> apply(Void complete) {
            if (fromDLSN.isPresent()) {
                return FutureUtils.value(reader);
            }
            LOG.info("Reader {} @ {} reading last commit position from subscription store after acquired lock.", subscriberId.get(), name);
            // we acquired lock
            final SubscriptionsStore subscriptionsStore = driver.getSubscriptionsStore(getStreamName());
            return subscriptionsStore.getLastCommitPosition(subscriberId.get()).thenCompose(lastCommitPosition -> {
                LOG.info("Reader {} @ {} positioned to last commit position {}.", new Object[] { subscriberId.get(), name, lastCommitPosition });
                try {
                    reader.setStartDLSN(lastCommitPosition);
                } catch (UnexpectedException e) {
                    return FutureUtils.exception(e);
                }
                return FutureUtils.value(reader);
            });
        }
    }).whenComplete(new FutureEventListener<AsyncLogReader>() {

        @Override
        public void onSuccess(AsyncLogReader r) {
            pendingReaders.remove(reader);
            FutureUtils.complete(createPromise, r);
        }

        @Override
        public void onFailure(final Throwable cause) {
            pendingReaders.remove(reader);
            FutureUtils.ensure(reader.asyncClose(), () -> FutureUtils.completeExceptionally(createPromise, cause));
        }
    });
    return createPromise;
}
Also used : Function(java.util.function.Function) UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) AsyncLogReader(org.apache.distributedlog.api.AsyncLogReader) CancellationException(java.util.concurrent.CancellationException) SubscriptionsStore(org.apache.distributedlog.api.subscription.SubscriptionsStore)

Example 14 with UnexpectedException

use of org.apache.distributedlog.exceptions.UnexpectedException in project bookkeeper by apache.

the class PerStreamLogSegmentCache method getLogSegments.

/**
 * Retrieve log segments from the cache.
 *- first sort the log segments in ascending order
 * - do validation and assign corresponding sequence id
 * - apply comparator after validation
 *
 * @param comparator
 *          comparator to sort the returned log segments.
 * @return list of sorted and filtered log segments.
 * @throws UnexpectedException if unexpected condition detected (e.g. ledger sequence number gap)
 */
public List<LogSegmentMetadata> getLogSegments(Comparator<LogSegmentMetadata> comparator) throws UnexpectedException {
    List<LogSegmentMetadata> segmentsToReturn;
    synchronized (logSegments) {
        segmentsToReturn = new ArrayList<LogSegmentMetadata>(logSegments.size());
        segmentsToReturn.addAll(logSegments.values());
    }
    Collections.sort(segmentsToReturn, LogSegmentMetadata.COMPARATOR);
    LogSegmentMetadata prevSegment = null;
    if (validateLogSegmentSequenceNumber) {
        // validation ledger sequence number to ensure the log segments are unique.
        for (int i = 0; i < segmentsToReturn.size(); i++) {
            LogSegmentMetadata segment = segmentsToReturn.get(i);
            if (null != prevSegment && prevSegment.getVersion() >= LogSegmentMetadata.LogSegmentMetadataVersion.VERSION_V2_LEDGER_SEQNO.value && segment.getVersion() >= LogSegmentMetadata.LogSegmentMetadataVersion.VERSION_V2_LEDGER_SEQNO.value && prevSegment.getLogSegmentSequenceNumber() + 1 != segment.getLogSegmentSequenceNumber()) {
                LOG.error("{} found ledger sequence number gap between log segment {} and {}", new Object[] { streamName, prevSegment, segment });
                throw new UnexpectedException(streamName + " found ledger sequence number gap between log segment " + prevSegment.getLogSegmentSequenceNumber() + " and " + segment.getLogSegmentSequenceNumber());
            }
            prevSegment = segment;
        }
    }
    prevSegment = null;
    long startSequenceId = DistributedLogConstants.UNASSIGNED_SEQUENCE_ID;
    for (int i = 0; i < segmentsToReturn.size(); i++) {
        LogSegmentMetadata segment = segmentsToReturn.get(i);
        // assign sequence id
        if (!segment.isInProgress()) {
            if (segment.supportsSequenceId()) {
                startSequenceId = segment.getStartSequenceId() + segment.getRecordCount();
                if (null != prevSegment && prevSegment.supportsSequenceId() && prevSegment.getStartSequenceId() > segment.getStartSequenceId()) {
                    LOG.warn("{} found decreasing start sequence id in log segment {}, previous is {}", new Object[] { streamName, segment, prevSegment });
                }
            } else {
                startSequenceId = DistributedLogConstants.UNASSIGNED_SEQUENCE_ID;
            }
        } else {
            if (segment.supportsSequenceId()) {
                LogSegmentMetadata newSegment = segment.mutator().setStartSequenceId(startSequenceId == DistributedLogConstants.UNASSIGNED_SEQUENCE_ID ? 0L : startSequenceId).build();
                segmentsToReturn.set(i, newSegment);
            }
            break;
        }
        prevSegment = segment;
    }
    if (comparator != LogSegmentMetadata.COMPARATOR) {
        Collections.sort(segmentsToReturn, comparator);
    }
    return segmentsToReturn;
}
Also used : UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) LogSegmentMetadata(org.apache.distributedlog.LogSegmentMetadata)

Aggregations

UnexpectedException (org.apache.distributedlog.exceptions.UnexpectedException)14 URI (java.net.URI)6 List (java.util.List)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 Test (org.junit.Test)3 IOException (java.io.IOException)2 Set (java.util.Set)2 CancellationException (java.util.concurrent.CancellationException)2 DLSN (org.apache.distributedlog.DLSN)2 DistributedLogConfiguration (org.apache.distributedlog.DistributedLogConfiguration)2 LogRecord (org.apache.distributedlog.LogRecord)2 AsyncLogReader (org.apache.distributedlog.api.AsyncLogReader)2 DistributedLogManager (org.apache.distributedlog.api.DistributedLogManager)2 Namespace (org.apache.distributedlog.api.namespace.Namespace)2 Optional (com.google.common.base.Optional)1 Stopwatch (com.google.common.base.Stopwatch)1 URISyntaxException (java.net.URISyntaxException)1 HashSet (java.util.HashSet)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Function (java.util.function.Function)1