From b03c4d33b48e0a6f5bae352e2ae39d0f5297dbe9 Mon Sep 17 00:00:00 2001 From: Cherian Mathew Date: Mon, 20 Oct 2014 11:05:56 +0000 Subject: [PATCH] added polytomous key tests and initial developments on caching --- .gitattributes | 13 + .gitignore | 1 + .../api/cache/CachedCommonServiceImpl.java | 198 ++++++++++++ .../cdm/api/cache/CdmEntityCacheManager.java | 30 ++ .../api/cache/CdmTransientEntityCacher.java | 179 +++++++++++ .../cdm/api/cache/ICachedCommonService.java | 45 +++ .../api/cache/LazyLoadingCachingUtils.java | 77 +++++ .../src/main/resources/etc/jetty/.svnignore | 1 + .../cdm/polytomouskey/PolytomousKeyTest.java | 281 ++++++++++++++++++ .../httpinvoker/CdmServerTestManager.java | 41 +++ .../lazyloading/CdmEntityCacherTest.java | 89 ++++++ ...PolytomousKeyTest.readPolytmousKeyData.xml | 104 +++++++ .../cdm/polytomouskey/PolytomousKeyTest.xml | 127 ++++++++ .../lazyloading/CdmEntityCacherTest.xml | 127 ++++++++ .../src/test/resources/log4j.properties | 17 ++ 15 files changed, 1330 insertions(+) create mode 100644 eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheManager.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/LazyLoadingCachingUtils.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/.svnignore create mode 100644 eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTestManager.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.java create mode 100644 eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.readPolytmousKeyData.xml create mode 100644 eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.xml create mode 100644 eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.xml create mode 100644 eu.etaxonomy.taxeditor.remoting/src/test/resources/log4j.properties diff --git a/.gitattributes b/.gitattributes index 628081ab6..26a406a13 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1011,7 +1011,12 @@ eu.etaxonomy.taxeditor.remoting/lib/.svnignore -text eu.etaxonomy.taxeditor.remoting/pom.xml -text eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java -text eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java -text +eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java -text +eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheManager.java -text eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java -text +eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java -text +eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java -text +eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/LazyLoadingCachingUtils.java -text eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmPersistentRemoteSource.java -text eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSource.java -text eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceBase.java -text @@ -1020,6 +1025,7 @@ eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/ICdmRemote eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/RemotingTestPluginActivator.java -text eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java -text eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java -text +eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/.svnignore -text eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/jetty-runner-9.2.3.v20140905.jar -text eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/start-9.2.3.v20140905.jar -text eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/config.properties -text @@ -1028,23 +1034,30 @@ eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/localApplica eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remotingApplicationContext.xml -text eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_persistence_security.xml -text eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_services_security.xml -text +eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/exception/CDMServerException.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/BaseRemotingTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CDMServer.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmPersistentRemoteSourceTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmRemoteSourceTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTest.java -text +eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTestManager.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/HttpInvokerServicesTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/AbstractLazyInitializerTest.java -text +eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmServiceCacherTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/RemoteLazyLoadingTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/RemotePersistentCollectionTest.java -text eu.etaxonomy.taxeditor.remoting/src/test/resources/datasources.xml -text eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/cdm.datasources.xml -text +eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.readPolytmousKeyData.xml -text +eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.xml -text eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/testRemotingApplicationContext.xml -text eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/AbstractLazyInitializerTest.xml -text +eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.xml -text eu.etaxonomy.taxeditor.remoting/src/test/resources/h2/cdmTest.h2.db -text eu.etaxonomy.taxeditor.remoting/src/test/resources/h2/cdmTest.trace.db -text +eu.etaxonomy.taxeditor.remoting/src/test/resources/log4j.properties -text eu.etaxonomy.taxeditor.remoting/src/test/resources/unitils.properties -text eu.etaxonomy.taxeditor.store/.classpath -text eu.etaxonomy.taxeditor.store/.project -text diff --git a/.gitignore b/.gitignore index dc0d24ec9..000adc05f 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ eu.etaxonomy.taxeditor.remoting/*.log eu.etaxonomy.taxeditor.remoting/.settings eu.etaxonomy.taxeditor.remoting/lib eu.etaxonomy.taxeditor.remoting/lib/*.jar +eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/cdmlib-remote-webapp.war eu.etaxonomy.taxeditor.remoting/target eu.etaxonomy.taxeditor.store/.settings eu.etaxonomy.taxeditor.store/hibernate.log diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java new file mode 100644 index 000000000..519025d45 --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java @@ -0,0 +1,198 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.cdm.api.cache; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.hibernate.collection.internal.PersistentList; +import org.hibernate.collection.internal.PersistentMap; +import org.hibernate.collection.internal.PersistentSet; +import org.hibernate.collection.internal.PersistentSortedMap; +import org.hibernate.collection.internal.PersistentSortedSet; +import org.hibernate.collection.spi.PersistentCollection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import eu.etaxonomy.cdm.api.cache.LazyLoadingCachingUtils.CollectionType; +import eu.etaxonomy.cdm.api.service.ICommonService; +import eu.etaxonomy.cdm.model.common.CdmBase; +import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText; + +/** + * @author cmathew + * @date 14 Oct 2014 + * + */ +@Component +public class CachedCommonServiceImpl implements ICachedCommonService { + + + @Autowired + private ICommonService commonService; + + private static boolean cacheEnabled = true; + + @Autowired + private CdmEntityCacheManager cdmEntityCacheManager; + + @Autowired + private LazyLoadingCachingUtils lazyLoadingCachingUtils; + + + public static boolean isCacheEnabled() { + return cacheEnabled; + } + + public static void setCacheEnabled(boolean cacheEnabled) { + CachedCommonServiceImpl.cacheEnabled = cacheEnabled; + } + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#find(java.lang.Class, int) + */ + @Override + public CdmBase find(Class clazz, int id){ + if(cacheEnabled) { + CdmBase cdmEntity = cdmEntityCacheManager.getCdmTransientEntityCacher().getFromCache(clazz, id); + if(cdmEntity != null) { + return cdmEntity; + } else { + cdmEntity = commonService.find(clazz, id); + cdmEntity = cdmEntityCacheManager.getCdmTransientEntityCacher().put(clazz, id, cdmEntity); + return cdmEntity; + } + } else { + return commonService.find(clazz, id); + } + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#initializeCollection(org.hibernate.collection.spi.PersistentCollection) + */ + @Override + public PersistentCollection initializeCollection(PersistentCollection col) { + PersistentCollection pc = commonService.initializeCollection(col); + + return pc; + } + + @Override + public void updatePersistentCollection(CollectionField colf) { + switch(colf.getType()) { + case MAP: + lazyLoadingCachingUtils.updatePersistentCollection((Map)colf.getCollection()); + case SET: + case LIST: + default: + } + } + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#isEmpty(org.hibernate.collection.spi.PersistentCollection) + */ + @Override + public boolean isEmpty(PersistentCollection col) { + return commonService.isEmpty(col); + + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#size(org.hibernate.collection.spi.PersistentCollection) + */ + @Override + public int size(PersistentCollection col) { + return commonService.size(col); + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#get(org.hibernate.collection.spi.PersistentCollection, int) + */ + @Override + public Object get(PersistentCollection col, int index) { + return commonService.get(col, index); + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#contains(org.hibernate.collection.spi.PersistentCollection, java.lang.Object) + */ + @Override + public boolean contains(PersistentCollection col, Object element) { + return commonService.contains(col, element); + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#containsKey(org.hibernate.collection.spi.PersistentCollection, java.lang.Object) + */ + @Override + public boolean containsKey(PersistentCollection col, Object key) { + return commonService.containsKey(col, key); + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#containsValue(org.hibernate.collection.spi.PersistentCollection, java.lang.Object) + */ + @Override + public boolean containsValue(PersistentCollection col, Object element) { + return commonService.containsValue(col, element); + } + + @Override + public CollectionField getCollectionField(PersistentCollection pc) { + if(pc != null) { + if(pc instanceof PersistentSet) { + return new CollectionField(new HashSet((Set)pc), CollectionType.SET); + } + if(pc instanceof PersistentSortedSet) { + return new CollectionField(new TreeSet((Set)pc), CollectionType.SET); + } + if(pc instanceof PersistentList) { + return new CollectionField(new ArrayList((List)pc), CollectionType.LIST); + } + if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) { + return new CollectionField(new HashMap((Map)pc), CollectionType.MAP); + } + if(pc instanceof PersistentSortedMap) { + return new CollectionField(new TreeMap((Map)pc), CollectionType.MAP); + } + } + return null; + } + + public class CollectionField { + private final Object col; + private final CollectionType type; + public CollectionField(Object col, CollectionType type) { + this.col = col; + this.type = type; + } + + public Object getCollection() { + return this.col; + } + + public CollectionType getType() { + return this.type; + } + } + +} diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheManager.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheManager.java new file mode 100644 index 000000000..46d08880a --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheManager.java @@ -0,0 +1,30 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.cdm.api.cache; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author cmathew + * @date 16 Oct 2014 + * + */ +@Component +public class CdmEntityCacheManager { + + @Autowired + private CdmTransientEntityCacher cdmTransientEntityCacher; + + + public CdmTransientEntityCacher getCdmTransientEntityCacher() { + return cdmTransientEntityCacher; + } +} diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java new file mode 100644 index 000000000..c53c2e9e0 --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java @@ -0,0 +1,179 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.cdm.api.cache; + +import java.util.UUID; + +import org.springframework.stereotype.Component; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.Element; +import net.sf.ehcache.config.CacheConfiguration; +import net.sf.ehcache.store.MemoryStoreEvictionPolicy; +import eu.etaxonomy.cdm.model.common.CdmBase; + +/** + * @author cmathew + * @date 14 Oct 2014 + * + */ +@Component +public class CdmTransientEntityCacher extends CdmServiceCacher { + + private static final String ENTITY_CACHE_NAME = "entityCache"; + + public CdmTransientEntityCacher() { + // Create entity cache + getDefaultCacheManager().addCache(new Cache(getEntityCacheConfiguration())); + } + /** + * Returns the default cache configuration. + * + * @return + */ + private CacheConfiguration getEntityCacheConfiguration() { + // For a better understanding on how to size caches, refer to + // http://ehcache.org/documentation/configuration/cache-size + return new CacheConfiguration(ENTITY_CACHE_NAME, 500) + .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU) + .eternal(false) + // default ttl and tti set to 2 hours + .timeToLiveSeconds(60*60*2) + .timeToIdleSeconds(60*60*2); + // This is 2.6.9 API + //.maxEntriesLocalDisk(1000); + //.persistence(new PersistenceConfiguration().strategy(Strategy.LOCALTEMPSWAP)); + } + + /** + * Returns the cache corresponding to the cache id + * + * @param cacheId + * @return + */ + private static Cache getCache() { + return getDefaultCacheManager().getCache(ENTITY_CACHE_NAME); + } + + + /** + * Puts the (Key,Value) pair of ({@link java.util.UUID}, {@link eu.etaxonomy.cdm.model.common.CdmBase}), + * in the cache corresponding to the given cache id + * + * @param cacheId + * @param uuid + * @param cdmEntity + */ + public T put(String id, T cdmEntity) { + T cachedCdmEntity = getFromCache(cdmEntity.getUuid()); + cachedCdmEntity = (cachedCdmEntity == null) ? getFromCache(id) : cachedCdmEntity; + if(cachedCdmEntity != null) { + return cachedCdmEntity; + } else { + getCache().put(new Element(id, cdmEntity)); + return cdmEntity; + } + } + + @Override + public T put(UUID uuid, T cdmEntity) { + T cachedCdmEntity = getFromCache(cdmEntity.getUuid()); + cachedCdmEntity = (cachedCdmEntity == null) ? getFromCache(uuid) : cachedCdmEntity; + if(cachedCdmEntity != null) { + return cachedCdmEntity; + } else { + getCache().put(new Element(uuid, cdmEntity)); + return cdmEntity; + } + } + + public T put(Class clazz, int id, T cdmEntity) { + String cacheId = generateId(clazz,id); + return put(cacheId, cdmEntity); + } + + /** + * Gets the cache element corresponding to the given {@link java.util.UUID} + * in the cache corresponding to the given cache id. + * + * @param uuid + * @return + */ + @Override + protected Element getCacheElement(UUID uuid) { + return getCache().get(uuid); + } + + private Element getCacheElement(String id) { + return getCache().get(id); + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.cdm.model.ICdmCacher#getFromCache(java.util.UUID) + */ + @Override + public T getFromCache(UUID uuid) { + Element e = getCacheElement(uuid); + e = (getCacheElement(uuid) == null) ? super.getCacheElement(uuid) : e; + if (e == null) { + return null; + } else { + return(T)e.getObjectValue(); + } + } + + public T getFromCache(String id) { + Element e = getCacheElement(id); + if (e == null) { + return null; + } else { + return (T) e.getObjectValue(); + } + } + + + public T getFromCache(Class clazz, int id) { + String cacheId = generateId(clazz,id); + return getFromCache(cacheId); + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.cdm.model.ICdmCacher#exists(java.util.UUID) + */ + @Override + public boolean exists(UUID uuid) { + return (getCacheElement(uuid) != null || super.getCacheElement(uuid) != null); + } + + public boolean exists(String id) { + return (getCacheElement(id) != null); + } + + + /* (non-Javadoc) + * @see eu.etaxonomy.cdm.model.ICdmCacher#existsAndIsNotNull(java.util.UUID) + */ + @Override + public boolean existsAndIsNotNull(UUID uuid) { + return getFromCache(uuid) != null; + } + + public boolean existsAndIsNotNull(String id) { + return getFromCache(id) != null; + } + + + private static String generateId(Class clazz, int id) { + return clazz.getName() + String.valueOf(id); + } + +} diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java new file mode 100644 index 000000000..10d02bfaa --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java @@ -0,0 +1,45 @@ +// $Id$ +/** + * Copyright (C) 2014 EDIT + * European Distributed Institute of Taxonomy + * http://www.e-taxonomy.eu + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * See LICENSE.TXT at the top of this package for the full license terms. + */ +package eu.etaxonomy.cdm.api.cache; + +import org.hibernate.collection.internal.PersistentMap; +import org.hibernate.collection.spi.PersistentCollection; + +import eu.etaxonomy.cdm.api.cache.CachedCommonServiceImpl.CollectionField; +import eu.etaxonomy.cdm.model.common.CdmBase; + +/** + * @author cmathew + * @date 14 Oct 2014 + * + */ +public interface ICachedCommonService { + + public CdmBase find(Class clazz, int id); + + public PersistentCollection initializeCollection(PersistentCollection col); + + public void updatePersistentCollection(CollectionField colf); + + public boolean isEmpty(PersistentCollection col); + + public int size(PersistentCollection col); + + public Object get(PersistentCollection col, int index); + + public boolean contains(PersistentCollection col, Object element); + + public boolean containsKey(PersistentCollection col, Object key); + + public boolean containsValue(PersistentCollection col, Object element); + + public CollectionField getCollectionField(PersistentCollection pc); + +} \ No newline at end of file diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/LazyLoadingCachingUtils.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/LazyLoadingCachingUtils.java new file mode 100644 index 000000000..64d00990c --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/LazyLoadingCachingUtils.java @@ -0,0 +1,77 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.cdm.api.cache; + +import java.util.Iterator; +import java.util.Map; + +import org.hibernate.collection.internal.PersistentMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import eu.etaxonomy.cdm.model.common.CdmBase; + +/** + * @author cmathew + * @date 15 Oct 2014 + * + */ +@Component +public class LazyLoadingCachingUtils { + + @Autowired + private CdmEntityCacheManager cdmEntityCacheManager; + + public static enum CollectionType { + SET, + LIST, + MAP; + + @Override + public String toString() { + return this.name().toLowerCase(); + } + } + + public void updatePersistentCollection(Map map) { + if(map == null || map.isEmpty()) { + return; + } + + int originalMapSize = map.size(); + Object[] result = new Object[ map.size() * 2 ]; + Iterator iter = map.entrySet().iterator(); + int i=0; + while ( iter.hasNext() ) { + Map.Entry e = (Map.Entry) iter.next(); + result[i++] = e.getKey(); + result[i++] = e.getValue(); + } + + for(i=0; i pKeys = polytomousKeyService.list(PolytomousKey.class, null, null, null, null); + for(PolytomousKey pKey : pKeys) { + logger.info("Polytomous Key : " + pKey.getTitleCache()); + } + } + + + @Test + //@DataSet("PolytomousKeyTest.readPolytmousKeyData.xml") + public void readPolytmousKeyData() { + PolytomousKey pKey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + Set taxonomicScope = pKey.getTaxonomicScope(); + Iterator tsItr = taxonomicScope.iterator(); + Taxon taxon = tsItr.next(); + logger.info("taxonomic scope : " + taxon.getTitleCache()); + Assert.assertEquals(taxon.getTitleCache(), "Achillea cretica L. sec. Cyprus"); + taxon = tsItr.next(); + logger.info("taxonomic scope : " + taxon.getTitleCache()); + Assert.assertEquals(taxon.getTitleCache(), "Achillea sec. Cyprus"); + Assert.assertEquals(tsItr.hasNext(), false); + + List credits = pKey.getCredits(); + AgentBase agent = credits.get(0).getAgent(); + Assert.assertEquals(agent.getId(),4809); + Assert.assertEquals(agent.getTitleCache(),"R. A. Graham"); + Assert.assertEquals(credits.get(0).getText(),"Credits Text Test"); + + Set exts = pKey.getExtensions(); + Iterator extItr = exts.iterator(); + Extension ext = extItr.next(); + Assert.assertEquals(ext.getValue(), "http://test.com"); + + Set rights = pKey.getRights(); + Iterator rightsItr = rights.iterator(); + Rights right = rightsItr.next(); + Assert.assertEquals(right.getText(),"Rights Text Test"); + + Set sources = pKey.getSources(); + Iterator sourcesItr = sources.iterator(); + IdentifiableSource source = sourcesItr.next(); + Assert.assertEquals(source.getId(), 23710); + source = sourcesItr.next(); + Assert.assertEquals(source.getId(), 23711); + + // TO DO : Added tests for Annotations , Markers + } + + @Test + public void readPolytomousKeyDataFromNodes() { + PolytomousKey pKey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + PolytomousKeyNode rootNode = pKey.getRoot(); + + + Assert.assertEquals(rootNode.getId(), 2750); + + Assert.assertEquals(rootNode.getChildAt(0).getId(), 2751); + Assert.assertEquals(rootNode.getChildAt(0).getParent().getId(), rootNode.getId()); + Assert.assertEquals(rootNode.getKey().getId(), pKey.getId()); + Integer sortIndex = (Integer)getFieldValueViaReflection(rootNode.getChildAt(0), "sortIndex"); + Assert.assertEquals(sortIndex, new Integer(0)); + String statement = "Capitula without ligulate ray-florets; leaves entire or subentire"; + Assert.assertEquals(rootNode.getChildAt(0).getStatement().getLabelText(english), statement); + + Assert.assertEquals(rootNode.getChildAt(1).getId(), 2753); + Assert.assertEquals(rootNode.getChildAt(1).getParent().getId(), rootNode.getId()); + Assert.assertEquals(rootNode.getChildAt(1).getKey().getId(), pKey.getId()); + sortIndex = (Integer)getFieldValueViaReflection(rootNode.getChildAt(1), "sortIndex"); + Assert.assertEquals(sortIndex, new Integer(1)); + statement = "Capitula with ligulate ray-florets; leaves pinnatisect"; + Assert.assertEquals(rootNode.getChildAt(1).getStatement().getLabelText(english), statement); + + Assert.assertEquals(rootNode.getChildAt(1).getChildAt(0).getId(), 2754); + Assert.assertEquals(rootNode.getChildAt(1).getChildAt(0).getParent().getId(), rootNode.getChildAt(1).getId()); + Assert.assertEquals(rootNode.getChildAt(1).getChildAt(0).getKey().getId(), pKey.getId()); + sortIndex = (Integer)getFieldValueViaReflection(rootNode.getChildAt(1).getChildAt(0), "sortIndex"); + Assert.assertEquals(sortIndex, new Integer(0)); + statement = "Ray-florets yellow"; + Assert.assertEquals(rootNode.getChildAt(1).getChildAt(0).getStatement().getLabelText(english), statement); + Assert.assertEquals(rootNode.getChildAt(1).getChildAt(0).getChildAt(0).getTaxon().getTitleCache(), "Achillea arabica Kotschy sec. Cyprus"); + } + + @Test + public void savePolytomousKeyNodeData() { + PolytomousKey pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + PolytomousKeyNode pkeynode = pkey.getRoot(); + String newQuestion = "New Question"; + String newStatement = "New Statement"; + + Assert.assertEquals("Question 1",pkeynode.getQuestion().getLabel().get(english).getText()); + for(PolytomousKeyNode node : pkeynode.getChildren()) { + + node.setQuestion(null); + node.setStatement(null); + } + //FIXME: Add tests for feature after fixing problem + + //Feature feature = pkeynode.getFeature(); + //Assert.assertEquals(feature.getTitleCache(),"Systematics"); + //pkeynode.setFeature(null); + + Assert.assertEquals(pkeynode.getChildAt(0).getModifyingText().get(english).getText(),"Modifying Text 1a"); + String modifyingText = "Modifying Text 1a updated"; + + //pkeynode.getChildAt(0).putModifyingText(english, modifyingText); + + Assert.assertEquals(pkeynode.getChildAt(0).getSubkey().getId(),751); + Assert.assertEquals(pkeynode.getChildAt(0).getSubkey().getTitleCache(),"Asphodeline"); + Assert.assertNull(pkeynode.getChildAt(1).getTaxon()); + Taxon taxon = CdmBase.deproxy(taxonService.find(taxon1Uuid),Taxon.class); + pkeynode.getChildAt(1).setTaxon(taxon); + + polytomousKeyService.merge(pkey); + + pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + pkeynode = pkey.getRoot(); + for(PolytomousKeyNode node : pkeynode.getChildren()) { + Assert.assertNull(node.getQuestion()); + node.setQuestion(KeyStatement.NewInstance(english,newQuestion)); + Assert.assertNull(node.getStatement()); + node.setStatement(KeyStatement.NewInstance(english,newStatement)); + } + //Assert.assertNull(pkeynode.getFeature()); + //pkeynode.setFeature(feature); + + //Assert.assertEquals(pkeynode.getChildAt(0).getModifyingText().get(english).getText(),modifyingText); + Assert.assertEquals(pkeynode.getChildAt(1).getTaxon(), taxon); + + polytomousKeyService.merge(pkey); + + pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + pkeynode = pkey.getRoot(); + for(PolytomousKeyNode node : pkeynode.getChildren()) { + Assert.assertNotNull(node.getQuestion()); + Map label = node.getQuestion().getLabel(); + Assert.assertEquals(newQuestion, label.get(english).getText()); + Assert.assertNotNull(node.getStatement()); + Assert.assertEquals(newStatement, node.getStatement().getLabel(english).getText()); + } + //Assert.assertEquals(pkeynode.getFeature().getId(), feature.getId()); + + } + + @Test + public void savePolytomousKeyNodeDataWithSameSubKey() { + //CachedCommonServiceImpl.setCacheEnabled(false); + PolytomousKey pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + PolytomousKeyNode pkeynode = pkey.getRoot(); + + PolytomousKey subkey1 = pkeynode.getChildAt(0).getSubkey(); + String subkey1title = subkey1.getTitleCache(); + subkey1.setTitleCache(subkey1title + "test", true); + + + PolytomousKey subkey2 = pkeynode.getChildAt(1).getChildAt(0).getSubkey(); + String subkey2title = subkey2.getTitleCache(); + subkey2.setTitleCache(subkey2title + "test", true); + + Assert.assertNotSame(subkey1, subkey2); + + + polytomousKeyService.merge(pkey); + } + + @Test + public void savePolytomousKeyNodeDataWithSameSubKeyUsingService() { + CachedCommonServiceImpl.setCacheEnabled(false); + PolytomousKey pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + PolytomousKeyNode pkeynode = pkey.getRoot(); + + PersistentCollection children = (PersistentCollection) pkeynode.getChildren(); + PolytomousKeyNode childNode0 = (PolytomousKeyNode)commonService.get(children, 0); + PolytomousKey subkey1 = CdmBase.deproxy(childNode0.getSubkey(),PolytomousKey.class); + String subkey1title = subkey1.getTitleCache(); + subkey1.setTitleCache(subkey1title + "test", true); + + PolytomousKeyNode childNode1 = (PolytomousKeyNode)commonService.get(children, 1); + PolytomousKey subkey2 = CdmBase.deproxy(childNode1.getSubkey(),PolytomousKey.class); + String subkey2title = subkey2.getTitleCache(); + subkey2.setTitleCache(subkey2title + "test", true); + + Assert.assertNotSame(subkey1, subkey2); + + polytomousKeyService.merge(pkey); + } + + + @Test + public void savePolytomousKeyNodeDataWithSameLanguageInLabel() { + PolytomousKey pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + PolytomousKeyNode pkeynode = pkey.getRoot(); + + Map label1 = pkeynode.getQuestion().getLabel(); + label1.size(); + //Language lang1 = label1.get(english).getLanguage(); + //String title1 = lang1.getTitleCache(); + + Map label2 = pkeynode.getChildAt(0).getStatement().getLabel(); + label2.size(); + //Language lang2 = label2.get(english).getLanguage(); + //String title2 = lang2.getTitleCache(); + + polytomousKeyService.merge(pkey); + } + + +} diff --git a/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTestManager.java b/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTestManager.java new file mode 100644 index 000000000..503cab461 --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTestManager.java @@ -0,0 +1,41 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.httpinvoker; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.unitils.UnitilsJUnit4; + +import eu.etaxonomy.taxeditor.lazyloading.AbstractLazyInitializerTest; + +/** + * @author cmathew + * @date 6 Oct 2014 + * + */ +public class CdmServerTestManager extends UnitilsJUnit4 { + private static final Logger logger = Logger.getLogger(CdmServerTestManager.class); + + + @Test + public void stopCdmServer() { + Logger.getRootLogger().setLevel(Level.INFO); + CDMServer.getInstance().setKeepServerRunning(true); + try { + CDMServer.getInstance().stop(); + } catch (Exception e) { + Assert.fail("Server could not be stopped. Reason : " + e.getMessage()); + } + } + +} diff --git a/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.java b/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.java new file mode 100644 index 000000000..f9954998b --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.java @@ -0,0 +1,89 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.lazyloading; + +import java.util.UUID; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.hibernate.collection.spi.PersistentCollection; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import eu.etaxonomy.cdm.api.service.ICommonService; +import eu.etaxonomy.cdm.api.service.IPolytomousKeyService; +import eu.etaxonomy.cdm.api.service.ITaxonService; +import eu.etaxonomy.cdm.model.common.CdmBase; +import eu.etaxonomy.cdm.model.common.Language; +import eu.etaxonomy.cdm.model.description.PolytomousKey; +import eu.etaxonomy.cdm.model.description.PolytomousKeyNode; +import eu.etaxonomy.cdm.model.name.NomenclaturalCode; +import eu.etaxonomy.taxeditor.httpinvoker.BaseRemotingTest; +import eu.etaxonomy.taxeditor.httpinvoker.CDMServer; + +/** + * @author cmathew + * @date 16 Oct 2014 + * + */ +public class CdmEntityCacherTest extends BaseRemotingTest { + + private static final Logger logger = Logger.getLogger(CdmEntityCacherTest.class); + + UUID polytomousKeyUuid = UUID.fromString("0d53ba20-7de4-4baa-bd8a-401048447d66"); + UUID taxon1Uuid = UUID.fromString("2b336df7-29e8-4f79-985f-66502739d22f"); + + + IPolytomousKeyService polytomousKeyService = getRemoteApplicationController().getPolytomousKeyService(); + ICommonService commonService = getRemoteApplicationController().getCommonService(); + ITaxonService taxonService = getRemoteApplicationController().getTaxonService(); + + Language english = Language.getLanguageFromUuid(Language.uuidEnglish); + + @BeforeClass + public static void initializePolytomousKeyTest() { + logger.setLevel(Level.INFO); + CDMServer.getInstance().setKeepServerRunning(true); + + initializeController("default", "127.0.0.1", 8080, "", NomenclaturalCode.ICNAFP); + } + + @Test + public void testSimpleCache() { + + + } + + @Test + public void testCachingCdmEntities() { + PolytomousKey pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class); + PolytomousKeyNode pkeynode = pkey.getRoot(); + + PersistentCollection children = (PersistentCollection) pkeynode.getChildren(); + PolytomousKeyNode childNode0 = (PolytomousKeyNode)commonService.get(children, 0); + PolytomousKey subkey1 = CdmBase.deproxy(childNode0.getSubkey(),PolytomousKey.class); + String subkey1title = subkey1.getTitleCache(); + subkey1.setTitleCache(subkey1title + "test", true); + + PolytomousKeyNode childNode1 = (PolytomousKeyNode)commonService.get(children, 1); + PolytomousKey subkey2 = CdmBase.deproxy(childNode1.getSubkey(),PolytomousKey.class); + String subkey2title = subkey2.getTitleCache(); + subkey2.setTitleCache(subkey2title + "test", true); + + Assert.assertNotSame(subkey1, subkey2); + + polytomousKeyService.merge(pkey); + + + } + + +} diff --git a/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.readPolytmousKeyData.xml b/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.readPolytmousKeyData.xml new file mode 100644 index 000000000..293407c52 --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.readPolytmousKeyData.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.xml b/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.xml new file mode 100644 index 000000000..ba231751c --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.xml b/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.xml new file mode 100644 index 000000000..ba231751c --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eu.etaxonomy.taxeditor.remoting/src/test/resources/log4j.properties b/eu.etaxonomy.taxeditor.remoting/src/test/resources/log4j.properties new file mode 100644 index 000000000..96951aa8a --- /dev/null +++ b/eu.etaxonomy.taxeditor.remoting/src/test/resources/log4j.properties @@ -0,0 +1,17 @@ +### ************ APPENDER ***********************************### + +### direct log messages to stdout ### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n + + +### ************* LOG LEVELS *********************************### + +### set log levels - for more verbose logging change 'info' to 'debug' ### +### levels: error, warn, debug, info +log4j.rootLogger=INFO, stdout + +### set directory-specific levels below +log4j.logger.eu.etaxonomy.taxeditor = INFO \ No newline at end of file -- 2.34.1