Improved ContextCache
This commit is contained in:
parent
54d387e035
commit
f6772e4647
|
@ -2,11 +2,12 @@ package org.gcube.informationsystem.resourceregistry.api.contexts;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -15,6 +16,7 @@ import org.gcube.informationsystem.contexts.impl.relations.IsParentOfImpl;
|
|||
import org.gcube.informationsystem.contexts.reference.entities.Context;
|
||||
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.informationsystem.tree.Tree;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -47,23 +49,6 @@ public class ContextCache {
|
|||
return singleton;
|
||||
}
|
||||
|
||||
public void cleanCache() {
|
||||
cleanCache(Calendar.getInstance());
|
||||
}
|
||||
|
||||
protected void cleanCache(Calendar now) {
|
||||
this.contexts = null;
|
||||
this.uuidToContext = new LinkedHashMap<>();
|
||||
this.uuidToContextFullName = new LinkedHashMap<>();
|
||||
this.contextFullNameToUUID = new TreeMap<>();
|
||||
this.creationTime = Calendar.getInstance();
|
||||
this.creationTime.setTimeInMillis(now.getTimeInMillis());
|
||||
this.expiringTime = Calendar.getInstance();
|
||||
this.expiringTime.setTimeInMillis(now.getTimeInMillis());
|
||||
this.expiringTime.add(Calendar.MILLISECOND, -1);
|
||||
this.expiringTime.add(Calendar.MILLISECOND, expiringTimeout);
|
||||
}
|
||||
|
||||
protected ContextCacheRenewal contextCacheRenewal;
|
||||
|
||||
// in millisec used for logging purposes only
|
||||
|
@ -75,12 +60,37 @@ public class ContextCache {
|
|||
protected Map<UUID, Context> uuidToContext;
|
||||
protected Map<UUID, String> uuidToContextFullName;
|
||||
protected Map<String, UUID> contextFullNameToUUID;
|
||||
protected Tree<Context> contextsTree;
|
||||
|
||||
public ContextCache() {
|
||||
Calendar now = Calendar.getInstance();
|
||||
cleanCache(now);
|
||||
}
|
||||
|
||||
public void cleanCache() {
|
||||
cleanCache(Calendar.getInstance());
|
||||
}
|
||||
|
||||
protected void cleanCache(Calendar calendar) {
|
||||
this.contexts = null;
|
||||
this.uuidToContext = new LinkedHashMap<>();
|
||||
this.uuidToContextFullName = new LinkedHashMap<>();
|
||||
this.contextFullNameToUUID = new TreeMap<>();
|
||||
this.contextsTree = new Tree<Context>(new ContextInformation());
|
||||
this.contextsTree.setAllowMultipleInheritance(false);
|
||||
this.creationTime = Calendar.getInstance();
|
||||
this.creationTime.setTimeInMillis(calendar.getTimeInMillis());
|
||||
this.expiringTime = Calendar.getInstance();
|
||||
this.expiringTime.setTimeInMillis(calendar.getTimeInMillis());
|
||||
this.expiringTime.add(Calendar.MILLISECOND, -1);
|
||||
this.expiringTime.add(Calendar.MILLISECOND, expiringTimeout);
|
||||
}
|
||||
|
||||
public void renew() throws ResourceRegistryException {
|
||||
cleanCache();
|
||||
refreshContextsIfNeeded();
|
||||
}
|
||||
|
||||
public ContextCacheRenewal getContextCacheRenewal() {
|
||||
return contextCacheRenewal;
|
||||
}
|
||||
|
@ -91,13 +101,12 @@ public class ContextCache {
|
|||
}
|
||||
}
|
||||
|
||||
public void refreshContextsIfNeeded() throws ResourceRegistryException {
|
||||
public synchronized void refreshContextsIfNeeded() throws ResourceRegistryException {
|
||||
Calendar now = Calendar.getInstance();
|
||||
if((now.after(expiringTime) || (contexts==null)) && contextCacheRenewal!=null) {
|
||||
try {
|
||||
List<Context> contexts = contextCacheRenewal.renew();
|
||||
cleanCache(now);
|
||||
setContexts(contexts);
|
||||
setContexts(now, contexts);
|
||||
} catch (ResourceRegistryException e) {
|
||||
logger.error("Unable to refresh Cache", e);
|
||||
if(contexts==null) {
|
||||
|
@ -113,7 +122,13 @@ public class ContextCache {
|
|||
return contexts;
|
||||
}
|
||||
|
||||
protected void setContexts(List<Context> contexts) {
|
||||
public void setContexts(List<Context> contexts) {
|
||||
Calendar now = Calendar.getInstance();
|
||||
setContexts(now, contexts);
|
||||
}
|
||||
|
||||
protected void setContexts(Calendar calendar, List<Context> contexts) {
|
||||
cleanCache(calendar);
|
||||
this.contexts = new ArrayList<>();
|
||||
|
||||
for(Context c : contexts) {
|
||||
|
@ -140,8 +155,6 @@ public class ContextCache {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(Context context : contexts) {
|
||||
UUID uuid = context.getID();
|
||||
String fullName = getContextFullName(context);
|
||||
|
@ -149,6 +162,13 @@ public class ContextCache {
|
|||
this.contextFullNameToUUID.put(fullName, uuid);
|
||||
}
|
||||
|
||||
SortedSet<String> contextFullNames = new TreeSet<String>(contextFullNameToUUID.keySet());
|
||||
for(String contextFullName : contextFullNames) {
|
||||
UUID uuid = contextFullNameToUUID.get(contextFullName);
|
||||
Context context = uuidToContext.get(uuid);
|
||||
contextsTree.addNode(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String getContextFullName(Context context) {
|
||||
|
@ -201,7 +221,7 @@ public class ContextCache {
|
|||
*/
|
||||
public synchronized Map<UUID, String> getUUIDToContextFullNameAssociation() throws ResourceRegistryException {
|
||||
refreshContextsIfNeeded();
|
||||
return new HashMap<>(uuidToContextFullName);
|
||||
return new LinkedHashMap<>(uuidToContextFullName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,7 +229,11 @@ public class ContextCache {
|
|||
*/
|
||||
public synchronized Map<String, UUID> getContextFullNameToUUIDAssociation() throws ResourceRegistryException {
|
||||
refreshContextsIfNeeded();
|
||||
return new HashMap<>(contextFullNameToUUID);
|
||||
return new TreeMap<>(contextFullNameToUUID);
|
||||
}
|
||||
|
||||
public Tree<Context> getContextsTree() {
|
||||
return contextsTree;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package org.gcube.informationsystem.resourceregistry.api.contexts;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.gcube.informationsystem.contexts.reference.entities.Context;
|
||||
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
|
||||
import org.gcube.informationsystem.tree.NodeInformation;
|
||||
|
||||
public class ContextInformation implements NodeInformation<Context> {
|
||||
|
||||
@Override
|
||||
public String getIdentifier(Context context) {
|
||||
return context.getID().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getParentIdentifiers(Context root, Context context) {
|
||||
Set<String> set = new LinkedHashSet<>();
|
||||
if(root !=null && context.getID().compareTo(root.getID())==0) {
|
||||
return set;
|
||||
}
|
||||
IsParentOf parent = context.getParent();
|
||||
if(parent!=null) {
|
||||
set.add(parent.getSource().getID().toString());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,7 @@ public class ContextUtility {
|
|||
|
||||
private static Logger logger = LoggerFactory.getLogger(ContextUtility.class);
|
||||
|
||||
// public static Set<UUID> getContextUUIDSe(String jsonArray) throws IOException {
|
||||
// public static Set<UUID> getContextUUIDSet(String jsonArray) throws IOException {
|
||||
// ObjectMapper mapper = ElementMapper.getObjectMapper();
|
||||
// JavaType type = mapper.getTypeFactory().constructCollectionType(HashSet.class, UUID.class);
|
||||
// return mapper.readValue(jsonArray, type);
|
||||
|
@ -33,7 +33,7 @@ public class ContextUtility {
|
|||
// Set<UUID> uuids = getContextUUIDSet(jsonArray);
|
||||
// return getContextFullNameSet(uuids);
|
||||
// }
|
||||
//
|
||||
|
||||
public static Map<UUID, String> getContextMap(String objectnode) throws JsonParseException, JsonMappingException, IOException{
|
||||
ObjectMapper mapper = ElementMapper.getObjectMapper();
|
||||
JavaType type = mapper.getTypeFactory().constructMapType(HashMap.class, UUID.class, String.class);
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package org.gcube.informationsystem.resourceregistry.api.contexts;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.gcube.informationsystem.contexts.reference.entities.Context;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.informationsystem.serialization.ElementMapper;
|
||||
import org.gcube.informationsystem.tree.Node;
|
||||
import org.gcube.informationsystem.tree.NodeElaborator;
|
||||
import org.gcube.informationsystem.tree.Tree;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class ContextCacheTest{
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContextCacheTest.class);
|
||||
|
||||
protected File getTypesDirectory() throws Exception {
|
||||
URL logbackFileURL = ContextCacheTest.class.getClassLoader().getResource("logback-test.xml");
|
||||
File logbackFile = new File(logbackFileURL.toURI());
|
||||
File resourcesDirectory = logbackFile.getParentFile();
|
||||
return new File(resourcesDirectory, "contexts");
|
||||
}
|
||||
|
||||
protected String readFile(File file) throws IOException {
|
||||
byte[] encoded = Files.readAllBytes(file.toPath());
|
||||
return new String(encoded, Charset.defaultCharset());
|
||||
}
|
||||
|
||||
protected List<Context> getContexts() throws Exception {
|
||||
File typesDirectory = getTypesDirectory();
|
||||
File file = new File(typesDirectory, "contexts.json");
|
||||
String json = readFile(file);
|
||||
List<Context> contexts = ElementMapper.unmarshalList(Context.class, json);
|
||||
return contexts;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
List<Context> contexts = getContexts();
|
||||
ContextCache contextCache = new ContextCache();
|
||||
contextCache.setContexts(contexts);
|
||||
contextCache.setContextCacheRenewal(new ContextCacheRenewal() {
|
||||
@Override
|
||||
public List<Context> renew() throws ResourceRegistryException {
|
||||
try {
|
||||
return getContexts();
|
||||
}catch (Exception e) {
|
||||
throw new ResourceRegistryException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
Tree<Context> contextTree = contextCache.getContextsTree();
|
||||
contextTree.elaborate(new NodeElaborator<Context>() {
|
||||
|
||||
@Override
|
||||
public void elaborate(Node<Context> node, int level) throws Exception {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
for (int i = 0; i < level; ++i) {
|
||||
stringBuffer.append(Node.INDENTATION);
|
||||
}
|
||||
|
||||
Context context = node.getNodeElement();
|
||||
UUID uuid = context.getID();
|
||||
String fullName = contextCache.getContextFullNameByUUID(uuid);
|
||||
logger.info("{}- {} (ID:{})", stringBuffer.toString(), fullName, uuid);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
[{"type":"Context","id":"9a7752f6-ca01-4a89-a9dd-f36aeb2cbf50","name":"gcube","parent":null,"children":[{"type":"IsParentOf","id":"b4bdbd3e-87c4-43d1-b642-532f6a30ad44","target":{"type":"Context","id":"4e6adfe6-ab93-47c0-a532-339bb92ad07a","name":"devNext"}},{"type":"IsParentOf","id":"542179cb-36fc-4d4e-9771-b55d3b2bd301","target":{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec"}}]},{"type":"Context","id":"4e6adfe6-ab93-47c0-a532-339bb92ad07a","name":"devNext","parent":{"type":"IsParentOf","id":"b4bdbd3e-87c4-43d1-b642-532f6a30ad44","source":{"type":"Context","id":"9a7752f6-ca01-4a89-a9dd-f36aeb2cbf50","name":"gcube"}},"children":[{"type":"IsParentOf","id":"01cc9e06-475b-43a4-a4cd-7f5070f0dc65","target":{"type":"Context","id":"c7f3af7e-7e8c-406e-8d5a-cd11c82b5fa3","name":"NextNext"}}]},{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec","parent":{"type":"IsParentOf","id":"542179cb-36fc-4d4e-9771-b55d3b2bd301","source":{"type":"Context","id":"9a7752f6-ca01-4a89-a9dd-f36aeb2cbf50","name":"gcube"}},"children":[{"type":"IsParentOf","id":"e28b8e16-84d5-4cd9-a5a1-8a55fa371d0c","target":{"type":"Context","id":"a3e40b10-01d0-11ed-8d67-f3498769ebff","name":"CCP"}},{"type":"IsParentOf","id":"e46696d5-3290-4d7a-b22a-71940bda7ec0","target":{"type":"Context","id":"8efe07f5-de24-49f9-a2fb-fbfdcfda8c91","name":"devVRE"}}]},{"type":"Context","id":"c7f3af7e-7e8c-406e-8d5a-cd11c82b5fa3","name":"NextNext","parent":{"type":"IsParentOf","id":"01cc9e06-475b-43a4-a4cd-7f5070f0dc65","source":{"type":"Context","id":"4e6adfe6-ab93-47c0-a532-339bb92ad07a","name":"devNext"}},"children":[]},{"type":"Context","id":"a3e40b10-01d0-11ed-8d67-f3498769ebff","name":"CCP","parent":{"type":"IsParentOf","id":"e28b8e16-84d5-4cd9-a5a1-8a55fa371d0c","source":{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec"}},"children":[]},{"type":"Context","id":"8efe07f5-de24-49f9-a2fb-fbfdcfda8c91","name":"devVRE","parent":{"type":"IsParentOf","id":"e46696d5-3290-4d7a-b22a-71940bda7ec0","source":{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec"}},"children":[]}]
|
Loading…
Reference in New Issue