/**
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.geowebcache.blobstore.memory.distributed;
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.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geowebcache.io.ByteArrayResource;
import org.geowebcache.io.Resource;
import org.geowebcache.storage.TileObject;
import org.geowebcache.storage.blobstore.memory.MemoryBlobStore;
import org.geowebcache.storage.blobstore.memory.NullBlobStore;
import org.geowebcache.storage.blobstore.memory.distributed.HazelcastCacheProvider;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* This test class is used for testing {@link HazelcastCacheProvider} functionalities.
*
* @author Nicola Lagomarsini Geosolutions
*/
public class HazelcastCacheProviderTest {
/** LOGGER */
public static final Log LOG = LogFactory.getLog(HazelcastCacheProviderTest.class);
/** Name of the application context */
public static final String APP_CONTEXT_FILENAME = "applicationContextTest.xml";
/** Name of the bean associated to the first cache */
public static final String CACHE_1_NAME = "HazelCastCacheProvider1";
/** Name of the bean associated to the first cache */
public static final String CACHE_2_NAME = "HazelCastCacheProvider2";
/** Cache object 1 */
private static HazelcastCacheProvider cache1;
/** Cache object 2 */
private static HazelcastCacheProvider cache2;
/** First {@link MemoryBlobStore} instance used for tests */
private static MemoryBlobStore mem1;
/** Second {@link MemoryBlobStore} instance used for tests */
private static MemoryBlobStore mem2;
@BeforeClass
public static void initialSetup() {
// Creating an Hazelcast configuration
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
APP_CONTEXT_FILENAME);
// Create a nullblobstore to add to the memory blobstore
NullBlobStore nbs = new NullBlobStore();
mem1 = new MemoryBlobStore();
mem1.setStore(nbs);
mem1.setCacheBeanName(CACHE_1_NAME);
mem1.setApplicationContext(appContext);
mem2 = new MemoryBlobStore();
mem2.setStore(nbs);
mem2.setCacheBeanName(CACHE_2_NAME);
mem2.setApplicationContext(appContext);
// Get the two Hazelcast Cache instances
cache1 = appContext.getBean(CACHE_1_NAME, HazelcastCacheProvider.class);
cache2 = appContext.getBean(CACHE_2_NAME, HazelcastCacheProvider.class);
// Ensure both the caches are available and immutable
assertTrue(cache1.isAvailable());
assertTrue(cache1.isImmutable());
assertTrue(cache2.isAvailable());
assertTrue(cache2.isImmutable());
}
@Test
public void testTilePut() throws Exception {
// Clearing cache
cache1.clear();
// Ensure that both caches are cleared
assertEquals(0, cache1.getStatistics().getActualSize());
assertEquals(0, cache2.getStatistics().getActualSize());
// 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);
mem1.put(to);
// Try to get the same TileObject
TileObject to2 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters);
mem2.get(to2);
// Checks on the format
assertEquals(to.getBlobFormat(), to2.getBlobFormat());
// Checks if the resources are equals
InputStream is = to.getBlob().getInputStream();
InputStream is2 = to2.getBlob().getInputStream();
checkInputStreams(is, is2);
// Ensure Caches contain the result
TileObject to3 = cache1.getTileObj(to);
assertNotNull(to3);
// Checks if the resources are equals
is = to.getBlob().getInputStream();
InputStream is3 = to3.getBlob().getInputStream();
checkInputStreams(is, is3);
TileObject to4 = cache2.getTileObj(to);
assertNotNull(to4);
// Checks if the resources are equals
is = to.getBlob().getInputStream();
InputStream is4 = to4.getBlob().getInputStream();
checkInputStreams(is, is4);
}
@Test
public void testTileDelete() throws Exception {
// Clearing cache
cache1.clear();
// Ensure that both caches are cleared
assertEquals(0, cache1.getStatistics().getActualSize());
assertEquals(0, cache2.getStatistics().getActualSize());
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);
mem1.put(to);
// Try to get the same TileObject
TileObject to2 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters);
mem2.get(to2);
// Checks if the resources are equals
InputStream is = to2.getBlob().getInputStream();
InputStream is2 = bytes.getInputStream();
checkInputStreams(is, is2);
// Delete TileObject
TileObject to3 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters);
mem1.delete(to3);
// Checks if the resource is not present
TileObject to4 = TileObject.createQueryTileObject("test:123123 112", xyz, "EPSG:4326",
"image/jpeg", parameters);
assertFalse(mem1.get(to4));
assertFalse(mem2.get(to4));
// Ensure that caches do not contain the TileObject
TileObject to5 = cache1.getTileObj(to);
assertNull(to5);
TileObject to6 = cache2.getTileObj(to);
assertNull(to6);
}
@AfterClass
public static void afterClass() throws Exception {
// Blobstore destroy
mem1.destroy();
mem2.destroy();
// Cache destruction
cache1.destroy();
cache2.destroy();
}
/**
* Checks if the streams are equals, note that this method also closes the {@link InputStream}
*/
private void checkInputStreams(InputStream is, InputStream is2) throws IOException {
try {
// Ensure the two contents are equal
assertTrue(IOUtils.contentEquals(is, is2));
} finally {
// Closing streams
try {
is.close();
} catch (IOException e) {
LOG.error(e.getMessage(), e);
assertTrue(false);
}
try {
is2.close();
} catch (IOException e) {
LOG.error(e.getMessage(), e);
assertTrue(false);
}
}
}
}