diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java index 64205b6..9a0309f 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java @@ -16,6 +16,8 @@ import org.gcube.common.homelibrary.home.workspace.exceptions.InsufficientPrivil import org.gcube.common.homelibrary.home.workspace.exceptions.ItemAlreadyExistException; import org.gcube.common.homelibrary.home.workspace.folder.items.ExternalFile; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.data_catalogue.grsf_publish_ws.utils.cache.CacheImpl; +import org.gcube.data_catalogue.grsf_publish_ws.utils.cache.CacheInterface; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogueFactory; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogueImpl; @@ -48,13 +50,17 @@ public abstract class HelperMethods { private static final String SOCIAL_SERVICE_APPLICATION_TOKEN = "2/tokens/generate-application-token/"; private static final String SOCIAL_SERVICE_WRITE_APPLICATION_POST = "2/posts/write-post-app/"; private static final String MEDIATYPE_JSON = "application/json"; - + // to be retrieved from the web.xml public static final String MANAGE_CONTEX_KEY = "ManageVRE"; public static final String PUBLIC_CONTEX_KEY = "PublicVRE"; private static final String CSV_MIME = "text/csv"; private static final String PATH_SEPARATOR = "/"; + // caches + private static CacheInterface userEmailCache = new CacheImpl(1000 * 60 * 30); + private static CacheInterface userFullnameCache = new CacheImpl(1000 * 60 * 30); + /** * Convert a group name to its id on ckan * @param origName @@ -126,13 +132,21 @@ public abstract class HelperMethods { * @return * @throws Exception */ + @SuppressWarnings("unchecked") public static String getUserEmail(String context, String token){ - String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath(); - String url = baseUrl + "users/getUserEmail?gcube-token=" + token; - logger.debug("Request url is " + url); - return executGETHttpRequest(url, 200); - + // check in cache + String result = null; + if((result = (String) userEmailCache.get(token)) != null){ + return result; + }else{ + String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath(); + String url = baseUrl + "users/getUserEmail?gcube-token=" + token; + logger.debug("Request url is " + url); + result = executGETHttpRequest(url, 200); + userEmailCache.insert(token, result); + } + return result; } /** @@ -142,13 +156,21 @@ public abstract class HelperMethods { * @return * @throws Exception */ + @SuppressWarnings("unchecked") public static String getUserFullname(String context, String token){ - String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath(); - String url = baseUrl + "users/getUserFullname?gcube-token=" + token; - logger.debug("Request url is " + url); - return executGETHttpRequest(url, 200); - + // check in cache + String result = null; + if((result = (String) userFullnameCache.get(token)) != null){ + return result; + }else{ + String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath(); + String url = baseUrl + "users/getUserFullname?gcube-token=" + token; + logger.debug("Request url is " + url); + result = executGETHttpRequest(url, 200); + userFullnameCache.insert(token, result); + } + return result; } /** @@ -321,7 +343,7 @@ public abstract class HelperMethods { withoutHTML = withoutHTML.replaceAll("[^\\p{ASCII}]", " "); return withoutHTML; } - + /** * Send notification to vre members about the created product by writing a post. * @param productName the title of the product diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheImpl.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheImpl.java new file mode 100644 index 0000000..4e66e04 --- /dev/null +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheImpl.java @@ -0,0 +1,53 @@ +package org.gcube.data_catalogue.grsf_publish_ws.utils.cache; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.LoggerFactory; + +/** + * Cache implementation. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +public class CacheImpl implements CacheInterface { + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CacheImpl.class); + + /** + * The hashmap + */ + private Map> userSpaceMap; + + /** + * Cache entry expires after EXPIRED_AFTER ms + */ + private long ttl; + + public CacheImpl(long timeout){ + ttl = timeout; + userSpaceMap = new ConcurrentHashMap<>(); + } + + @Override + public Long get(String key) { + + if(userSpaceMap.containsKey(key)){ + CacheValueBean bean = userSpaceMap.get(key); + if(CacheUtilities.expired(bean.getTTL(), ttl)){ + userSpaceMap.remove(key); + logger.debug("Amount of space in the infrastructure used expired for key " + key + ", returning null"); + } + else + return bean.getValue(); + } + return null; + } + + @Override + public boolean insert(String key, Long value) { + CacheValueBean newBean = new CacheValueBean(value, System.currentTimeMillis()); + userSpaceMap.put(key, newBean); + return true; + } +} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheInterface.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheInterface.java new file mode 100644 index 0000000..98882de --- /dev/null +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheInterface.java @@ -0,0 +1,26 @@ +package org.gcube.data_catalogue.grsf_publish_ws.utils.cache; + +/** + * Generic interface + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + * @param the key type + * @param the value type + */ +public interface CacheInterface { + + /** + * Retrieve a value V from the cache + * @param key + * @return + */ + public V get(K key); + + /** + * Insert an object V with key K into the cache + * @param key + * @param value + * @return + */ + public boolean insert(K key, V value); + +} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheUtilities.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheUtilities.java new file mode 100644 index 0000000..b169eea --- /dev/null +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheUtilities.java @@ -0,0 +1,24 @@ +package org.gcube.data_catalogue.grsf_publish_ws.utils.cache; + +/** + * Utility functions for caches + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class CacheUtilities { + /** + * Check if the bean expired + * @param beanTimestamp + * @param ttl + * @return if expired, otherwise + */ + public static boolean expired(long beanTimestamp, long ttl){ + + long currentTime = System.currentTimeMillis(); + + if((beanTimestamp + ttl) <= currentTime) + return true; + else + return false; + + } +} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheValueBean.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheValueBean.java new file mode 100644 index 0000000..02357d6 --- /dev/null +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/cache/CacheValueBean.java @@ -0,0 +1,38 @@ +package org.gcube.data_catalogue.grsf_publish_ws.utils.cache; + +/** + * A bean object to be used as value within the cache. It contains a TTL value too. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + * @param the value type + */ +public class CacheValueBean { + + private V value; + private long TTL; + + /** + * @param value + * @param TTL + */ + public CacheValueBean(V value, long ttl) { + super(); + this.value = value; + this.TTL = ttl; + } + public V getValue() { + return value; + } + public void setValue(V value) { + this.value = value; + } + public long getTTL() { + return TTL; + } + public void setTTL(long ttl) { + this.TTL = ttl; + } + @Override + public String toString() { + return "CacheValueBean [value=" + value + ", TTL=" + TTL + "]"; + } +}