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()); } }