package org.infinispan.stream;
import static org.testng.Assert.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.distribution.MagicKey;
import org.infinispan.filter.CacheFilters;
import org.infinispan.filter.KeyValueFilter;
import org.infinispan.marshall.core.ExternalPojo;
import org.infinispan.metadata.Metadata;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.transaction.TransactionMode;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
/**
* Test to verify distributed entry behavior when store as binary is used
*
* @author wburns
* @since 8.0
*/
@Test(groups = "functional", testName = "stream.DistributedStreamIteratorWithStoreAsBinaryTest")
public class DistributedStreamIteratorWithStoreAsBinaryTest extends MultipleCacheManagersTest {
protected final static String CACHE_NAME = "DistributedStreamIteratorWithStoreAsBinaryTest";
protected ConfigurationBuilder builderUsed;
protected final boolean tx = false;
protected final CacheMode cacheMode = CacheMode.DIST_SYNC;
@Override
protected void createCacheManagers() throws Throwable {
builderUsed = new ConfigurationBuilder();
builderUsed.clustering().cacheMode(cacheMode);
builderUsed.clustering().hash().numOwners(1);
builderUsed.dataContainer().storeAsBinary().enabled(true).storeKeysAsBinary(true).storeValuesAsBinary(true);
if (tx) {
builderUsed.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
}
createClusteredCaches(3, CACHE_NAME, builderUsed);
}
@Test
public void testFilterWithStoreAsBinary() throws InterruptedException, ExecutionException, TimeoutException {
Cache<MagicKey, String> cache0 = cache(0, CACHE_NAME);
Cache<MagicKey, String> cache1 = cache(1, CACHE_NAME);
Cache<MagicKey, String> cache2 = cache(2, CACHE_NAME);
Map<MagicKey, String> originalValues = new HashMap<>();
originalValues.put(new MagicKey(cache0), "cache0");
originalValues.put(new MagicKey(cache1), "cache1");
originalValues.put(new MagicKey(cache2), "cache2");
cache0.putAll(originalValues);
// Try filter for all values
Iterator<CacheEntry<MagicKey, String>> iterator = cache1.getAdvancedCache().cacheEntrySet().stream().
filter(CacheFilters.predicate(new MagicKeyStringFilter(originalValues))).iterator();
// we need this count since the map will replace same key'd value
int count = 0;
Map<MagicKey, String> results = new HashMap<MagicKey, String>();
while (iterator.hasNext()) {
Map.Entry<MagicKey, String> entry = iterator.next();
results.put(entry.getKey(), entry.getValue());
count++;
}
assertEquals(count, 3);
assertEquals(originalValues, results);
}
@Test
public void testFilterWithStoreAsBinaryPartialKeys() throws InterruptedException, ExecutionException, TimeoutException {
Cache<MagicKey, String> cache0 = cache(0, CACHE_NAME);
Cache<MagicKey, String> cache1 = cache(1, CACHE_NAME);
Cache<MagicKey, String> cache2 = cache(2, CACHE_NAME);
MagicKey findKey = new MagicKey(cache1);
Map<MagicKey, String> originalValues = new HashMap<>();
originalValues.put(new MagicKey(cache0), "cache0");
originalValues.put(findKey, "cache1");
originalValues.put(new MagicKey(cache2), "cache2");
cache0.putAll(originalValues);
// Try filter for all values
Iterator<CacheEntry<MagicKey, String>> iterator = cache1.getAdvancedCache().cacheEntrySet().stream().
filter(CacheFilters.predicate(new MagicKeyStringFilter(Collections.singletonMap(findKey, "cache1")))).iterator();
CacheEntry<MagicKey, String> entry = iterator.next();
AssertJUnit.assertEquals(findKey, entry.getKey());
AssertJUnit.assertEquals("cache1", entry.getValue());
assertFalse(iterator.hasNext());
}
private static class MagicKeyStringFilter implements KeyValueFilter<MagicKey, String>, Serializable, ExternalPojo {
private final Map<MagicKey, String> allowedEntries;
public MagicKeyStringFilter(Map<MagicKey, String> allowedEntries) {
this.allowedEntries = allowedEntries;
}
@Override
public boolean accept(MagicKey key, String value, Metadata metadata) {
String allowedValue = allowedEntries.get(key);
return allowedValue != null && allowedValue.equals(value);
}
}
}