package org.infinispan.client.hotrod.xsite;
import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
import static org.testng.AssertJUnit.assertEquals;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.infinispan.Cache;
import org.infinispan.client.hotrod.HitsAwareCacheManagersTest.HitCountInterceptor;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
import org.infinispan.client.hotrod.test.InternalRemoteCacheManager;
import org.infinispan.configuration.cache.BackupConfiguration.BackupStrategy;
import org.infinispan.configuration.cache.BackupConfigurationBuilder;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.server.hotrod.HotRodServer;
import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
import org.infinispan.test.TestingUtil;
import org.infinispan.xsite.AbstractXSiteTest;
import org.testng.annotations.AfterClass;
abstract class AbstractHotRodSiteFailoverTest extends AbstractXSiteTest {
static String SITE_A = "LON";
static String SITE_B = "NYC";
static int NODES_PER_SITE = 2;
Map<String, List<HotRodServer>> siteServers = new HashMap<>();
RemoteCacheManager client(String siteName, Optional<String> backupSiteName) {
HotRodServer server = siteServers.get(siteName).get(0);
org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder =
new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
clientBuilder
.addServer().host("localhost").port(server.getPort())
.maxRetries(3); // Some retries so that shutdown nodes can be skipped
Optional<Integer> backupPort = backupSiteName.map(name -> {
HotRodServer backupServer = siteServers.get(name).get(0);
clientBuilder.addCluster(name).addClusterNode("localhost", backupServer.getPort());
return backupServer.getPort();
});
if (backupPort.isPresent())
log.debugf("Client for site '%s' connecting to main server in port %d, and backup cluster node port is %d",
siteName, server.getPort(), backupPort.get());
else
log.debugf("Client for site '%s' connecting to main server in port %d",
siteName, server.getPort());
return new InternalRemoteCacheManager(clientBuilder.build());
}
int findServerPort(String siteName) {
return siteServers.get(siteName).get(0).getPort();
}
void killSite(String siteName) {
log.debugf("Kill site '%s' with ports: %s", siteName,
siteServers.get(siteName).stream().map(s -> String.valueOf(s.getPort())).collect(Collectors.joining(", ")));
siteServers.get(siteName).forEach(HotRodClientTestingUtil::killServers);
site(siteName).cacheManagers().forEach(TestingUtil::killCacheManagers);
}
@Override
protected void createSites() {
createHotRodSite(SITE_A, SITE_B, Optional.empty());
createHotRodSite(SITE_B, SITE_A, Optional.empty());
}
@AfterClass(alwaysRun = true) // run even if the test failed
protected void destroy() {
try {
siteServers.values().forEach(servers ->
servers.forEach(HotRodClientTestingUtil::killServers));
} finally {
super.destroy();
}
}
protected void createHotRodSite(String siteName, String backupSiteName, Optional<Integer> serverPort) {
ConfigurationBuilder builder = hotRodCacheConfiguration(
getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false));
BackupConfigurationBuilder backup = builder.sites().addBackup();
backup.site(backupSiteName).strategy(BackupStrategy.SYNC);
GlobalConfigurationBuilder globalBuilder = GlobalConfigurationBuilder.defaultClusteredBuilder();
globalBuilder.globalJmxStatistics().allowDuplicateDomains(true);
globalBuilder.site().localSite(siteName);
TestSite site = createSite(siteName, NODES_PER_SITE, globalBuilder, builder);
Collection<EmbeddedCacheManager> cacheManagers = site.cacheManagers();
List<HotRodServer> servers = cacheManagers.stream().map(cm -> serverPort
.map(port -> HotRodClientTestingUtil.startHotRodServer(cm, port, new HotRodServerConfigurationBuilder()))
.orElseGet(() -> HotRodClientTestingUtil.startHotRodServer(cm))).collect(Collectors.toList());
siteServers.put(siteName, servers);
log.debugf("Create site '%s' with ports: %s", siteName,
servers.stream().map(s -> String.valueOf(s.getPort())).collect(Collectors.joining(", ")));
}
protected void addHitCountInterceptors() {
siteServers.forEach((name, servers) ->
servers.forEach(server -> {
HitCountInterceptor interceptor = new HitCountInterceptor();
server.getCacheManager().getCache().getAdvancedCache().getAsyncInterceptorChain()
.addInterceptor(interceptor, 1);
})
);
}
protected void assertNoHits() {
siteServers.forEach((name, servers) ->
servers.forEach(server -> {
Cache<?, ?> cache = server.getCacheManager().getCache();
HitCountInterceptor interceptor = getHitCountInterceptor(cache);
assertEquals(0, interceptor.getHits());
})
);
}
protected void resetHitCounters() {
siteServers.forEach((name, servers) ->
servers.forEach(server -> {
Cache<?, ?> cache = server.getCacheManager().getCache();
HitCountInterceptor interceptor = getHitCountInterceptor(cache);
interceptor.reset();
})
);
}
protected void assertSiteHit(String siteName, int expectedHits) {
Stream<HotRodServer> serversHit = siteServers.get(siteName).stream().filter(server -> {
Cache<?, ?> cache = server.getCacheManager().getCache();
HitCountInterceptor interceptor = getHitCountInterceptor(cache);
return interceptor.getHits() == expectedHits;
});
assertEquals(1, serversHit.count());
resetHitCounters();
}
protected void assertSiteNotHit(String siteName) {
siteServers.get(siteName).forEach(server -> {
Cache<?, ?> cache = server.getCacheManager().getCache();
HitCountInterceptor interceptor = getHitCountInterceptor(cache);
assertEquals(0, interceptor.getHits());
});
}
protected HitCountInterceptor getHitCountInterceptor(Cache<?, ?> cache) {
return cache.getAdvancedCache().getAsyncInterceptorChain().findInterceptorWithClass(HitCountInterceptor.class);
}
}