You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ol...@apache.org on 2014/04/02 05:55:29 UTC

svn commit: r1583867 - in /archiva/trunk/archiva-modules: archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/ archiva-web/archiva-webapp/src/main/webapp/WEB-INF/ metadata/metadata-repository-api/src/main/java/...

Author: olamy
Date: Wed Apr  2 03:55:28 2014
New Revision: 1583867

URL: http://svn.apache.org/r1583867
Log:
[MRM-1802] Find a cache solution for browsing part (especially root browsing)

Modified:
    archiva/trunk/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml
    archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java
    archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml
    archiva/trunk/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java?rev=1583867&r1=1583866&r2=1583867&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java Wed Apr  2 03:55:28 2014
@@ -44,6 +44,7 @@ import org.apache.archiva.model.Artifact
 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 )

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml?rev=1583867&r1=1583866&r2=1583867&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml Wed Apr  2 03:55:28 2014
@@ -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 -->
   <!--

Modified: archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java?rev=1583867&r1=1583866&r2=1583867&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java (original)
+++ archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java Wed Apr  2 03:55:28 2014
@@ -29,6 +29,7 @@ import org.apache.archiva.metadata.repos
 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 );

Modified: archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml?rev=1583867&r1=1583866&r2=1583867&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml (original)
+++ archiva/trunk/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml Wed Apr  2 03:55:28 2014
@@ -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

Modified: archiva/trunk/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java?rev=1583867&r1=1583866&r2=1583867&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java (original)
+++ archiva/trunk/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java Wed Apr  2 03:55:28 2014
@@ -61,14 +61,11 @@ import org.apache.archiva.metadata.repos
 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() ) //