Search in sources :

Example 1 with BadKeyVersionException

use of io.pravega.segmentstore.contracts.tables.BadKeyVersionException in project pravega by pravega.

the class TableSegmentLayoutTestBase method conditionalUpdateCheck.

private void conditionalUpdateCheck(Map<BufferView, BufferView> expectedEntries, Collection<BufferView> nonExistentKeys, ContainerTableExtension ext) throws Exception {
    for (val e : expectedEntries.entrySet()) {
        val te = TableEntry.versioned(e.getKey(), e.getValue(), 1234L);
        AssertExtensions.assertSuppliedFutureThrows("Expected the update to have failed with BadKeyVersionException.", () -> ext.put(SEGMENT_NAME, Collections.singletonList(te), TIMEOUT), ex -> ex instanceof BadKeyVersionException);
    }
}
Also used : lombok.val(lombok.val) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException)

Example 2 with BadKeyVersionException

use of io.pravega.segmentstore.contracts.tables.BadKeyVersionException in project pravega by pravega.

the class TableBasedMetadataStoreMockTests method testBadKeyVersionExceptionDuringWrite.

@Test
public void testBadKeyVersionExceptionDuringWrite() {
    TableStore mockTableStore = mock(TableStore.class);
    @Cleanup TableBasedMetadataStore tableBasedMetadataStore = new TableBasedMetadataStore("test", mockTableStore, ChunkedSegmentStorageConfig.DEFAULT_CONFIG, executorService());
    when(mockTableStore.createSegment(any(), any(), any())).thenReturn(Futures.failedFuture(new CompletionException(new StreamSegmentExistsException("test"))));
    // Throw BadKeyVersionException exception
    Exception e = new CompletionException(new BadKeyVersionException("test", new HashMap<>()));
    val td = BaseMetadataStore.TransactionData.builder().key("foo").version(1L).dbObject(2L).build();
    CompletableFuture<List<Long>> f = new CompletableFuture<>();
    f.completeExceptionally(e);
    when(mockTableStore.put(anyString(), any(), any())).thenReturn(f);
    AssertExtensions.assertFutureThrows("write should throw an excpetion", tableBasedMetadataStore.writeAll(Collections.singleton(td)), ex -> ex instanceof StorageMetadataVersionMismatchException && ex.getCause() == e.getCause());
}
Also used : BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) lombok.val(lombok.val) HashMap(java.util.HashMap) Cleanup(lombok.Cleanup) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) DataLogWriterNotPrimaryException(io.pravega.segmentstore.storage.DataLogWriterNotPrimaryException) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) TableStore(io.pravega.segmentstore.contracts.tables.TableStore) InMemoryTableStore(io.pravega.segmentstore.storage.mocks.InMemoryTableStore) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) ArrayList(java.util.ArrayList) List(java.util.List) Test(org.junit.Test)

Example 3 with BadKeyVersionException

use of io.pravega.segmentstore.contracts.tables.BadKeyVersionException in project pravega by pravega.

the class TableMetadataStore method createSegment.

@Override
protected CompletableFuture<Void> createSegment(String segmentName, ArrayView segmentInfo, TimeoutTimer timer) {
    ensureInitialized();
    TableEntry entry = TableEntry.notExists(getTableKey(segmentName), segmentInfo);
    return this.tableStore.put(this.metadataSegmentName, Collections.singletonList(entry), timer.getRemaining()).handle((ignored, ex) -> {
        if (ex != null) {
            if (Exceptions.unwrap(ex) instanceof BadKeyVersionException) {
                ex = new StreamSegmentExistsException(segmentName);
            }
            throw new CompletionException(ex);
        }
        return null;
    });
}
Also used : TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) CompletionException(java.util.concurrent.CompletionException)

Example 4 with BadKeyVersionException

use of io.pravega.segmentstore.contracts.tables.BadKeyVersionException in project pravega by pravega.

the class ContainerKeyIndex method validateConditionalUpdateFailures.

private CompletableFuture<Void> validateConditionalUpdateFailures(DirectSegmentAccess segment, Map<TableKey, Long> expectedVersions, TimeoutTimer timer) {
    assert !expectedVersions.isEmpty();
    val bucketReader = TableBucketReader.key(segment, this::getBackpointerOffset, this.executor);
    val searches = expectedVersions.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> findBucketEntry(segment, bucketReader, e.getKey().getKey(), e.getValue(), timer)));
    return Futures.allOf(searches.values()).thenRun(() -> {
        val failed = new HashMap<TableKey, Long>();
        for (val e : searches.entrySet()) {
            val actual = e.getValue().join();
            boolean isValid = actual == null ? e.getKey().getVersion() == TableKey.NOT_EXISTS : e.getKey().getVersion() == actual.getVersion();
            if (!isValid) {
                failed.put(e.getKey(), actual == null ? TableKey.NOT_EXISTS : actual.getVersion());
            }
        }
        if (!failed.isEmpty()) {
            throw new CompletionException(new BadKeyVersionException(segment.getInfo().getName(), failed));
        }
    });
}
Also used : lombok.val(lombok.val) ScheduledFuture(java.util.concurrent.ScheduledFuture) SneakyThrows(lombok.SneakyThrows) RequiredArgsConstructor(lombok.RequiredArgsConstructor) TimeoutException(java.util.concurrent.TimeoutException) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Map(java.util.Map) AsyncReadResultProcessor(io.pravega.segmentstore.server.reading.AsyncReadResultProcessor) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) SegmentStoreMetrics(io.pravega.segmentstore.server.SegmentStoreMetrics) Predicate(java.util.function.Predicate) NonNull(lombok.NonNull) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CompletionException(java.util.concurrent.CompletionException) ThreadSafe(javax.annotation.concurrent.ThreadSafe) UUID(java.util.UUID) GuardedBy(javax.annotation.concurrent.GuardedBy) Collectors(java.util.stream.Collectors) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Futures(io.pravega.common.concurrent.Futures) ReadResult(io.pravega.segmentstore.contracts.ReadResult) CacheManager(io.pravega.segmentstore.server.CacheManager) ObjectClosedException(io.pravega.common.ObjectClosedException) TableAttributes(io.pravega.segmentstore.contracts.tables.TableAttributes) Getter(lombok.Getter) 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) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) TableSegmentNotEmptyException(io.pravega.segmentstore.contracts.tables.TableSegmentNotEmptyException) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) MultiKeySequentialProcessor(io.pravega.common.concurrent.MultiKeySequentialProcessor) ConditionalTableUpdateException(io.pravega.segmentstore.contracts.tables.ConditionalTableUpdateException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) StreamSegmentTruncatedException(io.pravega.segmentstore.contracts.StreamSegmentTruncatedException) TimeoutTimer(io.pravega.common.TimeoutTimer) KeyNotExistsException(io.pravega.segmentstore.contracts.tables.KeyNotExistsException) lombok.val(lombok.val) IOException(java.io.IOException) Maps(com.google.common.collect.Maps) Timer(io.pravega.common.Timer) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) AsyncSemaphore(io.pravega.common.concurrent.AsyncSemaphore) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) CompletionException(java.util.concurrent.CompletionException) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 5 with BadKeyVersionException

use of io.pravega.segmentstore.contracts.tables.BadKeyVersionException in project pravega by pravega.

the class ContainerKeyIndex method validateConditionalUpdate.

/**
 * Validates a list of UpdateBatchItems against their actual Table Bucket offsets.
 *
 * @param items         A list of {@link TableKeyBatch.Item} instances to validate.
 * @param bucketOffsets A Map of Key Hashes to their corresponding offsets (versions). Each {@link TableKeyBatch.Item}
 *                      will be looked up in this Map (based on the Item's KeyHash) and validated appropriately.
 * @param segmentName   The name of the segment on which the update is performed.
 * @throws KeyNotExistsException  If an UpdateBatchItem's Key does not exist in the Table but the item's version does
 *                                not indicate that the key must not exist.
 * @throws BadKeyVersionException If an UpdateBatchItem's Key does exist in the Table but the item's version is
 *                                different from that key's version.
 */
@SneakyThrows(ConditionalTableUpdateException.class)
private void validateConditionalUpdate(List<TableKeyBatch.Item> items, Map<UUID, Long> bucketOffsets, String segmentName) {
    // Key = Key that failed, Value = Key's bucket offset.
    val badKeyVersions = new HashMap<TableKey, Long>();
    for (val item : items) {
        // Validate compareVersion.
        TableKey key = item.getKey();
        Long bucketOffset = bucketOffsets.get(item.getHash());
        assert key.hasVersion() : "validateConditionalUpdate for TableKey with no compare version";
        if (bucketOffset == TableKey.NOT_EXISTS) {
            if (key.getVersion() != TableKey.NOT_EXISTS) {
                // Key does not exist, but the conditional update provided a specific version.
                throw new KeyNotExistsException(segmentName, key.getKey());
            }
        } else if (bucketOffset != key.getVersion()) {
            // Key does exist, but has the wrong version.
            badKeyVersions.put(key, bucketOffset);
        }
    }
    if (!badKeyVersions.isEmpty()) {
        // Throw the bad key version in bulk - helps speed verification.
        throw new BadKeyVersionException(segmentName, badKeyVersions);
    }
// All validations for all items passed.
}
Also used : lombok.val(lombok.val) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) KeyNotExistsException(io.pravega.segmentstore.contracts.tables.KeyNotExistsException) AtomicLong(java.util.concurrent.atomic.AtomicLong) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) SneakyThrows(lombok.SneakyThrows)

Aggregations

BadKeyVersionException (io.pravega.segmentstore.contracts.tables.BadKeyVersionException)10 lombok.val (lombok.val)9 KeyNotExistsException (io.pravega.segmentstore.contracts.tables.KeyNotExistsException)6 HashMap (java.util.HashMap)6 CompletableFuture (java.util.concurrent.CompletableFuture)6 CompletionException (java.util.concurrent.CompletionException)6 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 Exceptions (io.pravega.common.Exceptions)3 Timer (io.pravega.common.Timer)3 Futures (io.pravega.common.concurrent.Futures)3 BufferView (io.pravega.common.util.BufferView)3 TableKey (io.pravega.segmentstore.contracts.tables.TableKey)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 AtomicLong (java.util.concurrent.atomic.AtomicLong)3 SneakyThrows (lombok.SneakyThrows)3 Maps (com.google.common.collect.Maps)2 ObjectClosedException (io.pravega.common.ObjectClosedException)2