cache per le chiamate IS
This commit is contained in:
parent
7020180804
commit
7abf8eac7a
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
package org.gcube.portlets.user.cloudcomputing;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.portlet.PortletException;
|
||||||
|
import javax.portlet.RenderRequest;
|
||||||
|
import javax.portlet.RenderResponse;
|
||||||
|
|
||||||
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
||||||
|
|
||||||
|
public class CC_MethodsListPortlet extends CC_Portlet {
|
||||||
|
|
||||||
|
private static com.liferay.portal.kernel.log.Log _log = LogFactoryUtil
|
||||||
|
.getLog(CC_MethodsListPortlet.class);
|
||||||
|
|
||||||
|
public void render(RenderRequest renderRequest, RenderResponse renderResponse)
|
||||||
|
throws PortletException, IOException {
|
||||||
|
super.render(renderRequest, renderResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,5 +17,4 @@ public class CC_MethodsMonitorPortlet extends CC_Portlet {
|
||||||
throws PortletException, IOException {
|
throws PortletException, IOException {
|
||||||
super.render(renderRequest, renderResponse);
|
super.render(renderRequest, renderResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import org.gcube.common.portal.PortalContext;
|
import org.gcube.common.portal.PortalContext;
|
||||||
import org.gcube.portlets.user.cloudcomputing.config.CC_Config;
|
import org.gcube.portlets.user.cloudcomputing.config.CC_Config;
|
||||||
import org.gcube.portlets.user.cloudcomputing.is.IsClient;
|
import org.gcube.portlets.user.cloudcomputing.is.IsClient;
|
||||||
|
import org.gcube.portlets.user.cloudcomputing.is.IsClientFactory;
|
||||||
import org.gcube.portlets.user.cloudcomputing.is.IsServerConfig;
|
import org.gcube.portlets.user.cloudcomputing.is.IsServerConfig;
|
||||||
|
|
||||||
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
||||||
|
@ -22,7 +23,7 @@ import com.liferay.util.bridges.mvc.MVCPortlet;
|
||||||
public class CC_Portlet extends MVCPortlet {
|
public class CC_Portlet extends MVCPortlet {
|
||||||
private static com.liferay.portal.kernel.log.Log _log = LogFactoryUtil.getLog(CC_Portlet.class);
|
private static com.liferay.portal.kernel.log.Log _log = LogFactoryUtil.getLog(CC_Portlet.class);
|
||||||
|
|
||||||
private static CC_Config configuration = null;
|
private CC_Config configuration = null;
|
||||||
|
|
||||||
public final static String IS_AUTH_RESOURCE_NAME = "IAM";
|
public final static String IS_AUTH_RESOURCE_NAME = "IAM";
|
||||||
public final static String IS_AUTH_CATEGORY = "Service";
|
public final static String IS_AUTH_CATEGORY = "Service";
|
||||||
|
@ -59,15 +60,17 @@ public class CC_Portlet extends MVCPortlet {
|
||||||
String host = base_url.getHost();
|
String host = base_url.getHost();
|
||||||
config.gateway = host;
|
config.gateway = host;
|
||||||
|
|
||||||
IsServerConfig auth_config = IsClient.serviceConfigFromIS(IS_AUTH_RESOURCE_NAME,
|
IsClient isclient = IsClientFactory.getSingleton();
|
||||||
|
|
||||||
|
IsServerConfig auth_config = isclient.serviceConfigFromIS(IS_AUTH_RESOURCE_NAME,
|
||||||
IS_AUTH_CATEGORY, IS_AUTH_ENTRYPOINT);
|
IS_AUTH_CATEGORY, IS_AUTH_ENTRYPOINT);
|
||||||
config.auth_url = auth_config.getServerUrl();
|
config.auth_url = auth_config.getServerUrl();
|
||||||
|
|
||||||
IsServerConfig ccp_config = IsClient.serviceConfigFromIS(IS_CCP_RESOURCE_NAME,
|
IsServerConfig ccp_config = isclient.serviceConfigFromIS(IS_CCP_RESOURCE_NAME,
|
||||||
IS_CCP_CATEGORY, IS_CCP_ENTRYPOINT);
|
IS_CCP_CATEGORY, IS_CCP_ENTRYPOINT);
|
||||||
config.ccp_url = ccp_config.getServerUrl();
|
config.ccp_url = ccp_config.getServerUrl();
|
||||||
|
|
||||||
IsServerConfig cdn_config = IsClient.serviceConfigFromIS(IS_CCP_RESOURCE_NAME,
|
IsServerConfig cdn_config = isclient.serviceConfigFromIS(IS_CCP_RESOURCE_NAME,
|
||||||
IS_CCP_CATEGORY, IS_CDN_ENTRYPOINT);
|
IS_CCP_CATEGORY, IS_CDN_ENTRYPOINT);
|
||||||
config.cdn_url = cdn_config.getServerUrl();
|
config.cdn_url = cdn_config.getServerUrl();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
package org.gcube.portlets.user.cloudcomputing.is;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.rmi.ServerException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||||
|
|
||||||
|
import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
|
||||||
|
import com.liferay.portal.kernel.cache.PortalCache;
|
||||||
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to query EndPoints and search for AccessPoints from IS
|
||||||
|
*
|
||||||
|
* @author Alfredo Oliviero (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CacheIsClient extends IsClient {
|
||||||
|
private static com.liferay.portal.kernel.log.Log logger = LogFactoryUtil.getLog(CacheIsClient.class);
|
||||||
|
private static CacheIsClient _singleInstance;
|
||||||
|
|
||||||
|
// Class to represent a cache entry
|
||||||
|
|
||||||
|
static CacheIsClient getSingleton() {
|
||||||
|
if (_singleInstance == null) {
|
||||||
|
_singleInstance = new CacheIsClient();
|
||||||
|
}
|
||||||
|
return _singleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class CacheEntry implements Serializable {
|
||||||
|
List<ServiceEndpoint> endpoints;
|
||||||
|
long timestamp;
|
||||||
|
|
||||||
|
CacheEntry(List<ServiceEndpoint> endpoints, long timestamp) {
|
||||||
|
this.endpoints = endpoints;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the cache name
|
||||||
|
private static final String CACHE_NAME = "my-cache";
|
||||||
|
private PortalCache<Serializable, Serializable> portalCache = MultiVMPoolUtil.getCache(CACHE_NAME);
|
||||||
|
|
||||||
|
// Method to get the cache key
|
||||||
|
private String getCacheKey(String resourceName, String category) {
|
||||||
|
return resourceName + ":" + category;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main method with caching and locking
|
||||||
|
public synchronized List<ServiceEndpoint> getEndpointsFromISWithCache(String resource_name, String category) throws ServerException {
|
||||||
|
String key = getCacheKey(resource_name, category);
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
logger.info("Request received for resource: " + resource_name + ", category: " + category);
|
||||||
|
|
||||||
|
synchronized (key.intern()) {
|
||||||
|
logger.info("Acquired lock for key: " + key);
|
||||||
|
|
||||||
|
// Check if the entry is present in the cache and is valid
|
||||||
|
CacheEntry cacheEntry = (CacheEntry)portalCache.get(key);
|
||||||
|
if (cacheEntry != null) {
|
||||||
|
if (currentTime - cacheEntry.timestamp <= TimeUnit.MINUTES.toMillis(10)) {
|
||||||
|
// If the cache value is still valid, return it
|
||||||
|
logger.info("Cache hit for key: " + key);
|
||||||
|
return cacheEntry.endpoints;
|
||||||
|
} else {
|
||||||
|
// Otherwise, remove the expired entry
|
||||||
|
logger.info("Cache expired for key: " + key);
|
||||||
|
portalCache.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not present in the cache or is expired, make the request
|
||||||
|
logger.info("Cache miss for key: " + key + ". Making request to external service.");
|
||||||
|
List<ServiceEndpoint> endpoints;
|
||||||
|
try {
|
||||||
|
endpoints = super.getEndpointsFromIS(resource_name, category);
|
||||||
|
} catch (ServerException e) {
|
||||||
|
logger.error("Error fetching data from external service for key: " + key, e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the cache with the new result and timestamp
|
||||||
|
logger.info("Updating cache for key: " + key);
|
||||||
|
portalCache.put(key, new CacheEntry(endpoints, currentTime));
|
||||||
|
|
||||||
|
return endpoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Metodo principale con caching e locking
|
||||||
|
public List<ServiceEndpoint> getEndpointsFromIS(String resource_name, String category) throws ServerException {
|
||||||
|
logger.info("@@@ cached getEndpointsFromIS: " + resource_name + ":" + category);
|
||||||
|
|
||||||
|
return getEndpointsFromISWithCache(resource_name, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
package org.gcube.portlets.user.cloudcomputing.is;
|
||||||
|
|
||||||
|
import java.rmi.ServerException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||||
|
|
||||||
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to query EndPoints and search for AccessPoints from IS
|
||||||
|
*
|
||||||
|
* @author Alfredo Oliviero (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CacheIsClient extends IsClient {
|
||||||
|
private static com.liferay.portal.kernel.log.Log logger = LogFactoryUtil.getLog(CacheIsClient.class);
|
||||||
|
|
||||||
|
private static CacheIsClient _singleInstance = null;
|
||||||
|
|
||||||
|
public int CACHE_DURATION_SECONDS = 1 * 10;
|
||||||
|
|
||||||
|
static CacheIsClient getSingleton() {
|
||||||
|
if (_singleInstance == null) {
|
||||||
|
_singleInstance = new CacheIsClient();
|
||||||
|
}
|
||||||
|
return _singleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CacheEntry {
|
||||||
|
List<ServiceEndpoint> endpoints;
|
||||||
|
long timestamp;
|
||||||
|
|
||||||
|
CacheEntry(List<ServiceEndpoint> endpoints, long timestamp) {
|
||||||
|
this.endpoints = endpoints;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mappa per mantenere la cache
|
||||||
|
private ConcurrentHashMap<String, CacheEntry> cache = new ConcurrentHashMap<>();
|
||||||
|
// Mappa per mantenere i lock
|
||||||
|
private ConcurrentHashMap<String, Lock> locks = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// Metodo per ottenere la chiave della cache
|
||||||
|
private String getCacheKey(String resourceName, String category) {
|
||||||
|
return resourceName + ":" + category;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metodo principale con caching e locking
|
||||||
|
public List<ServiceEndpoint> getEndpointsFromIS(String resource_name, String category) throws ServerException {
|
||||||
|
return getEndpointsFromISWithCache(resource_name, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Main method with caching and locking
|
||||||
|
public List<ServiceEndpoint> getEndpointsFromISWithCache(String resource_name, String category) throws ServerException {
|
||||||
|
String key = getCacheKey(resource_name, category);
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
logger.info("Request received for resource: " + resource_name + ", category: " + category);
|
||||||
|
|
||||||
|
// Get or create a lock for the specific key
|
||||||
|
Lock lock = locks.computeIfAbsent(key, k -> new ReentrantLock());
|
||||||
|
logger.info("Lock object created/retrieved for key: " + key);
|
||||||
|
|
||||||
|
// Acquire the lock
|
||||||
|
logger.info("### Acquiring lock for key: " + key);
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
logger.info("### Lock acquired for key: " + key);
|
||||||
|
// Check if the entry is present in the cache and is valid
|
||||||
|
if (cache.containsKey(key)) {
|
||||||
|
CacheEntry cacheEntry = cache.get(key);
|
||||||
|
if (currentTime - cacheEntry.timestamp <= TimeUnit.MINUTES.toMillis(10)) {
|
||||||
|
// If the cache value is still valid, return it
|
||||||
|
logger.info(">>> Cache hit for key: " + key);
|
||||||
|
return cacheEntry.endpoints;
|
||||||
|
} else {
|
||||||
|
// Otherwise, remove the expired entry
|
||||||
|
logger.info(">>> Cache expired for key: " + key);
|
||||||
|
cache.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not present in the cache or is expired, make the request
|
||||||
|
logger.info(">>> Cache miss for key: " + key + ". Making request to external service.");
|
||||||
|
List<ServiceEndpoint> endpoints;
|
||||||
|
try {
|
||||||
|
endpoints = getEndpointsFromIS(resource_name, category);
|
||||||
|
} catch (ServerException e) {
|
||||||
|
logger.error( "Error fetching data from external service for key: " + key, e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the cache with the new result and timestamp
|
||||||
|
logger.info("Updating cache for key: " + key);
|
||||||
|
cache.put(key, new CacheEntry(endpoints, currentTime));
|
||||||
|
|
||||||
|
return endpoints;
|
||||||
|
} finally {
|
||||||
|
// Release the lock
|
||||||
|
logger.info("### Releasing lock for key: " + key);
|
||||||
|
lock.unlock();
|
||||||
|
// Remove the lock from the map to avoid memory leaks
|
||||||
|
logger.info("### Removing lock from map for key: " + key);
|
||||||
|
locks.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,15 @@ import com.liferay.portal.kernel.log.LogFactoryUtil;
|
||||||
public class IsClient {
|
public class IsClient {
|
||||||
private static com.liferay.portal.kernel.log.Log logger = LogFactoryUtil.getLog(IsClient.class);
|
private static com.liferay.portal.kernel.log.Log logger = LogFactoryUtil.getLog(IsClient.class);
|
||||||
|
|
||||||
|
private static IsClient _singleInstance = null;
|
||||||
|
|
||||||
|
static IsClient getSingleton() {
|
||||||
|
if (_singleInstance == null) {
|
||||||
|
_singleInstance = new IsClient();
|
||||||
|
}
|
||||||
|
return _singleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* obatins from IS the list of ServiceEndpoint matching the parameters
|
* obatins from IS the list of ServiceEndpoint matching the parameters
|
||||||
*
|
*
|
||||||
|
@ -42,10 +51,10 @@ public class IsClient {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static ServiceEndpoint getFirstEndopintsFromIS(String resource_name, String category)
|
public ServiceEndpoint getFirstEndopintsFromIS(String resource_name, String category)
|
||||||
throws ServerException {
|
throws ServerException {
|
||||||
|
|
||||||
List<ServiceEndpoint> endpoints = getEndopintsFromIS(resource_name, category);
|
List<ServiceEndpoint> endpoints = getEndpointsFromIS(resource_name, category);
|
||||||
if (endpoints == null || endpoints.size() == 0) {
|
if (endpoints == null || endpoints.size() == 0) {
|
||||||
logger.error("Unable to retrieve service endpoint " + resource_name);
|
logger.error("Unable to retrieve service endpoint " + resource_name);
|
||||||
return null;
|
return null;
|
||||||
|
@ -55,8 +64,10 @@ public class IsClient {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ServiceEndpoint> getEndopintsFromIS(String resource_name, String category
|
public List<ServiceEndpoint> getEndpointsFromIS(String resource_name, String category
|
||||||
/* , boolean root_service, Secret secret */) throws ServerException {
|
) throws ServerException {
|
||||||
|
logger.info("@@@ not cached getEndpointsFromIS: " + resource_name + ":" + category);
|
||||||
|
|
||||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||||
|
|
||||||
if (resource_name != null) {
|
if (resource_name != null) {
|
||||||
|
@ -74,6 +85,7 @@ public class IsClient {
|
||||||
ScopeProvider.instance.set(infrastructure);
|
ScopeProvider.instance.set(infrastructure);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.info (" IS CLIENT Requiring " + resource_name + ":"+ category);
|
||||||
// if (root_service) {
|
// if (root_service) {
|
||||||
|
|
||||||
// endpoints = AuthorizedTasks.executeSafely(() -> {
|
// endpoints = AuthorizedTasks.executeSafely(() -> {
|
||||||
|
@ -107,10 +119,10 @@ public class IsClient {
|
||||||
* @throws ServerException
|
* @throws ServerException
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static List<ServiceEndpoint.AccessPoint> getAccessPointsFromIS(String resource_name, String category,
|
public List<ServiceEndpoint.AccessPoint> getAccessPointsFromIS(String resource_name, String category,
|
||||||
String endPointName/* , boolean is_root_service, Secret secret */) throws ServerException {
|
String endPointName/* , boolean is_root_service, Secret secret */) throws ServerException {
|
||||||
|
|
||||||
List<ServiceEndpoint> resources = getEndopintsFromIS(resource_name, category/* , is_root_service, secret */);
|
List<ServiceEndpoint> resources = getEndpointsFromIS(resource_name, category/* , is_root_service, secret */);
|
||||||
|
|
||||||
if (resources.size() == 0) {
|
if (resources.size() == 0) {
|
||||||
logger.error("There is no Runtime Resource having name " + resource_name + " and Category "
|
logger.error("There is no Runtime Resource having name " + resource_name + " and Category "
|
||||||
|
@ -142,7 +154,7 @@ public class IsClient {
|
||||||
* @throws ServerException
|
* @throws ServerException
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static ServiceEndpoint.AccessPoint getFirstAccessPointFromIS(String resource_name, String category,
|
public ServiceEndpoint.AccessPoint getFirstAccessPointFromIS(String resource_name, String category,
|
||||||
String entryPointName/* , boolean root_service, Secret secret */) throws ServerException {
|
String entryPointName/* , boolean root_service, Secret secret */) throws ServerException {
|
||||||
|
|
||||||
List<ServiceEndpoint.AccessPoint> access_points = getAccessPointsFromIS(resource_name, category,
|
List<ServiceEndpoint.AccessPoint> access_points = getAccessPointsFromIS(resource_name, category,
|
||||||
|
@ -175,7 +187,7 @@ public class IsClient {
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static IsServerConfig serviceConfigFromIS(String resourceName, String category, String endPointName
|
public IsServerConfig serviceConfigFromIS(String resourceName, String category, String endPointName
|
||||||
/* , boolean is_root_service, Secret secret */)
|
/* , boolean is_root_service, Secret secret */)
|
||||||
throws ServerException {
|
throws ServerException {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package org.gcube.portlets.user.cloudcomputing.is;
|
||||||
|
|
||||||
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
||||||
|
|
||||||
|
// import org.gcube.common.security.AuthorizedTasks;
|
||||||
|
// import org.gcube.common.security.secrets.Secret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to query EndPoints and search for AccessPoints from IS
|
||||||
|
*
|
||||||
|
* @author Alfredo Oliviero (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class IsClientFactory {
|
||||||
|
private static com.liferay.portal.kernel.log.Log logger = LogFactoryUtil.getLog(IsClientFactory.class);
|
||||||
|
static boolean cache_enabled = true;
|
||||||
|
|
||||||
|
public static IsClient getSingleton(){
|
||||||
|
return getSingleton(cache_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IsClient getSingleton(boolean use_cache){
|
||||||
|
if (use_cache) {
|
||||||
|
logger.info("@@@ IsClientFactory cache enabled");
|
||||||
|
return CacheIsClient.getSingleton();
|
||||||
|
} else {
|
||||||
|
logger.info("@@@ IsClientFactory cache not enabled");
|
||||||
|
|
||||||
|
return IsClient.getSingleton();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue