package org.infinispan.client.hotrod;
import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
import static org.infinispan.test.TestingUtil.blockUntilCacheStatusAchieved;
import static org.infinispan.test.TestingUtil.blockUntilViewReceived;
import static org.infinispan.test.TestingUtil.killCacheManagers;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.infinispan.Cache;
import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.context.InvocationContext;
import org.infinispan.interceptors.BaseAsyncInterceptor;
import org.infinispan.lifecycle.ComponentStatus;
import org.infinispan.manager.CacheContainer;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.server.hotrod.HotRodServer;
import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
import org.infinispan.server.hotrod.test.HotRodTestingUtil;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeMethod;
/**
* @author Mircea.Markus@jboss.com
* @since 4.1
*/
public abstract class HitsAwareCacheManagersTest extends MultipleCacheManagersTest {
protected Map<SocketAddress, HotRodServer> addr2hrServer = new LinkedHashMap<>();
protected List<RemoteCacheManager> clients = new ArrayList<>();
protected void createHotRodServers(int num, ConfigurationBuilder defaultBuilder) {
// Start Hot Rod servers
for (int i = 0; i < num; i++) addHotRodServer(defaultBuilder);
// Verify that default caches should be started
for (int i = 0; i < num; i++) assert manager(i).getCache() != null;
// Block until views have been received
blockUntilViewReceived(manager(0).getCache(), num);
// Verify that caches running
for (int i = 0; i < num; i++) {
blockUntilCacheStatusAchieved(
manager(i).getCache(), ComponentStatus.RUNNING, 10000);
}
// Add hits tracking interceptors
addInterceptors();
for (int i = 0; i < num; i++) {
clients.add(createClient());
}
}
protected RemoteCacheManager client(int i) {
return clients.get(i);
}
protected RemoteCacheManager createClient() {
return new RemoteCacheManager(createHotRodClientConfigurationBuilder(
addr2hrServer.values().iterator().next().getPort()).build());
}
protected org.infinispan.client.hotrod.configuration.ConfigurationBuilder createHotRodClientConfigurationBuilder(int serverPort) {
org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
clientBuilder.addServer()
.host("localhost")
.port(serverPort);
return clientBuilder;
}
protected HotRodServer addHotRodServer(ConfigurationBuilder builder) {
EmbeddedCacheManager cm = addClusterEnabledCacheManager(builder);
HotRodServer server = HotRodClientTestingUtil.startHotRodServer(cm);
InetSocketAddress addr = new InetSocketAddress(server.getHost(), server.getPort());
addr2hrServer.put(addr, server);
return server;
}
protected HotRodServer addHotRodServer(ConfigurationBuilder builder, int port) {
EmbeddedCacheManager cm = addClusterEnabledCacheManager(builder);
HotRodServer server = HotRodTestingUtil.startHotRodServer(
cm, port, new HotRodServerConfigurationBuilder());
InetSocketAddress addr = new InetSocketAddress(server.getHost(), server.getPort());
addr2hrServer.put(addr, server);
return server;
}
protected void killServer() {
Iterator<HotRodServer> it = addr2hrServer.values().iterator();
HotRodServer server = it.next();
EmbeddedCacheManager cm = server.getCacheManager();
it.remove();
killServers(server);
killCacheManagers(cm);
cacheManagers.remove(cm);
}
@Override
@BeforeMethod(alwaysRun=true)
public void createBeforeMethod() throws Throwable {
if (cleanupAfterMethod()) {
addr2hrServer.clear();
}
super.createBeforeMethod();
}
protected HitCountInterceptor getHitCountInterceptor(Cache<?, ?> cache) {
return cache.getAdvancedCache().getAsyncInterceptorChain().findInterceptorWithClass(HitCountInterceptor.class);
}
protected void assertOnlyServerHit(SocketAddress serverAddress) {
assertServerHit(serverAddress, null, 1);
}
protected void assertServerHit(SocketAddress serverAddress, String cacheName, int expectedHits) {
CacheContainer cacheContainer = addr2hrServer.get(serverAddress).getCacheManager();
HitCountInterceptor interceptor = getHitCountInterceptor(namedCache(cacheName, cacheContainer));
assert interceptor.getHits() == expectedHits :
"Expected " + expectedHits + " hit(s) for " + serverAddress + " but received " + interceptor.getHits();
for (HotRodServer server : addr2hrServer.values()) {
if (server.getCacheManager() != cacheContainer) {
interceptor = getHitCountInterceptor(namedCache(cacheName, server.getCacheManager()));
assert interceptor.getHits() == 0 :
"Expected 0 hits in " + serverAddress + " but got " + interceptor.getHits();
}
}
}
private Cache<?, ?> namedCache(String cacheName, CacheContainer cacheContainer) {
return cacheName == null ? cacheContainer.getCache() : cacheContainer.getCache(cacheName);
}
protected void assertNoHits() {
for (HotRodServer server : addr2hrServer.values()) {
HitCountInterceptor interceptor = getHitCountInterceptor(server.getCacheManager().getCache());
assert interceptor.getHits() == 0 : "Expected 0 hits but got " + interceptor.getHits();
}
}
protected InetSocketAddress getAddress(HotRodServer hotRodServer) {
InetSocketAddress socketAddress = new InetSocketAddress(hotRodServer.getHost(), hotRodServer.getPort());
addr2hrServer.put(socketAddress, hotRodServer);
return socketAddress;
}
protected void resetStats() {
for (EmbeddedCacheManager manager : cacheManagers) {
HitCountInterceptor cmi = getHitCountInterceptor(manager.getCache());
cmi.reset();
}
}
protected void addInterceptors() {
addInterceptors(null);
}
protected void addInterceptors(String cacheName) {
for (EmbeddedCacheManager manager : cacheManagers) {
Cache<?, ?> cache = namedCache(cacheName, manager);
addHitCountInterceptor(cache);
}
}
private void addHitCountInterceptor(Cache<?, ?> cache) {
HitCountInterceptor interceptor = new HitCountInterceptor();
cache.getAdvancedCache().getAsyncInterceptorChain().addInterceptor(interceptor, 1);
}
@AfterClass(alwaysRun = true)
protected void destroy() {
addr2hrServer.values().forEach(HotRodClientTestingUtil::killServers);
super.destroy();
}
/**
* @author Mircea.Markus@jboss.com
* @since 4.1
*/
public static class HitCountInterceptor extends BaseAsyncInterceptor{
private static final Log log = LogFactory.getLog(HitCountInterceptor.class);
private final AtomicInteger invocationCount = new AtomicInteger(0);
@Override
public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable {
if (ctx.isOriginLocal()) {
int count = invocationCount.incrementAndGet();
log.infof("Hit %d for %s", count, command);
}
return invokeNext(ctx, command);
}
public int getHits() {
return invocationCount.get();
}
public void reset() {
invocationCount.set(0);
}
}
}