package org.infinispan.it.compatibility; import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager; import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers; import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.startHotRodServer; import static org.infinispan.server.memcached.test.MemcachedTestingUtil.killMemcachedClient; import static org.infinispan.server.memcached.test.MemcachedTestingUtil.killMemcachedServer; import static org.infinispan.server.memcached.test.MemcachedTestingUtil.startMemcachedTextServer; import static org.infinispan.test.TestingUtil.killCacheManagers; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Collections; import org.apache.commons.httpclient.HttpClient; import org.infinispan.Cache; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; import org.infinispan.commons.api.BasicCacheContainer; import org.infinispan.commons.api.Lifecycle; import org.infinispan.commons.equivalence.Equivalence; import org.infinispan.commons.marshall.Marshaller; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.rest.embedded.netty4.NettyRestServer; import org.infinispan.rest.configuration.RestServerConfigurationBuilder; import org.infinispan.server.hotrod.HotRodServer; import org.infinispan.server.hotrod.test.HotRodTestingUtil; import org.infinispan.server.memcached.MemcachedServer; import org.infinispan.test.fwk.TestCacheManagerFactory; import net.spy.memcached.ConnectionFactory; import net.spy.memcached.ConnectionFactoryBuilder; import net.spy.memcached.DefaultConnectionFactory; import net.spy.memcached.MemcachedClient; import net.spy.memcached.transcoders.Transcoder; /** * Compatibility cache factory taking care of construction and destruction of * caches, servers and clients for each of the endpoints being tested. * * @author Galder ZamarreƱo * @since 5.3 */ public class CompatibilityCacheFactory<K, V> { private static final int DEFAULT_NUM_OWNERS = 2; private EmbeddedCacheManager cacheManager; private HotRodServer hotrod; private RemoteCacheManager hotrodClient; private Lifecycle rest; private MemcachedServer memcached; private Cache<K, V> embeddedCache; private RemoteCache<K, V> hotrodCache; private HttpClient restClient; private MemcachedClient memcachedClient; private Transcoder transcoder; private final String cacheName; private final Marshaller marshaller; private final CacheMode cacheMode; private final int numOwners; private final boolean l1Enable; private final boolean memcachedWithDecoder; private int restPort; private Equivalence keyEquivalence = null; private Equivalence valueEquivalence = null; CompatibilityCacheFactory(CacheMode cacheMode) { this(cacheMode, DEFAULT_NUM_OWNERS, false); } CompatibilityCacheFactory(CacheMode cacheMode, int numOwners, boolean l1Enable) { this("", null, cacheMode, numOwners, l1Enable, null); } CompatibilityCacheFactory(String cacheName, Marshaller marshaller, CacheMode cacheMode) { this(cacheName, marshaller, cacheMode, DEFAULT_NUM_OWNERS); } CompatibilityCacheFactory(String cacheName, Marshaller marshaller, CacheMode cacheMode, int numOwners) { this(cacheName, marshaller, cacheMode, numOwners, false, null); } public CompatibilityCacheFactory(String cacheName, Marshaller marshaller, CacheMode cacheMode, Transcoder transcoder) { this(cacheName, marshaller, cacheMode, DEFAULT_NUM_OWNERS, false, transcoder); } CompatibilityCacheFactory(String cacheName, Marshaller marshaller, CacheMode cacheMode, int numOwners, boolean l1Enable, Transcoder transcoder) { this.cacheName = cacheName; this.marshaller = marshaller; this.cacheMode = cacheMode; this.numOwners = numOwners; this.l1Enable = l1Enable; this.transcoder = transcoder; this.memcachedWithDecoder = transcoder != null; } CompatibilityCacheFactory<K, V> keyEquivalence(Equivalence equivalence) { this.keyEquivalence = equivalence; return this; } CompatibilityCacheFactory<K, V> valueEquivalence(Equivalence equivalence) { this.valueEquivalence = equivalence; return this; } public CompatibilityCacheFactory<K, V> setup() throws Exception { createEmbeddedCache(); createHotRodCache(); createRestMemcachedCaches(); return this; } CompatibilityCacheFactory<K, V> setup(int baseHotRodPort, int portOffset) throws Exception { createEmbeddedCache(); createHotRodCache(baseHotRodPort + portOffset); createRestMemcachedCaches(portOffset); return this; } private void createRestMemcachedCaches() throws Exception { restPort = hotrod.getPort() + 20; final int memcachedPort = hotrod.getPort() + 40; createRestCache(restPort); createMemcachedCache(memcachedPort); } private void createRestMemcachedCaches(int portOffset) throws Exception { restPort = hotrod.getPort() + 20 + portOffset; final int memcachedPort = hotrod.getPort() + 40 + portOffset; createRestCache(restPort); createMemcachedCache(memcachedPort); } void createEmbeddedCache() { org.infinispan.configuration.cache.ConfigurationBuilder builder = new org.infinispan.configuration.cache.ConfigurationBuilder(); builder.clustering().cacheMode(cacheMode) .compatibility().enable().marshaller(marshaller); if (cacheMode.isDistributed() && numOwners != DEFAULT_NUM_OWNERS) { builder.clustering().hash().numOwners(numOwners); } if (cacheMode.isDistributed() && l1Enable) { builder.clustering().l1().enable(); } if (keyEquivalence != null) { builder.dataContainer().keyEquivalence(keyEquivalence); } if (valueEquivalence != null) { builder.dataContainer().valueEquivalence(valueEquivalence); } cacheManager = cacheMode.isClustered() ? TestCacheManagerFactory.createClusteredCacheManager(builder) : TestCacheManagerFactory.createCacheManager(builder); if (!cacheName.isEmpty()) cacheManager.defineConfiguration(cacheName, builder.build()); embeddedCache = cacheName.isEmpty() ? cacheManager.getCache() : cacheManager.getCache(cacheName); } private void createHotRodCache() { createHotRodCache(startHotRodServer(cacheManager)); } private void createHotRodCache(int port) { createHotRodCache(HotRodTestingUtil .startHotRodServer(cacheManager, port)); } private void createHotRodCache(HotRodServer server) { hotrod = server; hotrodClient = new RemoteCacheManager(new ConfigurationBuilder() .addServers("localhost:" + hotrod.getPort()) .marshaller(marshaller) .build()); hotrodCache = cacheName.isEmpty() ? hotrodClient.getCache() : hotrodClient.getCache(cacheName); } void createRestCache(int port) throws Exception { RestServerConfigurationBuilder builder = new RestServerConfigurationBuilder(); builder.port(port); rest = NettyRestServer.createServer(builder.build(), cacheManager); rest.start(); restClient = new HttpClient(); } private void createMemcachedCache(int port) throws IOException { memcached = memcachedWithDecoder ? startMemcachedTextServer(cacheManager, port, cacheName) : startMemcachedTextServer(cacheManager, port); memcachedClient = createMemcachedClient(60000, memcached.getPort()); } private MemcachedClient createMemcachedClient(long timeout, int port) throws IOException { ConnectionFactory cf = new DefaultConnectionFactory() { @Override public long getOperationTimeout() { return timeout; } }; if (transcoder != null) { cf = new ConnectionFactoryBuilder(cf).setTranscoder(transcoder).build(); } return new MemcachedClient(cf, Collections.singletonList(new InetSocketAddress("127.0.0.1", port))); } public static void killCacheFactories(CompatibilityCacheFactory... cacheFactories) { if (cacheFactories != null) { for (CompatibilityCacheFactory cacheFactory : cacheFactories) { if (cacheFactory != null) cacheFactory.teardown(); } } } void teardown() { killRemoteCacheManager(hotrodClient); killServers(hotrod); killRestServer(rest); killMemcachedClient(memcachedClient); killMemcachedServer(memcached); killCacheManagers(cacheManager); } void killRestServer(Lifecycle rest) { if (rest != null) { try { rest.stop(); } catch (Exception e) { // Ignore } } } public Marshaller getMarshaller() { return marshaller; } public Cache<K, V> getEmbeddedCache() { return embeddedCache; } public RemoteCache<K, V> getHotRodCache() { return hotrodCache; } int getHotRodPort() { return hotrod.getPort(); } public HttpClient getRestClient() { return restClient; } public MemcachedClient getMemcachedClient() { return memcachedClient; } int getMemcachedPort() { return memcached.getPort(); } public String getRestUrl() { String restCacheName = cacheName.isEmpty() ? BasicCacheContainer.DEFAULT_CACHE_NAME : cacheName; return String.format("http://localhost:%s/rest/%s", restPort, restCacheName); } HotRodServer getHotrodServer() { return hotrod; } }