Search in sources :

Example 1 with DataCorruptionException

use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.

the class StreamSegmentMapperTests method testCreateAlreadyExists.

/**
 * General test for verifying behavior when a Segment/Transaction is attempted to be created but it already exists.
 *
 * @param segmentName   The name of the segment/transaction to create.
 * @param createSegment A BiFunction that is given an instance of a StreamSegmentMapper and a Collection of AttributeUpdates
 *                      that, when invoked, will create the given segment.
 */
private void testCreateAlreadyExists(String segmentName, BiFunction<StreamSegmentMapper, Collection<AttributeUpdate>, CompletableFuture<?>> createSegment) {
    final String stateSegmentName = StreamSegmentNameUtils.getStateSegmentName(segmentName);
    final Map<UUID, Long> correctAttributes = Collections.singletonMap(UUID.randomUUID(), 123L);
    final Collection<AttributeUpdate> correctAttributeUpdates = correctAttributes.entrySet().stream().map(e -> new AttributeUpdate(e.getKey(), AttributeUpdateType.Replace, e.getValue())).collect(Collectors.toList());
    final Map<UUID, Long> badAttributes = Collections.singletonMap(UUID.randomUUID(), 456L);
    final Collection<AttributeUpdate> badAttributeUpdates = badAttributes.entrySet().stream().map(e -> new AttributeUpdate(e.getKey(), AttributeUpdateType.Replace, e.getValue())).collect(Collectors.toList());
    @Cleanup TestContext context = new TestContext();
    @Cleanup val storage = InMemoryStorageFactory.newStorage(executorService());
    storage.initialize(1);
    val store = new SegmentStateStore(storage, executorService());
    val mapper = new StreamSegmentMapper(context.metadata, context.operationLog, store, context.noOpMetadataCleanup, storage, executorService());
    // 1. Segment Exists, and so does State File (and it's not corrupted) -> Exception must be bubbled up.
    createSegment.apply(mapper, correctAttributeUpdates).join();
    AssertExtensions.assertThrows("createNewStreamSegment did not fail when Segment already exists.", () -> createSegment.apply(mapper, badAttributeUpdates), ex -> ex instanceof StreamSegmentExistsException);
    val state1 = store.get(segmentName, TIMEOUT).join();
    AssertExtensions.assertMapEquals("Unexpected attributes after failed attempt to recreate correctly created segment", correctAttributes, state1.getAttributes());
    // 2. Segment Exists, but with empty State File: State file re-created & no exception bubbled up.
    storage.openWrite(stateSegmentName).thenCompose(handle -> storage.delete(handle, TIMEOUT)).thenCompose(v -> storage.create(stateSegmentName, TIMEOUT)).join();
    Assert.assertNull("Expected a null SegmentState.", store.get(segmentName, TIMEOUT).join());
    createSegment.apply(mapper, correctAttributeUpdates).join();
    val state2 = store.get(segmentName, TIMEOUT).join();
    AssertExtensions.assertMapEquals("Unexpected attributes after successful attempt to complete segment creation (missing state file)", correctAttributes, state2.getAttributes());
    // 3. Segment Exists, but with corrupted State File: State file re-created & no exception bubbled up.
    storage.openWrite(stateSegmentName).thenCompose(handle -> storage.delete(handle, TIMEOUT)).thenCompose(v -> storage.create(stateSegmentName, TIMEOUT)).thenCompose(v -> storage.openWrite(stateSegmentName)).thenCompose(handle -> storage.write(handle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT)).join();
    AssertExtensions.assertThrows("Expected a DataCorruptionException when reading a corrupted State File.", () -> store.get(segmentName, TIMEOUT), ex -> ex instanceof DataCorruptionException);
    createSegment.apply(mapper, correctAttributeUpdates).join();
    val state3 = store.get(segmentName, TIMEOUT).join();
    AssertExtensions.assertMapEquals("Unexpected attributes after successful attempt to complete segment creation (corrupted state file)", correctAttributes, state3.getAttributes());
    // 4. Segment Exists with non-zero length, but with empty/corrupted State File: State File re-created and exception thrown.
    storage.openWrite(stateSegmentName).thenCompose(handle -> storage.delete(handle, TIMEOUT)).thenCompose(v -> storage.create(stateSegmentName, TIMEOUT)).thenCompose(v -> storage.openWrite(segmentName)).thenCompose(handle -> storage.write(handle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT)).join();
    AssertExtensions.assertThrows("createNewStreamSegment did not fail when Segment already exists (non-zero length, missing state file).", () -> createSegment.apply(mapper, correctAttributeUpdates), ex -> ex instanceof StreamSegmentExistsException);
    val state4 = store.get(segmentName, TIMEOUT).join();
    AssertExtensions.assertMapEquals("Unexpected attributes after failed attempt to recreate segment with non-zero length", correctAttributes, state4.getAttributes());
}
Also used : Arrays(java.util.Arrays) Storage(io.pravega.segmentstore.storage.Storage) StreamSegmentInformation(io.pravega.segmentstore.contracts.StreamSegmentInformation) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) AssertExtensions(io.pravega.test.common.AssertExtensions) BiFunction(java.util.function.BiFunction) ContainerMetadata(io.pravega.segmentstore.server.ContainerMetadata) TimeoutException(java.util.concurrent.TimeoutException) Cleanup(lombok.Cleanup) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) ByteArrayInputStream(java.io.ByteArrayInputStream) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InMemoryStorageFactory(io.pravega.segmentstore.storage.mocks.InMemoryStorageFactory) Duration(java.time.Duration) Map(java.util.Map) Operation(io.pravega.segmentstore.server.logs.operations.Operation) Attributes(io.pravega.segmentstore.contracts.Attributes) Predicate(java.util.function.Predicate) Collection(java.util.Collection) InMemoryStorage(io.pravega.segmentstore.storage.mocks.InMemoryStorage) Set(java.util.Set) CompletionException(java.util.concurrent.CompletionException) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) SegmentMetadataComparer(io.pravega.segmentstore.server.SegmentMetadataComparer) StreamSegmentNameUtils(io.pravega.shared.segment.StreamSegmentNameUtils) List(java.util.List) AsyncMap(io.pravega.common.util.AsyncMap) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Futures(io.pravega.common.concurrent.Futures) MetadataBuilder(io.pravega.segmentstore.server.MetadataBuilder) SegmentRollingPolicy(io.pravega.segmentstore.storage.SegmentRollingPolicy) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) Timeout(org.junit.rules.Timeout) StreamSegmentMapOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentMapOperation) MathHelpers(io.pravega.common.MathHelpers) Iterator(java.util.Iterator) Executor(java.util.concurrent.Executor) IntentionalException(io.pravega.test.common.IntentionalException) lombok.val(lombok.val) OperationLog(io.pravega.segmentstore.server.OperationLog) Test(org.junit.Test) Service(com.google.common.util.concurrent.Service) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) Rule(org.junit.Rule) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Assert(org.junit.Assert) Collections(java.util.Collections) InputStream(java.io.InputStream) lombok.val(lombok.val) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) Cleanup(lombok.Cleanup) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) ByteArrayInputStream(java.io.ByteArrayInputStream) AtomicLong(java.util.concurrent.atomic.AtomicLong) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) UUID(java.util.UUID)

Example 2 with DataCorruptionException

use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.

the class StorageWriter method getSegmentAggregator.

// endregion
// region Helpers
/**
 * Gets, or creates, a SegmentAggregator for the given StorageOperation.
 *
 * @param streamSegmentId The Id of the StreamSegment to get the aggregator for.
 */
private CompletableFuture<SegmentAggregator> getSegmentAggregator(long streamSegmentId) {
    SegmentAggregator existingAggregator = this.aggregators.getOrDefault(streamSegmentId, null);
    if (existingAggregator != null) {
        if (closeIfNecessary(existingAggregator).isClosed()) {
            // Existing SegmentAggregator has become stale (most likely due to its SegmentMetadata being evicted),
            // so it has been closed and we need to create a new one.
            this.aggregators.remove(streamSegmentId);
        } else {
            return CompletableFuture.completedFuture(existingAggregator);
        }
    }
    // Get the SegmentAggregator's Metadata.
    UpdateableSegmentMetadata segmentMetadata = this.dataSource.getStreamSegmentMetadata(streamSegmentId);
    if (segmentMetadata == null) {
        return Futures.failedFuture(new DataCorruptionException(String.format("No StreamSegment with id '%d' is registered in the metadata.", streamSegmentId)));
    }
    // Then create the aggregator, and only register it after a successful initialization. Otherwise we risk
    // having a registered aggregator that is not initialized.
    SegmentAggregator newAggregator = new SegmentAggregator(segmentMetadata, this.dataSource, this.storage, this.config, this.timer, this.executor);
    try {
        CompletableFuture<Void> init = newAggregator.initialize(this.config.getFlushTimeout());
        Futures.exceptionListener(init, ex -> newAggregator.close());
        return init.thenApply(ignored -> {
            this.aggregators.put(streamSegmentId, newAggregator);
            return newAggregator;
        });
    } catch (Exception ex) {
        newAggregator.close();
        throw ex;
    }
}
Also used : UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) ObjectClosedException(io.pravega.common.ObjectClosedException) TimeoutException(java.util.concurrent.TimeoutException) CancellationException(java.util.concurrent.CancellationException) CompletionException(java.util.concurrent.CompletionException) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException)

Example 3 with DataCorruptionException

use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.

the class SegmentStateStoreTests method testGetCorruptedState.

/**
 * Tests the get() method when there exists a state in Storage, however it is a corrupted file.
 */
@Test
public void testGetCorruptedState() throws Exception {
    final String segmentName = "foo";
    final String stateSegment = StreamSegmentNameUtils.getStateSegmentName(segmentName);
    val store = createStateStore();
    // Write some dummy contents in the file which is not how a SegmentState would be serialized.
    this.storage.create(stateSegment, TIMEOUT).thenCompose(si -> this.storage.openWrite(stateSegment)).thenCompose(handle -> this.storage.write(handle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT)).join();
    AssertExtensions.assertThrows("Unexpected behavior when attempting to read a corrupted state file.", () -> store.get(segmentName, TIMEOUT), ex -> ex instanceof DataCorruptionException);
}
Also used : lombok.val(lombok.val) TimeUnit(java.util.concurrent.TimeUnit) Storage(io.pravega.segmentstore.storage.Storage) AsyncMap(io.pravega.common.util.AsyncMap) ByteArrayInputStream(java.io.ByteArrayInputStream) AssertExtensions(io.pravega.test.common.AssertExtensions) InMemoryStorageFactory(io.pravega.segmentstore.storage.mocks.InMemoryStorageFactory) lombok.val(lombok.val) Test(org.junit.Test) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Assert(org.junit.Assert) StreamSegmentNameUtils(io.pravega.shared.segment.StreamSegmentNameUtils) Before(org.junit.Before) ByteArrayInputStream(java.io.ByteArrayInputStream) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Test(org.junit.Test)

Example 4 with DataCorruptionException

use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.

the class BookkeeperCommandsTest method testRecoveryState.

@Test
public void testRecoveryState() {
    CommandArgs args = new CommandArgs(Collections.singletonList("0"), STATE.get());
    ContainerRecoverCommand.RecoveryState state = new ContainerRecoverCommand(args).new RecoveryState();
    Operation op = new TestOperation();
    List<DataFrameRecord.EntryInfo> entries = new ArrayList<>();
    entries.add(new TestEntryInfo());
    // Exercise RecoveryState logic.
    state.operationComplete(op, new DataCorruptionException("Test exception"));
    state.newOperation(op, entries);
    state.operationComplete(op, null);
}
Also used : CommandArgs(io.pravega.cli.admin.CommandArgs) ArrayList(java.util.ArrayList) Operation(io.pravega.segmentstore.server.logs.operations.Operation) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Test(org.junit.Test)

Example 5 with DataCorruptionException

use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.

the class BookkeeperCommandsTest method testBookKeeperRecoveryCommand.

@Test
public void testBookKeeperRecoveryCommand() throws Exception {
    createLedgerInBookkeeperTestCluster(0);
    String commandResult = TestUtils.executeCommand("container recover 0", STATE.get());
    Assert.assertTrue(commandResult.contains("Recovery complete"));
    CommandArgs args = new CommandArgs(Collections.singletonList("0"), STATE.get());
    ContainerRecoverCommand command = new ContainerRecoverCommand(args);
    // Test unwrap exception options.
    command.unwrapDataCorruptionException(new DataCorruptionException("test"));
    command.unwrapDataCorruptionException(new DataCorruptionException("test", "test"));
    command.unwrapDataCorruptionException(new DataCorruptionException("test", Arrays.asList("test", "test")));
    command.unwrapDataCorruptionException(new DataCorruptionException("test", (DataCorruptionException) null));
    // Check that exception is thrown if ZK is not available.
    this.zkUtil.stopCluster();
    AssertExtensions.assertThrows(DataLogNotAvailableException.class, () -> TestUtils.executeCommand("container recover 0", STATE.get()));
}
Also used : CommandArgs(io.pravega.cli.admin.CommandArgs) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Test(org.junit.Test)

Aggregations

DataCorruptionException (io.pravega.segmentstore.server.DataCorruptionException)34 Test (org.junit.Test)17 Cleanup (lombok.Cleanup)16 lombok.val (lombok.val)16 CachedStreamSegmentAppendOperation (io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation)12 StorageOperation (io.pravega.segmentstore.server.logs.operations.StorageOperation)12 Operation (io.pravega.segmentstore.server.logs.operations.Operation)10 StreamSegmentAppendOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation)10 CompletionException (java.util.concurrent.CompletionException)10 UpdateableSegmentMetadata (io.pravega.segmentstore.server.UpdateableSegmentMetadata)9 SegmentMetadata (io.pravega.segmentstore.server.SegmentMetadata)8 MergeSegmentOperation (io.pravega.segmentstore.server.logs.operations.MergeSegmentOperation)8 StreamSegmentSealOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentSealOperation)8 Storage (io.pravega.segmentstore.storage.Storage)8 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)7 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)7 Exceptions (io.pravega.common.Exceptions)6 StreamSegmentSealedException (io.pravega.segmentstore.contracts.StreamSegmentSealedException)6 Duration (java.time.Duration)6 TimeoutTimer (io.pravega.common.TimeoutTimer)4