package org.infinispan.server.test.cs.rocksdb;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import org.apache.commons.codec.binary.Hex;
import org.infinispan.arquillian.core.InfinispanResource;
import org.infinispan.arquillian.core.RemoteInfinispanServer;
import org.infinispan.arquillian.model.RemoteInfinispanCache;
import org.infinispan.arquillian.model.RemoteInfinispanCacheManager;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.commons.io.ByteBuffer;
import org.infinispan.commons.io.ByteBufferImpl;
import org.infinispan.commons.logging.Log;
import org.infinispan.commons.logging.LogFactory;
import org.infinispan.commons.marshall.AbstractMarshaller;
import org.infinispan.commons.util.Util;
import org.infinispan.server.test.category.CacheStore;
import org.infinispan.server.test.util.ITestUtils;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.rocksdb.Options;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksIterator;
/**
* Tests RocksDB cache store.
*
* @author Michal Linhard (mlinhard@redhat.com)
*
*/
@RunWith(Arquillian.class)
@Category(CacheStore.class)
public class RocksDBCacheStoreIT {
private static final Log log = LogFactory.getLog(RocksDBCacheStoreIT.class);
@InfinispanResource("rocksdb")
RemoteInfinispanServer server;
// in suite-client-local this is testsuite/standalone-rocksdb-local.xml
@ArquillianResource
ContainerController controller;
public static final String CONTAINER = "rocksdb";
private static File dataDir = new File(ITestUtils.SERVER_DATA_DIR + File.separator + "rocksdbtestcache");
private static File expiredDir = new File(ITestUtils.SERVER_DATA_DIR + File.separator + "rocksdb-expiredtestcache");
private final TestMarshaller clientMarshaller = new TestMarshaller();
@Before
@After
public void removeDataFilesIfExists() {
Util.recursiveFileRemove(dataDir);
Util.recursiveFileRemove(expiredDir);
}
@Test
public void testDataSurvivesRestart() throws Exception {
controller.start(CONTAINER);
RemoteInfinispanCacheManager managerJmx = server.getCacheManager("local");
RemoteInfinispanCache cacheJmx = managerJmx.getCache("testcache");
RemoteCache<String, String> cache = createManager().getCache();
cache.clear();
assertEquals(0, cacheJmx.getNumberOfEntries());
cache.put("key1", "1");
cache.put("key2", "2");
cache.put("key3", "3");
assertEquals("1", cache.get("key1"));
assertEquals("2", cache.get("key2"));
assertEquals("3", cache.get("key3"));
log.tracef("Stored via Hot Rod:");
assertTrue(dataDir.exists());
assertTrue(dataDir.isDirectory());
assertTrue(expiredDir.exists());
assertTrue(expiredDir.isDirectory());
controller.stop(CONTAINER);
controller.start(CONTAINER);
assertEquals("1", cache.get("key1"));
assertEquals("2", cache.get("key2"));
assertEquals("3", cache.get("key3"));
controller.stop(CONTAINER);
}
@Test
public void testDataRetrievableViaRocksDbApi() throws Exception {
controller.start(CONTAINER);
RemoteInfinispanCacheManager managerJmx = server.getCacheManager("local");
RemoteInfinispanCache cacheJmx = managerJmx.getCache("testcache");
RemoteCache<String, String> cache = createManager().getCache();
cache.clear();
assertEquals(0, cacheJmx.getNumberOfEntries());
cache.put("key1", "1");
assertEquals("1", cache.get("key1"));
System.out.println("Stored via Hot Rod:");
assertTrue(dataDir.exists());
assertTrue(dataDir.isDirectory());
assertTrue(expiredDir.exists());
assertTrue(expiredDir.isDirectory());
controller.stop(CONTAINER);
RocksDB db = RocksDB.open(new Options(), dataDir.getAbsolutePath());
log.tracef("RocksDB file " + dataDir.getAbsolutePath() + " contents:");
for(RocksIterator i = db.newIterator(); i.isValid(); i.next()) {
log.tracef("key \"" + Hex.encodeHexString(i.key()) + "\": value \""
+ Hex.encodeHexString(i.value()) + "\"");
assertNotNull(i.value());
}
}
private static class TestMarshaller extends AbstractMarshaller {
@Override
public Object objectFromByteBuffer(byte[] buf, int offset, int length) throws IOException, ClassNotFoundException {
byte[] bytes = new byte[length];
System.arraycopy(buf, offset, bytes, 0, length);
return new String(bytes);
}
@Override
public boolean isMarshallable(Object o) throws Exception {
return (o instanceof String);
}
@Override
protected ByteBuffer objectToBuffer(Object o, int estimatedSize) throws IOException, InterruptedException {
if (o instanceof String) {
String str = (String) o;
byte[] bytes = str.getBytes();
return new ByteBufferImpl(bytes, 0, bytes.length);
} else {
throw new IllegalArgumentException("type not marshallable");
}
}
}
private RemoteCacheManager createManager() {
ConfigurationBuilder cfgBuild = ITestUtils.createConfigBuilder(server.getHotrodEndpoint().getInetAddress().getHostName(),
server.getHotrodEndpoint().getPort());
cfgBuild.marshaller(clientMarshaller);
return new RemoteCacheManager(cfgBuild.build());
}
}