You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2016/06/02 21:09:43 UTC

svn commit: r1746634 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: plugins/observation/filter/ACFilter.java security/authorization/permission/PermissionProviderImpl.java

Author: mreutegg
Date: Thu Jun  2 21:09:43 2016
New Revision: 1746634

URL: http://svn.apache.org/viewvc?rev=1746634&view=rev
Log:
OAK-4361: Reduce performance impact of observation ACFilter

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ACFilter.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ACFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ACFilter.java?rev=1746634&r1=1746633&r2=1746634&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ACFilter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ACFilter.java Thu Jun  2 21:09:43 2016
@@ -32,11 +32,30 @@ import org.apache.jackrabbit.oak.spi.sta
 /**
  * {@code EventTypeFilter} filters based on the access rights of the observing session.
  */
-public class ACFilter implements EventFilter {
-    private final TreePermission treePermission;
+public final class ACFilter implements EventFilter {
 
-    private ACFilter(@Nonnull TreePermission treePermission) {
-        this.treePermission = checkNotNull(treePermission);
+    private final NodeState before;
+
+    private final NodeState after;
+
+    private final String name;
+
+    private final ACFilter parentFilter;
+
+    private final PermissionProvider permissionProvider;
+
+    private TreePermission treePermission;
+
+    private ACFilter(@Nonnull NodeState before,
+                     @Nonnull NodeState after,
+                     @Nonnull String name,
+                     @Nonnull PermissionProvider permissionProvider,
+                     @Nonnull ACFilter parentFilter) {
+        this.before = checkNotNull(before);
+        this.after = checkNotNull(after);
+        this.name = checkNotNull(name);
+        this.permissionProvider = checkNotNull(permissionProvider);
+        this.parentFilter = checkNotNull(parentFilter);
     }
 
     /**
@@ -47,52 +66,71 @@ public class ACFilter implements EventFi
      * @param after  after state
      * @param permissionProvider  permission provider for access control evaluation
      */
-    public ACFilter(@Nonnull NodeState before, @Nonnull NodeState after,
-            @Nonnull PermissionProvider permissionProvider) {
-        this(permissionProvider.getTreePermission(
-                TreeFactory.createReadOnlyTree((after.exists() ? after : before)), TreePermission.EMPTY));
+    public ACFilter(@Nonnull NodeState before,
+                    @Nonnull NodeState after,
+                    @Nonnull PermissionProvider permissionProvider) {
+        this.before = checkNotNull(before);
+        this.after = checkNotNull(after);
+        this.name = null;
+        this.permissionProvider = checkNotNull(permissionProvider);
+        this.parentFilter = null;
     }
 
     @Override
     public boolean includeAdd(PropertyState after) {
-        return treePermission.canRead(after);
+        return getTreePermission().canRead(after);
     }
 
     @Override
     public boolean includeChange(PropertyState before, PropertyState after) {
-        return treePermission.canRead(after);
+        return getTreePermission().canRead(after);
     }
 
     @Override
     public boolean includeDelete(PropertyState before) {
-        return treePermission.canRead(before);
+        return getTreePermission().canRead(before);
     }
 
     @Override
     public boolean includeAdd(String name, NodeState after) {
-        return treePermission.getChildPermission(name, after).canRead();
+        return getTreePermission().getChildPermission(name, after).canRead();
     }
 
     @Override
     public boolean includeDelete(String name, NodeState before) {
-        return treePermission.getChildPermission(name, before).canRead();
+        return getTreePermission().getChildPermission(name, before).canRead();
     }
 
     @Override
     public boolean includeMove(String sourcePath, String name, NodeState moved) {
         // TODO: check access to the source path, it might not be accessible
-        return treePermission.getChildPermission(name, moved).canRead();
+        return getTreePermission().getChildPermission(name, moved).canRead();
     }
 
     @Override
     public boolean includeReorder(String destName, String name, NodeState reordered) {
         // TODO: check access to the dest name, it might not be accessible
-        return treePermission.getChildPermission(name, reordered).canRead();
+        return getTreePermission().getChildPermission(name, reordered).canRead();
     }
 
     @Override
     public EventFilter create(String name, NodeState before, NodeState after) {
-        return new ACFilter(treePermission.getChildPermission(name, after));
+        return new ACFilter(before, after, name, permissionProvider, this);
     }
 
+    //-----------------------------< internal >---------------------------------
+
+    private TreePermission getTreePermission() {
+        TreePermission tp = treePermission;
+        if (tp == null) {
+            if (parentFilter == null) {
+                tp = permissionProvider.getTreePermission(
+                        TreeFactory.createReadOnlyTree((after.exists() ? after : before)), TreePermission.EMPTY);
+            } else {
+                tp = parentFilter.getTreePermission().getChildPermission(name, after);
+            }
+            treePermission = tp;
+        }
+        return tp;
+    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java?rev=1746634&r1=1746633&r2=1746634&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java Thu Jun  2 21:09:43 2016
@@ -48,9 +48,15 @@ public class PermissionProviderImpl impl
 
     private final String workspaceName;
 
+    private final Set<Principal> principals;
+
+    private final RestrictionProvider restrictionProvider;
+
+    private final ConfigurationParameters options;
+
     private final Context ctx;
 
-    private final CompiledPermissions compiledPermissions;
+    private CompiledPermissions compiledPermissions;
 
     private Root immutableRoot;
 
@@ -61,49 +67,46 @@ public class PermissionProviderImpl impl
                                   @Nonnull Context ctx) {
         this.root = root;
         this.workspaceName = workspaceName;
+        this.principals = principals;
+        this.restrictionProvider = restrictionProvider;
+        this.options = options;
         this.ctx = ctx;
 
         immutableRoot = RootFactory.createReadOnlyRoot(root);
-
-        if (PermissionUtil.isAdminOrSystem(principals, options)) {
-            compiledPermissions = AllPermissions.getInstance();
-        } else {
-            compiledPermissions = CompiledPermissionImpl.create(immutableRoot, workspaceName, principals, restrictionProvider, options, ctx);
-        }
     }
 
     @Override
     public void refresh() {
         immutableRoot = RootFactory.createReadOnlyRoot(root);
-        compiledPermissions.refresh(immutableRoot, workspaceName);
+        getCompiledPermissions().refresh(immutableRoot, workspaceName);
     }
 
     @Nonnull
     @Override
     public Set<String> getPrivileges(@Nullable Tree tree) {
-        return compiledPermissions.getPrivileges(PermissionUtil.getImmutableTree(tree, immutableRoot));
+        return getCompiledPermissions().getPrivileges(PermissionUtil.getImmutableTree(tree, immutableRoot));
     }
 
     @Override
     public boolean hasPrivileges(@Nullable Tree tree, @Nonnull String... privilegeNames) {
-        return compiledPermissions.hasPrivileges(PermissionUtil.getImmutableTree(tree, immutableRoot), privilegeNames);
+        return getCompiledPermissions().hasPrivileges(PermissionUtil.getImmutableTree(tree, immutableRoot), privilegeNames);
     }
 
     @Nonnull
     @Override
     public RepositoryPermission getRepositoryPermission() {
-        return compiledPermissions.getRepositoryPermission();
+        return getCompiledPermissions().getRepositoryPermission();
     }
 
     @Nonnull
     @Override
     public TreePermission getTreePermission(@Nonnull Tree tree, @Nonnull TreePermission parentPermission) {
-        return compiledPermissions.getTreePermission(PermissionUtil.getImmutableTree(tree, immutableRoot), parentPermission);
+        return getCompiledPermissions().getTreePermission(PermissionUtil.getImmutableTree(tree, immutableRoot), parentPermission);
     }
 
     @Override
     public boolean isGranted(@Nonnull Tree tree, @Nullable PropertyState property, long permissions) {
-        return compiledPermissions.isGranted(PermissionUtil.getImmutableTree(tree, immutableRoot), property, permissions);
+        return getCompiledPermissions().isGranted(PermissionUtil.getImmutableTree(tree, immutableRoot), property, permissions);
     }
 
     @Override
@@ -145,11 +148,24 @@ public class PermissionProviderImpl impl
     @Nonnull
     @Override
     public TreePermission getTreePermission(@Nonnull Tree tree, @Nonnull TreeType type, @Nonnull TreePermission parentPermission) {
-        return compiledPermissions.getTreePermission(PermissionUtil.getImmutableTree(tree, immutableRoot), type, parentPermission);
+        return getCompiledPermissions().getTreePermission(PermissionUtil.getImmutableTree(tree, immutableRoot), type, parentPermission);
     }
 
     //--------------------------------------------------------------------------
 
+    private CompiledPermissions getCompiledPermissions() {
+        CompiledPermissions cp = compiledPermissions;
+        if (cp == null) {
+            if (PermissionUtil.isAdminOrSystem(principals, options)) {
+                cp = AllPermissions.getInstance();
+            } else {
+                cp = CompiledPermissionImpl.create(immutableRoot, workspaceName, principals, restrictionProvider, options, ctx);
+            }
+            compiledPermissions = cp;
+        }
+        return cp;
+    }
+
     private static boolean isVersionStorePath(@Nonnull String oakPath) {
         return oakPath.startsWith(VersionConstants.VERSION_STORE_PATH);
     }
@@ -161,7 +177,7 @@ public class PermissionProviderImpl impl
         if (tree != null) {
             isGranted = isGranted(tree, property, permissions);
         } else if (!isVersionStorePath(location.getPath())) {
-            isGranted = compiledPermissions.isGranted(oakPath, permissions);
+            isGranted = getCompiledPermissions().isGranted(oakPath, permissions);
         }
         return isGranted;
     }