diff options
author | Olivier Lamy <olamy@apache.org> | 2014-04-02 03:55:28 +0000 |
---|---|---|
committer | Olivier Lamy <olamy@apache.org> | 2014-04-02 03:55:28 +0000 |
commit | fa2a3efcc7bfd8e15a04d95c8cc05c92fc59066f (patch) | |
tree | b025b65967ae2875392f5e64832bcbe0f1f37970 | |
parent | f9c01084da93d2876e1b023b8de1079f835e54bc (diff) | |
download | archiva-fa2a3efcc7bfd8e15a04d95c8cc05c92fc59066f.tar.gz archiva-fa2a3efcc7bfd8e15a04d95c8cc05c92fc59066f.zip |
[MRM-1802] Find a cache solution for browsing part (especially root browsing)
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1583867 13f79535-47bb-0310-9956-ffa450edef68
5 files changed, 90 insertions, 20 deletions
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java index b9935199b..eb62d85a7 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java @@ -44,6 +44,7 @@ import org.apache.archiva.model.ArtifactReference; import org.apache.archiva.model.VersionedReference; import org.apache.archiva.redback.authentication.AuthenticationResult; import org.apache.archiva.redback.authorization.AuthorizationException; +import org.apache.archiva.redback.components.cache.Cache; import org.apache.archiva.redback.components.taskqueue.TaskQueueException; import org.apache.archiva.redback.system.DefaultSecuritySession; import org.apache.archiva.redback.system.SecuritySession; @@ -149,6 +150,13 @@ public class DefaultRepositoriesService @Inject private RepositoryScanner repoScanner; + /** + * Cache used for namespaces + */ + @Inject + @Named( value = "cache#namespaces" ) + private Cache<String, Collection<String>> namespacesCache; + private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 }; public Boolean scanRepository( String repositoryId, boolean fullScan ) @@ -980,6 +988,10 @@ public class DefaultRepositoriesService metadataRepository.removeNamespace( repositoryId, groupId ); + // just invalidate cache entry + String cacheKey = repositoryId + "-" + groupId; + namespacesCache.remove( cacheKey ); + metadataRepository.save(); } catch ( MetadataRepositoryException e ) diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml index 254bf6206..17bf30c81 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml @@ -290,6 +290,17 @@ <property name="timeToLiveSeconds" value="600"/> </bean> + <bean name="cache#namespaces" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache" + init-method="initialize"> + <property name="diskPersistent" value="false"/> + <property name="eternal" value="false"/> + <property name="maxElementsInMemory" value="1000"/> + <property name="memoryEvictionPolicy" value="LRU"/> + <property name="name" value="usersCache"/> + <property name="timeToIdleSeconds" value="600"/> + <property name="timeToLiveSeconds" value="600"/> + </bean> + <!-- override jcr repository location --> <!-- START SNIPPET: jcr-location --> <!-- diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java index 469b4cf46..5c921d68b 100644 --- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java +++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java @@ -29,6 +29,7 @@ import org.apache.archiva.metadata.repository.storage.RepositoryStorage; import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException; import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException; import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; +import org.apache.archiva.redback.components.cache.Cache; import org.apache.archiva.repository.events.RepositoryListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,21 +44,21 @@ import java.util.List; /** * Default implementation of the metadata resolver API. At present it will handle updating the content repository * from new or changed information in the model and artifacts from the repository storage. - * <p> + * <p/> * This is a singleton component to allow an alternate implementation to be provided. It is intended to be the same * system-wide for the whole content repository instead of on a per-managed-repository basis. Therefore, the session is * passed in as an argument to obtain any necessary resources, rather than the class being instantiated within the * session in the context of a single managed repository's resolution needs. - * <p> + * <p/> * Note that the caller is responsible for the session, such as closing and saving (which is implied by the resolver * being obtained from within the session). The {@link RepositorySession#markDirty()} method is used as a hint to ensure * that the session knows we've made changes at close. We cannot ensure the changes will be persisted if the caller * chooses to revert first. This is preferable to storing the metadata immediately - a separate session would require * having a bi-directional link with the session factory, and saving the existing session might save other changes * unknowingly by the caller. - * <p> + * <p/> */ -@Service ("metadataResolver#default") +@Service("metadataResolver#default") public class DefaultMetadataResolver implements MetadataResolver { @@ -67,20 +68,24 @@ public class DefaultMetadataResolver /** * FIXME: this needs to be configurable based on storage type - and could also be instantiated per repo. Change to a * factory, and perhaps retrieve from the session. We should avoid creating one per request, however. - * <p> + * <p/> * TODO: Also need to accommodate availability of proxy module * ... could be a different type since we need methods to modify the storage metadata, which would also allow more * appropriate methods to pass in the already determined repository configuration, for example, instead of the ID */ @Inject - @Named (value = "repositoryStorage#maven2") + @Named(value = "repositoryStorage#maven2") private RepositoryStorage repositoryStorage; + @Inject + private List<RepositoryListener> listeners; + /** - * + * Cache used for namespaces */ @Inject - private List<RepositoryListener> listeners; + @Named( value = "cache#namespaces" ) + private Cache<String, Collection<String>> namespacesCache; public ProjectVersionMetadata resolveProjectVersion( RepositorySession session, String repoId, String namespace, String projectId, String projectVersion ) @@ -176,8 +181,15 @@ public class DefaultMetadataResolver { try { + + Collection<String> namespaces = namespacesCache.get( repoId ); + if ( namespaces != null ) + { + return namespaces; + } + MetadataRepository metadataRepository = session.getRepository(); - Collection<String> namespaces = metadataRepository.getRootNamespaces( repoId ); + namespaces = metadataRepository.getRootNamespaces( repoId ); Collection<String> storageNamespaces = repositoryStorage.listRootNamespaces( repoId, new ExcludesFilter<String>( namespaces ) ); if ( storageNamespaces != null && !storageNamespaces.isEmpty() ) @@ -190,6 +202,9 @@ public class DefaultMetadataResolver try { metadataRepository.updateNamespace( repoId, n ); + // just invalidate cache entry + String cacheKey = repoId + "-" + n; + namespacesCache.remove( cacheKey ); } catch ( MetadataRepositoryException e ) { @@ -201,6 +216,9 @@ public class DefaultMetadataResolver namespaces = new ArrayList<String>( namespaces ); namespaces.addAll( storageNamespaces ); } + + namespacesCache.put( repoId, namespaces ); + return namespaces; } catch ( RepositoryStorageRuntimeException e ) @@ -215,7 +233,13 @@ public class DefaultMetadataResolver try { MetadataRepository metadataRepository = session.getRepository(); - Collection<String> namespaces = metadataRepository.getNamespaces( repoId, namespace ); + String cacheKey = repoId + "-" + namespace; + Collection<String> namespaces = namespacesCache.get( cacheKey ); + if ( namespaces == null ) + { + namespaces = metadataRepository.getNamespaces( repoId, namespace ); + namespacesCache.put( cacheKey, namespaces ); + } Collection<String> exclusions = new ArrayList<String>( namespaces ); exclusions.addAll( metadataRepository.getProjects( repoId, namespace ) ); Collection<String> storageNamespaces = @@ -230,6 +254,9 @@ public class DefaultMetadataResolver try { metadataRepository.updateNamespace( repoId, namespace + "." + n ); + // just invalidate cache entry + cacheKey = repoId + "-" + namespace + "." + n; + namespacesCache.remove( cacheKey ); } catch ( MetadataRepositoryException e ) { @@ -257,7 +284,17 @@ public class DefaultMetadataResolver MetadataRepository metadataRepository = session.getRepository(); Collection<String> projects = metadataRepository.getProjects( repoId, namespace ); Collection<String> exclusions = new ArrayList<String>( projects ); - exclusions.addAll( metadataRepository.getNamespaces( repoId, namespace ) ); + + String cacheKey = repoId + "-" + namespace; + Collection<String> namespaces = namespacesCache.get( cacheKey ); + if ( namespaces == null ) + { + namespaces = metadataRepository.getNamespaces( repoId, namespace ); + namespacesCache.put( cacheKey, namespaces ); + } + + exclusions.addAll( namespaces ); + Collection<String> storageProjects = repositoryStorage.listProjects( repoId, namespace, new ExcludesFilter<String>( exclusions ) ); if ( storageProjects != null && !storageProjects.isEmpty() ) @@ -333,7 +370,7 @@ public class DefaultMetadataResolver { log.warn( "Not update project in metadata repository due to an error resolving it from storage: {}", - e.getMessage() ); + e.getMessage() ); for ( RepositoryListener listener : listeners ) { @@ -373,8 +410,8 @@ public class DefaultMetadataResolver ExcludesFilter<String> filter = new ExcludesFilter<String>( createArtifactIdList( artifacts ) ); ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( repoId ).namespace( namespace ).projectId( projectId ).projectVersion( - projectVersion ).filter( filter ); + new ReadMetadataRequest().repositoryId( repoId ).namespace( namespace ).projectId( + projectId ).projectVersion( projectVersion ).filter( filter ); Collection<ArtifactMetadata> storageArtifacts = repositoryStorage.readArtifactsMetadata( readMetadataRequest ); diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml b/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml index e7c511811..34e5c3d5d 100644 --- a/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml +++ b/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml @@ -39,4 +39,15 @@ </constructor-arg> </bean> + <bean name="cache#namespaces" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache" + init-method="initialize"> + <property name="diskPersistent" value="false"/> + <property name="eternal" value="false"/> + <property name="maxElementsInMemory" value="1000"/> + <property name="memoryEvictionPolicy" value="LRU"/> + <property name="name" value="usersCache"/> + <property name="timeToIdleSeconds" value="600"/> + <property name="timeToLiveSeconds" value="600"/> + </bean> + </beans>
\ No newline at end of file diff --git a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java index 0241e48a9..fa46ea0fb 100644 --- a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java +++ b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java @@ -61,14 +61,11 @@ import org.apache.archiva.metadata.repository.cassandra.model.Namespace; import org.apache.archiva.metadata.repository.cassandra.model.Project; import org.apache.archiva.metadata.repository.cassandra.model.ProjectVersionMetadataModel; import org.apache.archiva.metadata.repository.cassandra.model.Repository; -import org.apache.archiva.redback.components.cache.Cache; import org.apache.commons.lang.StringUtils; import org.modelmapper.ModelMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.inject.Inject; -import javax.inject.Named; import javax.persistence.PersistenceException; import java.util.ArrayList; import java.util.Collection; @@ -241,7 +238,7 @@ public class CassandraMetadataRepository updateOrAddNamespace( repositoryId, namespaceId ); } - public Namespace updateOrAddNamespace( String repositoryId, String namespaceId ) + private Namespace updateOrAddNamespace( String repositoryId, String namespaceId ) throws MetadataRepositoryException { try @@ -300,8 +297,10 @@ public class CassandraMetadataRepository try { - String key = - new Namespace.KeyBuilder().withNamespace( namespaceId ).withRepositoryId( repositoryId ).build(); + String key = new Namespace.KeyBuilder() // + .withNamespace( namespaceId ) // + .withRepositoryId( repositoryId ) // + .build(); HFactory.createMutator( cassandraArchivaManager.getKeyspace(), new StringSerializer() ) // .addDeletion( key, cassandraArchivaManager.getNamespaceFamilyName() ) // |