/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.gwc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.geoserver.gwc.config.GWCConfig;
import org.geoserver.test.GeoServerSystemTestSupport;
import org.geotools.util.logging.Logging;
import org.geowebcache.io.ByteArrayResource;
import org.geowebcache.io.Resource;
import org.geowebcache.storage.BlobStore;
import org.geowebcache.storage.TileObject;
import org.geowebcache.storage.blobstore.file.FileBlobStore;
import org.geowebcache.storage.blobstore.memory.CacheConfiguration;
import org.geowebcache.storage.blobstore.memory.CacheProvider;
import org.geowebcache.storage.blobstore.memory.MemoryBlobStore;
import org.geowebcache.storage.blobstore.memory.NullBlobStore;
import org.geowebcache.storage.blobstore.memory.distributed.HazelcastCacheProvider;
import org.geowebcache.storage.blobstore.memory.distributed.HazelcastLoader;
import org.geowebcache.storage.blobstore.memory.guava.GuavaCacheProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MapConfig.EvictionPolicy;
import com.hazelcast.config.MaxSizeConfig;
import com.hazelcast.config.MaxSizeConfig.MaxSizePolicy;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
/**
* This class tests the functionalities of the {@link ConfigurableBlobStore} class.
*
* @author Nicola Lagomarsini Geosolutions
*/
public class HazelcastTest extends GeoServerSystemTestSupport {
/** {@link Logger} used for reporting exceptions */
private static final Logger LOGGER = Logging.getLogger(HazelcastTest.class);
/** Name of the test directory */
public static final String TEST_BLOB_DIR_NAME = "gwcTestBlobs";
/** {@link CacheProvider} object used for testing purposes */
private static CacheProvider cache;
/** {@link ConfigurableBlobStore} object to test */
private static ConfigurableBlobStore blobStore;
/** Directory containing files for the {@link FileBlobStore} */
private File directory;
@BeforeClass
public static void initialSetup() {
cache = new GuavaCacheProvider(new CacheConfiguration());
}
@Before
public void setup() throws IOException {
// Setup the fileBlobStore
File dataDirectoryRoot = getTestData().getDataDirectoryRoot();
MemoryBlobStore mbs = new MemoryBlobStore();
NullBlobStore nbs = new NullBlobStore();
directory = new File(dataDirectoryRoot, "testConfigurableBlobStore");
if (directory.exists()) {
FileUtils.deleteDirectory(directory);
}
directory.mkdirs();
BlobStore defaultStore = new FileBlobStore(directory.getAbsolutePath());
blobStore = new ConfigurableBlobStore(defaultStore, mbs, nbs);
blobStore.setCache(cache);
}
@After
public void after() throws IOException {
// Delete the created directory
if (directory.exists()) {
FileUtils.deleteDirectory(directory);
}
}
@SuppressWarnings("serial")
@Test
public void testHazelcast() throws Exception {
// Configuring hazelcast caching
Config config = new Config();
MapConfig mapConfig = new MapConfig(HazelcastCacheProvider.HAZELCAST_MAP_DEFINITION);
MaxSizeConfig maxSizeConf = new MaxSizeConfig(16, MaxSizePolicy.USED_HEAP_SIZE);
mapConfig.setMaxSizeConfig(maxSizeConf);
mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
config.addMapConfig(mapConfig);
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
config.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(new ArrayList<String>() {
{
add("127.0.0.1");
}
});
config.getNetworkConfig().getInterfaces().addInterface("127.0.0.1");
HazelcastInstance instance1 = Hazelcast.newHazelcastInstance(config);
HazelcastLoader loader1 = new HazelcastLoader();
loader1.setInstance(instance1);
loader1.afterPropertiesSet();
// Creating another cacheprovider for ensuring hazelcast is behaving correctly
HazelcastCacheProvider cacheProvider1 = new HazelcastCacheProvider(loader1);
HazelcastInstance instance2 = Hazelcast.newHazelcastInstance(config);
HazelcastLoader loader2 = new HazelcastLoader();
loader2.setInstance(instance2);
loader2.afterPropertiesSet();
HazelcastCacheProvider cacheProvider2 = new HazelcastCacheProvider(loader2);
// Configure the blobstore
GWCConfig gwcConfig = new GWCConfig();
gwcConfig.setInnerCachingEnabled(true);
gwcConfig.setEnabledPersistence(false);
blobStore.setChanged(gwcConfig, false);
blobStore.setCache(cacheProvider1);
assertTrue(blobStore.getDelegate() instanceof MemoryBlobStore);
assertTrue(((MemoryBlobStore) blobStore.getDelegate()).getStore() instanceof NullBlobStore);
// Put a TileObject
Resource bytes = new ByteArrayResource("1 2 3 4 5 6 test".getBytes());
long[] xyz = { 1L, 2L, 3L };
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("a", "x");
parameters.put("b", "ΓΈ");
TileObject to = TileObject.createCompleteTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters, bytes);
blobStore.put(to);
// Try to get the Tile Object
TileObject to2 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters);
blobStore.get(to2);
// Check formats
assertEquals(to.getBlobFormat(), to2.getBlobFormat());
// Check if the resources are equals
InputStream is = to.getBlob().getInputStream();
InputStream is2 = to2.getBlob().getInputStream();
checkInputStreams(is, is2);
// Ensure Caches contain the result
// cache1
TileObject to3 = cacheProvider1.getTileObj(to);
assertNotNull(to3);
is = to.getBlob().getInputStream();
InputStream is3 = to3.getBlob().getInputStream();
checkInputStreams(is, is3);
// cache2
TileObject to4 = cacheProvider2.getTileObj(to);
assertNotNull(to4);
is = to.getBlob().getInputStream();
InputStream is4 = to4.getBlob().getInputStream();
checkInputStreams(is, is4);
// DELETE
// Remove TileObject
TileObject to5 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters);
blobStore.delete(to5);
// Ensure TileObject is no more present
TileObject to6 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters);
assertFalse(blobStore.get(to6));
// Ensure that each cache provider does not contain the tile object
assertNull(cacheProvider1.getTileObj(to6));
assertNull(cacheProvider2.getTileObj(to6));
// At the end, destroy the caches
cacheProvider1.destroy();
cacheProvider2.destroy();
}
/**
* Checks if the streams are equals, note that the {@link InputStream}s are also closed.
*/
private void checkInputStreams(InputStream is, InputStream is2) throws IOException {
try {
assertTrue(IOUtils.contentEquals(is, is2));
} finally {
try {
is.close();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
assertTrue(false);
}
try {
is2.close();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
assertTrue(false);
}
}
}
}