aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Lamy <olamy@apache.org>2014-04-02 03:55:28 +0000
committerOlivier Lamy <olamy@apache.org>2014-04-02 03:55:28 +0000
commitfa2a3efcc7bfd8e15a04d95c8cc05c92fc59066f (patch)
treeb025b65967ae2875392f5e64832bcbe0f1f37970
parentf9c01084da93d2876e1b023b8de1079f835e54bc (diff)
downloadarchiva-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
-rw-r--r--archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java12
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml11
-rw-r--r--archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java65
-rw-r--r--archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml11
-rw-r--r--archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java11
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() ) //