Search in sources :

Example 1 with PreWriteCheck

use of com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.PreWriteCheck in project fdb-record-layer by FoundationDB.

the class ResolverCreateHooksTest method testPreWriteChecks.

@Test
void testPreWriteChecks() {
    // reads the key, and chooses the resolver based on the value
    final PreWriteCheck check = (context, providedResolver) -> {
        CompletableFuture<LocatableResolver> expectedResolverFuture = root().add("should-use-A").toTupleAsync(context).thenCompose(keyTuple -> context.ensureActive().get(keyTuple.pack())).thenApply(value -> {
            boolean useA = Tuple.fromBytes(value).getBoolean(0);
            return new ScopedInterningLayer(database, resolverPath(context, useA ? "A" : "B"));
        });
        return expectedResolverFuture.thenApply(expectedResolver -> expectedResolver.equals(providedResolver));
    };
    final ResolverCreateHooks hooks = new ResolverCreateHooks(check, ResolverCreateHooks.DEFAULT_HOOK);
    // use resolver A
    database.run(context -> root().add("should-use-A").toTupleAsync(context).thenAccept(tuple -> context.ensureActive().set(tuple.pack(), Tuple.from(true).pack())));
    try (FDBRecordContext context = database.openContext()) {
        LocatableResolver resolverA = new ScopedInterningLayer(database, resolverPath(context, "A"));
        LocatableResolver resolverB = new ScopedInterningLayer(database, resolverPath(context, "B"));
        assertChecks(context, resolverA, hooks, true);
        assertChecks(context, resolverB, hooks, false);
    }
    // use resolver B
    database.run(context -> root().add("should-use-A").toTupleAsync(context).thenAccept(tuple -> context.ensureActive().set(tuple.pack(), Tuple.from(false).pack())));
    // after migration
    try (FDBRecordContext context = database.openContext()) {
        LocatableResolver resolverA = new ScopedInterningLayer(database, resolverPath(context, "A"));
        LocatableResolver resolverB = new ScopedInterningLayer(database, resolverPath(context, "B"));
        assertChecks(context, resolverA, hooks, false);
        assertChecks(context, resolverB, hooks, true);
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Tags(com.apple.test.Tags) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) ScopedInterningLayer(com.apple.foundationdb.record.provider.foundationdb.layers.interning.ScopedInterningLayer) Collectors(java.util.stream.Collectors) FDBTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBTestBase) Test(org.junit.jupiter.api.Test) Tuple(com.apple.foundationdb.tuple.Tuple) AfterEach(org.junit.jupiter.api.AfterEach) List(java.util.List) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) PreWriteCheck(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.PreWriteCheck) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) Tag(org.junit.jupiter.api.Tag) CompletableFuture(java.util.concurrent.CompletableFuture) PreWriteCheck(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.PreWriteCheck) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScopedInterningLayer(com.apple.foundationdb.record.provider.foundationdb.layers.interning.ScopedInterningLayer) Test(org.junit.jupiter.api.Test)

Example 2 with PreWriteCheck

use of com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.PreWriteCheck in project fdb-record-layer by FoundationDB.

the class LocatableResolverTest method testWriteSafetyCheck.

@Test
public void testWriteSafetyCheck() {
    KeySpace keySpace = new KeySpace(new KeySpaceDirectory("path1", KeyType.STRING, "path1"), new KeySpaceDirectory("path2", KeyType.STRING, "path2"));
    final LocatableResolver path1Resolver;
    final LocatableResolver path2Resolver;
    try (FDBRecordContext context = database.openContext()) {
        ResolvedKeySpacePath path1 = keySpace.path("path1").toResolvedPath(context);
        ResolvedKeySpacePath path2 = keySpace.path("path2").toResolvedPath(context);
        path1Resolver = resolverFactory.create(path1);
        path2Resolver = resolverFactory.create(path2);
    }
    PreWriteCheck validCheck = (context, resolver) -> CompletableFuture.completedFuture(Objects.equals(path1Resolver, resolver));
    PreWriteCheck invalidCheck = (context, resolver) -> CompletableFuture.completedFuture(Objects.equals(path2Resolver, resolver));
    ResolverCreateHooks validHooks = new ResolverCreateHooks(validCheck, DEFAULT_HOOK);
    ResolverCreateHooks invalidHooks = new ResolverCreateHooks(invalidCheck, DEFAULT_HOOK);
    Long value = path1Resolver.resolve("some-key", validHooks).join();
    try (FDBRecordContext context = database.openContext()) {
        assertThat("it succeeds and writes the value", path1Resolver.mustResolve(context, "some-key").join(), is(value));
    }
    assertThat("when reading the same key it doesn't perform the check", path1Resolver.resolve("some-key", invalidHooks).join(), is(value));
    try {
        path1Resolver.resolve("another-key", invalidHooks).join();
        fail("should throw CompletionException");
    } catch (CompletionException ex) {
        assertThat("it has the correct cause", ex.getCause(), is(instanceOf(LocatableResolverLockedException.class)));
        assertThat(ex, hasMessageContaining("prewrite check failed"));
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) CoreMatchers.hasItem(org.hamcrest.CoreMatchers.hasItem) BiFunction(java.util.function.BiFunction) Matchers.not(org.hamcrest.Matchers.not) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Random(java.util.Random) LocatableResolverLockedException(com.apple.foundationdb.record.provider.foundationdb.keyspace.LocatableResolver.LocatableResolverLockedException) TestHelpers.consistently(com.apple.foundationdb.record.TestHelpers.consistently) Matchers.hasKey(org.hamcrest.Matchers.hasKey) ExceptionMessageMatcher.hasMessageContaining(com.apple.foundationdb.record.TestHelpers.ExceptionMessageMatcher.hasMessageContaining) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) Tuple(com.apple.foundationdb.tuple.Tuple) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Is.is(org.hamcrest.core.Is.is) Assertions.assertAll(org.junit.jupiter.api.Assertions.assertAll) Tag(org.junit.jupiter.api.Tag) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) Matchers.allOf(org.hamcrest.Matchers.allOf) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) Set(java.util.Set) CompletionException(java.util.concurrent.CompletionException) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) FDBRecordContextConfig(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContextConfig) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) List(java.util.List) Matchers.contains(org.hamcrest.Matchers.contains) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Optional(java.util.Optional) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) CacheBuilder(com.google.common.cache.CacheBuilder) DEFAULT_CHECK(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.DEFAULT_CHECK) CacheStats(com.google.common.cache.CacheStats) FDBDatabaseFactoryImpl(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactoryImpl) IntStream(java.util.stream.IntStream) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) MetadataHook(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.MetadataHook) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) Supplier(java.util.function.Supplier) FDBTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBTestBase) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) TestHelpers.eventually(com.apple.foundationdb.record.TestHelpers.eventually) KeyType(com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpaceDirectory.KeyType) ImmutableList(com.google.common.collect.ImmutableList) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) ScanProperties(com.apple.foundationdb.record.ScanProperties) BooleanSource(com.apple.test.BooleanSource) Matchers.hasSize(org.hamcrest.Matchers.hasSize) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) NoSuchElementException(java.util.NoSuchElementException) Nonnull(javax.annotation.Nonnull) CoreMatchers.nullValue(org.hamcrest.CoreMatchers.nullValue) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) Tags(com.apple.test.Tags) TimeUnit(java.util.concurrent.TimeUnit) DEFAULT_HOOK(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.DEFAULT_HOOK) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) PreWriteCheck(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.PreWriteCheck) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) Cache(com.google.common.cache.Cache) Collections(java.util.Collections) LocatableResolverLockedException(com.apple.foundationdb.record.provider.foundationdb.keyspace.LocatableResolver.LocatableResolverLockedException) PreWriteCheck(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.PreWriteCheck) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) CompletionException(java.util.concurrent.CompletionException) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

FDBDatabase (com.apple.foundationdb.record.provider.foundationdb.FDBDatabase)2 FDBDatabaseFactory (com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory)2 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)2 FDBTestBase (com.apple.foundationdb.record.provider.foundationdb.FDBTestBase)2 PreWriteCheck (com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.PreWriteCheck)2 Tuple (com.apple.foundationdb.tuple.Tuple)2 Tags (com.apple.test.Tags)2 List (java.util.List)2 Random (java.util.Random)2 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)1 MoreAsyncUtil (com.apple.foundationdb.async.MoreAsyncUtil)1 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)1 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)1 ScanProperties (com.apple.foundationdb.record.ScanProperties)1 ExceptionMessageMatcher.hasMessageContaining (com.apple.foundationdb.record.TestHelpers.ExceptionMessageMatcher.hasMessageContaining)1 TestHelpers.consistently (com.apple.foundationdb.record.TestHelpers.consistently)1 TestHelpers.eventually (com.apple.foundationdb.record.TestHelpers.eventually)1 FDBDatabaseFactoryImpl (com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactoryImpl)1 FDBRecordContextConfig (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContextConfig)1 FDBStoreTimer (com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer)1