2020-11-04 16:22:35 +01:00
|
|
|
package org.gcube.informationsystem.resourceregistry.api.contexts;
|
2020-11-03 16:28:53 +01:00
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Calendar;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
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;
|
2020-11-04 16:22:35 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
2020-11-03 16:28:53 +01:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
public class ContextCache {
|
|
|
|
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(ContextCache.class);
|
|
|
|
|
|
|
|
// in millisec
|
|
|
|
public static final long DEFAULT_EXPIRING_TIMEOUT;
|
|
|
|
public static int expiringTimeout;
|
|
|
|
|
|
|
|
static {
|
|
|
|
DEFAULT_EXPIRING_TIMEOUT = TimeUnit.HOURS.toMillis(6);
|
|
|
|
expiringTimeout = (int) DEFAULT_EXPIRING_TIMEOUT;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void setExpiringTimeout(int expiringTimeout) {
|
|
|
|
ContextCache.expiringTimeout = expiringTimeout;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static ContextCache singleton;
|
|
|
|
|
|
|
|
public synchronized static ContextCache getInstance() {
|
|
|
|
if(singleton==null) {
|
|
|
|
singleton = new ContextCache();
|
|
|
|
}
|
|
|
|
return singleton;
|
|
|
|
}
|
|
|
|
|
2020-11-04 16:22:35 +01:00
|
|
|
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;
|
|
|
|
|
2020-11-03 16:28:53 +01:00
|
|
|
// in millisec used for logging purposes only
|
|
|
|
protected Calendar creationTime;
|
|
|
|
// in millisec
|
|
|
|
protected Calendar expiringTime;
|
|
|
|
|
|
|
|
protected List<Context> contexts;
|
|
|
|
protected Map<UUID, Context> uuidToContext;
|
|
|
|
protected Map<UUID, String> uuidToContextFullName;
|
|
|
|
protected Map<String, UUID> contextFullNameToUUID;
|
|
|
|
|
|
|
|
public ContextCache() {
|
2020-11-04 16:22:35 +01:00
|
|
|
Calendar now = Calendar.getInstance();
|
|
|
|
cleanCache(now);
|
2020-11-03 16:28:53 +01:00
|
|
|
}
|
|
|
|
|
2020-11-04 16:22:35 +01:00
|
|
|
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<Context> 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<Context> getContexts() throws ResourceRegistryException {
|
|
|
|
refreshContextsIfNeeded();
|
2020-11-03 16:28:53 +01:00
|
|
|
return contexts;
|
|
|
|
}
|
|
|
|
|
2020-11-04 16:22:35 +01:00
|
|
|
private void setContexts(List<Context> contexts) {
|
2020-11-03 16:28:53 +01:00
|
|
|
this.contexts = new ArrayList<>();
|
|
|
|
this.uuidToContext = new HashMap<>();
|
|
|
|
|
|
|
|
for(Context c : contexts) {
|
|
|
|
UUID uuid = c.getHeader().getUUID();
|
|
|
|
Context context = new ContextImpl(c.getName());
|
|
|
|
context.setHeader(c.getHeader());
|
|
|
|
this.contexts.add(context);
|
|
|
|
this.uuidToContext.put(uuid, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(Context c : contexts) {
|
|
|
|
UUID uuid = c.getHeader().getUUID();
|
|
|
|
Context context = this.uuidToContext.get(uuid);
|
|
|
|
if(c.getParent()!=null) {
|
|
|
|
IsParentOf ipo = c.getParent();
|
|
|
|
UUID parentUUID = ipo.getSource().getHeader().getUUID();
|
|
|
|
Context parent = this.uuidToContext.get(parentUUID);
|
|
|
|
IsParentOf isParentOf = new IsParentOfImpl(parent, context);
|
|
|
|
isParentOf.setHeader(ipo.getHeader());
|
|
|
|
parent.addChild(isParentOf);
|
|
|
|
context.setParent(isParentOf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.uuidToContextFullName = new HashMap<>();
|
|
|
|
this.contextFullNameToUUID = new HashMap<>();
|
|
|
|
|
|
|
|
for(Context context : contexts) {
|
|
|
|
UUID uuid = context.getHeader().getUUID();
|
|
|
|
String fullName = getContextFullName(context);
|
|
|
|
this.uuidToContextFullName.put(uuid, fullName);
|
|
|
|
this.contextFullNameToUUID.put(fullName, uuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getContextFullName(Context context) {
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
IsParentOf ipo = context.getParent();
|
|
|
|
if(ipo!=null) {
|
|
|
|
Context c = ipo.getSource();
|
|
|
|
c = uuidToContext.get(c.getHeader().getUUID());
|
|
|
|
String parentFullName = getContextFullName(c);
|
|
|
|
stringBuilder.append(parentFullName);
|
|
|
|
}
|
|
|
|
stringBuilder.append("/");
|
|
|
|
stringBuilder.append(context.getName());
|
|
|
|
return stringBuilder.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-11-04 16:22:35 +01:00
|
|
|
public synchronized String getContextFullNameByUUID(UUID uuid) throws ResourceRegistryException {
|
|
|
|
refreshContextsIfNeeded();
|
|
|
|
return uuidToContextFullName.get(uuid);
|
2020-11-03 16:28:53 +01:00
|
|
|
}
|
|
|
|
|
2020-11-04 16:22:35 +01:00
|
|
|
public synchronized UUID getUUIDByFullName(String contextFullName) throws ResourceRegistryException {
|
|
|
|
refreshContextsIfNeeded();
|
|
|
|
return contextFullNameToUUID.get(contextFullName);
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized Context getContextByUUID(UUID uuid) throws ResourceRegistryException {
|
|
|
|
refreshContextsIfNeeded();
|
|
|
|
return uuidToContext.get(uuid);
|
2020-11-03 16:28:53 +01:00
|
|
|
}
|
|
|
|
|
2020-11-04 16:22:35 +01:00
|
|
|
public synchronized Context getContextByFullName(String contextFullName) throws ResourceRegistryException {
|
|
|
|
UUID uuid = getUUIDByFullName(contextFullName);
|
2020-11-03 16:28:53 +01:00
|
|
|
return uuidToContext.get(uuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return an Map containing UUID to Context FullName association
|
|
|
|
*/
|
2020-11-04 16:22:35 +01:00
|
|
|
public synchronized Map<UUID, String> getUUIDToContextFullNameAssociation() throws ResourceRegistryException {
|
|
|
|
refreshContextsIfNeeded();
|
2020-11-03 16:28:53 +01:00
|
|
|
return new HashMap<>(uuidToContextFullName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return an Map containing Context FullName to UUID association
|
|
|
|
*/
|
2020-11-04 16:22:35 +01:00
|
|
|
public synchronized Map<String, UUID> getContextFullNameToUUIDAssociation() throws ResourceRegistryException {
|
|
|
|
refreshContextsIfNeeded();
|
2020-11-03 16:28:53 +01:00
|
|
|
return new HashMap<>(contextFullNameToUUID);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|