use of org.infinispan.interceptors.impl.EntryWrappingInterceptor in project infinispan by infinispan.
the class GetGroupKeysTest method injectIfAbsent.
private BlockCommandInterceptor injectIfAbsent(Cache<?, ?> cache) {
log.debugf("Injecting BlockCommandInterceptor in %s", cache);
AsyncInterceptorChain chain = cache.getAdvancedCache().getAsyncInterceptorChain();
BlockCommandInterceptor interceptor = chain.findInterceptorExtending(BlockCommandInterceptor.class);
if (interceptor == null) {
interceptor = new BlockCommandInterceptor(log);
EntryWrappingInterceptor ewi = chain.findInterceptorExtending(EntryWrappingInterceptor.class);
AssertJUnit.assertTrue(chain.addInterceptorAfter(interceptor, ewi.getClass()));
}
interceptor.reset();
log.debugf("Injected BlockCommandInterceptor in %s. Interceptor=%s", cache, interceptor);
return interceptor;
}
use of org.infinispan.interceptors.impl.EntryWrappingInterceptor in project infinispan by infinispan.
the class InterceptorChainFactory method buildInterceptorChain.
private AsyncInterceptorChain buildInterceptorChain() {
TransactionMode transactionMode = configuration.transaction().transactionMode();
boolean needsVersionAwareComponents = Configurations.isTxVersioned(configuration);
AsyncInterceptorChain interceptorChain = new AsyncInterceptorChainImpl();
boolean invocationBatching = configuration.invocationBatching().enabled();
CacheMode cacheMode = configuration.clustering().cacheMode();
// load the icInterceptor first
if (invocationBatching) {
interceptorChain.appendInterceptor(createInterceptor(new BatchingInterceptor(), BatchingInterceptor.class), false);
}
interceptorChain.appendInterceptor(createInterceptor(new InvocationContextInterceptor(), InvocationContextInterceptor.class), false);
if (!configuration.transaction().transactionMode().isTransactional()) {
interceptorChain.appendInterceptor(createInterceptor(new VersionInterceptor(), VersionInterceptor.class), false);
}
// add marshallable check interceptor for situations where we want to figure out before marshalling
if (hasAsyncStore())
interceptorChain.appendInterceptor(createInterceptor(new IsMarshallableInterceptor(), IsMarshallableInterceptor.class), false);
// load the cache management interceptor next
if (configuration.statistics().available()) {
interceptorChain.appendInterceptor(createInterceptor(new CacheMgmtInterceptor(), CacheMgmtInterceptor.class), false);
}
// the only exception is non-tx invalidation mode, which ignores lock owners
if (cacheMode.needsStateTransfer() || cacheMode.isInvalidation() && transactionMode.isTransactional()) {
interceptorChain.appendInterceptor(createInterceptor(new StateTransferInterceptor(), StateTransferInterceptor.class), false);
}
if (cacheMode.needsStateTransfer()) {
if (transactionMode.isTransactional()) {
interceptorChain.appendInterceptor(createInterceptor(new TransactionSynchronizerInterceptor(), TransactionSynchronizerInterceptor.class), false);
}
if (configuration.clustering().partitionHandling().whenSplit() != PartitionHandling.ALLOW_READ_WRITES) {
interceptorChain.appendInterceptor(createInterceptor(new PartitionHandlingInterceptor(), PartitionHandlingInterceptor.class), false);
}
}
// load the tx interceptor
if (transactionMode.isTransactional())
interceptorChain.appendInterceptor(createInterceptor(new TxInterceptor<>(), TxInterceptor.class), false);
if (!cacheMode.isScattered()) {
if (transactionMode.isTransactional()) {
if (configuration.transaction().lockingMode() == LockingMode.PESSIMISTIC) {
interceptorChain.appendInterceptor(createInterceptor(new PessimisticLockingInterceptor(), PessimisticLockingInterceptor.class), false);
} else {
interceptorChain.appendInterceptor(createInterceptor(new OptimisticLockingInterceptor(), OptimisticLockingInterceptor.class), false);
}
} else {
interceptorChain.appendInterceptor(createInterceptor(new NonTransactionalLockingInterceptor(), NonTransactionalLockingInterceptor.class), false);
}
}
// This needs to be after locking interceptor to guarantee that locks are still held when raising notifications
if (transactionMode.isTransactional() && configuration.transaction().notifications()) {
interceptorChain.appendInterceptor(createInterceptor(new NotificationInterceptor(), NotificationInterceptor.class), false);
}
if (configuration.sites().hasBackups()) {
if (transactionMode == TransactionMode.TRANSACTIONAL) {
if (configuration.transaction().lockingMode() == LockingMode.OPTIMISTIC) {
interceptorChain.appendInterceptor(createInterceptor(new OptimisticBackupInterceptor(), OptimisticBackupInterceptor.class), false);
} else {
interceptorChain.appendInterceptor(createInterceptor(new PessimisticBackupInterceptor(), PessimisticBackupInterceptor.class), false);
}
} else {
interceptorChain.appendInterceptor(createInterceptor(new NonTransactionalBackupInterceptor(), NonTransactionalBackupInterceptor.class), false);
}
}
// This needs to be added after the locking interceptor (for tx caches) but before the wrapping interceptor.
if (configuration.clustering().l1().enabled()) {
interceptorChain.appendInterceptor(createInterceptor(new L1LastChanceInterceptor(), L1LastChanceInterceptor.class), false);
}
if (configuration.clustering().hash().groups().enabled()) {
interceptorChain.appendInterceptor(createInterceptor(new GroupingInterceptor(), GroupingInterceptor.class), false);
}
if (cacheMode.isScattered()) {
interceptorChain.appendInterceptor(createInterceptor(new PrefetchInterceptor(), PrefetchInterceptor.class), false);
}
if (needsVersionAwareComponents) {
interceptorChain.appendInterceptor(createInterceptor(new VersionedEntryWrappingInterceptor(), VersionedEntryWrappingInterceptor.class), false);
} else if (cacheMode.isScattered()) {
if (configuration.clustering().biasAcquisition() == BiasAcquisition.NEVER) {
interceptorChain.appendInterceptor(createInterceptor(new RetryingEntryWrappingInterceptor(), RetryingEntryWrappingInterceptor.class), false);
} else {
interceptorChain.appendInterceptor(createInterceptor(new BiasedEntryWrappingInterceptor(), BiasedEntryWrappingInterceptor.class), false);
}
} else {
interceptorChain.appendInterceptor(createInterceptor(new EntryWrappingInterceptor(), EntryWrappingInterceptor.class), false);
}
// Has to be after entry wrapping interceptor so it can properly see context values even when removed
if (transactionMode.isTransactional()) {
if (configuration.memory().evictionStrategy().isExceptionBased()) {
interceptorChain.appendInterceptor(createInterceptor(new TransactionalExceptionEvictionInterceptor(), TransactionalExceptionEvictionInterceptor.class), false);
}
}
if (configuration.persistence().usingStores()) {
addPersistenceInterceptors(interceptorChain, configuration, configuration.persistence().stores());
}
if (configuration.clustering().l1().enabled()) {
if (transactionMode.isTransactional()) {
interceptorChain.appendInterceptor(createInterceptor(new L1TxInterceptor(), L1TxInterceptor.class), false);
} else {
interceptorChain.appendInterceptor(createInterceptor(new L1NonTxInterceptor(), L1NonTxInterceptor.class), false);
}
}
if (configuration.sites().hasAsyncEnabledBackups() && cacheMode.isClustered()) {
if (transactionMode == TransactionMode.TRANSACTIONAL) {
if (configuration.transaction().lockingMode() == LockingMode.OPTIMISTIC) {
interceptorChain.appendInterceptor(createInterceptor(new OptimisticTxIracLocalSiteInterceptor(), OptimisticTxIracLocalSiteInterceptor.class), false);
} else {
interceptorChain.appendInterceptor(createInterceptor(new PessimisticTxIracLocalInterceptor(), PessimisticTxIracLocalInterceptor.class), false);
}
} else {
interceptorChain.appendInterceptor(createInterceptor(new NonTxIracLocalSiteInterceptor(), NonTxIracLocalSiteInterceptor.class), false);
}
}
switch(cacheMode) {
case INVALIDATION_SYNC:
case INVALIDATION_ASYNC:
interceptorChain.appendInterceptor(createInterceptor(new InvalidationInterceptor(), InvalidationInterceptor.class), false);
break;
case DIST_SYNC:
case REPL_SYNC:
if (needsVersionAwareComponents) {
interceptorChain.appendInterceptor(createInterceptor(new VersionedDistributionInterceptor(), VersionedDistributionInterceptor.class), false);
break;
}
case DIST_ASYNC:
case REPL_ASYNC:
if (transactionMode.isTransactional()) {
interceptorChain.appendInterceptor(createInterceptor(new TxDistributionInterceptor(), TxDistributionInterceptor.class), false);
} else {
if (cacheMode.isDistributed() && Configurations.isEmbeddedMode(globalConfiguration)) {
interceptorChain.appendInterceptor(createInterceptor(new TriangleDistributionInterceptor(), TriangleDistributionInterceptor.class), false);
} else {
interceptorChain.appendInterceptor(createInterceptor(new NonTxDistributionInterceptor(), NonTxDistributionInterceptor.class), false);
}
}
break;
case SCATTERED_SYNC:
if (configuration.clustering().biasAcquisition() != BiasAcquisition.NEVER) {
interceptorChain.appendInterceptor(createInterceptor(new BiasedScatteredDistributionInterceptor(), BiasedScatteredDistributionInterceptor.class), false);
} else {
interceptorChain.appendInterceptor(createInterceptor(new ScatteredDistributionInterceptor(), ScatteredDistributionInterceptor.class), false);
}
break;
case LOCAL:
}
if (cacheMode.isClustered()) {
// local caches not involved in Cross Site Replication
interceptorChain.appendInterceptor(createInterceptor(new NonTxIracRemoteSiteInterceptor(needsVersionAwareComponents), NonTxIracRemoteSiteInterceptor.class), false);
}
AsyncInterceptor callInterceptor = createInterceptor(new CallInterceptor(), CallInterceptor.class);
interceptorChain.appendInterceptor(callInterceptor, false);
log.trace("Finished building default interceptor chain.");
buildCustomInterceptors(interceptorChain, configuration.customInterceptors());
return interceptorChain;
}
use of org.infinispan.interceptors.impl.EntryWrappingInterceptor in project infinispan by infinispan.
the class InterceptorChainFactory method addPersistenceInterceptors.
/**
* Adds all the interceptors related to persistence to the stack.
*
* @param interceptorChain The chain
* @param cacheConfiguration The configuration of the cache that owns the interceptor
* @param stores A list of {@link StoreConfiguration} possibly not present in the cacheConfiguration
*/
public void addPersistenceInterceptors(AsyncInterceptorChain interceptorChain, Configuration cacheConfiguration, List<StoreConfiguration> stores) {
TransactionMode transactionMode = cacheConfiguration.transaction().transactionMode();
CacheMode cacheMode = cacheConfiguration.clustering().cacheMode();
EntryWrappingInterceptor ewi = interceptorChain.findInterceptorExtending(EntryWrappingInterceptor.class);
if (ewi == null) {
throw new CacheException("Cannot find instance of EntryWrappingInterceptor in the interceptor chain");
}
Class<? extends AsyncInterceptor> lastAdded = ewi.getClass();
if (cacheConfiguration.persistence().passivation()) {
if (cacheMode.isClustered()) {
lastAdded = addInterceptor(interceptorChain, new PassivationClusteredCacheLoaderInterceptor<>(), CacheLoaderInterceptor.class, lastAdded);
} else {
lastAdded = addInterceptor(interceptorChain, new PassivationCacheLoaderInterceptor<>(), CacheLoaderInterceptor.class, lastAdded);
}
addInterceptor(interceptorChain, new PassivationWriterInterceptor(), PassivationWriterInterceptor.class, lastAdded);
} else {
if (cacheMode.isClustered()) {
lastAdded = addInterceptor(interceptorChain, new ClusteredCacheLoaderInterceptor<>(), CacheLoaderInterceptor.class, lastAdded);
} else {
lastAdded = addInterceptor(interceptorChain, new CacheLoaderInterceptor<>(), CacheLoaderInterceptor.class, lastAdded);
}
boolean transactionalStore = cacheConfiguration.persistence().stores().stream().anyMatch(StoreConfiguration::transactional) || stores.stream().anyMatch(StoreConfiguration::transactional);
if (transactionalStore && transactionMode.isTransactional())
lastAdded = addInterceptor(interceptorChain, new TransactionalStoreInterceptor(), TransactionalStoreInterceptor.class, lastAdded);
switch(cacheMode) {
case DIST_SYNC:
case DIST_ASYNC:
case REPL_SYNC:
case REPL_ASYNC:
addInterceptor(interceptorChain, new DistCacheWriterInterceptor(), DistCacheWriterInterceptor.class, lastAdded);
break;
case SCATTERED_SYNC:
addInterceptor(interceptorChain, new ScatteredCacheWriterInterceptor(), ScatteredCacheWriterInterceptor.class, lastAdded);
break;
default:
addInterceptor(interceptorChain, new CacheWriterInterceptor(), CacheWriterInterceptor.class, lastAdded);
break;
}
}
}
use of org.infinispan.interceptors.impl.EntryWrappingInterceptor in project infinispan by infinispan.
the class StateTransferGetGroupKeysTest method injectBlockCommandInterceptorIfAbsent.
private static BlockCommandInterceptor injectBlockCommandInterceptorIfAbsent(Cache<GroupKey, String> cache) {
AsyncInterceptorChain chain = cache.getAdvancedCache().getAsyncInterceptorChain();
BlockCommandInterceptor interceptor = chain.findInterceptorWithClass(BlockCommandInterceptor.class);
if (interceptor == null) {
interceptor = new BlockCommandInterceptor();
EntryWrappingInterceptor ewi = chain.findInterceptorExtending(EntryWrappingInterceptor.class);
assertNotNull(ewi);
chain.addInterceptorAfter(interceptor, ewi.getClass());
}
interceptor.reset();
return interceptor;
}
use of org.infinispan.interceptors.impl.EntryWrappingInterceptor in project infinispan by infinispan.
the class StateTransferOverwritingValueTest method doTest.
private void doTest(final TestWriteOperation op) throws Exception {
// Test scenario:
// cache0 is the only member in the cluster, cache1 joins
// Key k is in the cache, and is transferred to cache1
// A user operation/tx also modifies key k
// The user tx must update k even if it doesn't find key k in the data container.
final AdvancedCache<Object, Object> cache0 = advancedCache(0);
final String key = "key";
// Prepare for replace/remove: put a previous value in cache0
final Object previousValue = op.getPreviousValue();
if (previousValue != null) {
cache0.put(key, previousValue);
assertEquals(previousValue, cache0.get(key));
log.tracef("Previous value inserted: %s = %s", key, previousValue);
}
int preJoinTopologyId = cache0.getDistributionManager().getCacheTopology().getTopologyId();
// Block any state response commands on cache0
CheckPoint checkPoint = new CheckPoint();
ControlledRpcManager blockingRpcManager0 = replaceRpcManager(cache0);
blockingRpcManager0.excludeCommands(WriteCommand.class, BackupWriteCommand.class, RevokeBiasCommand.class, InvalidateVersionsCommand.class, AbstractTransactionBoundaryCommand.class, TxCompletionNotificationCommand.class);
int rebalanceTopologyId = preJoinTopologyId + 1;
// Block the rebalance confirmation on cache0
blockRebalanceConfirmation(manager(0), checkPoint, rebalanceTopologyId);
// Start the joiner
log.tracef("Starting the cache on the joiner");
ConfigurationBuilder c = getConfigurationBuilder();
c.clustering().stateTransfer().awaitInitialTransfer(false).timeout(30, SECONDS);
addClusterEnabledCacheManager(c);
final AdvancedCache<Object, Object> cache1 = advancedCache(1);
// Wait for joiner to finish requesting segments, so that write commands are not blocked
StateTransferLock stateTransferLock1 = TestingUtil.extractComponent(cache1, StateTransferLock.class);
stateTransferLock1.transactionDataFuture(rebalanceTopologyId).toCompletableFuture().get(10, SECONDS);
assertEquals(2, cache1.getRpcManager().getMembers().size());
// Every PutKeyValueCommand will be blocked before committing the entry on cache1
CyclicBarrier beforeCommitCache1Barrier = new CyclicBarrier(2);
// Scattered cache mode uses only PKVC or RemoveCommands for backup
BlockingInterceptor<?> blockingInterceptor1 = new BlockingInterceptor<>(beforeCommitCache1Barrier, true, false, cacheMode.isScattered() ? t -> t instanceof PutKeyValueCommand || t instanceof RemoveCommand : t -> t.getClass().equals(op.getCommandClass()));
AsyncInterceptorChain interceptorChain1 = TestingUtil.extractInterceptorChain(cache1);
Class<? extends EntryWrappingInterceptor> ewi = interceptorChain1.findInterceptorExtending(EntryWrappingInterceptor.class).getClass();
assertTrue(interceptorChain1.addInterceptorAfter(blockingInterceptor1, ewi));
// Wait for cache0 to collect the state to send to cache1 (including our previous value).
ControlledRpcManager.BlockedRequest<?> blockedStateResponse = blockingRpcManager0.expectCommand(StateResponseCommand.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(cache0, key));
// Wait for the entry to be wrapped on cache1
beforeCommitCache1Barrier.await(10, TimeUnit.SECONDS);
// Stop blocking, otherwise we'll block the state transfer put commands as well
blockingInterceptor1.suspend(true);
// Allow the state to be applied on cache1 (writing the old value for our entry)
blockedStateResponse.send().receiveAll();
if (cacheMode.isScattered()) {
blockingRpcManager0.expectCommand(StateResponseCommand.class).send().receiveAll();
}
// Wait for cache1 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.)
checkPoint.awaitStrict("pre_rebalance_confirmation_" + rebalanceTopologyId + "_from_" + address(1), 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_" + address(0));
checkPoint.trigger("resume_rebalance_confirmation_" + rebalanceTopologyId + "_from_" + address(1));
TestingUtil.waitForNoRebalance(cache0, cache1);
// Check the value on all the nodes
assertEquals(op.getValue(), cache0.get(key));
assertEquals(op.getValue(), cache1.get(key));
blockingRpcManager0.stopBlocking();
}
Aggregations