package org.infinispan.server.hotrod;
import static org.infinispan.server.hotrod.test.HotRodTestingUtil.assertStatus;
import static org.infinispan.server.hotrod.test.HotRodTestingUtil.k;
import static org.infinispan.server.hotrod.test.HotRodTestingUtil.v;
import java.lang.reflect.Method;
import java.util.Iterator;
import org.infinispan.commands.FlagAffectedCommand;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.commons.CacheException;
import org.infinispan.context.InvocationContext;
import org.infinispan.context.impl.FlagBitSets;
import org.infinispan.interceptors.base.BaseCustomInterceptor;
import org.infinispan.interceptors.base.CommandInterceptor;
import org.testng.annotations.Test;
/**
* Tests if the {@link ProtocolFlag#SkipIndexing} flag is processed on server.
*
* @author Tristan Tarrant
* @since 7.0
*/
@Test(groups = "functional", testName = "server.hotrod.SkipIndexingHotRodTest")
public class SkipIndexingHotRodTest extends HotRodSingleNodeTest {
private static final int SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE = join(ProtocolFlag.SkipIndexing.getValue(), ProtocolFlag.ForceReturnPreviousValue.getValue());
public void testPut(Method m) {
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
//PUT
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().put(k(m), 0, 0, v(m), 0), OperationStatus.Success);
commandInterceptor.expectSkipIndexingFlag = true;
assertStatus(client().put(k(m), 0, 0, v(m), ProtocolFlag.SkipIndexing.getValue()), OperationStatus.Success);
assertStatus(client().put(k(m), 0, 0, v(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.SuccessWithPrevious);
}
public void testReplace(Method m) {
//REPLACE
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().replace(k(m), 0, 0, v(m), 0), OperationStatus.OperationNotExecuted);
commandInterceptor.expectSkipIndexingFlag = true;
assertStatus(client().replace(k(m), 0, 0, v(m), ProtocolFlag.SkipIndexing.getValue()),
OperationStatus.OperationNotExecuted);
assertStatus(client().replace(k(m), 0, 0, v(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.OperationNotExecuted);
}
public void testPutIfAbsent(Method m) {
//PUT_IF_ABSENT
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().putIfAbsent(k(m), 0, 0, v(m), 0), OperationStatus.Success);
commandInterceptor.expectSkipIndexingFlag = true;
assertStatus(client().putIfAbsent(k(m), 0, 0, v(m), ProtocolFlag.SkipIndexing.getValue()),
OperationStatus.OperationNotExecuted);
assertStatus(client().putIfAbsent(k(m), 0, 0, v(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.NotExecutedWithPrevious);
}
public void testReplaceIfUnmodified(Method m) {
//REPLACE_IF_UNMODIFIED
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().replaceIfUnmodified(k(m), 0, 0, v(m), 0, 0), OperationStatus.KeyDoesNotExist);
commandInterceptor.expectSkipIndexingFlag = true;
assertStatus(client().replaceIfUnmodified(k(m), 0, 0, v(m), 0, ProtocolFlag.SkipIndexing.getValue()),
OperationStatus.KeyDoesNotExist);
assertStatus(client().replaceIfUnmodified(k(m), 0, 0, v(m), 0, SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.KeyDoesNotExist);
}
public void testGet(Method m) {
//GET
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().get(k(m), 0), OperationStatus.KeyDoesNotExist);
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().get(k(m), ProtocolFlag.SkipIndexing.getValue()), OperationStatus.KeyDoesNotExist);
assertStatus(client().get(k(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.KeyDoesNotExist);
}
public void testGetWithVersion(Method m) {
//GET_WITH_VERSION
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().getWithVersion(k(m), 0), OperationStatus.KeyDoesNotExist);
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().getWithVersion(k(m), ProtocolFlag.SkipIndexing.getValue()),
OperationStatus.KeyDoesNotExist);
assertStatus(client().getWithVersion(k(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.KeyDoesNotExist);
}
public void testGetWithMetadata(Method m) {
//GET_WITH_METADATA
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().getWithMetadata(k(m), 0), OperationStatus.KeyDoesNotExist);
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().getWithMetadata(k(m), ProtocolFlag.SkipIndexing.getValue()),
OperationStatus.KeyDoesNotExist);
assertStatus(client().getWithMetadata(k(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.KeyDoesNotExist);
}
public void testRemove(Method m) {
//REMOVE
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().remove(k(m), 0), OperationStatus.KeyDoesNotExist);
commandInterceptor.expectSkipIndexingFlag = true;
assertStatus(client().remove(k(m), ProtocolFlag.SkipIndexing.getValue()), OperationStatus.KeyDoesNotExist);
assertStatus(client().remove(k(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE), OperationStatus.KeyDoesNotExist);
}
public void testRemoveIfUnmodified(Method m) {
//REMOVE_IF_UNMODIFIED
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().removeIfUnmodified(k(m), 0, 0), OperationStatus.KeyDoesNotExist);
commandInterceptor.expectSkipIndexingFlag = true;
assertStatus(client().removeIfUnmodified(k(m), 0, ProtocolFlag.SkipIndexing.getValue()),
OperationStatus.KeyDoesNotExist);
assertStatus(client().removeIfUnmodified(k(m), 0, SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.KeyDoesNotExist);
}
public void testContainsKey(Method m) {
//CONTAINS_KEY
SkipIndexingFlagCheckCommandInterceptor commandInterceptor = init();
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().containsKey(k(m), 0), OperationStatus.KeyDoesNotExist);
commandInterceptor.expectSkipIndexingFlag = false;
assertStatus(client().containsKey(k(m), ProtocolFlag.SkipIndexing.getValue()), OperationStatus.KeyDoesNotExist);
assertStatus(client().containsKey(k(m), SKIP_INDEXING_AND_RETURN_PREVIOUS_VALUE),
OperationStatus.KeyDoesNotExist);
}
private SkipIndexingFlagCheckCommandInterceptor init() {
Iterator<CommandInterceptor> iterator =
cacheManager.getCache(cacheName).getAdvancedCache().getInterceptorChain().iterator();
while (iterator.hasNext()) {
CommandInterceptor commandInterceptor = iterator.next();
if (commandInterceptor instanceof SkipIndexingFlagCheckCommandInterceptor)
return (SkipIndexingFlagCheckCommandInterceptor) commandInterceptor;
}
SkipIndexingFlagCheckCommandInterceptor ci = new SkipIndexingFlagCheckCommandInterceptor();
cacheManager.getCache(cacheName).getAdvancedCache().getAsyncInterceptorChain().addInterceptor(ci, 1);
return ci;
}
private static int join(int flagId, int joinId) {
return joinId | flagId;
}
}
class SkipIndexingFlagCheckCommandInterceptor extends BaseCustomInterceptor {
volatile boolean expectSkipIndexingFlag = false;
protected @Override
Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
if (command instanceof FlagAffectedCommand) {
FlagAffectedCommand flagAffectedCommand = (FlagAffectedCommand) command;
boolean hasFlag = flagAffectedCommand.hasAnyFlag(FlagBitSets.SKIP_INDEXING);
if (expectSkipIndexingFlag && !hasFlag) {
throw new CacheException("SKIP_INDEXING flag is expected!");
} else if (!expectSkipIndexingFlag && hasFlag) {
throw new CacheException("SKIP_INDEXING flag is *not* expected!");
}
}
return super.handleDefault(ctx, command);
}
}