Search in sources :

Example 1 with StreamSegmentExistsException

use of io.pravega.segmentstore.contracts.StreamSegmentExistsException in project pravega by pravega.

the class StreamSegmentMapperTests method testCreateTransactionAlreadyExists.

/**
 * Tests the ability of the StreamSegmentMapper to create a new Transaction if the Transaction already exists (partially
 * or fully).
 */
@Test
public void testCreateTransactionAlreadyExists() {
    final String parentSegmentName = "NewSegment";
    final UUID txnId = UUID.randomUUID();
    final String txnName = StreamSegmentNameUtils.getTransactionNameFromId(parentSegmentName, txnId);
    testCreateAlreadyExists(txnName, (mapper, attributes) -> mapper.createNewStreamSegment(parentSegmentName, null, TIMEOUT).exceptionally(ex -> {
        if (Exceptions.unwrap(ex) instanceof StreamSegmentExistsException) {
            return null;
        }
        throw new CompletionException(ex);
    }).thenCompose(v -> mapper.createNewTransactionStreamSegment(parentSegmentName, txnId, attributes, TIMEOUT)));
}
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) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) CompletionException(java.util.concurrent.CompletionException) UUID(java.util.UUID) Test(org.junit.Test)

Example 2 with StreamSegmentExistsException

use of io.pravega.segmentstore.contracts.StreamSegmentExistsException 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 3 with StreamSegmentExistsException

use of io.pravega.segmentstore.contracts.StreamSegmentExistsException in project pravega by pravega.

the class AppendProcessor method handleException.

private void handleException(UUID writerId, long requestId, String segment, String doingWhat, Throwable u) {
    if (u == null) {
        IllegalStateException exception = new IllegalStateException("No exception to handle.");
        log.error("Append processor: Error {} on segment = '{}'", doingWhat, segment, exception);
        throw exception;
    }
    u = Exceptions.unwrap(u);
    if (u instanceof StreamSegmentExistsException) {
        log.warn("Segment '{}' already exists and {} cannot perform operation '{}'.", segment, writerId, doingWhat);
        connection.send(new SegmentAlreadyExists(requestId, segment));
    } else if (u instanceof StreamSegmentNotExistsException) {
        log.warn("Segment '{}' does not exist and {} cannot perform operation '{}'.", segment, writerId, doingWhat);
        connection.send(new NoSuchSegment(requestId, segment));
    } else if (u instanceof StreamSegmentSealedException) {
        log.info("Segment '{}' is sealed and {} cannot perform operation '{}'.", segment, writerId, doingWhat);
        connection.send(new SegmentIsSealed(requestId, segment));
    } else if (u instanceof ContainerNotFoundException) {
        int containerId = ((ContainerNotFoundException) u).getContainerId();
        log.warn("Wrong host. Segment '{}' (Container {}) is not owned and {} cannot perform operation '{}'.", segment, containerId, writerId, doingWhat);
        connection.send(new WrongHost(requestId, segment, ""));
    } else if (u instanceof BadAttributeUpdateException) {
        log.warn("Bad attribute update by {} on segment {}.", writerId, segment, u);
        connection.send(new InvalidEventNumber(writerId, requestId));
        connection.close();
    } else if (u instanceof TooManyAttributesException) {
        log.warn("Attribute limit would be exceeded by {} on segment {}.", writerId, segment, u);
        connection.send(new InvalidEventNumber(writerId, requestId));
        connection.close();
    } else if (u instanceof AuthenticationException) {
        log.warn("Token check failed while being written by {} on segment {}.", writerId, segment, u);
        connection.send(new WireCommands.AuthTokenCheckFailed(requestId));
        connection.close();
    } else if (u instanceof UnsupportedOperationException) {
        log.warn("Unsupported Operation '{}'.", doingWhat, u);
        connection.send(new OperationUnsupported(requestId, doingWhat));
    } else {
        log.error("Error (Segment = '{}', Operation = 'append')", segment, u);
        // Closing connection should reinitialize things, and hopefully fix the problem
        connection.close();
    }
}
Also used : TooManyAttributesException(io.pravega.segmentstore.contracts.TooManyAttributesException) OperationUnsupported(io.pravega.shared.protocol.netty.WireCommands.OperationUnsupported) AuthenticationException(io.pravega.common.auth.AuthenticationException) WrongHost(io.pravega.shared.protocol.netty.WireCommands.WrongHost) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) SegmentAlreadyExists(io.pravega.shared.protocol.netty.WireCommands.SegmentAlreadyExists) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) SegmentIsSealed(io.pravega.shared.protocol.netty.WireCommands.SegmentIsSealed) BadAttributeUpdateException(io.pravega.segmentstore.contracts.BadAttributeUpdateException) InvalidEventNumber(io.pravega.shared.protocol.netty.WireCommands.InvalidEventNumber) NoSuchSegment(io.pravega.shared.protocol.netty.WireCommands.NoSuchSegment) WireCommands(io.pravega.shared.protocol.netty.WireCommands) ContainerNotFoundException(io.pravega.segmentstore.contracts.ContainerNotFoundException)

Example 4 with StreamSegmentExistsException

use of io.pravega.segmentstore.contracts.StreamSegmentExistsException in project pravega by pravega.

the class StreamSegmentMapper method createNewStreamSegment.

// endregion
// region Create Segments
/**
 * Creates a new StreamSegment with given name (in Storage) and persists the given attributes (in Storage).
 *
 * @param streamSegmentName The case-sensitive StreamSegment Name.
 * @param attributes        The initial attributes for the StreamSegment, if any.
 * @param timeout           Timeout for the operation.
 * @return A CompletableFuture that, when completed normally, will indicate the operation completed normally.
 * If the operation failed, this will contain the exception that caused the failure.
 */
public CompletableFuture<Void> createNewStreamSegment(String streamSegmentName, Collection<AttributeUpdate> attributes, Duration timeout) {
    long traceId = LoggerHelpers.traceEnterWithContext(log, traceObjectId, "createNewStreamSegment", streamSegmentName);
    long segmentId = this.containerMetadata.getStreamSegmentId(streamSegmentName, true);
    if (isValidStreamSegmentId(segmentId)) {
        // Quick fail: see if this is an active Segment, and if so, don't bother with anything else.
        return Futures.failedFuture(new StreamSegmentExistsException(streamSegmentName));
    }
    CompletableFuture<Void> result = createSegmentInStorageWithRecovery(streamSegmentName, attributes, new TimeoutTimer(timeout));
    if (log.isTraceEnabled()) {
        result.thenAccept(v -> LoggerHelpers.traceLeave(log, traceObjectId, "createNewStreamSegment", traceId, streamSegmentName));
    }
    return result;
}
Also used : StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) TimeoutTimer(io.pravega.common.TimeoutTimer)

Example 5 with StreamSegmentExistsException

use of io.pravega.segmentstore.contracts.StreamSegmentExistsException in project pravega by pravega.

the class ClientAdapterBase method createStream.

@Override
public CompletableFuture<Void> createStream(String streamName, Duration timeout) {
    ensureRunning();
    return CompletableFuture.runAsync(() -> {
        if (this.streamWriters.containsKey(streamName)) {
            throw new CompletionException(new StreamSegmentExistsException(streamName));
        }
        StreamConfiguration config = StreamConfiguration.builder().streamName(streamName).scalingPolicy(ScalingPolicy.fixed(this.testConfig.getSegmentsPerStream())).scope(SCOPE).build();
        if (!getStreamManager().createStream(SCOPE, streamName, config)) {
            throw new CompletionException(new StreamingException(String.format("Unable to create Stream '%s'.", streamName)));
        }
        int writerCount = Math.max(1, this.testConfig.getProducerCount() / this.testConfig.getStreamCount());
        List<EventStreamWriter<byte[]>> writers = new ArrayList<>(writerCount);
        if (this.streamWriters.putIfAbsent(streamName, writers) == null) {
            for (int i = 0; i < writerCount; i++) {
                writers.add(getClientFactory().createEventWriter(streamName, SERIALIZER, WRITER_CONFIG));
            }
        }
    }, this.testExecutor);
}
Also used : StreamingException(io.pravega.segmentstore.contracts.StreamingException) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) CompletionException(java.util.concurrent.CompletionException) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) ArrayList(java.util.ArrayList) EventStreamWriter(io.pravega.client.stream.EventStreamWriter)

Aggregations

StreamSegmentExistsException (io.pravega.segmentstore.contracts.StreamSegmentExistsException)12 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)5 lombok.val (lombok.val)5 CompletionException (java.util.concurrent.CompletionException)4 Test (org.junit.Test)4 StreamSegmentSealedException (io.pravega.segmentstore.contracts.StreamSegmentSealedException)3 SegmentHandle (io.pravega.segmentstore.storage.SegmentHandle)3 Storage (io.pravega.segmentstore.storage.Storage)3 InMemoryStorage (io.pravega.segmentstore.storage.mocks.InMemoryStorage)3 ArrayList (java.util.ArrayList)3 Cleanup (lombok.Cleanup)3 Service (com.google.common.util.concurrent.Service)2 Exceptions (io.pravega.common.Exceptions)2 MathHelpers (io.pravega.common.MathHelpers)2 Futures (io.pravega.common.concurrent.Futures)2 AsyncMap (io.pravega.common.util.AsyncMap)2 AttributeUpdate (io.pravega.segmentstore.contracts.AttributeUpdate)2 AttributeUpdateType (io.pravega.segmentstore.contracts.AttributeUpdateType)2 Attributes (io.pravega.segmentstore.contracts.Attributes)2 SegmentProperties (io.pravega.segmentstore.contracts.SegmentProperties)2