/* (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.*; import java.io.File; import java.io.IOException; import java.io.InputStream; 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.BlobStoreListener; import org.geowebcache.storage.TileObject; import org.geowebcache.storage.blobstore.memory.CacheConfiguration; import org.geowebcache.storage.blobstore.memory.CacheProvider; import org.geowebcache.storage.blobstore.memory.guava.GuavaCacheProvider; import org.geowebcache.storage.blobstore.memory.MemoryBlobStore; import org.geowebcache.storage.blobstore.memory.NullBlobStore; import org.geowebcache.storage.blobstore.file.FileBlobStore; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; /** * This class tests the functionalities of the {@link ConfigurableBlobStore} class. * * @author Nicola Lagomarsini Geosolutions */ public class ConfigurableBlobStoreTest extends GeoServerSystemTestSupport { /** {@link Logger} used for reporting exceptions */ private static final Logger LOGGER = Logging.getLogger(ConfigurableBlobStoreTest.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; private BlobStore defaultStore; /** {@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(); defaultStore = Mockito.spy(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); } } @Test public void testNullStore() throws Exception { // Configure the blobstore GWCConfig gwcConfig = new GWCConfig(); gwcConfig.setInnerCachingEnabled(true); gwcConfig.setEnabledPersistence(false); blobStore.setChanged(gwcConfig, false); BlobStore delegate = blobStore.getDelegate(); assertTrue(delegate instanceof MemoryBlobStore); assertTrue(((MemoryBlobStore) delegate).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 Cache contains the result TileObject to3 = cache.getTileObj(to); assertNotNull(to3); assertEquals(to.getBlobFormat(), to3.getBlobFormat()); // Check if the resources are equals is = to.getBlob().getInputStream(); InputStream is3 = to3.getBlob().getInputStream(); checkInputStreams(is, is3); // Ensure that NullBlobStore does not contain anything assertFalse(((MemoryBlobStore) delegate).getStore().get(to)); } @Test public void testTilePut() throws Exception { // Configure the blobstore GWCConfig gwcConfig = new GWCConfig(); gwcConfig.setInnerCachingEnabled(true); gwcConfig.setEnabledPersistence(true); blobStore.setChanged(gwcConfig, false); assertTrue(blobStore.getDelegate() instanceof MemoryBlobStore); // 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 Cache contains the result TileObject to3 = cache.getTileObj(to); assertNotNull(to3); assertEquals(to.getBlobFormat(), to3.getBlobFormat()); is = to.getBlob().getInputStream(); InputStream is3 = to3.getBlob().getInputStream(); checkInputStreams(is, is3); } @Test public void testTileDelete() throws Exception { GWCConfig gwcConfig = new GWCConfig(); gwcConfig.setInnerCachingEnabled(false); blobStore.setChanged(gwcConfig, false); assertTrue(blobStore.getDelegate() instanceof FileBlobStore); Map<String, String> parameters = new HashMap<String, String>(); parameters.put("a", "x"); parameters.put("b", "ø"); // Put a TileObject Resource bytes = new ByteArrayResource("1 2 3 4 5 6 test".getBytes()); long[] xyz = { 5L, 6L, 7L }; 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 if the resources are equals InputStream is = to2.getBlob().getInputStream(); InputStream is2 = bytes.getInputStream(); checkInputStreams(is, is2); // Remove TileObject TileObject to3 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326", "image/jpeg", parameters); blobStore.delete(to3); // Ensure TileObject is no more present TileObject to4 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326", "image/jpeg", parameters); assertFalse(blobStore.get(to4)); } @Test public void testListeners() throws Exception { // Configure the blobstore GWCConfig gwcConfig = new GWCConfig(); gwcConfig.setInnerCachingEnabled(true); gwcConfig.setEnabledPersistence(true); blobStore.setChanged(gwcConfig, false); BlobStoreListener l1 = Mockito.mock(BlobStoreListener.class); BlobStoreListener l2 = Mockito.mock(BlobStoreListener.class); assertTrue(blobStore.getDelegate() instanceof MemoryBlobStore); blobStore.addListener(l1); blobStore.addListener(l2); Mockito.verify(defaultStore, Mockito.times(2)).addListener(Mockito.any(BlobStoreListener.class)); Mockito.reset(defaultStore); // change the configuration GWCConfig newConfig = new GWCConfig(); newConfig.setInnerCachingEnabled(false); newConfig.setEnabledPersistence(true); blobStore.setChanged(newConfig, false); assertFalse(blobStore.getDelegate() instanceof MemoryBlobStore); Mockito.verify(defaultStore, Mockito.times(2)).removeListener(Mockito.any(BlobStoreListener.class)); Mockito.verify(defaultStore, Mockito.times(2)).addListener(Mockito.any(BlobStoreListener.class)); } /** * 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); } } } }