package com.hazelcast.map; import com.hazelcast.config.Config; import com.hazelcast.config.InMemoryFormat; import com.hazelcast.config.MapConfig; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import com.hazelcast.core.Offloadable; import com.hazelcast.core.ReadOnly; import com.hazelcast.internal.serialization.InternalSerializationService; import com.hazelcast.map.impl.LockAwareLazyMapEntry; import com.hazelcast.query.TruePredicate; import com.hazelcast.query.impl.getters.Extractors; import com.hazelcast.test.HazelcastParametersRunnerFactory; import com.hazelcast.test.HazelcastTestSupport; import com.hazelcast.test.annotation.ParallelTest; import com.hazelcast.test.annotation.QuickTest; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.concurrent.ExecutionException; import static com.hazelcast.config.InMemoryFormat.BINARY; import static com.hazelcast.config.InMemoryFormat.OBJECT; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @RunWith(Parameterized.class) @Parameterized.UseParametersRunnerFactory(HazelcastParametersRunnerFactory.class) @Category({QuickTest.class, ParallelTest.class}) public class EntryProcessorLockTest extends HazelcastTestSupport { public static final String MAP_NAME = "EntryProcessorLockTest"; @Parameterized.Parameter public InMemoryFormat inMemoryFormat; @Parameterized.Parameters(name = "{index}: {0}") public static Collection<Object[]> data() { return asList(new Object[][]{ {BINARY}, {OBJECT} }); } @Override public Config getConfig() { Config config = super.getConfig(); MapConfig mapConfig = new MapConfig(MAP_NAME); mapConfig.setInMemoryFormat(inMemoryFormat); config.addMapConfig(mapConfig); return config; } private IMap<String, String> getInitializedMap() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, String> map = instance.getMap(MAP_NAME); map.put("key1", "value1"); map.put("key2", "value2"); return map; } @Test public void test_executeOnEntries() { IMap<String, String> map = getInitializedMap(); map.lock("key1"); Map<String, Object> result = map.executeOnEntries(new TestNonOffloadableEntryProcessor()); assertTrue((Boolean) result.get("key1")); assertFalse((Boolean) result.get("key2")); } @Test public void test_executeOnEntries_withPredicate() { IMap<String, String> map = getInitializedMap(); map.lock("key1"); Map<String, Object> result = map.executeOnEntries(new TestNonOffloadableEntryProcessor(), TruePredicate.INSTANCE); assertTrue((Boolean) result.get("key1")); assertFalse((Boolean) result.get("key2")); } @Test public void test_executeOnKeys() { IMap<String, String> map = getInitializedMap(); map.lock("key1"); Map<String, Object> result = map.executeOnKeys(new HashSet<String>(asList("key1", "key2")), new TestNonOffloadableEntryProcessor()); assertTrue((Boolean) result.get("key1")); assertFalse((Boolean) result.get("key2")); } @Test public void test_executeOnKey_notOffloadable() { IMap<String, String> map = getInitializedMap(); Boolean result = (Boolean) map.executeOnKey("key1", new TestNonOffloadableEntryProcessor()); assertFalse(result); } @Test public void test_executeOnKey_Offloadable() { IMap<String, String> map = getInitializedMap(); Boolean result = (Boolean) map.executeOnKey("key1", new TestOffloadableEntryProcessor()); assertNull(result); } @Test public void test_executeOnKey_Offloadable_ReadOnly() { IMap<String, String> map = getInitializedMap(); Boolean result = (Boolean) map.executeOnKey("key1", new TestOffloadableReadOnlyEntryProcessor()); assertNull(result); } @Test public void test_submitToKey_notOffloadable() throws ExecutionException, InterruptedException { IMap<String, String> map = getInitializedMap(); Boolean result = (Boolean) map.submitToKey("key1", new TestNonOffloadableEntryProcessor()).get(); assertFalse(result); } @Test public void test_submitToKey_Offloadable() throws ExecutionException, InterruptedException { IMap<String, String> map = getInitializedMap(); Boolean result = (Boolean) map.submitToKey("key1", new TestOffloadableEntryProcessor()).get(); assertNull(result); } @Test public void test_submitToKey_Offloadable_ReadOnly() throws ExecutionException, InterruptedException { IMap<String, String> map = getInitializedMap(); Boolean result = (Boolean) map.submitToKey("key1", new TestOffloadableReadOnlyEntryProcessor()).get(); assertNull(result); } @Test public void test_Serialization_LockAwareLazyMapEntry_deserializesAs_LazyMapEntry() throws ExecutionException, InterruptedException { InternalSerializationService ss = getSerializationService(createHazelcastInstance(getConfig())); LockAwareLazyMapEntry entry = new LockAwareLazyMapEntry(ss.toData("key"), "value", ss, Extractors.empty(), false); LockAwareLazyMapEntry deserializedEntry = ss.toObject(ss.toData(entry)); assertEquals(LockAwareLazyMapEntry.class, deserializedEntry.getClass()); assertEquals("key", deserializedEntry.getKey()); assertEquals("value", deserializedEntry.getValue()); assertNull(deserializedEntry.isLocked()); } private static class TestNonOffloadableEntryProcessor implements EntryProcessor { @Override public Object process(Map.Entry entry) { return ((LockAware) entry).isLocked(); } @Override public EntryBackupProcessor getBackupProcessor() { return null; } } private static class TestOffloadableEntryProcessor implements EntryProcessor, Offloadable { @Override public String getExecutorName() { return OFFLOADABLE_EXECUTOR; } @Override public Object process(Map.Entry entry) { return ((LockAware) entry).isLocked(); } @Override public EntryBackupProcessor getBackupProcessor() { return null; } } private static class TestOffloadableReadOnlyEntryProcessor implements EntryProcessor, Offloadable, ReadOnly { @Override public String getExecutorName() { return OFFLOADABLE_EXECUTOR; } @Override public Object process(Map.Entry entry) { return ((LockAware) entry).isLocked(); } @Override public EntryBackupProcessor getBackupProcessor() { return null; } } }