diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/utils/ContextCache.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/contexts/ContextCache.java similarity index 58% rename from src/main/java/org/gcube/informationsystem/resourceregistry/api/utils/ContextCache.java rename to src/main/java/org/gcube/informationsystem/resourceregistry/api/contexts/ContextCache.java index 7fe5a20..ab8137f 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/utils/ContextCache.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/contexts/ContextCache.java @@ -1,4 +1,4 @@ -package org.gcube.informationsystem.resourceregistry.api.utils; +package org.gcube.informationsystem.resourceregistry.api.contexts; import java.util.ArrayList; import java.util.Calendar; @@ -12,6 +12,7 @@ import org.gcube.informationsystem.context.impl.entities.ContextImpl; import org.gcube.informationsystem.context.impl.relations.IsParentOfImpl; import org.gcube.informationsystem.context.reference.entities.Context; import org.gcube.informationsystem.context.reference.relations.IsParentOf; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,25 +36,30 @@ public class ContextCache { protected static ContextCache singleton; public synchronized static ContextCache getInstance() { - Calendar now = Calendar.getInstance(); - - if(singleton!=null && now.after(singleton.expiringTime)) { - logger.debug("Context Cache has been expired. It must be renewed."); - singleton = null; - } - if(singleton==null) { singleton = new ContextCache(); - singleton.creationTime = Calendar.getInstance(); - singleton.creationTime.setTimeInMillis(now.getTimeInMillis()); - singleton.expiringTime = Calendar.getInstance(); - singleton.expiringTime.setTimeInMillis(now.getTimeInMillis()); - singleton.expiringTime.add(Calendar.MILLISECOND, expiringTimeout); } - return singleton; } + public void cleanCache() { + cleanCache(Calendar.getInstance()); + } + + private void cleanCache(Calendar now) { + this.contexts = null; + this.uuidToContext = null; + this.uuidToContextFullName = null; + this.contextFullNameToUUID = null; + this.creationTime = Calendar.getInstance(); + this.creationTime.setTimeInMillis(now.getTimeInMillis()); + this.expiringTime = Calendar.getInstance(); + this.expiringTime.setTimeInMillis(now.getTimeInMillis()); + this.expiringTime.add(Calendar.MILLISECOND, expiringTimeout); + } + + protected ContextCacheRenewal contextCacheRenewal; + // in millisec used for logging purposes only protected Calendar creationTime; // in millisec @@ -65,17 +71,41 @@ public class ContextCache { protected Map contextFullNameToUUID; public ContextCache() { - contexts = null; - uuidToContext = null; - uuidToContextFullName = null; - contextFullNameToUUID = null; + Calendar now = Calendar.getInstance(); + cleanCache(now); } - public synchronized List getContexts() { + public void setContextCacheRenewal(ContextCacheRenewal contextCacheRenewal) { + if(this.contextCacheRenewal==null) { + this.contextCacheRenewal = contextCacheRenewal; + } + } + + public void refreshContextsIfNeeded() throws ResourceRegistryException { + Calendar now = Calendar.getInstance(); + + if(now.after(expiringTime) || (contexts==null && contextCacheRenewal!=null)) { + try { + + List contexts = contextCacheRenewal.renew(); + singleton.cleanCache(now); + setContexts(contexts); + } catch (ResourceRegistryException e) { + logger.error("Unable to refresh Cache", e); + if(contexts==null) { + throw e; + } + } + + } + } + + public synchronized List getContexts() throws ResourceRegistryException { + refreshContextsIfNeeded(); return contexts; } - public synchronized void setContexts(List contexts) { + private void setContexts(List contexts) { this.contexts = new ArrayList<>(); this.uuidToContext = new HashMap<>(); @@ -128,29 +158,39 @@ public class ContextCache { } - public String getContextFullNameByUUID(UUID uuid) { - return uuidToContextFullName.get(uuid); + public synchronized String getContextFullNameByUUID(UUID uuid) throws ResourceRegistryException { + refreshContextsIfNeeded(); + return uuidToContextFullName.get(uuid); } - public UUID getUUIDByFullName(String fullName) { - return contextFullNameToUUID.get(fullName); + public synchronized UUID getUUIDByFullName(String contextFullName) throws ResourceRegistryException { + refreshContextsIfNeeded(); + return contextFullNameToUUID.get(contextFullName); } - public Context getContextByUUID(UUID uuid) { + public synchronized Context getContextByUUID(UUID uuid) throws ResourceRegistryException { + refreshContextsIfNeeded(); + return uuidToContext.get(uuid); + } + + public synchronized Context getContextByFullName(String contextFullName) throws ResourceRegistryException { + UUID uuid = getUUIDByFullName(contextFullName); return uuidToContext.get(uuid); } /** * @return an Map containing UUID to Context FullName association */ - public Map getUUIDToContextFullNameAssociation() { + public synchronized Map getUUIDToContextFullNameAssociation() throws ResourceRegistryException { + refreshContextsIfNeeded(); return new HashMap<>(uuidToContextFullName); } /** * @return an Map containing Context FullName to UUID association */ - public Map getContextFullNameToUUIDAssociation() { + public synchronized Map getContextFullNameToUUIDAssociation() throws ResourceRegistryException { + refreshContextsIfNeeded(); return new HashMap<>(contextFullNameToUUID); } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/contexts/ContextCacheRenewal.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/contexts/ContextCacheRenewal.java new file mode 100644 index 0000000..935d4b6 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/contexts/ContextCacheRenewal.java @@ -0,0 +1,12 @@ +package org.gcube.informationsystem.resourceregistry.api.contexts; + +import java.util.List; + +import org.gcube.informationsystem.context.reference.entities.Context; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; + +public interface ContextCacheRenewal { + + public List renew() throws ResourceRegistryException; + +}