You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2010/07/16 12:38:28 UTC

svn commit: r964744 - in /jackrabbit/branches/2.1: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/ jackrabbit-core/src/test/java/org/apache/jac...

Author: angela
Date: Fri Jul 16 10:38:28 2010
New Revision: 964744

URL: http://svn.apache.org/viewvc?rev=964744&view=rev
Log:
JCR-2672 - Cache also failed principal lookups   [merge changes into 2.1 branch]

Added:
    jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProviderTest.java
      - copied unchanged from r964362, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProviderTest.java
    jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/DefaultPrincipalProviderTest.java
      - copied unchanged from r964362, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/DefaultPrincipalProviderTest.java
Removed:
    jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProviderTest.java
Modified:
    jackrabbit/branches/2.1/   (props changed)
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java
    jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/TestAll.java
    jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java

Propchange: jackrabbit/branches/2.1/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 16 10:38:28 2010
@@ -2,4 +2,4 @@
 /jackrabbit/sandbox/JCR-1456:774917-886178
 /jackrabbit/sandbox/JCR-2170:812417-816332
 /jackrabbit/sandbox/tripod-JCR-2209:795441-795863
-/jackrabbit/trunk:931121,931479,931483-931484,931504,931609,931613,931838,931919,932318-932319,933144,933197,933203,933213,933216,933554,933646,933694,934405,934412,934849,935557,955222,955229,955307
+/jackrabbit/trunk:931121,931479,931483-931484,931504,931609,931613,931838,931919,932318-932319,933144,933197,933203,933213,933216,933554,933646,933694,934405,934412,934849,935557,955222,955229,955307,964362

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java?rev=964744&r1=964743&r2=964744&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java Fri Jul 16 10:38:28 2010
@@ -34,10 +34,18 @@ public abstract class AbstractPrincipalP
 
     /** Option name for the max size of the cache to use */
     public static final String MAXSIZE_KEY = "cacheMaxSize";
+    /** Option name to enable negative cache entries (see JCR-2672) */
+    public static final String NEGATIVE_ENTRY_KEY = "cacheIncludesNegative";
 
     /** flag indicating if the instance has not been {@link #close() closed} */
     private boolean initialized;
 
+    /**
+     * flag indicating if the cache should include 'negative' entries.
+     * @see #NEGATIVE_ENTRY_KEY
+     */
+    private boolean includeNegative;
+
     /** the principal cache */
     private LRUMap cache;
 
@@ -90,19 +98,23 @@ public abstract class AbstractPrincipalP
     /**
      * {@inheritDoc}
      *
-     * {@link #providePrincipal(String)} is called, if no principal with the
-     * given name is present in the cache.
+     * {@link #providePrincipal(String)} is called, if no matching entry
+     * is present in the cache.<br>
+     * NOTE: If the cache is enabled to contain negative entries (see
+     * {@link #NEGATIVE_ENTRY_KEY} configuration option), the cache will also
+     * store negative matches (as <code>null</code> values) in the principal cache.
      */
     public synchronized Principal getPrincipal(String principalName) {
         checkInitialized();
-        Principal principal = (Principal) cache.get(principalName);
-        if (principal == null) {
-            principal = providePrincipal(principalName);
-            if (principal != null) {
-                addToCache(principal);
+        if (cache.containsKey(principalName)) {
+            return (Principal) cache.get(principalName);
+        } else {
+            Principal principal = providePrincipal(principalName);
+            if (principal != null || includeNegative) {
+                cache.put(principalName, principal);
             }
+            return principal;
         }
-        return principal;
     }
 
     /**
@@ -115,7 +127,8 @@ public abstract class AbstractPrincipalP
 
         int maxSize = Integer.parseInt(options.getProperty(MAXSIZE_KEY, "1000"));
         cache = new LRUMap(maxSize);
-
+        includeNegative = Boolean.parseBoolean(options.getProperty(NEGATIVE_ENTRY_KEY, "false"));
+        
         initialized = true;
     }
 

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java?rev=964744&r1=964743&r2=964744&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java Fri Jul 16 10:38:28 2010
@@ -24,6 +24,7 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.observation.SynchronousEventListener;
 import org.apache.jackrabbit.core.security.SystemPrincipal;
 import org.apache.jackrabbit.core.security.user.UserManagerImpl;
 import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
@@ -41,6 +42,7 @@ import java.security.Principal;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 
 /**
@@ -50,9 +52,20 @@ import java.util.Set;
  * Principal}s retrieved from those <code>Authorizable</code> objects.
  * <p/>
  * In addition this provider exposes the <i>everyone</i> principal, which has no
- * content (user/group) represention.
+ * content (user/group) representation.
+ * <p/>
+ * Unless explicitly configured (see {@link #NEGATIVE_ENTRY_KEY negative entry
+ * option} this implementation of the <code>PrincipalProvider</code> interface
+ * caches both positive and negative (null) results of the {@link #providePrincipal}
+ * method. The cache is kept up to date by observation listening to creation
+ * and removal of users and groups.
+ * <p/>
+ * Membership cache:<br>
+ * In addition to the caching provided by <code>AbstractPrincipalProvider</code>
+ * this implementation keeps an extra membership cache, which is notified in
+ * case of changes made to the members of any group.
  */
-public class DefaultPrincipalProvider extends AbstractPrincipalProvider implements EventListener {
+public class DefaultPrincipalProvider extends AbstractPrincipalProvider implements SynchronousEventListener {
 
     /**
      * the default logger
@@ -91,22 +104,29 @@ public class DefaultPrincipalProvider ex
         membershipCache = new LRUMap();
 
         // listen to modifications of group-membership
-        String[] ntNames = new String[1];
+        String[] ntNames = new String[2];
         if (securitySession instanceof SessionImpl) {
             NameResolver resolver = (NameResolver) securitySession;
             ntNames[0] = resolver.getJCRName(UserManagerImpl.NT_REP_GROUP);
+            ntNames[1] = resolver.getJCRName(UserManagerImpl.NT_REP_AUTHORIZABLE_FOLDER);
             pMembers = resolver.getJCRName(UserManagerImpl.P_MEMBERS);
             pPrincipalName = resolver.getJCRName(UserManagerImpl.P_PRINCIPAL_NAME);
         } else {
             ntNames[0] = "rep:Group";
+            ntNames[1] = "rep:AuthorizableFolder";
             pMembers = "rep:members";
             pPrincipalName = "rep:principalName";
         }
 
         String groupPath = userManager.getGroupsPath();
+        String userPath = userManager.getUsersPath();
+        String targetPath = groupPath;
+        while (!Text.isDescendantOrEqual(targetPath, userPath)) {
+            targetPath = Text.getRelativeParent(targetPath, 1);
+        }
         securitySession.getWorkspace().getObservationManager().addEventListener(this,
-                Event.NODE_REMOVED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED,
-                groupPath,
+                Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED,
+                targetPath,
                 true,
                 null,
                 ntNames,
@@ -138,6 +158,21 @@ public class DefaultPrincipalProvider ex
         return null;
     }
 
+    /**
+     * Sets the {@link #NEGATIVE_ENTRY_KEY} option value to <code>true</code> if
+     * it isn't included yet in the passed options, before calling the init
+     * method of the base class.
+     * 
+     * @param options
+     */
+    @Override
+    public void init(Properties options) {
+        if (!options.containsKey(NEGATIVE_ENTRY_KEY)) {
+            options.put(NEGATIVE_ENTRY_KEY, "true");
+        }
+        super.init(options);
+    }
+
     //--------------------------------------------------< PrincipalProvider >---
     /**
      * @see PrincipalProvider#findPrincipals(String)

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/TestAll.java?rev=964744&r1=964743&r2=964744&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/TestAll.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/TestAll.java Fri Jul 16 10:38:28 2010
@@ -35,8 +35,8 @@ public class TestAll extends TestCase {
     public static Test suite() {
         TestSuite suite = new TestSuite("core.security.principal tests");
 
-        suite.addTestSuite(DefaultPrincipalProviderTest.class);
-
+        suite.addTestSuite(AbstractPrincipalProviderTest.class);
+        
         return suite;
     }
 }

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java?rev=964744&r1=964743&r2=964744&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java Fri Jul 16 10:38:28 2010
@@ -49,6 +49,8 @@ public class TestAll extends TestCase {
 
         suite.addTestSuite(UserImporterTest.class);
 
+        suite.addTestSuite(DefaultPrincipalProviderTest.class);
+
         return suite;
     }
 }