package org.infinispan.server.test.client.hotrod.security; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import org.infinispan.client.hotrod.Flag; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.ServerStatistics; import org.infinispan.client.hotrod.VersionedValue; import org.infinispan.client.hotrod.annotation.ClientCacheEntryCreated; import org.infinispan.client.hotrod.annotation.ClientCacheEntryModified; import org.infinispan.client.hotrod.annotation.ClientCacheEntryRemoved; import org.infinispan.client.hotrod.annotation.ClientListener; import org.infinispan.client.hotrod.event.ClientCacheEntryCreatedEvent; import org.infinispan.client.hotrod.event.ClientCacheEntryModifiedEvent; import org.infinispan.client.hotrod.event.ClientCacheEntryRemovedEvent; /** * * Tests for HotRod operations (especially for {@link RemoteCache} API), which can be used in * various security test. Some operations (e.g. #testClear(RemoteCache<String, String> remoteCache)) * don't test functionality of the operation itself, but only checks that operation was executed * without throwing security exception. In general intention of these test is not to test the * functionality of the operations themselves, but rather test that the operation are executed * without throwing security exceptions. * * @author vjuranek * @since 7.0 */ public class HotRodAuthzOperationTests { public static final String KEY1 = "key1"; public static final String VALUE1 = "value1"; public static final String KEY2 = "key2"; public static final String VALUE2 = "value2"; public static final String NON_EXISTENT_KEY = "nonExistentKey"; public static final int ASYNC_TIMEOUT = 1; //in seconds public static void testClear(RemoteCache<String, String> remoteCache) { remoteCache.clear(); assertTrue(remoteCache.isEmpty()); } public static void testClearAsync(RemoteCache<String, String> remoteCache) throws Exception { CompletableFuture<Void> f = remoteCache.clearAsync(); f.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); assertTrue(remoteCache.isEmpty()); } public static void testPutClear(RemoteCache<String, String> remoteCache) { remoteCache.put(KEY1, VALUE1); remoteCache.put(KEY2, VALUE2); remoteCache.clear(); assertFalse(remoteCache.containsKey(KEY1)); assertFalse(remoteCache.containsKey(KEY2)); assertTrue(remoteCache.isEmpty()); } public static void testPutClearAsync(RemoteCache<String, String> remoteCache) throws Exception { CompletableFuture<String> f1 = remoteCache.putAsync(KEY1, VALUE1); CompletableFuture<String> f2 = remoteCache.putAsync(KEY2, VALUE2); f1.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); f2.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); CompletableFuture<Void> c = remoteCache.clearAsync(); c.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); assertFalse(remoteCache.containsKey(KEY1)); assertFalse(remoteCache.containsKey(KEY2)); assertTrue(remoteCache.isEmpty()); } public static void testContainsKey(RemoteCache<String, String> remoteCache) { assertFalse(remoteCache.containsKey(NON_EXISTENT_KEY)); } public static void testPutContainsKey(RemoteCache<String, String> remoteCache) { remoteCache.put(KEY1, VALUE1); assertTrue(remoteCache.containsKey(KEY1)); } public static void testGet(RemoteCache<String, String> remoteCache) { assertTrue(remoteCache.containsKey(KEY1)); assertEquals(VALUE1, remoteCache.get(KEY1)); } public static void testGetAsync(RemoteCache<String, String> remoteCache) throws Exception { assertTrue(remoteCache.containsKey(KEY1)); CompletableFuture<String> f = remoteCache.getAsync(KEY1); assertEquals(VALUE1, f.get(ASYNC_TIMEOUT, TimeUnit.SECONDS)); } public static void testGetNonExistent(RemoteCache<String, String> remoteCache) { assertEquals(null, remoteCache.get("nonExistentKey")); } public static void testGetNonExistentAsync(RemoteCache<String, String> remoteCache) throws Exception { assertEquals(null, remoteCache.getAsync("nonExistentKey").get(ASYNC_TIMEOUT, TimeUnit.SECONDS)); } public static void testKeySet(RemoteCache<String, String> remoteCache) { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); remoteCache.put(KEY2, VALUE2); assertEquals(2, remoteCache.keySet().size()); } public static void testPut(RemoteCache<String, String> remoteCache) { assertNull(remoteCache.put(KEY1, VALUE1)); } public static void testPutAsync(RemoteCache<String, String> remoteCache) throws Exception { CompletableFuture<String> f = remoteCache.putAsync(KEY1, VALUE1); assertNull(f.get(ASYNC_TIMEOUT, TimeUnit.SECONDS)); } public static void testPutGet(RemoteCache<String, String> remoteCache) { testPut(remoteCache); testGet(remoteCache); } public static void testPutGetAsync(RemoteCache<String, String> remoteCache) throws Exception { testPutAsync(remoteCache); testGetAsync(remoteCache); } public static void testPutAll(RemoteCache<String, String> remoteCache) { remoteCache.clear(); Map<String, String> entries = new HashMap<String, String>(2); entries.put(KEY1, VALUE1); entries.put(KEY2, VALUE2); remoteCache.putAll(entries); assertEquals(2, remoteCache.size()); } public static void testPutAllAsync(RemoteCache<String, String> remoteCache) throws Exception { remoteCache.clear(); Map<String, String> entries = new HashMap<String, String>(2); entries.put(KEY1, VALUE1); entries.put(KEY2, VALUE2); CompletableFuture<Void> f = remoteCache.putAllAsync(entries); f.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); assertEquals(2, remoteCache.size()); } public static void testRemove(RemoteCache<String, String> remoteCache) { assertNull(remoteCache.remove(NON_EXISTENT_KEY)); } public static void testRemoveAsync(RemoteCache<String, String> remoteCache) throws Exception { assertNull(remoteCache.removeAsync(NON_EXISTENT_KEY).get(ASYNC_TIMEOUT, TimeUnit.SECONDS)); } public static void testRemoveContains(RemoteCache<String, String> remoteCache) { remoteCache.put(KEY1, VALUE1); assertTrue(remoteCache.containsKey(KEY1)); remoteCache.remove(KEY1); assertFalse(remoteCache.containsKey(KEY1)); } public static void testRemoveContainsAsync(RemoteCache<String, String> remoteCache) throws Exception { remoteCache.put(KEY1, VALUE1); assertTrue(remoteCache.containsKey(KEY1)); CompletableFuture<String> f = remoteCache.removeAsync(KEY1); f.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); assertFalse(remoteCache.containsKey(KEY1)); } public static void testSize(RemoteCache<String, String> remoteCache) { assertTrue(remoteCache.size() > 0); } public static void testPutIfAbsent(RemoteCache<String, String> remoteCache) { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); assertNull(remoteCache.putIfAbsent(KEY1, "some test value")); assertEquals(VALUE1, remoteCache.get(KEY1)); } public static void testPutIfAbsentAsync(RemoteCache<String, String> remoteCache) throws Exception { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); assertNull(remoteCache.putIfAbsentAsync(KEY1, "some test value").get(ASYNC_TIMEOUT, TimeUnit.SECONDS)); assertEquals(VALUE1, remoteCache.getAsync(KEY1).get(ASYNC_TIMEOUT, TimeUnit.SECONDS)); } public static void testReplaceWitFlag(RemoteCache<String, String> remoteCache) { remoteCache.put(KEY1, VALUE1); assertEquals(VALUE1, remoteCache.withFlags(Flag.FORCE_RETURN_VALUE).replace(KEY1, "replace value")); } public static void testReplaceWitFlagAsync(RemoteCache<String, String> remoteCache) throws Exception { remoteCache.put(KEY1, VALUE1); assertEquals( VALUE1, remoteCache.withFlags(Flag.FORCE_RETURN_VALUE).replaceAsync(KEY1, "replace value") .get(ASYNC_TIMEOUT, TimeUnit.SECONDS)); } public static void testPutGetBulk(RemoteCache<String, String> remoteCache) { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); remoteCache.put(KEY2, VALUE2); assertEquals(2, remoteCache.getBulk().size()); } public static void testGetWithMetadata(RemoteCache<String, String> remoteCache) { assertNull(remoteCache.getWithMetadata(NON_EXISTENT_KEY)); } public static void testPutGetWithMetadata(RemoteCache<String, String> remoteCache) { remoteCache.put(KEY1, VALUE1); assertNotNull(remoteCache.getWithMetadata(KEY1)); } public static void testGetVersioned(RemoteCache<String, String> remoteCache) { assertNull(remoteCache.getVersioned(NON_EXISTENT_KEY)); } public static void testPutGetVersioned(RemoteCache<String, String> remoteCache) { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); VersionedValue<String> v = remoteCache.getVersioned(KEY1); assertEquals(VALUE1, v.getValue()); assertTrue(v.getVersion() != 0); } public static void testReplaceWithVersioned(RemoteCache<String, String> remoteCache) { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); VersionedValue<String> v = remoteCache.getVersioned(KEY1); assertEquals(VALUE1, v.getValue()); long ver = v.getVersion(); remoteCache.replaceWithVersion(KEY1, VALUE2, ver); v = remoteCache.getVersioned(KEY1); assertEquals(VALUE2, v.getValue()); assertTrue(ver != v.getVersion()); } public static void testReplaceWithVersionAsync(RemoteCache<String, String> remoteCache) throws Exception { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); VersionedValue<String> v = remoteCache.getVersioned(KEY1); assertEquals(VALUE1, v.getValue()); long ver = v.getVersion(); CompletableFuture<Boolean> f = remoteCache.replaceWithVersionAsync(KEY1, VALUE2, ver); f.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); v = remoteCache.getVersioned(KEY1); assertEquals(VALUE2, v.getValue()); assertTrue(ver != v.getVersion()); } public static void testRemoveWithVersion(RemoteCache<String, String> remoteCache) { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); VersionedValue<String> v = remoteCache.getVersioned(KEY1); assertEquals(VALUE1, v.getValue()); long ver = v.getVersion(); remoteCache.removeWithVersion(KEY1, ver); v = remoteCache.getVersioned(KEY1); if (v != null) assertTrue(ver != v.getVersion()); } public static void testRemoveWithVersionAsync(RemoteCache<String, String> remoteCache) throws Exception { remoteCache.clear(); remoteCache.put(KEY1, VALUE1); VersionedValue<String> v = remoteCache.getVersioned(KEY1); assertEquals(VALUE1, v.getValue()); long ver = v.getVersion(); CompletableFuture<Boolean> f = remoteCache.removeWithVersionAsync(KEY1, ver); f.get(ASYNC_TIMEOUT, TimeUnit.SECONDS); v = remoteCache.getVersioned(KEY1); if (v != null) assertTrue(ver != v.getVersion()); } public static void testStats(RemoteCache<String, String> remoteCache) { ServerStatistics s = remoteCache.stats(); assertNotNull(s); } public static void testGetRemoteCacheManager(RemoteCache<String, String> remoteCache) { RemoteCacheManager rcm = remoteCache.getRemoteCacheManager(); assertNotNull(rcm); } public static void testAddGetClientListener(RemoteCache<String, String> remoteCache) { remoteCache.addClientListener(new NoopEventListener()); Set<Object> s = remoteCache.getListeners(); assertTrue(s.size() > 0); } public static void testRemoveClientListener(RemoteCache<String, String> remoteCache) { NoopEventListener c = new NoopEventListener(); int initialListenerCount = remoteCache.getListeners().size(); remoteCache.addClientListener(c); assertEquals(initialListenerCount + 1, remoteCache.getListeners().size()); remoteCache.removeClientListener(c); assertEquals(initialListenerCount, remoteCache.getListeners().size()); } @ClientListener public static class NoopEventListener { @ClientCacheEntryCreated public void handleCreatedEvent(ClientCacheEntryCreatedEvent<?> e) { //no-op } @ClientCacheEntryModified public void handleModifiedEvent(ClientCacheEntryModifiedEvent<?> e) { //no-op } @ClientCacheEntryRemoved public void handleRemovedEvent(ClientCacheEntryRemovedEvent<?> e) { //no-op } } }