package org.openstack.atlas.service.domain.cache;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.BinaryConnectionFactory;
import net.spy.memcached.MemcachedClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openstack.atlas.cfg.RestApiConfiguration;
import org.openstack.atlas.cfg.ServicesConfigurationKeys;
import org.openstack.atlas.service.domain.exceptions.MissingFieldException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class AtlasCache {
private final Log LOG = LogFactory.getLog(AtlasCache.class);
private static MemcachedClient cacheClient;
private String ttl = "300";
@Autowired
public AtlasCache(RestApiConfiguration configuration) throws IOException {
String cacheHosts;
//need to get config from a common place..
if (configuration.hasKeys(ServicesConfigurationKeys.memcached_servers)) {
cacheHosts = configuration.getString(ServicesConfigurationKeys.memcached_servers);
buildCacheInstance(cacheHosts);
} else {
throw new MissingFieldException("The cache server host(s) information could not be found for the current configuration.");
}
if (configuration.hasKeys(ServicesConfigurationKeys.ttl)) {
this.ttl = configuration.getString(ServicesConfigurationKeys.ttl);
}
}
/**
* This method will set the object in cache using the provided key and ttl
*
* @param key the key for the caching store object
* @param ttl the ttl for the caching store object
* @param o the object to set
*/
public void set(String key, int ttl, final Object o) {
try {
cacheClient.set(key, ttl, o);
} catch (RuntimeException ex) {
//Server is down..
}
}
/**
* This method will set the object in cache using the default ttl
*
* @param key the key for the caching store object
* @param o the object to set
*/
public void set(String key, final Object o) {
set(key, Integer.valueOf(this.ttl), o);
}
/**
* This method will retrieve the object based on the provided key
*
* @param key the key for the caching store object
* @return return the object
*/
public Object get(String key) {
Object o = null;
try {
o = cacheClient.get(key);
if (o == null) {
//Sometimes connection is stale
LOG.info("Cache miss Retrying...");
o = cacheClient.get(key);
}
} catch (RuntimeException ex) {
LOG.info("Server is down...");
}
return o;
}
/**
* This method will delete the object using the provided key
*
* @param key the key for the caching store object
* @return Future<Boolean>
*/
public Object delete(String key) {
try {
return cacheClient.delete(key);
} catch (RuntimeException ex) {
LOG.info("Server is down...");
}
return null;
}
/**
* This method will verify the key lives in the caching store
*
* @param key the key for the caching store object
* @return boolean if the key belongs or not
*/
public boolean containsKey(String key) {
try {
return cacheClient.get(key) != null;
} catch (RuntimeException ex) {
LOG.info("Server is down...");
}
return false;
}
/**
* This method builds cache client
*
* @param cacheHosts the hosts names to connect to
* @throws java.io.IOException
*/
private void buildCacheInstance(String cacheHosts) throws IOException {
cacheClient = new MemcachedClient(
new BinaryConnectionFactory(),
AddrUtil.getAddresses(cacheHosts));
}
}