/*
* JBoss, Home of Professional Open Source
* Copyright 2010 Red Hat Inc. and/or its affiliates and other
* contributors as indicated by the @author tags. All rights reserved.
* See the copyright.txt in the distribution for a full listing of
* individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.infinispan.client.hotrod;
import org.infinispan.Cache;
import org.infinispan.config.Configuration;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.marshall.Marshaller;
import org.infinispan.marshall.jboss.JBossMarshaller;
import org.infinispan.server.core.CacheValue;
import org.infinispan.server.hotrod.HotRodServer;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.infinispan.util.ByteArrayKey;
import org.infinispan.util.concurrent.NotifyingFuture;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import static org.infinispan.test.TestingUtil.k;
import static org.infinispan.test.TestingUtil.v;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
/**
* @author mmarkus
* @since 4.1
*/
@Test (testName = "client.hotrod.HotRodIntegrationTest", groups = "functional" )
public class HotRodIntegrationTest extends SingleCacheManagerTest {
private static final Log log = LogFactory.getLog(HotRodIntegrationTest.class);
private static final String CACHE_NAME = "replSync";
private Cache cache;
private Cache defaultCache;
RemoteCache defaultRemote;
RemoteCache remoteCache;
private RemoteCacheManager remoteCacheManager;
protected HotRodServer hotrodServer;
@Override
protected EmbeddedCacheManager createCacheManager() throws Exception {
Configuration standaloneConfig = getDefaultStandaloneConfig(false);
cacheManager = TestCacheManagerFactory.createLocalCacheManager(false);
cacheManager.defineConfiguration(CACHE_NAME, standaloneConfig);
defaultCache = cacheManager.getCache();
cache = cacheManager.getCache(CACHE_NAME);
//pass the config file to the cache
hotrodServer = TestHelper.startHotRodServer(cacheManager);
log.info("Started server on port: " + hotrodServer.getPort());
remoteCacheManager = getRemoteCacheManager();
defaultRemote = remoteCacheManager.getCache();
remoteCache = remoteCacheManager.getCache(CACHE_NAME);
return cacheManager;
}
protected RemoteCacheManager getRemoteCacheManager() {
Properties config = new Properties();
config.put("infinispan.client.hotrod.server_list", "127.0.0.1:" + hotrodServer.getPort());
return new RemoteCacheManager(config);
}
@AfterClass
public void testDestroyRemoteCacheFactory() {
remoteCacheManager.stop();
hotrodServer.stop();
}
public void testPut() throws Exception {
assert null == remoteCache.put("aKey", "aValue");
assertCacheContains(cache, "aKey", "aValue");
assert null == defaultRemote.put("otherKey", "otherValue");
assertCacheContains(defaultCache, "otherKey", "otherValue");
assert remoteCache.containsKey("aKey");
assert defaultRemote.containsKey("otherKey");
assert remoteCache.get("aKey").equals("aValue");
assert defaultRemote.get("otherKey").equals("otherValue");
}
public void testRemove() throws Exception {
assert null == remoteCache.put("aKey", "aValue");
assertCacheContains(cache, "aKey", "aValue");
assert remoteCache.get("aKey").equals("aValue");
assert null == remoteCache.remove("aKey");
assertCacheContains(cache, "aKey", null);
assert !remoteCache.containsKey("aKey");
}
public void testContains() {
assert !remoteCache.containsKey("aKey");
remoteCache.put("aKey", "aValue");
assert remoteCache.containsKey("aKey");
}
public void testGetVersionedCacheEntry() {
VersionedValue value = remoteCache.getVersioned("aKey");
assertNull("expected null but received: " + value, remoteCache.getVersioned("aKey"));
remoteCache.put("aKey", "aValue");
assert remoteCache.get("aKey").equals("aValue");
VersionedValue valueBinary = remoteCache.getVersioned("aKey");
assert valueBinary != null;
assertEquals(valueBinary.getValue(), "aValue");
log.info("Version is: " + valueBinary.getVersion());
//now put the same value
remoteCache.put("aKey", "aValue");
VersionedValue entry2 = remoteCache.getVersioned("aKey");
assertEquals(entry2.getValue(), "aValue");
assert entry2.getVersion() != valueBinary.getVersion();
assert !valueBinary.equals(entry2);
//now put a different value
remoteCache.put("aKey", "anotherValue");
VersionedValue entry3 = remoteCache.getVersioned("aKey");
assertEquals(entry3.getValue(), "anotherValue");
assert entry3.getVersion() != entry2.getVersion();
assert !entry3.equals(entry2);
}
public void testReplace() {
assert null == remoteCache.replace("aKey", "anotherValue");
remoteCache.put("aKey", "aValue");
assert null == remoteCache.replace("aKey", "anotherValue");
assert remoteCache.get("aKey").equals("anotherValue");
}
public void testReplaceIfUnmodified() {
assert null == remoteCache.replace("aKey", "aValue");
remoteCache.put("aKey", "aValue");
VersionedValue valueBinary = remoteCache.getVersioned("aKey");
assert remoteCache.replaceWithVersion("aKey", "aNewValue", valueBinary.getVersion());
VersionedValue entry2 = remoteCache.getVersioned("aKey");
assert entry2.getVersion() != valueBinary.getVersion();
assertEquals(entry2.getValue(), "aNewValue");
assert !remoteCache.replaceWithVersion("aKey", "aNewValue", valueBinary.getVersion());
}
public void testReplaceIfUnmodifiedWithExpiry(Method m) throws InterruptedException {
final int key = 1;
remoteCache.put(key, v(m));
VersionedValue valueBinary = remoteCache.getVersioned(key);
int lifespanSecs = 3; // seconds
long lifespan = TimeUnit.SECONDS.toMillis(lifespanSecs);
long startTime = System.currentTimeMillis();
String newValue = v(m, 2);
assert remoteCache.replaceWithVersion(key, newValue, valueBinary.getVersion(), lifespanSecs);
while (true) {
Object value = remoteCache.get(key);
if (System.currentTimeMillis() >= startTime + lifespan)
break;
assertEquals(v(m, 2), value);
Thread.sleep(100);
}
while (System.currentTimeMillis() < startTime + lifespan + 2000) {
if (remoteCache.get(key) == null) break;
Thread.sleep(50);
}
assertNull(remoteCache.get(key));
}
public void testReplaceWithVersionWithLifespanAsync(Method m) throws Exception {
int lifespanInSecs = 1; //seconds
final String k = k(m), v = v(m), newV = v(m, 2);
assertNull(remoteCache.replace(k, v));
remoteCache.put(k, v);
VersionedValue valueBinary = remoteCache.getVersioned(k);
long lifespan = TimeUnit.SECONDS.toMillis(lifespanInSecs);
long startTime = System.currentTimeMillis();
NotifyingFuture<Boolean> future = remoteCache.replaceWithVersionAsync(
k, newV, valueBinary.getVersion(), lifespanInSecs);
assert future.get();
while (true) {
VersionedValue entry2 = remoteCache.getVersioned(k);
if (System.currentTimeMillis() >= startTime + lifespan)
break;
// version should have changed; value should have changed
assert entry2.getVersion() != valueBinary.getVersion();
assertEquals(newV, entry2.getValue());
Thread.sleep(100);
}
while (System.currentTimeMillis() < startTime + lifespan + 2000) {
if (remoteCache.get(k) == null) break;
Thread.sleep(50);
}
assertNull(remoteCache.getVersioned(k));
}
public void testRemoveIfUnmodified() {
assert !remoteCache.removeWithVersion("aKey", 12321212l);
remoteCache.put("aKey", "aValue");
VersionedValue valueBinary = remoteCache.getVersioned("aKey");
assert remoteCache.removeWithVersion("aKey", valueBinary.getVersion());
assert !cache.containsKey("aKey");
remoteCache.put("aKey", "aNewValue");
VersionedValue entry2 = remoteCache.getVersioned("aKey");
assert entry2.getVersion() != valueBinary.getVersion();
assertEquals(entry2.getValue(), "aNewValue");
assert !remoteCache.removeWithVersion("aKey", valueBinary.getVersion());
}
public void testPutIfAbsent() {
remoteCache.put("aKey", "aValue");
assert null == remoteCache.putIfAbsent("aKey", "anotherValue");
assertEquals(remoteCache.get("aKey"),"aValue");
assertEquals(remoteCache.get("aKey"),"aValue");
assert remoteCache.containsKey("aKey");
assert true : remoteCache.replace("aKey", "anotherValue");
}
public void testClear() {
remoteCache.put("aKey", "aValue");
remoteCache.put("aKey2", "aValue");
remoteCache.clear();
assert !remoteCache.containsKey("aKey");
assert !remoteCache.containsKey("aKey2");
assert cache.isEmpty();
}
private void assertCacheContains(Cache cache, String key, String value) throws Exception {
Marshaller marshaller = new JBossMarshaller();
byte[] keyBytes = marshaller.objectToByteBuffer(key, 64);
byte[] valueBytes = marshaller.objectToByteBuffer(value, 64);
ByteArrayKey cacheKey = new ByteArrayKey(keyBytes);
CacheValue cacheValue = (CacheValue) cache.get(cacheKey);
if (value == null) {
assert cacheValue == null : "Expected null value but received: " + cacheValue;
} else {
assert Arrays.equals(valueBytes, (byte[])cacheValue.data());
}
}
}