Search in sources :

Example 16 with MagicKey

use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.

the class DenyReadWriteRemoveAllTest method beforeSplit.

@Override
protected void beforeSplit() {
    // Put values locally before the split as an AvaililibityException will be thrown during the split
    conflictKey = new MagicKey(cache(p0.node(0)), cache(p1.node(0)));
    cache(p0.node(0)).put(conflictKey, "V1");
    cache(p1.node(0)).getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL).put(conflictKey, "V2");
}
Also used : MagicKey(org.infinispan.distribution.MagicKey)

Example 17 with MagicKey

use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.

the class PessimisticReplTxTest method createCacheManagers.

@Override
protected void createCacheManagers() throws Throwable {
    final ConfigurationBuilder conf = buildConfiguration();
    createCluster(TestDataSCI.INSTANCE, conf, 2);
    waitForClusterToForm();
    k = new MagicKey(cache(0));
}
Also used : ConfigurationBuilder(org.infinispan.configuration.cache.ConfigurationBuilder) MagicKey(org.infinispan.distribution.MagicKey)

Example 18 with MagicKey

use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.

the class NonTxPrimaryOwnerLeavingTest method doTest.

private void doTest(TestWriteOperation operation, boolean blockTopologyOnOriginator) throws Exception {
    final AdvancedCache<Object, Object> cache0 = advancedCache(0);
    AdvancedCache<Object, Object> cache1 = advancedCache(1);
    AdvancedCache<Object, Object> cache2 = advancedCache(2);
    TopologyUpdateListener listener0 = new TopologyUpdateListener();
    cache0.addListener(listener0);
    TopologyUpdateListener listener2 = new TopologyUpdateListener();
    cache2.addListener(listener2);
    // Block remote put commands invoked from cache0
    ControlledRpcManager crm = ControlledRpcManager.replaceRpcManager(cache0);
    crm.excludeCommands(StateTransferStartCommand.class, StateResponseCommand.class);
    // Try to put a key/value from cache0 with cache1 the primary owner
    final MagicKey key = new MagicKey(cache1);
    Future<Object> future = fork(() -> operation.perform(cache0, key));
    // After the write command was sent, kill cache1
    ControlledRpcManager.BlockedRequest blockedWrite = crm.expectCommand(operation.getCommandClass());
    cache1.stop();
    if (!blockTopologyOnOriginator) {
        listener0.unblockOnce();
        listener0.waitForTopologyToFinish();
    }
    // Now that cache1 is stopped, unblock the write command and wait for the responses
    blockedWrite.send().expectResponse(address(1), CacheNotFoundResponse.INSTANCE).receive();
    if (blockTopologyOnOriginator) {
        // The retry should be blocked on the originator until we unblock the topology update
        crm.expectNoCommand(100, TimeUnit.MILLISECONDS);
        listener0.unblockOnce();
        listener0.waitForTopologyToFinish();
    }
    // Install the new topology without cache1 on cache2 as well
    listener2.unblockOnce();
    listener2.waitForTopologyToFinish();
    // Retry the write command with a single owner (rebalance topology is blocked).
    if (!cache0.getDistributionManager().getCacheTopology().getDistribution(key).isPrimary()) {
        crm.expectCommand(operation.getCommandClass()).send().receiveAll();
    }
    // Check that the put command didn't fail
    Object result = future.get(10, TimeUnit.SECONDS);
    assertNull(result);
    log.tracef("Write operation is done");
    cache0.removeListener(listener0);
    cache2.removeListener(listener2);
    listener0.unblockOnce();
    listener0.unblockOnce();
    crm.stopBlocking();
    // Check the value on the remaining node
    assertEquals(operation.getValue(), cache0.get(key));
    assertEquals(operation.getValue(), cache2.get(key));
}
Also used : ControlledRpcManager(org.infinispan.util.ControlledRpcManager) MagicKey(org.infinispan.distribution.MagicKey)

Example 19 with MagicKey

use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.

the class BaseTxStateTransferOverwriteTest method doStateTransferInBetweenPrepareCommit.

protected void doStateTransferInBetweenPrepareCommit(final TestWriteOperation op, final boolean additionalValueOnNonOwner) throws Exception {
    // Test scenario:
    // cache0,1,2 are in the cluster, an owner leaves
    // Key k is in the cache, and is transferred to the non owner
    // A user operation also modifies key k causing an invalidation
    // on the non owner which is getting the state transfer
    final AdvancedCache<Object, Object> primaryOwnerCache = advancedCache(0, cacheName);
    final AdvancedCache<Object, Object> backupOwnerCache = advancedCache(1, cacheName);
    final AdvancedCache<Object, Object> nonOwnerCache = advancedCache(2, cacheName);
    final MagicKey key = new MagicKey(op + "-key", cache(0, cacheName), cache(1, cacheName));
    // Prepare for replace/remove: put a previous value in cache0
    final Object previousValue = op.getPreviousValue();
    if (previousValue != null) {
        primaryOwnerCache.put(key, previousValue);
        assertEquals(previousValue, primaryOwnerCache.get(key));
        log.tracef("Previous value inserted: %s = %s", key, previousValue);
        assertEquals(previousValue, nonOwnerCache.get(key));
        if (l1Enabled()) {
            assertIsInL1(nonOwnerCache, key);
        }
    }
    // Need to block after Prepare command was sent after it clears the StateTransferInterceptor
    final CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
    try {
        TransactionManager tm = primaryOwnerCache.getTransactionManager();
        Future<?> future = fork(runWithTx(tm, () -> {
            if (additionalValueOnNonOwner) {
                MagicKey mk = new MagicKey("placeholder", nonOwnerCache);
                String value = "somevalue";
                primaryOwnerCache.put(mk, value);
                log.tracef("Adding additional value on nonOwner value inserted: %s = %s", mk, value);
            }
            extractInterceptorChain(primaryOwnerCache).addInterceptorBefore(new BlockingInterceptor<>(cyclicBarrier, getVisitableCommand(op), true, false), StateTransferInterceptor.class);
            return op.perform(primaryOwnerCache, key);
        }));
        cyclicBarrier.await(10, SECONDS);
        // After the barrier  has been hit remove the interceptor, since we can just wake it up through the barrier,
        // this way the state transfer won't be blocked if the normal put occurs before it.
        removeAllBlockingInterceptorsFromCache(primaryOwnerCache);
        // Block the rebalance confirmation on nonOwnerCache
        CheckPoint checkPoint = new CheckPoint();
        log.trace("Adding proxy to state transfer");
        waitUntilStateBeingTransferred(nonOwnerCache, checkPoint);
        backupOwnerCache.getCacheManager().stop();
        // Wait for non owner to just about get state
        checkPoint.awaitStrict("pre_state_apply_invoked_for_" + nonOwnerCache, 10, SECONDS);
        // let prepare complete and thus commit command invalidating on nonOwner
        cyclicBarrier.await(10, SECONDS);
        assertEquals(op.getReturnValue(), future.get(10, SECONDS));
        // let state transfer go
        checkPoint.trigger("pre_state_apply_release_for_" + nonOwnerCache);
        TestingUtil.waitForNoRebalance(primaryOwnerCache, nonOwnerCache);
        switch(op) {
            case REMOVE:
            case REMOVE_EXACT:
                break;
            default:
                assertIsInContainerImmortal(primaryOwnerCache, key);
                assertIsInContainerImmortal(nonOwnerCache, key);
                break;
        }
        // Check the value to make sure data container contains correct value
        assertEquals(op.getValue(), primaryOwnerCache.get(key));
        assertEquals(op.getValue(), nonOwnerCache.get(key));
    } finally {
        removeAllBlockingInterceptorsFromCache(primaryOwnerCache);
    }
}
Also used : BlockingInterceptor(org.infinispan.distribution.BlockingInterceptor) StateTransferInterceptor(org.infinispan.statetransfer.StateTransferInterceptor) TransactionManager(javax.transaction.TransactionManager) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) MagicKey(org.infinispan.distribution.MagicKey) CyclicBarrier(java.util.concurrent.CyclicBarrier) CheckPoint(org.infinispan.test.fwk.CheckPoint)

Example 20 with MagicKey

use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.

the class BaseTxStateTransferOverwriteTest method doTestWhereCommitOccursAfterStateTransferBeginsBeforeCompletion.

/**
 * When L1 is enabled this test should not be ran when a previous value is present as it will cause timeouts.  Due
 * to how locking works with L1 this cannot occur when the previous value exists.
 */
protected void doTestWhereCommitOccursAfterStateTransferBeginsBeforeCompletion(final TestWriteOperation op) throws Exception {
    if (l1Enabled() && op.getPreviousValue() != null) {
        fail("This test cannot be ran with L1 when a previous value is set");
    }
    // Test scenario:
    // cache0,1,2 are in the cluster, an owner leaves
    // Key k is in the cache, and is transferred to the non owner
    // A user operation also modifies key k causing an invalidation
    // on the non owner which is getting the state transfer
    final AdvancedCache<Object, Object> primaryOwnerCache = cache(0, cacheName).getAdvancedCache();
    final AdvancedCache<Object, Object> backupOwnerCache = cache(1, cacheName).getAdvancedCache();
    final AdvancedCache<Object, Object> nonOwnerCache = cache(2, cacheName).getAdvancedCache();
    final MagicKey key = new MagicKey(primaryOwnerCache, backupOwnerCache);
    // Prepare for replace/remove: put a previous value in cache0
    final Object previousValue = op.getPreviousValue();
    if (previousValue != null) {
        primaryOwnerCache.put(key, previousValue);
        assertEquals(previousValue, primaryOwnerCache.get(key));
        log.tracef("Previous value inserted: %s = %s", key, previousValue);
        assertEquals(previousValue, nonOwnerCache.get(key));
        if (l1Enabled()) {
            assertIsInL1(nonOwnerCache, key);
        }
    }
    int preJoinTopologyId = primaryOwnerCache.getDistributionManager().getCacheTopology().getTopologyId();
    // Block any state response commands on cache0
    CheckPoint checkPoint = new CheckPoint();
    ControlledRpcManager blockingRpcManager0 = ControlledRpcManager.replaceRpcManager(primaryOwnerCache);
    ControlledRpcManager blockingRpcManager2 = ControlledRpcManager.replaceRpcManager(nonOwnerCache);
    // The execution of the write/prepare/commit commands is controlled with the BlockingInterceptor
    blockingRpcManager0.excludeCommands(BackupWriteCommand.class, PrepareCommand.class, CommitCommand.class, TxCompletionNotificationCommand.class);
    blockingRpcManager2.excludeCommands(BackupAckCommand.class);
    // Block the rebalance confirmation on cache0
    int rebalanceTopologyId = preJoinTopologyId + 2;
    blockRebalanceConfirmation(primaryOwnerCache.getCacheManager(), checkPoint, rebalanceTopologyId);
    assertEquals(primaryOwnerCache.getCacheManager().getCoordinator(), primaryOwnerCache.getCacheManager().getAddress());
    // Remove the leaver
    log.trace("Stopping the cache");
    backupOwnerCache.getCacheManager().stop();
    // Wait for the write CH to contain the joiner everywhere
    eventuallyEquals(2, () -> primaryOwnerCache.getRpcManager().getMembers().size());
    eventuallyEquals(2, () -> nonOwnerCache.getRpcManager().getMembers().size());
    assertEquals(primaryOwnerCache.getCacheManager().getCoordinator(), primaryOwnerCache.getCacheManager().getAddress());
    // Wait for both nodes to start state transfer
    if (transactional) {
        blockingRpcManager0.expectCommand(StateTransferGetTransactionsCommand.class).send().receiveAll();
        blockingRpcManager2.expectCommand(StateTransferGetTransactionsCommand.class).send().receiveAll();
    }
    ControlledRpcManager.BlockedRequest<StateTransferStartCommand> blockedStateRequest0 = blockingRpcManager0.expectCommand(StateTransferStartCommand.class);
    ControlledRpcManager.BlockedRequest<StateTransferStartCommand> blockedStateRequest2 = blockingRpcManager2.expectCommand(StateTransferStartCommand.class);
    // Unblock the state request from node 2
    // Don't wait for response, because node 2 might be sending the first state response on the request thread
    blockedStateRequest2.send().receiveAllAsync();
    // Wait for cache0 to collect the state to send to node 2 (including our previous value).
    ControlledRpcManager.BlockedRequest<StateResponseCommand> blockedStateResponse0 = blockingRpcManager0.expectCommand(StateResponseCommand.class);
    // Every PutKeyValueCommand will be blocked before committing the entry on cache1
    CyclicBarrier beforeCommitCache1Barrier = new CyclicBarrier(2);
    BlockingInterceptor<?> blockingInterceptor1 = new BlockingInterceptor<>(beforeCommitCache1Barrier, op.getCommandClass(), true, false);
    extractInterceptorChain(nonOwnerCache).addInterceptorAfter(blockingInterceptor1, EntryWrappingInterceptor.class);
    // Put/Replace/Remove from cache0 with cache0 as primary owner, cache1 will become a backup owner for the retry
    // The put command will be blocked on cache1 just before committing the entry.
    Future<Object> future = fork(() -> op.perform(primaryOwnerCache, key));
    // Wait for the entry to be wrapped on node 2
    // The replicated command could be either a non-tx BackupWriteCommand or a PrepareCommand
    beforeCommitCache1Barrier.await(10, TimeUnit.SECONDS);
    // Remove the interceptor so we don't mess up any other state transfer puts
    removeAllBlockingInterceptorsFromCache(nonOwnerCache);
    // Allow the state to be applied on cache1 (writing the old value for our entry)
    blockedStateResponse0.send().receiveAll();
    // Wait for second in line to finish applying the state, but don't allow the rebalance confirmation to be processed.
    // (It would change the topology and it would trigger a retry for the command.)
    // Don't wait for response, because node 2 might be sending the first state response on the request thread
    blockedStateRequest0.send().receiveAllAsync();
    blockingRpcManager2.expectCommand(StateResponseCommand.class).send().receiveAll();
    checkPoint.awaitStrict("pre_rebalance_confirmation_" + rebalanceTopologyId + "_from_" + primaryOwnerCache.getCacheManager().getAddress(), 10, SECONDS);
    // Now allow the command to commit on cache1
    beforeCommitCache1Barrier.await(10, TimeUnit.SECONDS);
    // Wait for the command to finish and check that it didn't fail
    Object result = future.get(10, TimeUnit.SECONDS);
    assertEquals(op.getReturnValue(), result);
    log.tracef("%s operation is done", op);
    // Allow the rebalance confirmation to proceed and wait for the topology to change everywhere
    checkPoint.trigger("resume_rebalance_confirmation_" + rebalanceTopologyId + "_from_" + primaryOwnerCache.getCacheManager().getAddress());
    checkPoint.trigger("resume_rebalance_confirmation_" + rebalanceTopologyId + "_from_" + nonOwnerCache.getCacheManager().getAddress());
    TestingUtil.waitForNoRebalance(primaryOwnerCache, nonOwnerCache);
    switch(op) {
        case REMOVE:
        case REMOVE_EXACT:
            break;
        default:
            assertIsInContainerImmortal(primaryOwnerCache, key);
            assertIsInContainerImmortal(nonOwnerCache, key);
            break;
    }
    // Check the value to make sure data container contains correct value
    assertEquals(op.getValue(), primaryOwnerCache.get(key));
    assertEquals(op.getValue(), nonOwnerCache.get(key));
}
Also used : BlockingInterceptor(org.infinispan.distribution.BlockingInterceptor) CheckPoint(org.infinispan.test.fwk.CheckPoint) CyclicBarrier(java.util.concurrent.CyclicBarrier) StateTransferStartCommand(org.infinispan.commands.statetransfer.StateTransferStartCommand) StateResponseCommand(org.infinispan.commands.statetransfer.StateResponseCommand) MagicKey(org.infinispan.distribution.MagicKey) ControlledRpcManager(org.infinispan.util.ControlledRpcManager) CheckPoint(org.infinispan.test.fwk.CheckPoint)

Aggregations

MagicKey (org.infinispan.distribution.MagicKey)185 Test (org.testng.annotations.Test)74 TransactionManager (javax.transaction.TransactionManager)23 CheckPoint (org.infinispan.test.fwk.CheckPoint)20 HashMap (java.util.HashMap)16 Map (java.util.Map)16 Transaction (javax.transaction.Transaction)16 Cache (org.infinispan.Cache)16 ConfigurationBuilder (org.infinispan.configuration.cache.ConfigurationBuilder)15 CountDownLatch (java.util.concurrent.CountDownLatch)10 CacheMode (org.infinispan.configuration.cache.CacheMode)10 CacheEntry (org.infinispan.container.entries.CacheEntry)10 Address (org.infinispan.remoting.transport.Address)10 StateSequencer (org.infinispan.test.concurrent.StateSequencer)9 AssertJUnit.assertEquals (org.testng.AssertJUnit.assertEquals)9 ArrayList (java.util.ArrayList)8 CyclicBarrier (java.util.concurrent.CyclicBarrier)8 DistributionManager (org.infinispan.distribution.DistributionManager)8 MultipleCacheManagersTest (org.infinispan.test.MultipleCacheManagersTest)8 RollbackException (javax.transaction.RollbackException)7