/*
* Copyright (C) 2014 Stichting Akvo (Akvo Foundation)
*
* This file is part of Akvo FLOW.
*
* Akvo FLOW is free software: you can redistribute it and modify it under the terms of
* the GNU Affero General Public License (AGPL) as published by the Free Software Foundation,
* either version 3 of the License or any later version.
*
* Akvo FLOW 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 Affero General Public License included below for more details.
*
* The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>.
*/
package com.gallatinsystems.common.util;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.jsr107cache.Cache;
import net.sf.jsr107cache.CacheFactory;
import net.sf.jsr107cache.CacheManager;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.stdimpl.GCacheFactory;
public class MemCacheUtils {
private static Logger log = Logger.getLogger(MemCacheUtils.class.getName());
/**
* Initialize a Cache object with a expiration delta defined in seconds
*
* @param expirySeconds Expiration delta defined in seconds
* @return A Cache object or <b>null</b> when the runtime couldn't initialize the object
*/
@SuppressWarnings({
"unchecked", "rawtypes"
})
public static Cache initCache(Integer expirySeconds) {
Cache cache = null;
Map props = new HashMap();
props.put(GCacheFactory.EXPIRATION_DELTA, expirySeconds);
props.put(MemcacheService.SetPolicy.SET_ALWAYS, true);
try {
CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
cache = cacheFactory.createCache(props);
} catch (Exception e) {
log.log(Level.SEVERE, "Couldn't initialize cache: " + e.getMessage(), e);
}
return cache;
}
/**
* Puts an object in the cache, the expiration is already defined in the cache object.<br>
* The current implementation of Cache.put always return null, therefore this method doesn't
* return any value. <b>NOTE:</b> A failed put operation will get logged but also fail silently
* to the executing program
*
* @param cache An initialized Cache object
* @param key The key (must implement java.io.Serializable)
* @param value The value (must implement java.io.Serializable)
*/
public static void putObject(Cache cache, Object key, Object value) {
try {
if (cache == null) {
log.log(Level.WARNING, "Attempting to use an not initialized cache object");
return;
}
cache.put(key, value);
} catch (Exception e) {
log.log(Level.SEVERE, "Failed to store value in memcache: " + e.getMessage(), e);
}
}
/**
* Puts a set of objects in the cache, the expiration is already defined in the cache object.<br>
*
* @param cache An initialized Cache object
* @param objects A map containing objects to be cached along with their corresponding cache
* keys. The keys and objects must implement java.io.Serializable.
*/
public static void putObjects(Cache cache, Map<Object, Object> objects) {
try {
if (cache == null) {
log.log(Level.WARNING, "Attempting to use an not initialized cache object");
return;
}
cache.putAll(objects);
} catch (Exception e) {
log.log(Level.SEVERE, "Failed to store values in memcache: " + e.getMessage(), e);
}
}
/**
* Delegates testing to `Cache.containsKey`, handles runtime exceptions.<br>
* The runtime could raise an exception on "too long" requests, or partial service outage
*
* @param cache Initialized Cache object
* @param key Key to search (must implement java.io.Serializable)
* @return true|false depending if the Cache contains that key.<br>
* Returns <b>false</b> on runtime exception (e.g. Memcache service problem)
*/
public static boolean containsKey(Cache cache, Object key) {
try {
if (cache == null) {
log.log(Level.WARNING, "Attempting to use an not initialized cache object");
return false;
}
return cache.containsKey(key);
} catch (Exception e) {
log.log(Level.SEVERE, "Failed testing containsKey: " + e.getMessage(), e);
}
return false;
}
/**
* Takes in a list of keys and returns the objects which are found in the cache
*
* @param keys
* @return
*/
@SuppressWarnings("rawtypes")
public static Map getObjects(Cache cache, Collection keys) {
try {
if (cache == null) {
log.log(Level.WARNING, "Attempting to use an uninitialized cache object");
return Collections.emptyMap();
}
return cache.getAll(keys);
} catch (Exception e) {
log.log(Level.SEVERE, "Failed to retrieve values from memcache: " + e.getMessage(), e);
}
return Collections.emptyMap();
}
}