Author: angela
Date: Tue May 28 08:35:31 2019
New Revision: 1860199

URL: http://svn.apache.org/viewvc?rev=1860199&view=rev
Log:
OAK-8227 : Performance benchmarks (wip)

Added:
    
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/
    
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/HasItemGetItemIsModifiedTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PermissionEvaluationTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PrinicipalBasedReadTest.java
   (with props)
Modified:
    jackrabbit/oak/trunk/oak-benchmarks/pom.xml
    
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java

Modified: jackrabbit/oak/trunk/oak-benchmarks/pom.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-benchmarks/pom.xml?rev=1860199&r1=1860198&r2=1860199&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-benchmarks/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-benchmarks/pom.xml Tue May 28 08:35:31 2019
@@ -148,6 +148,11 @@
             <artifactId>oak-authorization-cug</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>oak-authorization-principalbased</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>javax.jcr</groupId>

Modified: 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java?rev=1860199&r1=1860198&r2=1860199&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
 Tue May 28 08:35:31 2019
@@ -49,12 +49,16 @@ import org.apache.jackrabbit.oak.benchma
 import 
org.apache.jackrabbit.oak.benchmark.authentication.external.SyncExternalUsersTest;
 import org.apache.jackrabbit.oak.benchmark.authorization.AceCreationTest;
 import org.apache.jackrabbit.oak.benchmark.authorization.CanReadNonExisting;
+import 
org.apache.jackrabbit.oak.benchmark.authorization.principalbased.HasItemGetItemIsModifiedTest;
+import 
org.apache.jackrabbit.oak.benchmark.authorization.principalbased.PermissionEvaluationTest;
+import 
org.apache.jackrabbit.oak.benchmark.authorization.principalbased.PrinicipalBasedReadTest;
 import org.apache.jackrabbit.oak.benchmark.wikipedia.WikipediaImport;
 import org.apache.jackrabbit.oak.fixture.JackrabbitRepositoryFixture;
 import org.apache.jackrabbit.oak.fixture.OakFixture;
 import org.apache.jackrabbit.oak.fixture.OakRepositoryFixture;
 import org.apache.jackrabbit.oak.fixture.RepositoryFixture;
 import org.apache.jackrabbit.oak.plugins.metric.MetricStatisticsProvider;
+import 
org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration;
 import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 
@@ -126,7 +130,7 @@ public class BenchmarkRunner {
         OptionSpec<Integer> noIterations = parser.accepts("noIterations", 
"Change default 'passwordHashIterations' parameter.")
                 
.withOptionalArg().ofType(Integer.class).defaultsTo(AbstractLoginTest.DEFAULT_ITERATIONS);
         OptionSpec<Long> expiration = parser.accepts("expiration", "Expiration 
time (e.g. principal cache.")
-                        
.withOptionalArg().ofType(Long.class).defaultsTo(AbstractLoginTest.NO_CACHE);
+                
.withOptionalArg().ofType(Long.class).defaultsTo(AbstractLoginTest.NO_CACHE);
         OptionSpec<Integer> numberOfGroups = parser.accepts("numberOfGroups", 
"Number of groups to create.")
                 
.withOptionalArg().ofType(Integer.class).defaultsTo(LoginWithMembershipTest.NUMBER_OF_GROUPS_DEFAULT);
         OptionSpec<Integer> queryMaxCount = parser.accepts("queryMaxCount", 
"Max number of query results.")
@@ -136,11 +140,19 @@ public class BenchmarkRunner {
         OptionSpec<Integer> numberOfInitialAce = 
parser.accepts("numberOfInitialAce", "Number of ACE to create before running 
the test.")
                 
.withOptionalArg().ofType(Integer.class).defaultsTo(AceCreationTest.NUMBER_OF_INITIAL_ACE_DEFAULT);
         OptionSpec<Boolean> nestedGroups = parser.accepts("nestedGroups", "Use 
nested groups.")
-                        
.withOptionalArg().ofType(Boolean.class).defaultsTo(false);
+                .withOptionalArg().ofType(Boolean.class).defaultsTo(false);
+        OptionSpec<Boolean> entriesForEachPrincipal = 
parser.accepts("entriesForEachPrincipal", "Create ACEs for each principal (vs 
rotating).")
+                .withOptionalArg().ofType(Boolean.class).defaultsTo(false);
+        OptionSpec<String> compositionType = parser.accepts("compositionType", 
"Defines composition type for benchmarks with multiple authorization models.")
+                .withOptionalArg().ofType(String.class)
+                
.defaultsTo(CompositeAuthorizationConfiguration.CompositionType.AND.name());
+        OptionSpec<Boolean> useAggregationFilter = 
parser.accepts("useAggregationFilter", "Run principal-based tests with 
'AggregationFilter'")
+                .withOptionalArg().ofType(Boolean.class)
+                .defaultsTo(Boolean.FALSE);
         OptionSpec<Integer> batchSize = parser.accepts("batchSize", "Batch 
size before persisting operations.")
                 
.withOptionalArg().ofType(Integer.class).defaultsTo(AddMembersTest.DEFAULT_BATCH_SIZE);
         OptionSpec<String> importBehavior = parser.accepts("importBehavior", 
"Protected Item Import Behavior")
-                                
.withOptionalArg().ofType(String.class).defaultsTo(ImportBehavior.NAME_BESTEFFORT);
+                
.withOptionalArg().ofType(String.class).defaultsTo(ImportBehavior.NAME_BESTEFFORT);
         OptionSpec<Integer> itemsToRead = parser.accepts("itemsToRead", 
"Number of items to read")
                 .withRequiredArg().ofType(Integer.class).defaultsTo(1000);
         OptionSpec<Integer> concurrency = parser.accepts("concurrency", 
"Number of test threads.")
@@ -158,7 +170,7 @@ public class BenchmarkRunner {
         OptionSpec<Integer> numberOfUsers = parser.accepts("numberOfUsers")
                 .withOptionalArg().ofType(Integer.class).defaultsTo(10000);
         OptionSpec<Boolean> setScope = parser.accepts("setScope", "Whether to 
use include setScope in the user query.")
-                        .withOptionalArg().ofType(Boolean.class)
+                .withOptionalArg().ofType(Boolean.class)
                 .defaultsTo(Boolean.FALSE);
         OptionSpec<Boolean> reverseOrder = parser.accepts("reverseOrder", 
"Invert order of configurations in composite setup.")
                 .withOptionalArg().ofType(Boolean.class)
@@ -170,7 +182,7 @@ public class BenchmarkRunner {
         OptionSpec<String> autoMembership = parser.accepts("autoMembership", 
"Ids of those groups a given external identity automatically become member of.")
                 
.withOptionalArg().ofType(String.class).withValuesSeparatedBy(',');
         OptionSpec<Integer> roundtripDelay = parser.accepts("roundtripDelay", 
"Use simplified principal name lookup from ExtIdRef by specifying roundtrip 
delay of value < 0.")
-                        .withOptionalArg().ofType(Integer.class).defaultsTo(0);
+                .withOptionalArg().ofType(Integer.class).defaultsTo(0);
         OptionSpec<Boolean> transientWrites = parser.accepts("transient", "Do 
not save data.")
                 .withOptionalArg().ofType(Boolean.class)
                 .defaultsTo(Boolean.FALSE);
@@ -179,23 +191,19 @@ public class BenchmarkRunner {
         OptionSpec<Integer> coldSyncInterval = 
parser.accepts("coldSyncInterval", "interval between sync cycles in sec 
(Segment-Tar-Cold only)")
                 .withRequiredArg().ofType(Integer.class).defaultsTo(5);
         OptionSpec<Boolean> coldUseDataStore = parser
-                .accepts("useDataStore",
-                        "Whether to use a datastore in the cold standby 
topology (Segment-Tar-Cold only)")
+                .accepts("useDataStore", "Whether to use a datastore in the 
cold standby topology (Segment-Tar-Cold only)")
                 .withOptionalArg().ofType(Boolean.class)
                 .defaultsTo(Boolean.TRUE);
         OptionSpec<Boolean> coldShareDataStore = parser
-                .accepts("shareDataStore",
-                        "Whether to share the datastore for primary and 
standby in the cold standby topology (Segment-Tar-Cold only)")
+                .accepts("shareDataStore", "Whether to share the datastore for 
primary and standby in the cold standby topology (Segment-Tar-Cold only)")
                 .withOptionalArg().ofType(Boolean.class)
                 .defaultsTo(Boolean.FALSE);
         OptionSpec<Boolean> coldOneShotRun = parser
-                .accepts("oneShotRun",
-                        "Whether to do a continuous sync between client and 
server or sync only once (Segment-Tar-Cold only)")
+                .accepts("oneShotRun", "Whether to do a continuous sync 
between client and server or sync only once (Segment-Tar-Cold only)")
                 .withOptionalArg().ofType(Boolean.class)
                 .defaultsTo(Boolean.FALSE);
         OptionSpec<Boolean> coldSecure = parser
-                .accepts("secure",
-                        "Whether to enable secure communication between 
primary and standby in the cold standby topology (Segment-Tar-Cold only)")
+                .accepts("secure", "Whether to enable secure communication 
between primary and standby in the cold standby topology (Segment-Tar-Cold 
only)")
                 .withOptionalArg().ofType(Boolean.class)
                 .defaultsTo(Boolean.FALSE);
         
@@ -345,6 +353,33 @@ public class BenchmarkRunner {
                         randomUser.value(options),
                         supportedPaths.values(options),
                         reverseOrder.value(options)),
+            new PrinicipalBasedReadTest(
+                    itemsToRead.value(options),
+                    numberOfInitialAce.value(options),
+                    numberOfUsers.value(options),
+                    entriesForEachPrincipal.value(options),
+                    reverseOrder.value(options),
+                    compositionType.value(options),
+                    useAggregationFilter.value(options),
+                    report.value(options)),
+            new PermissionEvaluationTest(
+                    itemsToRead.value(options),
+                    numberOfInitialAce.value(options),
+                    numberOfUsers.value(options),
+                    entriesForEachPrincipal.value(options),
+                    reverseOrder.value(options),
+                    compositionType.value(options),
+                    useAggregationFilter.value(options),
+                    report.value(options)),
+            new HasItemGetItemIsModifiedTest(
+                    itemsToRead.value(options),
+                    numberOfInitialAce.value(options),
+                    numberOfUsers.value(options),
+                    entriesForEachPrincipal.value(options),
+                    reverseOrder.value(options),
+                    compositionType.value(options),
+                    useAggregationFilter.value(options),
+                    report.value(options)),
             new ConcurrentReadDeepTreeTest(
                     runAsAdmin.value(options),
                     itemsToRead.value(options),

Added: 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/HasItemGetItemIsModifiedTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/HasItemGetItemIsModifiedTest.java?rev=1860199&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/HasItemGetItemIsModifiedTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/HasItemGetItemIsModifiedTest.java
 Tue May 28 08:35:31 2019
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.benchmark.authorization.principalbased;
+
+import org.jetbrains.annotations.NotNull;
+
+import javax.jcr.Item;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.util.List;
+
+public class HasItemGetItemIsModifiedTest extends PrinicipalBasedReadTest {
+
+    public HasItemGetItemIsModifiedTest(int itemsToRead, int numberOfACEs, int 
subjectSize, boolean entriesForEachPrincipal, boolean testDefault, @NotNull 
String compositionType, boolean useAggregationFilter, boolean doReport) {
+        super(itemsToRead, numberOfACEs, subjectSize, entriesForEachPrincipal, 
testDefault, compositionType, useAggregationFilter, doReport);
+    }
+
+    protected void randomRead(Session testSession, List<String> allPaths, int 
cnt) throws RepositoryException {
+        boolean logout = false;
+        if (testSession == null) {
+            testSession = getTestSession();
+            logout = true;
+        }
+        try {
+            int nodeCnt = 0;
+            int propertyCnt = 0;
+            int noAccess = 0;
+            int size = allPaths.size();
+            long start = System.currentTimeMillis();
+            for (int i = 0; i < cnt; i++) {
+                double rand = size * Math.random();
+                int index = (int) Math.floor(rand);
+                String path = allPaths.get(index);
+                if (testSession.itemExists(path)) {
+                    Item item = testSession.getItem(path);
+                    if (item.isNode()) {
+                        nodeCnt++;
+                    } else {
+                        propertyCnt++;
+                    }
+                    item.isModified();
+                } else {
+                    noAccess++;
+                }
+            }
+            long end = System.currentTimeMillis();
+            if (doReport) {
+                System.out.println("Session " + testSession.getUserID() + " 
reading " + cnt + " (Nodes: "+ nodeCnt +"; Properties: "+propertyCnt+"; no 
access: "+noAccess+") completed in " + (end - start));
+            }
+        } finally {
+            if (logout) {
+                logout(testSession);
+            }
+        }
+    }
+
+    @NotNull
+    @Override
+    protected String getTestNodeName() {
+        return "HasItemGetItemIsModifiedTest";
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/HasItemGetItemIsModifiedTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PermissionEvaluationTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PermissionEvaluationTest.java?rev=1860199&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PermissionEvaluationTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PermissionEvaluationTest.java
 Tue May 28 08:35:31 2019
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.benchmark.authorization.principalbased;
+
+import com.google.common.collect.ImmutableList;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import org.jetbrains.annotations.NotNull;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.util.List;
+
+public class PermissionEvaluationTest extends PrinicipalBasedReadTest {
+
+    public PermissionEvaluationTest(int itemsToRead, int numberOfACEs, int 
subjectSize, boolean entriesForEachPrincipal, boolean testDefault, @NotNull 
String compositionType, boolean useAggregationFilter, boolean doReport) {
+        super(itemsToRead, numberOfACEs, subjectSize, entriesForEachPrincipal, 
testDefault, compositionType, useAggregationFilter, doReport);
+    }
+
+    protected void randomRead(Session testSession, List<String> allPaths, int 
cnt) throws RepositoryException {
+        boolean logout = false;
+        if (testSession == null) {
+            testSession = getTestSession();
+            logout = true;
+        }
+        try {
+            List<String> permissionNames = 
ImmutableList.copyOf(Permissions.PERMISSION_NAMES.values());
+            int access = 0;
+            int noAccess = 0;
+            long start = System.currentTimeMillis();
+            for (int i = 0; i < cnt; i++) {
+                String path = getRandom(allPaths);
+                String permissionName = getRandom(permissionNames);
+                if (testSession.hasPermission(path, permissionName)) {
+                    access++;
+                } else {
+                    noAccess++;
+                }
+            }
+            long end = System.currentTimeMillis();
+            if (doReport) {
+                System.out.println("Session " + testSession.getUserID() + " 
hasPermissions (granted = " + access + "; denied = "+ noAccess+") completed in 
" + (end - start));
+            }
+        } finally {
+            if (logout) {
+                logout(testSession);
+            }
+        }
+    }
+
+    @NotNull
+    @Override
+    protected String getTestNodeName() {
+        return "PermissionEvaluationTest";
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PermissionEvaluationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PrinicipalBasedReadTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PrinicipalBasedReadTest.java?rev=1860199&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PrinicipalBasedReadTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PrinicipalBasedReadTest.java
 Tue May 28 08:35:31 2019
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.benchmark.authorization.principalbased;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
+import 
org.apache.jackrabbit.api.security.authorization.PrincipalAccessControlList;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import 
org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.benchmark.ReadDeepTreeTest;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.composite.MountInfoProviderService;
+import org.apache.jackrabbit.oak.fixture.OakRepositoryFixture;
+import org.apache.jackrabbit.oak.fixture.RepositoryFixture;
+import org.apache.jackrabbit.oak.jcr.Jcr;
+import 
org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration;
+import org.apache.jackrabbit.oak.security.internal.SecurityProviderBuilder;
+import org.apache.jackrabbit.oak.security.internal.SecurityProviderHelper;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.FilterProviderImpl;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.PrincipalBasedAuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.sling.testing.mock.osgi.context.OsgiContextImpl;
+import org.jetbrains.annotations.NotNull;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.security.Privilege;
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.jcr.security.Privilege.JCR_ALL;
+
+public class PrinicipalBasedReadTest extends ReadDeepTreeTest {
+
+    private final int numberOfACEs;
+
+    private final int subjectSize;
+    private Subject subject;
+
+    private final boolean entriesForEachPrincipal;
+
+    private final boolean testDefault;
+    private final String compositionType;
+    private final boolean useAggregationFilter;
+
+    private List<String> nodePaths = new ArrayList<>();
+
+    public PrinicipalBasedReadTest(int itemsToRead, int numberOfACEs, int 
subjectSize, boolean entriesForEachPrincipal, boolean testDefault, @NotNull 
String compositionType, boolean useAggregationFilter, boolean doReport) {
+        super(false, itemsToRead, doReport, false);
+
+        this.numberOfACEs = numberOfACEs;
+        this.subjectSize = subjectSize;
+        this.entriesForEachPrincipal = entriesForEachPrincipal;
+        this.testDefault = testDefault;
+        this.compositionType = compositionType;
+        this.useAggregationFilter = useAggregationFilter;
+    }
+
+    @Override
+    protected void beforeSuite() throws Exception {
+        super.beforeSuite();
+
+        // populate subject
+        subject = new Subject();
+        UserManager userManager = ((JackrabbitSession) 
adminSession).getUserManager();
+        for (int i = 0; i < subjectSize; i++) {
+            User user = userManager.createSystemUser("system_" +i, null);
+            subject.getPrincipals().add(user.getPrincipal());
+        }
+        adminSession.save();
+
+        JackrabbitAccessControlManager acMgr = 
(JackrabbitAccessControlManager) adminSession.getAccessControlManager();
+
+        // grant read at the root
+        Principal principal = subject.getPrincipals().iterator().next();
+        Privilege[] readPrivs = AccessControlUtils.privilegesFromNames(acMgr, 
Privilege.JCR_READ);
+        addEntry(acMgr, principal, PathUtils.ROOT_PATH, readPrivs, 
testDefault);
+        // for AND-composite-evaluation with principal-based: also need to 
grant on default model (see repository setup below)
+        if (!testDefault && 
CompositeAuthorizationConfiguration.CompositionType.AND == 
CompositeAuthorizationConfiguration.CompositionType.valueOf(compositionType)) {
+            addEntry(acMgr, principal, PathUtils.ROOT_PATH, readPrivs, true);
+        }
+
+        // create additional ACEs according to benchmark configuration
+        List<Privilege> allPrivileges = 
Lists.newArrayList(acMgr.privilegeFromName(JCR_ALL).getAggregatePrivileges());
+        if (!entriesForEachPrincipal) {
+            createForRotatingPrincipal(acMgr, allPrivileges);
+        } else {
+            createForEachPrincipal(acMgr, allPrivileges);
+        }
+
+        adminSession.save();
+    }
+
+    @Override
+    protected void visitingNode(Node node, int i) throws RepositoryException {
+        super.visitingNode(node, i);
+        String path = node.getPath();
+        if (!path.contains(AccessControlConstants.REP_POLICY)) {
+            nodePaths.add(path);
+        }
+    }
+
+    private void createForRotatingPrincipal(@NotNull 
JackrabbitAccessControlManager acMgr, @NotNull List<Privilege> allPrivileges) 
throws RepositoryException {
+        Iterator<Principal> principalIterator = 
Iterators.cycle(subject.getPrincipals());
+        int cnt = 0;
+        while (cnt < numberOfACEs) {
+            if (!principalIterator.hasNext()) {
+                throw new IllegalStateException("Cannot setup ACE. no 
principals available.");
+            }
+            if (addEntry(acMgr, principalIterator.next(), 
getRandom(nodePaths), getRandomPrivileges(allPrivileges), testDefault)) {
+                cnt++;
+            }
+        }
+    }
+
+    private void createForEachPrincipal(@NotNull 
JackrabbitAccessControlManager acMgr, @NotNull List<Privilege> allPrivileges) 
throws RepositoryException {
+        for (Principal principal : subject.getPrincipals()) {
+            int cnt = 0;
+            while (cnt < numberOfACEs) {
+                if (addEntry(acMgr, principal, getRandom(nodePaths), 
getRandomPrivileges(allPrivileges), testDefault)) {
+                    cnt++;
+                }
+            }
+        }
+    }
+
+    @NotNull
+    static String getRandom(@NotNull List<String> paths) {
+        int index = (int) Math.floor(paths.size() * Math.random());
+        return paths.get(index);
+    }
+
+    @NotNull
+    private static Privilege[] getRandomPrivileges(@NotNull List<Privilege> 
allPrivileges) {
+        Collections.shuffle(allPrivileges);
+        return allPrivileges.subList(0, 3).toArray(new Privilege[0]);
+    }
+
+    private static boolean addEntry(@NotNull JackrabbitAccessControlManager 
acMgr, @NotNull Principal principal, @NotNull String path, @NotNull Privilege[] 
privileges, boolean useDefault) throws RepositoryException {
+        boolean added = false;
+        JackrabbitAccessControlList acl = null;
+        if (useDefault) {
+            acl = AccessControlUtils.getAccessControlList(acMgr, path);
+            if (acl == null) {
+                throw new IllegalStateException("No policy to setup ACE.");
+            }
+            added = acl.addAccessControlEntry(principal, privileges);
+        } else {
+            for (JackrabbitAccessControlPolicy policy : 
Iterables.concat(ImmutableList.copyOf(acMgr.getApplicablePolicies(principal)), 
ImmutableList.copyOf(acMgr.getPolicies(principal)))) {
+                if (policy instanceof PrincipalAccessControlList) {
+                    acl = (PrincipalAccessControlList) policy;
+                    break;
+                }
+            }
+            if (acl == null) {
+                throw new IllegalStateException("No principal policy to setup 
ACE.");
+            }
+            added = ((PrincipalAccessControlList) acl).addEntry(path, 
privileges);
+        }
+        if (added) {
+            acMgr.setPolicy(acl.getPath(), acl);
+        }
+        return added;
+    }
+
+    @Override
+    protected void afterSuite() throws Exception {
+        try {
+            UserManager userManager = ((JackrabbitSession) 
adminSession).getUserManager();
+            for (Principal p : subject.getPrincipals()) {
+                Authorizable a = userManager.getAuthorizable(p);
+                if (a != null) {
+                    a.remove();
+                }
+            }
+            adminSession.save();
+        }  finally  {
+            super.afterSuite();
+        }
+    }
+
+    @NotNull
+    @Override
+    protected Session getTestSession() {
+        return loginSubject(subject);
+    }
+
+    @NotNull
+    @Override
+    protected Repository[] createRepository(RepositoryFixture fixture) throws 
Exception {
+        if (fixture instanceof OakRepositoryFixture) {
+            return ((OakRepositoryFixture) fixture).setUpCluster(1, oak -> new 
Jcr(oak).with(createSecurityProvider()));
+        } else {
+            throw new IllegalArgumentException("Fixture " + fixture + " not 
supported for this benchmark.");
+        }
+    }
+
+    @NotNull
+    @Override
+    protected String getImportFileName() {
+        return "deepTree.xml";
+    }
+
+    @NotNull
+    @Override
+    protected String getTestNodeName() {
+        return "PrinicipalBasedReadTest";
+    }
+
+    private SecurityProvider createSecurityProvider() {
+        SecurityProvider delegate = 
SecurityProviderBuilder.newBuilder().build();
+        CompositeAuthorizationConfiguration authorizationConfiguration = 
(CompositeAuthorizationConfiguration) delegate
+                .getConfiguration((AuthorizationConfiguration.class));
+        authorizationConfiguration.withCompositionType(compositionType);
+        AuthorizationConfiguration defaultAuthorization = 
checkNotNull(authorizationConfiguration.getDefaultConfig());
+        if (testDefault) {
+            authorizationConfiguration.addConfiguration(defaultAuthorization);
+        } else {
+            PrincipalBasedAuthorizationConfiguration pbConfiguration = new 
PrincipalBasedAuthorizationConfiguration();
+            // NOTE: this sets up a ANDing-composite with prinipal-based and 
default
+            //       if 'stop-evaluation' is configured the latter will be 
called for principal-based evaluation
+            SecurityProviderHelper.updateConfig(delegate, pbConfiguration, 
AuthorizationConfiguration.class);
+
+            OsgiContextImpl context = new OsgiContextImpl();
+            // register the filter provider to get it's activate method invoked
+            Map<String, Object> props = ImmutableMap.of("path", 
PathUtils.concat(UserConstants.DEFAULT_USER_PATH, 
UserConstants.DEFAULT_SYSTEM_RELATIVE_PATH));
+            context.registerInjectActivateService(new FilterProviderImpl(), 
props);
+
+            // register mountinfo-provider
+            context.registerInjectActivateService(new 
MountInfoProviderService());
+
+            if (useAggregationFilter) {
+                // TODO: register 'AggregationFilter' if 'stop-evaluation' 
option is set
+            }
+
+            // register the authorization configuration to have filterprovider 
bound to it.
+            context.registerInjectActivateService(pbConfiguration);
+        }
+        return delegate;
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/principalbased/PrinicipalBasedReadTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to