package org.infinispan.distribution.groups; import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import org.infinispan.AdvancedCache; import org.infinispan.Cache; import org.infinispan.distribution.DistributionInfo; import org.infinispan.distribution.DistributionManager; import org.infinispan.distribution.group.Group; import org.infinispan.marshall.core.ExternalPojo; import org.infinispan.test.MultipleCacheManagersTest; import org.infinispan.test.TestingUtil; /** * This class contains some utility methods to the grouping advanced interface tests. * * @author Pedro Ruivo * @since 7.0 */ public abstract class BaseUtilGroupTest extends MultipleCacheManagersTest { protected static final String GROUP = "test-group"; protected final TestCacheFactory factory; protected BaseUtilGroupTest(TestCacheFactory factory) { this.factory = factory; } @Override protected String parameters() { String parameters = super.parameters(); if (parameters == null) return "[" + factory + "]"; else return "[" + factory + ", " + parameters.substring(1); } protected static GroupKey key(int index) { return new GroupKey(GROUP, index); } protected static String value(int index) { return "v" + index; } protected abstract void resetCaches(List<Cache<GroupKey, String>> cacheList); protected static boolean isGroupOwner(Cache<?, ?> cache, String groupName) { return TestingUtil.extractComponent(cache, DistributionManager.class).getCacheTopology().isWriteOwner(groupName); } protected static AdvancedCache<GroupKey, String> extractTargetCache(TestCache testCache) { if (isGroupOwner(testCache.testCache, GROUP)) { return testCache.testCache; } else { //the command will be forwarded to the primary owner. return testCache.primaryOwner.getAdvancedCache(); } } protected static void initCache(Cache<GroupKey, String> cache) { for (int i = 0; i < 10; ++i) { cache.put(key(i), value(i)); cache.put(new GroupKey("other-group", i), value(i)); } } protected static Map<GroupKey, String> createMap(int from, int to) { Map<GroupKey, String> map = new HashMap<>(); for (int i = from; i < to; ++i) { map.put(key(i), value(i)); } return map; } protected final TestCache createTestCacheAndReset(String groupName, List<Cache<GroupKey, String>> cacheList) { resetCaches(cacheList); return factory.create(groupName, cacheList); } public enum TestCacheFactory { PRIMARY_OWNER { @Override public TestCache create(String groupName, List<Cache<GroupKey, String>> cacheList) { for (Cache<GroupKey, String> cache : cacheList) { DistributionManager distributionManager = TestingUtil.extractComponent(cache, DistributionManager.class); DistributionInfo distributionInfo = distributionManager.getCacheTopology().getDistribution(groupName); if (distributionInfo.isPrimary()) { return new TestCache(cache, cache.getAdvancedCache()); } } throw new IllegalStateException("didn't find a cache... should never happen!"); } }, BACKUP_OWNER { @Override public TestCache create(String groupName, List<Cache<GroupKey, String>> cacheList) { Cache<GroupKey, String> primaryOwner = null; AdvancedCache<GroupKey, String> backupOwner = null; for (Cache<GroupKey, String> cache : cacheList) { DistributionManager distributionManager = TestingUtil.extractComponent(cache, DistributionManager.class); DistributionInfo distributionInfo = distributionManager.getCacheTopology().getDistribution(groupName); if (primaryOwner == null && distributionInfo.isPrimary()) { primaryOwner = cache; } else if (backupOwner == null && distributionInfo.isWriteOwner()) { backupOwner = cache.getAdvancedCache(); } if (primaryOwner != null && backupOwner != null) { return new TestCache(primaryOwner, backupOwner); } } throw new IllegalStateException("didn't find a cache... should never happen!"); } }, NON_OWNER { @Override public TestCache create(String groupName, List<Cache<GroupKey, String>> cacheList) { Cache<GroupKey, String> primaryOwner = null; AdvancedCache<GroupKey, String> nonOwner = null; for (Cache<GroupKey, String> cache : cacheList) { DistributionManager distributionManager = TestingUtil.extractComponent(cache, DistributionManager.class); DistributionInfo distributionInfo = distributionManager.getCacheTopology().getDistribution(groupName); if (primaryOwner == null && distributionInfo.isPrimary()) { primaryOwner = cache; } else if (nonOwner == null && !distributionInfo.isWriteOwner()) { nonOwner = cache.getAdvancedCache(); } if (primaryOwner != null && nonOwner != null) { return new TestCache(primaryOwner, nonOwner); } } throw new IllegalStateException("didn't find a cache... should never happen!"); } }; public abstract TestCache create(String groupName, List<Cache<GroupKey, String>> cacheList); } public static class GroupKey implements Serializable, ExternalPojo { private final String group; private final int key; GroupKey(String group, int key) { this.group = group; this.key = key; } @Group public String getGroup() { return group; } public int getKey() { return key; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; GroupKey groupKey = (GroupKey) o; return key == groupKey.key && group.equals(groupKey.group); } @Override public int hashCode() { int result = group.hashCode(); result = 31 * result + key; return result; } @Override public String toString() { return "GroupKey{" + "group='" + group + '\'' + ", key=" + key + '}'; } } public static class TestCache { public final Cache<GroupKey, String> primaryOwner; public final AdvancedCache<GroupKey, String> testCache; public TestCache(Cache<GroupKey, String> primaryOwner, AdvancedCache<GroupKey, String> testCache) { this.primaryOwner = primaryOwner; this.testCache = testCache; } } }