Search in sources :

Example 6 with Storage

use of io.pravega.segmentstore.storage.Storage in project pravega by pravega.

the class DebugRecoveryProcessor method create.

/**
 * Creates a new instance of the DebugRecoveryProcessor class with the given arguments.
 *
 * @param containerId     The Id of the Container to recover.
 * @param durableDataLog  A DurableDataLog to recover from.
 * @param config          A ContainerConfig to use during recovery.
 * @param readIndexConfig A ReadIndexConfig to use during recovery.
 * @param executor        An Executor to use for background tasks.
 * @param callbacks       Callbacks to invoke during recovery.
 * @return A new instance of the DebugRecoveryProcessor.
 */
public static DebugRecoveryProcessor create(int containerId, DurableDataLog durableDataLog, ContainerConfig config, ReadIndexConfig readIndexConfig, ScheduledExecutorService executor, OperationCallbacks callbacks) {
    Preconditions.checkNotNull(durableDataLog, "durableDataLog");
    Preconditions.checkNotNull(config, "config");
    Preconditions.checkNotNull(readIndexConfig, "readIndexConfig");
    Preconditions.checkNotNull(executor, "executor");
    Preconditions.checkNotNull(callbacks, callbacks);
    StreamSegmentContainerMetadata metadata = new StreamSegmentContainerMetadata(containerId, config.getMaxActiveSegmentCount());
    ContainerReadIndexFactory rf = new ContainerReadIndexFactory(readIndexConfig, new NoOpCacheFactory(), executor);
    Storage s = new InMemoryStorageFactory(executor).createStorageAdapter();
    return new DebugRecoveryProcessor(metadata, durableDataLog, rf, s, callbacks);
}
Also used : Storage(io.pravega.segmentstore.storage.Storage) ContainerReadIndexFactory(io.pravega.segmentstore.server.reading.ContainerReadIndexFactory) InMemoryStorageFactory(io.pravega.segmentstore.storage.mocks.InMemoryStorageFactory) StreamSegmentContainerMetadata(io.pravega.segmentstore.server.containers.StreamSegmentContainerMetadata)

Example 7 with Storage

use of io.pravega.segmentstore.storage.Storage in project pravega by pravega.

the class SegmentAggregator method reconcileAppendOperation.

/**
 * Attempts to reconcile the given Append Operation. Since Append Operations can be partially flushed, reconciliation
 * may be for the full operation or for a part of it.
 *
 * @param op          The Operation (StreamSegmentAppendOperation or CachedStreamSegmentAppendOperation) to reconcile.
 * @param storageInfo The current state of the Segment in Storage.
 * @param timer       Timer for the operation.
 * @return A CompletableFuture containing a FlushResult with the number of bytes reconciled, or failed with a ReconciliationFailureException,
 * if the operation cannot be reconciled, based on the in-memory metadata or the current state of the Segment in Storage.
 */
private CompletableFuture<FlushResult> reconcileAppendOperation(StorageOperation op, SegmentProperties storageInfo, TimeoutTimer timer) {
    Preconditions.checkArgument(op instanceof AggregatedAppendOperation, "Not given an append operation.");
    // Read data from Storage, and compare byte-by-byte.
    InputStream appendStream = this.dataSource.getAppendData(op.getStreamSegmentId(), op.getStreamSegmentOffset(), (int) op.getLength());
    if (appendStream == null) {
        return Futures.failedFuture(new ReconciliationFailureException(String.format("Unable to reconcile operation '%s' because no append data is associated with it.", op), this.metadata, storageInfo));
    }
    // Only read as much data as we need.
    long readLength = Math.min(op.getLastStreamSegmentOffset(), storageInfo.getLength()) - op.getStreamSegmentOffset();
    assert readLength > 0 : "Append Operation to be reconciled is beyond the Segment's StorageLength " + op;
    AtomicInteger bytesReadSoFar = new AtomicInteger();
    // Read all data from storage.
    byte[] storageData = new byte[(int) readLength];
    return Futures.loop(() -> bytesReadSoFar.get() < readLength, () -> this.storage.read(this.handle.get(), op.getStreamSegmentOffset() + bytesReadSoFar.get(), storageData, bytesReadSoFar.get(), (int) readLength - bytesReadSoFar.get(), timer.getRemaining()), bytesRead -> {
        assert bytesRead > 0 : String.format("Unable to make any read progress when reconciling operation '%s' after reading %s bytes.", op, bytesReadSoFar);
        bytesReadSoFar.addAndGet(bytesRead);
    }, this.executor).thenApplyAsync(v -> {
        // Compare, byte-by-byte, the contents of the append.
        verifySame(appendStream, storageData, op, storageInfo);
        if (readLength >= op.getLength() && op.getLastStreamSegmentOffset() <= storageInfo.getLength()) {
            // Operation has been completely validated; pop it off the list.
            StorageOperation removedOp = this.operations.removeFirst();
            assert op == removedOp : "Reconciled operation is not the same as removed operation";
        }
        return new FlushResult().withFlushedBytes(readLength);
    }, this.executor);
}
Also used : Storage(io.pravega.segmentstore.storage.Storage) Getter(lombok.Getter) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) SneakyThrows(lombok.SneakyThrows) Exceptions(io.pravega.common.Exceptions) RequiredArgsConstructor(lombok.RequiredArgsConstructor) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) AbstractTimer(io.pravega.common.AbstractTimer) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Operation(io.pravega.segmentstore.server.logs.operations.Operation) StreamSegmentTruncateOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentTruncateOperation) LoggerHelpers(io.pravega.common.LoggerHelpers) TimeoutTimer(io.pravega.common.TimeoutTimer) Executor(java.util.concurrent.Executor) CompletionException(java.util.concurrent.CompletionException) ThreadSafe(javax.annotation.concurrent.ThreadSafe) GuardedBy(javax.annotation.concurrent.GuardedBy) AtomicLong(java.util.concurrent.atomic.AtomicLong) Slf4j(lombok.extern.slf4j.Slf4j) CachedStreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation) StorageOperation(io.pravega.segmentstore.server.logs.operations.StorageOperation) StreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation) BadOffsetException(io.pravega.segmentstore.contracts.BadOffsetException) Preconditions(com.google.common.base.Preconditions) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) ArrayDeque(java.util.ArrayDeque) MergeTransactionOperation(io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation) Futures(io.pravega.common.concurrent.Futures) StreamSegmentSealOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentSealOperation) InputStream(java.io.InputStream) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InputStream(java.io.InputStream) StorageOperation(io.pravega.segmentstore.server.logs.operations.StorageOperation)

Example 8 with Storage

use of io.pravega.segmentstore.storage.Storage in project pravega by pravega.

the class SegmentStateMapperTests method testGetSegmentInfoFromStorage.

/**
 * Tests the ability to retrieve Segment Info from Storage (base info and its State).
 */
@Test
public void testGetSegmentInfoFromStorage() {
    final UUID attributeId = UUID.randomUUID();
    @Cleanup val s = createStorage();
    val stateStore = new InMemoryStateStore();
    val m = new SegmentStateMapper(stateStore, s);
    // Save some state.
    val info = s.create("s", TIMEOUT).thenCompose(si -> s.openWrite(si.getName())).thenCompose(handle -> s.write(handle, 0, new ByteArrayInputStream(new byte[10]), 10, TIMEOUT).thenCompose(v -> s.seal(handle, TIMEOUT)).thenCompose(v -> s.getStreamSegmentInfo(handle.getSegmentName(), TIMEOUT))).join();
    val expectedInfo = StreamSegmentInformation.from(info).startOffset(info.getLength() / 2).build();
    val attributes = Collections.singleton(new AttributeUpdate(attributeId, AttributeUpdateType.Replace, 100L));
    val expectedAttributes = Collections.singletonMap(attributeId, 100L);
    m.saveState(expectedInfo, attributes, TIMEOUT).join();
    // Retrieve the state and verify it.
    val actual = m.getSegmentInfoFromStorage(expectedInfo.getName(), TIMEOUT).join();
    Assert.assertEquals("Unexpected Name.", expectedInfo.getName(), actual.getName());
    Assert.assertEquals("Unexpected Length.", expectedInfo.getLength(), actual.getLength());
    Assert.assertEquals("Unexpected Sealed status.", expectedInfo.isSealed(), actual.isSealed());
    Assert.assertEquals("Unexpected Start Offset.", expectedInfo.getStartOffset(), actual.getStartOffset());
    AssertExtensions.assertMapEquals("Unexpected Attributes.", expectedAttributes, actual.getAttributes());
}
Also used : lombok.val(lombok.val) Storage(io.pravega.segmentstore.storage.Storage) StreamSegmentInformation(io.pravega.segmentstore.contracts.StreamSegmentInformation) AssertExtensions(io.pravega.test.common.AssertExtensions) lombok.val(lombok.val) Cleanup(lombok.Cleanup) Test(org.junit.Test) UUID(java.util.UUID) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) Rule(org.junit.Rule) ByteArrayInputStream(java.io.ByteArrayInputStream) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) InMemoryStorageFactory(io.pravega.segmentstore.storage.mocks.InMemoryStorageFactory) Duration(java.time.Duration) Timeout(org.junit.rules.Timeout) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) Assert(org.junit.Assert) Collections(java.util.Collections) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) ByteArrayInputStream(java.io.ByteArrayInputStream) UUID(java.util.UUID) Cleanup(lombok.Cleanup) Test(org.junit.Test)

Example 9 with Storage

use of io.pravega.segmentstore.storage.Storage 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 10 with Storage

use of io.pravega.segmentstore.storage.Storage in project pravega by pravega.

the class StreamSegmentMapper method createNewTransactionStreamSegment.

/**
 * Creates a new Transaction StreamSegment for an existing Parent StreamSegment and persists the given attributes (in Storage).
 *
 * @param parentStreamSegmentName The case-sensitive StreamSegment Name of the Parent StreamSegment.
 * @param transactionId           A unique identifier for the transaction to be created.
 * @param attributes              The initial attributes for the Transaction, if any.
 * @param timeout                 Timeout for the operation.
 * @return A CompletableFuture that, when completed normally, will contain the name of the newly created Transaction StreamSegment.
 * If the operation failed, this will contain the exception that caused the failure.
 * @throws IllegalArgumentException If the given parent StreamSegment cannot have a Transaction (because it is deleted, sealed, inexistent).
 */
public CompletableFuture<String> createNewTransactionStreamSegment(String parentStreamSegmentName, UUID transactionId, Collection<AttributeUpdate> attributes, Duration timeout) {
    long traceId = LoggerHelpers.traceEnterWithContext(log, traceObjectId, "createNewTransactionStreamSegment", parentStreamSegmentName);
    // We cannot create a Transaction StreamSegment for a what looks like another Transaction.
    Exceptions.checkArgument(StreamSegmentNameUtils.getParentStreamSegmentName(parentStreamSegmentName) == null, "parentStreamSegmentName", "Cannot create a Transaction for a Transaction.");
    // Validate that Parent StreamSegment exists.
    TimeoutTimer timer = new TimeoutTimer(timeout);
    CompletableFuture<Void> parentCheck = null;
    long mappedParentId = this.containerMetadata.getStreamSegmentId(parentStreamSegmentName, true);
    if (isValidStreamSegmentId(mappedParentId)) {
        SegmentProperties parentInfo = this.containerMetadata.getStreamSegmentMetadata(mappedParentId);
        if (parentInfo != null) {
            parentCheck = validateParentSegmentEligibility(parentInfo);
        }
    }
    if (parentCheck == null) {
        // The parent is not registered in the metadata. Get required info from Storage and don't map it unnecessarily.
        parentCheck = this.storage.getStreamSegmentInfo(parentStreamSegmentName, timer.getRemaining()).thenCompose(this::validateParentSegmentEligibility);
    }
    String transactionName = StreamSegmentNameUtils.getTransactionNameFromId(parentStreamSegmentName, transactionId);
    return parentCheck.thenComposeAsync(parentId -> createSegmentInStorageWithRecovery(transactionName, attributes, timer), this.executor).thenApply(v -> {
        LoggerHelpers.traceLeave(log, traceObjectId, "createNewTransactionStreamSegment", traceId, parentStreamSegmentName, transactionName);
        return transactionName;
    });
}
Also used : Storage(io.pravega.segmentstore.storage.Storage) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) SegmentRollingPolicy(io.pravega.segmentstore.storage.SegmentRollingPolicy) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Exceptions(io.pravega.common.Exceptions) RequiredArgsConstructor(lombok.RequiredArgsConstructor) ContainerMetadata(io.pravega.segmentstore.server.ContainerMetadata) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) Duration(java.time.Duration) BiConsumer(java.util.function.BiConsumer) StreamSegmentMapOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentMapOperation) LoggerHelpers(io.pravega.common.LoggerHelpers) Attributes(io.pravega.segmentstore.contracts.Attributes) TimeoutTimer(io.pravega.common.TimeoutTimer) Executor(java.util.concurrent.Executor) Collection(java.util.Collection) OperationLog(io.pravega.segmentstore.server.OperationLog) CompletionException(java.util.concurrent.CompletionException) ThreadSafe(javax.annotation.concurrent.ThreadSafe) UUID(java.util.UUID) GuardedBy(javax.annotation.concurrent.GuardedBy) StreamSegmentNameUtils(io.pravega.shared.segment.StreamSegmentNameUtils) Slf4j(lombok.extern.slf4j.Slf4j) AsyncMap(io.pravega.common.util.AsyncMap) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Futures(io.pravega.common.concurrent.Futures) NotThreadSafe(javax.annotation.concurrent.NotThreadSafe) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) TimeoutTimer(io.pravega.common.TimeoutTimer)

Aggregations

Storage (io.pravega.segmentstore.storage.Storage)32 Test (org.junit.Test)22 lombok.val (lombok.val)18 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)15 Operation (io.pravega.segmentstore.server.logs.operations.Operation)15 Duration (java.time.Duration)15 Cleanup (lombok.Cleanup)15 ByteArrayInputStream (java.io.ByteArrayInputStream)14 Futures (io.pravega.common.concurrent.Futures)13 DataCorruptionException (io.pravega.segmentstore.server.DataCorruptionException)13 SegmentMetadata (io.pravega.segmentstore.server.SegmentMetadata)13 StreamSegmentAppendOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation)13 CompletableFuture (java.util.concurrent.CompletableFuture)13 StorageOperation (io.pravega.segmentstore.server.logs.operations.StorageOperation)12 Exceptions (io.pravega.common.Exceptions)11 UpdateableSegmentMetadata (io.pravega.segmentstore.server.UpdateableSegmentMetadata)11 CompletionException (java.util.concurrent.CompletionException)11 AtomicLong (java.util.concurrent.atomic.AtomicLong)11 InputStream (java.io.InputStream)10 UpdateableContainerMetadata (io.pravega.segmentstore.server.UpdateableContainerMetadata)9