diff --git a/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/FileCache.java b/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/FileCache.java
index 84f28d1317e..09149c66525 100644
--- a/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/FileCache.java
+++ b/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/FileCache.java
@@ -176,6 +176,9 @@ public static FileCache build(long maxSize /* bytes */, File root,
return new FileCache(maxSize, root, loader, executor);
}
return new FileCache() {
+
+ private final Cache,?> cache = new CacheLIRS<>(0);
+
@Override public void put(String key, File file) {
}
@@ -195,7 +198,7 @@ public static FileCache build(long maxSize /* bytes */, File root,
}
@Override public DataStoreCacheStatsMBean getStats() {
- return new FileCacheStats(this, weigher, memWeigher, 0);
+ return new FileCacheStats(cache, weigher, memWeigher, 0);
}
@Override public void close() {
diff --git a/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/FileCacheTest.java b/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/FileCacheTest.java
index a94eddc79cc..d23834d1bb8 100644
--- a/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/FileCacheTest.java
+++ b/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/FileCacheTest.java
@@ -108,6 +108,19 @@ public void zeroCache() throws Exception {
assertNull(cache.getIfPresent(ID_PREFIX + 0));
assertNull(cache.get(ID_PREFIX + 0));
assertEquals(0, cache.getStats().getMaxTotalWeight());
+ assertEquals(0, cache.getStats().getElementCount());
+ assertEquals(0, cache.getStats().getEvictionCount());
+ assertEquals(0, cache.getStats().getTotalLoadTime());
+ assertEquals(0, cache.getStats().getLoadSuccessCount());
+ assertEquals(0.0, cache.getStats().getMissRate(), 0.0);
+ assertEquals(0, cache.getStats().getMissCount());
+ assertEquals(0, cache.getStats().getHitCount());
+ assertEquals(1.0, cache.getStats().getHitRate(), 0.0);
+ assertEquals(0.0, cache.getStats().getAverageLoadPenalty(), 0.0);
+ assertEquals(0, cache.getStats().getLoadCount());
+ assertEquals(0, cache.getStats().getLoadExceptionCount());
+ assertEquals(0.0, cache.getStats().getLoadExceptionRate(), 0.0);
+ assertEquals(0, cache.getStats().getRequestCount());
cache.invalidate(ID_PREFIX + 0);
assertFalse(cache.containsKey(ID_PREFIX + 0));
cache.close();
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImpl.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImpl.java
index 5f47a95997c..adc30fbcccd 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImpl.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImpl.java
@@ -16,11 +16,6 @@
*/
package org.apache.jackrabbit.oak.security.authentication.token;
-import java.security.Principal;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -29,6 +24,7 @@
import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
import org.apache.jackrabbit.oak.spi.security.ConfigurationBase;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.Context;
import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.authentication.credentials.CompositeCredentialsSupport;
@@ -48,6 +44,12 @@
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
import static org.apache.jackrabbit.oak.spi.security.RegistrationConstants.OAK_SECURITY_NAME;
/**
@@ -148,6 +150,11 @@ public List extends ValidatorProvider> getValidators(@NotNull String workspace
return ImmutableList.of(vp);
}
+ @Override
+ public @NotNull Context getContext() {
+ return TokenContext.getInstance();
+ }
+
//-------------------------------------------------< TokenConfiguration >---
/**
* Returns a new instance of {@link org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider}.
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenContext.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenContext.java
new file mode 100644
index 00000000000..4c1f76c8691
--- /dev/null
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenContext.java
@@ -0,0 +1,74 @@
+/*
+ * 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.security.authentication.token;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConstants;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConstants.TOKEN_NT_NAME;
+
+final class TokenContext implements Context {
+
+ private static final Context INSTANCE = new TokenContext();
+
+ private TokenContext() {}
+
+ static Context getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public boolean definesProperty(@NotNull Tree parent, @NotNull PropertyState property) {
+ return isTokenNode(parent);
+ }
+
+ @Override
+ public boolean definesContextRoot(@NotNull Tree tree) {
+ return TokenConstants.TOKENS_NODE_NAME.equals(tree.getName());
+ }
+
+ @Override
+ public boolean definesTree(@NotNull Tree tree) {
+ return definesContextRoot(tree) || isTokenNode(tree);
+ }
+
+ @Override
+ public boolean definesLocation(@NotNull TreeLocation location) {
+ PropertyState ps = location.getProperty();
+ TreeLocation l = (ps != null) ? location.getParent() : location;
+ Tree t = l.getTree();
+ if (t == null) {
+ return false;
+ } else {
+ return (ps == null) ? definesTree(t) : definesProperty(t, ps);
+ }
+ }
+
+ @Override
+ public boolean definesInternal(@NotNull Tree tree) {
+ return false;
+ }
+
+ private static boolean isTokenNode(@NotNull Tree tree) {
+ return TOKEN_NT_NAME.equals(TreeUtil.getPrimaryTypeName(tree));
+ }
+}
\ No newline at end of file
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java
index 20fe4643623..73ef193aae2 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java
@@ -38,7 +38,6 @@
import org.jetbrains.annotations.Nullable;
import java.util.List;
-import java.util.Set;
import java.util.function.Function;
/**
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProviderOr.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProviderOr.java
index e31819e6be7..ff69a4d51df 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProviderOr.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProviderOr.java
@@ -117,7 +117,7 @@ public boolean isGranted(@NotNull Tree parent, @Nullable PropertyState property,
for (AggregatedPermissionProvider aggregatedPermissionProvider : getPermissionProviders()) {
long supportedPermissions = aggregatedPermissionProvider.supportedPermissions(immParent, property, permissions);
if (Util.doEvaluate(supportedPermissions)) {
- for (long p : Permissions.aggregates(permissions)) {
+ for (long p : Permissions.aggregates(supportedPermissions)) {
if (aggregatedPermissionProvider.isGranted(immParent, property, p)) {
coveredPermissions |= p;
isGranted = true;
@@ -144,7 +144,7 @@ public boolean isGranted(@NotNull TreeLocation location, long permissions) {
for (AggregatedPermissionProvider aggregatedPermissionProvider : getPermissionProviders()) {
long supportedPermissions = aggregatedPermissionProvider.supportedPermissions(location, permissions);
if (Util.doEvaluate(supportedPermissions)) {
- for (long p : Permissions.aggregates(permissions)) {
+ for (long p : Permissions.aggregates(supportedPermissions)) {
if (aggregatedPermissionProvider.isGranted(location, p)) {
coveredPermissions |= p;
isGranted = true;
@@ -171,7 +171,7 @@ public boolean isGranted(long repositoryPermissions) {
long supportedPermissions = aggregatedPermissionProvider.supportedPermissions((Tree) null, null, repositoryPermissions);
if (Util.doEvaluate(supportedPermissions)) {
RepositoryPermission rp = aggregatedPermissionProvider.getRepositoryPermission();
- for (long p : Permissions.aggregates(repositoryPermissions)) {
+ for (long p : Permissions.aggregates(supportedPermissions)) {
if (rp.isGranted(p)) {
coveredPermissions |= p;
isGranted = true;
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImplTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImplTest.java
index 44d07b17c70..c08f5ab8862 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImplTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenConfigurationImplTest.java
@@ -22,6 +22,7 @@
import org.apache.jackrabbit.oak.spi.commit.MoveTracker;
import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.Context;
import org.apache.jackrabbit.oak.spi.security.authentication.credentials.CredentialsSupport;
import org.apache.jackrabbit.oak.spi.security.authentication.credentials.SimpleCredentialsSupport;
import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration;
@@ -30,7 +31,6 @@
import javax.jcr.Credentials;
import javax.jcr.SimpleCredentials;
-import java.security.Principal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -160,6 +160,11 @@ public void testBindMultipleCredentialsSupport() {
verify(cs, times(4)).getCredentialClasses();
verify(cs, times(2)).getAttributes(creds);
-
+ }
+
+ @Test
+ public void testGetContext() {
+ Context ctx = tc.getContext();
+ assertTrue(ctx instanceof TokenContext);
}
}
\ No newline at end of file
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenContextTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenContextTest.java
new file mode 100644
index 00000000000..f963a84d16d
--- /dev/null
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenContextTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.security.authentication.token;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConstants;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConstants.TOKENS_NODE_NAME;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class TokenContextTest {
+
+ private final Context ctx = TokenContext.getInstance();
+
+ @Test
+ public void testDefinesProperty() {
+ PropertyState ps = mock(PropertyState.class);
+ Tree t = when(mock(Tree.class).getName()).thenReturn(TOKENS_NODE_NAME).getMock();
+
+ assertFalse(ctx.definesProperty(t, ps));
+
+ when(t.getName()).thenReturn("anyName");
+ PropertyState primaryType = PropertyStates.createProperty(JCR_PRIMARYTYPE, TokenConstants.TOKEN_NT_NAME, Type.NAME);
+ when(t.getProperty(JCR_PRIMARYTYPE)).thenReturn(primaryType);
+
+ assertTrue(ctx.definesProperty(t, ps));
+
+ PropertyState primaryType2 = PropertyStates.createProperty(JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED, Type.NAME);
+ when(t.getProperty(JCR_PRIMARYTYPE)).thenReturn(primaryType2);
+
+ assertFalse(ctx.definesProperty(t, primaryType2));
+
+ verifyNoInteractions(ps);
+ verify(t, never()).getName();
+ verify(t, times(3)).getProperty(JCR_PRIMARYTYPE);
+ verifyNoMoreInteractions(t);
+ }
+
+ @Test
+ public void testDefinesContextRoot() {
+ Tree t = when(mock(Tree.class).getName()).thenReturn(TOKENS_NODE_NAME).getMock();
+ assertTrue(ctx.definesContextRoot(t));
+
+ when(t.getName()).thenReturn("anyName", TokenConstants.TOKEN_ATTRIBUTE, TokenConstants.TOKEN_ATTRIBUTE_KEY);
+ assertFalse(ctx.definesContextRoot(t));
+ assertFalse(ctx.definesContextRoot(t));
+ assertFalse(ctx.definesContextRoot(t));
+
+ verify(t, times(4)).getName();
+ verifyNoMoreInteractions(t);
+ }
+
+ @Test
+ public void testDefinesTree() {
+ Tree t = when(mock(Tree.class).getName()).thenReturn(TOKENS_NODE_NAME).getMock();
+ assertTrue(ctx.definesTree(t));
+
+ when(t.getName()).thenReturn("anyName");
+ PropertyState ps = PropertyStates.createProperty(JCR_PRIMARYTYPE, TokenConstants.TOKEN_NT_NAME, Type.NAME);
+ when(t.getProperty(JCR_PRIMARYTYPE)).thenReturn(ps);
+
+ assertTrue(ctx.definesTree(t));
+
+ PropertyState ps2 = PropertyStates.createProperty(JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED, Type.NAME);
+ when(t.getProperty(JCR_PRIMARYTYPE)).thenReturn(ps2);
+
+ assertFalse(ctx.definesTree(t));
+
+ verify(t, times(3)).getName();
+ verify(t, times(2)).getProperty(anyString());
+
+ verifyNoMoreInteractions(t);
+ }
+
+ @Test
+ public void testDefinesLocation() {
+ PropertyState ps = mock(PropertyState.class);
+
+ TreeLocation tl = mock(TreeLocation.class);
+ when(tl.getName()).thenReturn(TOKENS_NODE_NAME);
+
+ assertFalse(ctx.definesLocation(tl));
+ verifyTL(tl, false);
+
+ when(tl.getName()).thenReturn("any");
+
+ assertFalse(ctx.definesLocation(tl));
+ verifyTL(tl, false);
+
+ Tree t = when(mock(Tree.class).getName()).thenReturn(TOKENS_NODE_NAME).getMock();
+ when(tl.getTree()).thenReturn(t);
+
+ assertTrue(ctx.definesLocation(tl));
+ verifyTL(tl, false);
+ verify(t).getName();
+ verifyNoMoreInteractions(t);
+ reset(t);
+
+ when(t.getName()).thenReturn("any").getMock();
+ PropertyState primary = PropertyStates.createProperty(JCR_PRIMARYTYPE, TokenConstants.TOKEN_NT_NAME, Type.NAME);
+ when(t.getProperty(JCR_PRIMARYTYPE)).thenReturn(primary);
+ when(tl.getTree()).thenReturn(t);
+
+ assertTrue(ctx.definesLocation(tl));
+ verifyTL(tl, false);
+ verify(t).getName();
+ verify(t).getProperty(JCR_PRIMARYTYPE);
+ verifyNoMoreInteractions(t);
+
+ when(tl.getProperty()).thenReturn(ps);
+ when(tl.getTree()).thenReturn(t);
+ when(tl.getParent()).thenReturn(tl);
+
+ assertTrue(ctx.definesLocation(tl));
+ verifyTL(tl, true);
+
+ PropertyState primary2 = PropertyStates.createProperty(JCR_PRIMARYTYPE, NodeTypeConstants.NT_OAK_UNSTRUCTURED, Type.NAME);
+ when(t.getProperty(JCR_PRIMARYTYPE)).thenReturn(primary2);
+
+ when(tl.getProperty()).thenReturn(ps);
+ when(tl.getTree()).thenReturn(t);
+ when(tl.getParent()).thenReturn(tl);
+
+ assertFalse(ctx.definesLocation(tl));
+ verifyTL(tl, true);
+
+ verifyNoInteractions(ps);
+ }
+
+ private static void verifyTL(@NotNull TreeLocation tl, boolean isProperty) {
+ verify(tl).getProperty();
+ verify(tl).getTree();
+ if (isProperty) {
+ verify(tl).getParent();
+ }
+ verifyNoMoreInteractions(tl);
+ reset(tl);
+ }
+
+ @Test
+ public void testDefinesInternal() {
+ Tree t = when(mock(Tree.class).getName()).thenReturn(TOKENS_NODE_NAME).getMock();
+ assertFalse(ctx.definesInternal(t));
+
+ when(t.getName()).thenReturn("anyName");
+ assertFalse(ctx.definesInternal(t));
+
+ verifyNoInteractions(t);
+ }
+}
\ No newline at end of file
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java
index 980100b2f5e..10def7d131d 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java
@@ -101,16 +101,7 @@ public abstract class AbstractCompositeProviderTest extends AbstractSecurityTest
public void before() throws Exception {
super.before();
- Tree rootNode = root.getTree("/");
-
- Tree test = TreeUtil.addChild(rootNode, "test", NT_OAK_UNSTRUCTURED);
- TreeUtil.addChild(test, "child", NT_OAK_UNSTRUCTURED);
- Tree a = TreeUtil.addChild(test, "a", NT_OAK_UNSTRUCTURED);
- TreeUtil.addChild(a, "b2", NT_OAK_UNSTRUCTURED);
- Tree b = TreeUtil.addChild(a, "b", NT_OAK_UNSTRUCTURED);
- TreeUtil.addChild(b, "c", NT_OAK_UNSTRUCTURED);
-
- TreeUtil.addChild(rootNode, "test2", NT_OAK_UNSTRUCTURED);
+ setupTestContent(root);
AccessControlManager acMgr = getAccessControlManager(root);
Principal everyone = EveryonePrincipal.getInstance();
@@ -156,8 +147,8 @@ public void before() throws Exception {
Permissions.VERSION_MANAGEMENT).
build();
defPrivileges = ImmutableMap.>builder().
- put(ROOT_PATH, ImmutableSet.of()).
- put(TEST_PATH_2, ImmutableSet.of()).
+ put(ROOT_PATH, ImmutableSet.of()).
+ put(TEST_PATH_2, ImmutableSet.of()).
put(TEST_PATH, ImmutableSet.of(JCR_READ)).
put(TEST_CHILD_PATH, ImmutableSet.of(JCR_READ, JCR_READ_ACCESS_CONTROL)).
put(TEST_A_PATH, ImmutableSet.of(JCR_READ, JCR_WRITE, JCR_VERSION_MANAGEMENT)).
@@ -193,6 +184,20 @@ public void after() throws Exception {
super.after();
}
}
+
+ static void setupTestContent(@NotNull Root root) throws Exception {
+ Tree rootNode = root.getTree("/");
+
+ Tree test = TreeUtil.addChild(rootNode, "test", NT_OAK_UNSTRUCTURED);
+ TreeUtil.addChild(test, "child", NT_OAK_UNSTRUCTURED);
+ Tree a = TreeUtil.addChild(test, "a", NT_OAK_UNSTRUCTURED);
+ TreeUtil.addChild(a, "b2", NT_OAK_UNSTRUCTURED);
+ Tree b = TreeUtil.addChild(a, "b", NT_OAK_UNSTRUCTURED);
+ TreeUtil.addChild(b, "c", NT_OAK_UNSTRUCTURED);
+
+ TreeUtil.addChild(rootNode, "test2", NT_OAK_UNSTRUCTURED);
+ root.commit();
+ }
private static void allow(@NotNull AccessControlManager acMgr,
@NotNull Principal principal,
@@ -267,13 +272,13 @@ CompositePermissionProvider createPermissionProviderOR(Set principals
}
@Test
- public void testRefresh() throws Exception {
+ public void testRefresh() {
createPermissionProvider().refresh();
createPermissionProviderOR().refresh();
}
@Test
- public void testHasPrivilegesJcrAll() throws Exception {
+ public void testHasPrivilegesJcrAll() {
PermissionProvider pp = createPermissionProvider();
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
@@ -291,7 +296,7 @@ public void testHasPrivilegesJcrAllOR() throws Exception {
}
@Test
- public void testHasPrivilegesNone() throws Exception {
+ public void testHasPrivilegesNone() {
PermissionProvider pp = createPermissionProvider();
PermissionProvider ppo = createPermissionProviderOR();
for (String p : NODE_PATHS) {
@@ -310,7 +315,7 @@ public void testHasPrivilegesOnRepoJcrAll() throws Exception {
}
@Test
- public void testHasPrivilegesOnRepoNone() throws Exception {
+ public void testHasPrivilegesOnRepoNone() {
PermissionProvider pp = createPermissionProvider();
assertTrue(pp.hasPrivileges(null));
PermissionProvider ppo = createPermissionProviderOR();
@@ -334,7 +339,7 @@ public void testIsGrantedAll() throws Exception {
}
@Test
- public void testIsGrantedNone() throws Exception {
+ public void testIsGrantedNone() {
PermissionProvider pp = createPermissionProvider();
PermissionProvider ppo = createPermissionProviderOR();
@@ -366,7 +371,7 @@ public void testIsNotGranted() throws Exception {
}
@Test
- public void testIsGrantedActionNone() throws Exception {
+ public void testIsGrantedActionNone() {
PermissionProvider pp = createPermissionProvider();
PermissionProvider ppo = createPermissionProviderOR();
String actions = "";
@@ -407,7 +412,7 @@ public void testIsNotGrantedAction() throws Exception {
}
@Test
- public void testGetTreePermissionAllParent() throws Exception {
+ public void testGetTreePermissionAllParent() {
TreePermission tp = createPermissionProvider().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.ALL);
assertSame(TreePermission.ALL, tp);
TreePermission tpo = createPermissionProviderOR().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.ALL);
@@ -415,7 +420,7 @@ public void testGetTreePermissionAllParent() throws Exception {
}
@Test
- public void testGetTreePermissionEmptyParent() throws Exception {
+ public void testGetTreePermissionEmptyParent() {
TreePermission tp = createPermissionProvider().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.EMPTY);
assertSame(TreePermission.EMPTY, tp);
TreePermission tpo = createPermissionProviderOR().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.EMPTY);
@@ -423,7 +428,7 @@ public void testGetTreePermissionEmptyParent() throws Exception {
}
@Test
- public void testTreePermissionIsGrantedAll() throws Exception {
+ public void testTreePermissionIsGrantedAll() {
PermissionProvider pp = createPermissionProvider();
TreePermission parentPermission = TreePermission.EMPTY;
@@ -459,7 +464,7 @@ public void testTreePermissionIsGrantedAllOR() throws Exception {
}
@Test
- public void testTreePermissionIsNotGranted() throws Exception {
+ public void testTreePermissionIsNotGranted() {
PermissionProvider pp = createPermissionProvider();
TreePermission parentPermission = TreePermission.EMPTY;
@@ -499,7 +504,7 @@ public void testTreePermissionIsNotGrantedOR() throws Exception {
}
@Test
- public void testTreePermissionCanReadAll() throws Exception {
+ public void testTreePermissionCanReadAll() {
PermissionProvider pp = createPermissionProvider();
TreePermission parentPermission = TreePermission.EMPTY;
PermissionProvider ppO = createPermissionProviderOR();
@@ -517,7 +522,7 @@ public void testTreePermissionCanReadAll() throws Exception {
}
@Test
- public void testTreePermissionCanReadProperties() throws Exception {
+ public void testTreePermissionCanReadProperties() {
PermissionProvider pp = createPermissionProvider();
TreePermission parentPermission = TreePermission.EMPTY;
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProviderOrTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProviderOrTest.java
new file mode 100644
index 00000000000..e8350006a69
--- /dev/null
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProviderOrTest.java
@@ -0,0 +1,266 @@
+/*
+ * 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.security.authorization.composite;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.plugins.tree.TreeType;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.util.Text;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_PATH;
+import static org.apache.jackrabbit.oak.security.authorization.composite.AbstractCompositeProviderTest.TEST_A_B_C_PATH;
+import static org.apache.jackrabbit.oak.security.authorization.composite.AbstractCompositeProviderTest.TEST_A_PATH;
+import static org.apache.jackrabbit.oak.security.authorization.composite.AbstractCompositeProviderTest.TEST_CHILD_PATH;
+import static org.apache.jackrabbit.oak.security.authorization.composite.AbstractCompositeProviderTest.TEST_PATH;
+import static org.apache.jackrabbit.oak.security.authorization.composite.AbstractCompositeProviderTest.TEST_PATH_2;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.ADD_NODE;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.ALL;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.MODIFY_ACCESS_CONTROL;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.NODE_TYPE_DEFINITION_MANAGEMENT;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.NO_PERMISSION;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.READ;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.READ_NODE;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.SET_PROPERTY;
+import static org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.WORKSPACE_MANAGEMENT;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for OAK-9798
+ *
+ * @see CompositeTreePermissionOrTest#testIsGrantedUncoveredPermissions() for a similar test covering the behavior of {@code CompositeTreePermissionOr}.
+ */
+@RunWith(Parameterized.class)
+public class CompositePermissionProviderOrTest extends AbstractSecurityTest {
+
+ private final boolean extraVerification;
+
+ private CompositePermissionProvider pp;
+ private Root readOnlyRoot;
+
+ @Parameterized.Parameters(name = "name={1}")
+ public static Collection
- ]]>
+ ]]>
-
+ https://github.com/apache/jackrabbit-oak/edit/trunk/oak-doc
org.apache.maven.skins
maven-fluido-skin
- 1.6
+ 1.11.0
@@ -207,11 +192,16 @@ under the License.
apache/jackrabbit-oak
right
-
- jackrabbit-oak
- thin-badge
-
-
+
+
+ 4
+ https://analytics.apache.org
+
+
+
+
+
+
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionImpl.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionImpl.java
index 52d96d9c0bc..72b783cfbf4 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionImpl.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionImpl.java
@@ -16,10 +16,10 @@
*/
package org.apache.jackrabbit.oak.jcr.session;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Sets.newTreeSet;
import static org.apache.jackrabbit.api.stats.RepositoryStatistics.Type.SESSION_COUNT;
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
+import static java.util.Objects.requireNonNull;
import java.io.IOException;
import java.io.InputStream;
@@ -147,8 +147,7 @@ private void checkAlive() throws RepositoryException {
}
@NotNull
- private String getOakPathOrThrow(@NotNull String absPath)
- throws RepositoryException {
+ private String getOakPathOrThrow(@NotNull String absPath) throws RepositoryException {
String p = sessionContext.getOakPathOrThrow(absPath);
if (!PathUtils.isAbsolute(p)) {
throw new RepositoryException("Not an absolute path: " + absPath);
@@ -157,14 +156,12 @@ private String getOakPathOrThrow(@NotNull String absPath)
}
@NotNull
- private String getOakPathOrThrowNotFound(@NotNull String absPath)
- throws PathNotFoundException {
+ private String getOakPathOrThrowNotFound(@NotNull String absPath) throws PathNotFoundException {
return sessionContext.getOakPathOrThrowNotFound(absPath);
}
@Nullable
- private ItemImpl> getItemInternal(@NotNull String oakPath)
- throws RepositoryException {
+ private ItemImpl> getItemInternal(@NotNull String oakPath) throws RepositoryException {
checkAlive();
ItemDelegate item = sd.getItem(oakPath);
if (item instanceof NodeDelegate) {
@@ -179,7 +176,7 @@ private ItemImpl> getItemInternal(@NotNull String oakPath)
@Override
@Nullable
public Node getNodeOrNull(final String absPath) throws RepositoryException {
- checkNotNull(absPath);
+ requireNonNull(absPath, "parameter 'absPath' must not be null");
checkAlive();
return sd.performNullable(new ReadOperation("getNodeOrNull") {
@Override
@@ -197,7 +194,7 @@ public Node performNullable() throws RepositoryException {
@Nullable
public Property getPropertyOrNull(final String absPath) throws RepositoryException {
checkAlive();
- if (checkNotNull(absPath).equals("/")) {
+ if (requireNonNull(absPath, "parameter 'absPath' must not be null").equals("/")) {
return null;
} else {
final String oakPath;
@@ -223,7 +220,7 @@ public Property performNullable() {
@Override
@Nullable
public Item getItemOrNull(final String absPath) throws RepositoryException {
- checkNotNull(absPath);
+ requireNonNull(absPath, "parameter 'absPath' must not be null");
checkAlive();
return sd.performNullable(new ReadOperation- ("getItemOrNull") {
@Override
@@ -246,23 +243,25 @@ public Node performNullable() throws RepositoryException {
}
});
}
-
- private static void checkContext(@NotNull ItemImpl item, @NotNull SessionContext context) throws RepositoryException {
+
+ private static void checkContext(@NotNull ItemImpl item, @NotNull SessionContext context)
+ throws RepositoryException {
if (item.sessionContext != context) {
throw new RepositoryException("Item '" + item + "' has been obtained through a different Session.");
}
}
-
+
@NotNull
private static ItemImpl checkItemImpl(@NotNull Item item) throws RepositoryException {
if (item instanceof ItemImpl) {
return (ItemImpl) item;
} else {
- throw new RepositoryException("Invalid item implementation '" + item.getClass().getName() + "'. Expected " + ItemImpl.class.getName());
+ throw new RepositoryException("Invalid item implementation '" + item.getClass().getName() + "'. Expected "
+ + ItemImpl.class.getName());
}
}
- //------------------------------------------------------------< Session >---
+ // ------------------------------------------------------------< Session >---
@Override
@NotNull
@@ -295,7 +294,8 @@ public Object getAttribute(String name) {
return attribute;
}
- @Override @NotNull
+ @Override
+ @NotNull
public Workspace getWorkspace() {
return sessionContext.getWorkspace();
}
@@ -306,7 +306,7 @@ public Session impersonate(Credentials credentials) throws RepositoryException {
checkAlive();
ImpersonationCredentials impCreds = new ImpersonationCredentials(
- checkNotNull(credentials), sd.getAuthInfo());
+ requireNonNull(credentials, "parameter 'credentials' must not be null"), sd.getAuthInfo());
return getRepository().login(impCreds, sd.getWorkspaceName());
}
@@ -336,7 +336,7 @@ public Node perform() throws RepositoryException {
@Override
public Node getNode(String absPath) throws RepositoryException {
- Node node = getNodeOrNull(checkNotNull(absPath));
+ Node node = getNodeOrNull(requireNonNull(absPath, "parameter 'absPath' must not be null"));
if (node == null) {
throw new PathNotFoundException("Node with path " + absPath + " does not exist.");
}
@@ -345,7 +345,7 @@ public Node getNode(String absPath) throws RepositoryException {
@Override
public boolean nodeExists(String absPath) throws RepositoryException {
- return getNodeOrNull(checkNotNull(absPath)) != null;
+ return getNodeOrNull(requireNonNull(absPath, "parameter 'absPath' must not be null")) != null;
}
@NotNull
@@ -371,18 +371,18 @@ public Node perform() throws RepositoryException {
@Override
@NotNull
public Node getNodeByUUID(String uuid) throws RepositoryException {
- return getNodeById(checkNotNull(uuid));
+ return getNodeById(requireNonNull(uuid, "parameter 'uuid' must not be null"));
}
@Override
@NotNull
public Node getNodeByIdentifier(String id) throws RepositoryException {
- return getNodeById(checkNotNull(id));
+ return getNodeById(requireNonNull(id, "parameter 'id' must not be null"));
}
@Override
public Property getProperty(String absPath) throws RepositoryException {
- Property property = getPropertyOrNull(checkNotNull(absPath));
+ Property property = getPropertyOrNull(requireNonNull(absPath, "parameter 'absPath' must not be null"));
if (property == null) {
throw new PathNotFoundException(absPath);
}
@@ -391,12 +391,12 @@ public Property getProperty(String absPath) throws RepositoryException {
@Override
public boolean propertyExists(String absPath) throws RepositoryException {
- return getPropertyOrNull(checkNotNull(absPath)) != null;
+ return getPropertyOrNull(requireNonNull(absPath, "parameter 'absPath' must not be null")) != null;
}
@Override
public Item getItem(String absPath) throws RepositoryException {
- Item item = getItemOrNull(checkNotNull(absPath));
+ Item item = getItemOrNull(requireNonNull(absPath, "parameter 'absPath' must not be null"));
if (item == null) {
throw new PathNotFoundException(absPath);
}
@@ -405,14 +405,14 @@ public Item getItem(String absPath) throws RepositoryException {
@Override
public boolean itemExists(String absPath) throws RepositoryException {
- return getItemOrNull(checkNotNull(absPath)) != null;
+ return getItemOrNull(requireNonNull(absPath, "parameter 'absPath' must not be null")) != null;
}
@Override
public void move(String srcAbsPath, final String destAbsPath) throws RepositoryException {
checkAlive();
- checkIndexOnName(checkNotNull(destAbsPath));
- final String srcOakPath = getOakPathOrThrowNotFound(checkNotNull(srcAbsPath));
+ checkIndexOnName(requireNonNull(destAbsPath, "parameter 'destAbsPath' must not be null"));
+ final String srcOakPath = getOakPathOrThrowNotFound(requireNonNull(srcAbsPath, "parameter 'srcAbsPath' must not be null"));
final String destOakPath = getOakPathOrThrowNotFound(destAbsPath);
sd.performVoid(new WriteOperation("move") {
@Override
@@ -432,7 +432,7 @@ public void performVoid() throws RepositoryException {
@Override
public void removeItem(final String absPath) throws RepositoryException {
checkAlive();
- final String oakPath = getOakPathOrThrowNotFound(checkNotNull(absPath));
+ final String oakPath = getOakPathOrThrowNotFound(requireNonNull(absPath, "parameter 'absPath' must not be null"));
sd.performVoid(new WriteOperation("removeItem") {
@Override
public void performVoid() throws RepositoryException {
@@ -440,11 +440,9 @@ public void performVoid() throws RepositoryException {
if (item == null) {
throw new PathNotFoundException(absPath);
} else if (item.isProtected()) {
- throw new ConstraintViolationException(
- item.getPath() + " is protected");
+ throw new ConstraintViolationException(item.getPath() + " is protected");
} else if (!item.remove()) {
- throw new RepositoryException(
- item.getPath() + " could not be removed");
+ throw new RepositoryException(item.getPath() + " could not be removed");
}
}
});
@@ -523,9 +521,8 @@ public boolean isLogout() {
@Override
@NotNull
- public ContentHandler getImportContentHandler(String parentAbsPath,
- int uuidBehavior) throws RepositoryException {
- return new ImportHandler(checkNotNull(parentAbsPath), sessionContext,
+ public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws RepositoryException {
+ return new ImportHandler(requireNonNull(parentAbsPath, "parameter 'parentAbsPath' must not be null"), sessionContext,
uuidBehavior, false);
}
@@ -534,7 +531,7 @@ public void importXML(String parentAbsPath, InputStream in, int uuidBehavior)
throws IOException, RepositoryException {
try {
ContentHandler handler = getImportContentHandler(
- checkNotNull(parentAbsPath), uuidBehavior);
+ requireNonNull(parentAbsPath, "parameter 'parentAbsPath' must not be null"), uuidBehavior);
new ParsingContentHandler(handler).parse(in);
} catch (SAXException e) {
Throwable exception = e.getException();
@@ -564,8 +561,7 @@ public void importXML(String parentAbsPath, InputStream in, int uuidBehavior)
* @throws SAXException if the SAX event handler failed
* @throws RepositoryException if another error occurs
*/
- private synchronized void export(String path, Exporter exporter)
- throws SAXException, RepositoryException {
+ private synchronized void export(String path, Exporter exporter) throws SAXException, RepositoryException {
Item item = getItem(path);
if (item.isNode()) {
exporter.export((Node) item);
@@ -575,21 +571,19 @@ private synchronized void export(String path, Exporter exporter)
}
@Override
- public void exportSystemView(String absPath, ContentHandler contentHandler,
- boolean skipBinary, boolean noRecurse) throws SAXException,
- RepositoryException {
- export(checkNotNull(absPath), new SystemViewExporter(this,
- checkNotNull(contentHandler), !noRecurse, !skipBinary));
+ public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
+ throws SAXException, RepositoryException {
+ export(requireNonNull(absPath, "parameter 'absPath' must not be null"), new SystemViewExporter(this,
+ requireNonNull(contentHandler, "parameter 'contentHandler' must not be null"), !noRecurse, !skipBinary));
}
@Override
- public void exportSystemView(String absPath, OutputStream out,
- boolean skipBinary, boolean noRecurse) throws IOException,
- RepositoryException {
+ public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
+ throws IOException, RepositoryException {
try {
- ContentHandler handler = new ToXmlContentHandler(checkNotNull(out));
- export(checkNotNull(absPath), new SystemViewExporter(this, handler,
- !noRecurse, !skipBinary));
+ ContentHandler handler = new ToXmlContentHandler(requireNonNull(out, "parameter 'out' must not be null"));
+ export(requireNonNull(absPath, "parameter 'absPath' must not be null"),
+ new SystemViewExporter(this, handler, !noRecurse, !skipBinary));
} catch (SAXException e) {
Exception exception = e.getException();
if (exception instanceof RepositoryException) {
@@ -597,28 +591,25 @@ public void exportSystemView(String absPath, OutputStream out,
} else if (exception instanceof IOException) {
throw (IOException) exception;
} else {
- throw new RepositoryException(
- "Error serializing system view XML", e);
+ throw new RepositoryException("Error serializing system view XML", e);
}
}
}
@Override
- public void exportDocumentView(String absPath,
- ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
+ public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
throws SAXException, RepositoryException {
- export(checkNotNull(absPath), new DocumentViewExporter(this,
- checkNotNull(contentHandler), !noRecurse, !skipBinary));
+ export(requireNonNull(absPath, "parameter 'absPath' must not be null"), new DocumentViewExporter(this,
+ requireNonNull(contentHandler, "parameter 'contentHandler' must not be null"), !noRecurse, !skipBinary));
}
@Override
- public void exportDocumentView(String absPath, OutputStream out,
- boolean skipBinary, boolean noRecurse) throws IOException,
- RepositoryException {
+ public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
+ throws IOException, RepositoryException {
try {
- ContentHandler handler = new ToXmlContentHandler(checkNotNull(out));
- export(checkNotNull(absPath), new DocumentViewExporter(this,
- handler, !noRecurse, !skipBinary));
+ ContentHandler handler = new ToXmlContentHandler(requireNonNull(out, "parameter 'out' must not be null"));
+ export(requireNonNull(absPath, "parameter 'absPath' must not be null"),
+ new DocumentViewExporter(this, handler, !noRecurse, !skipBinary));
} catch (SAXException e) {
Exception exception = e.getException();
if (exception instanceof RepositoryException) {
@@ -626,8 +617,7 @@ public void exportDocumentView(String absPath, OutputStream out,
} else if (exception instanceof IOException) {
throw (IOException) exception;
} else {
- throw new RepositoryException(
- "Error serializing document view XML", e);
+ throw new RepositoryException("Error serializing document view XML", e);
}
}
}
@@ -635,13 +625,14 @@ public void exportDocumentView(String absPath, OutputStream out,
@Override
public void addLockToken(String lt) {
try {
- getWorkspace().getLockManager().addLockToken(checkNotNull(lt));
+ getWorkspace().getLockManager().addLockToken(requireNonNull(lt, "parameter 'lt' must not be null"));
} catch (RepositoryException e) {
log.warn("Unable to add lock token " + lt + " to session", e);
}
}
- @Override @NotNull
+ @Override
+ @NotNull
public String[] getLockTokens() {
try {
return getWorkspace().getLockManager().getLockTokens();
@@ -654,7 +645,7 @@ public String[] getLockTokens() {
@Override
public void removeLockToken(String lt) {
try {
- getWorkspace().getLockManager().removeLockToken(checkNotNull(lt));
+ getWorkspace().getLockManager().removeLockToken(requireNonNull(lt, "parameter 'lt' must not be null"));
} catch (RepositoryException e) {
log.warn("Unable to remove lock token " + lt + " from session", e);
}
@@ -663,8 +654,8 @@ public void removeLockToken(String lt) {
@Override
public boolean hasPermission(String absPath, final String actions) throws RepositoryException {
checkAlive();
- final String oakPath = getOakPathOrThrow(checkNotNull(absPath));
- checkNotNull(actions);
+ final String oakPath = getOakPathOrThrow(requireNonNull(absPath, "parameter 'absPath' must not be null"));
+ requireNonNull(actions, "parameter 'actions' must not be null");
return sd.perform(new ReadOperation("hasPermission") {
@NotNull
@Override
@@ -676,15 +667,16 @@ public Boolean perform() throws RepositoryException {
@Override
public void checkPermission(String absPath, String actions) throws RepositoryException {
- if (!hasPermission(checkNotNull(absPath), checkNotNull(actions))) {
+ if (!hasPermission(requireNonNull(absPath, "parameter 'absPath' must not be null"),
+ requireNonNull(actions, "parameter 'actions' must not be null"))) {
throw new AccessControlException("Access denied.");
}
}
@Override
public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
- checkNotNull(methodName);
- checkNotNull(target);
+ requireNonNull(methodName, "parameter 'methodName' must not be null");
+ requireNonNull(target, "parameter 'target' must not be null");
checkAlive();
if (target instanceof ItemImpl) {
@@ -698,7 +690,8 @@ public boolean hasCapability(String methodName, Object target, Object[] argument
if (!parent.isCheckedOut()) {
return false;
}
- boolean hasLocking = sessionContext.getRepository().getDescriptorValue(Repository.OPTION_LOCKING_SUPPORTED).getBoolean();
+ boolean hasLocking = sessionContext.getRepository().getDescriptorValue(Repository.OPTION_LOCKING_SUPPORTED)
+ .getBoolean();
if (hasLocking && parent.isLocked()) {
return false;
}
@@ -711,10 +704,12 @@ public boolean hasCapability(String methodName, Object target, Object[] argument
if (arguments != null && arguments.length > 0) {
// add-node needs to be checked on the (path of) the
// new node that has/will be added
- String path = PathUtils.concat(tree.getPath(), sessionContext.getOakName(arguments[0].toString()));
- return accessMgr.hasPermissions(path, Session.ACTION_ADD_NODE) && !isMountedReadOnly(path);
+ String path = PathUtils.concat(tree.getPath(),
+ sessionContext.getOakName(arguments[0].toString()));
+ return accessMgr.hasPermissions(path, Session.ACTION_ADD_NODE) && !isMountedReadOnly(path);
}
- } else if ("setPrimaryType".equals(methodName) || "addMixin".equals(methodName) || "removeMixin".equals(methodName)) {
+ } else if ("setPrimaryType".equals(methodName) || "addMixin".equals(methodName)
+ || "removeMixin".equals(methodName)) {
permission = Permissions.NODE_TYPE_MANAGEMENT;
} else if ("orderBefore".equals(methodName)) {
if (tree.isRoot()) {
@@ -737,10 +732,13 @@ public boolean hasCapability(String methodName, Object target, Object[] argument
}
NodeDelegate parentDelegate = dlg.getParent();
if (parentDelegate != null) {
- return accessMgr.hasPermissions(parentDelegate.getTree(), ((PropertyDelegate) dlg).getPropertyState(), permission)
+ return accessMgr.hasPermissions(parentDelegate.getTree(),
+ ((PropertyDelegate) dlg).getPropertyState(), permission)
&& !isMountedReadOnly(parentDelegate.getPath());
} else {
- return accessMgr.hasPermissions(dlg.getPath(), (permission == Permissions.MODIFY_PROPERTY) ? Session.ACTION_SET_PROPERTY : Session.ACTION_REMOVE)
+ return accessMgr.hasPermissions(dlg.getPath(),
+ (permission == Permissions.MODIFY_PROPERTY) ? Session.ACTION_SET_PROPERTY
+ : Session.ACTION_REMOVE)
&& !isMountedReadOnly(dlg.getPath());
}
}
@@ -769,13 +767,12 @@ public RetentionManager getRetentionManager() throws RepositoryException {
throw new UnsupportedRepositoryOperationException("Retention Management is not supported.");
}
- //---------------------------------------------------------< Namespaces >---
+ // ---------------------------------------------------------< Namespaces >---
@Override
- public void setNamespacePrefix(String prefix, String uri)
- throws RepositoryException {
- sessionContext.getNamespaces().setNamespacePrefix(checkNotNull(prefix),
- checkNotNull(uri));
+ public void setNamespacePrefix(String prefix, String uri) throws RepositoryException {
+ sessionContext.getNamespaces().setNamespacePrefix(requireNonNull(prefix, "parameter 'prefix' must not be null"),
+ requireNonNull(uri, "parameter 'uri' must not be null"));
}
@Override
@@ -785,17 +782,15 @@ public String[] getNamespacePrefixes() throws RepositoryException {
@Override
public String getNamespaceURI(String prefix) throws RepositoryException {
- return sessionContext.getNamespaces().getNamespaceURI(
- checkNotNull(prefix));
+ return sessionContext.getNamespaces().getNamespaceURI(requireNonNull(prefix, "parameter 'prefix' must not be null"));
}
@Override
public String getNamespacePrefix(String uri) throws RepositoryException {
- return sessionContext.getNamespaces().getNamespacePrefix(
- checkNotNull(uri));
+ return sessionContext.getNamespaces().getNamespacePrefix(requireNonNull(uri, "parameter 'uri' must not be null"));
}
- //--------------------------------------------------< JackrabbitSession >---
+ // --------------------------------------------------< JackrabbitSession >---
@Override
public boolean hasPermission(@NotNull String absPath, @NotNull String... actions) throws RepositoryException {
diff --git a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
index b0713b155f2..fdd445d1621 100644
--- a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
+++ b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
@@ -170,5 +170,4 @@ public interface LuceneIndexConstants extends FulltextIndexConstants {
*/
@Deprecated
String INDEX_PATH = "indexPath";
-
}
diff --git a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexDefinitionBuilder.java b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexDefinitionBuilder.java
index 48b55b32831..ee16e391003 100644
--- a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexDefinitionBuilder.java
+++ b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexDefinitionBuilder.java
@@ -19,9 +19,14 @@
package org.apache.jackrabbit.oak.plugins.index.lucene.util;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
import org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import java.util.Arrays;
+
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
public final class LuceneIndexDefinitionBuilder extends IndexDefinitionBuilder {
@@ -41,5 +46,4 @@ public LuceneIndexDefinitionBuilder(NodeBuilder nodeBuilder, boolean autoManageR
protected String getIndexType() {
return TYPE_LUCENE;
}
-
}
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
index a9f29694522..930512e48c1 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
@@ -2988,6 +2988,122 @@ public void testRepSimilarWithBinaryFeatureVectors() throws Exception {
}
}
+ @Test
+ public void testRepSimilarWithBinaryFeatureVectorsWithIndexSimilarityBinariesDefinedAsLucene() throws Exception {
+
+ IndexDefinitionBuilder idxb = new LuceneIndexDefinitionBuilder().noAsync().indexSimilarityBinaries("lucene");
+ idxb.indexRule("nt:base").property("fv").useInSimilarity().nodeScopeIndex().propertyIndex();
+
+ Tree idx = root.getTree("/").getChild("oak:index").addChild("test1");
+ idxb.build(idx);
+ root.commit();
+
+ Tree test = root.getTree("/").addChild("test");
+
+ URI uri = getClass().getResource("/org/apache/jackrabbit/oak/query/fvs.csv").toURI();
+ File file = new File(uri);
+
+ Collection children = new LinkedList<>();
+ for (String line : IOUtils.readLines(new FileInputStream(file), Charset.defaultCharset())) {
+ String[] split = line.split(",");
+ List values = new LinkedList<>();
+ int i = 0;
+ for (String s : split) {
+ if (i > 0) {
+ values.add(Double.parseDouble(s));
+ }
+ i++;
+ }
+
+ byte[] bytes = SimSearchUtils.toByteArray(values);
+ List actual = SimSearchUtils.toDoubles(bytes);
+ assertEquals(values, actual);
+
+ Blob blob = root.createBlob(new ByteArrayInputStream(bytes));
+ String name = split[0];
+ Tree child = test.addChild(name);
+ child.setProperty("fv", blob, Type.BINARY);
+ children.add(child.getPath());
+ }
+ root.commit();
+
+ // check that similarity changes across different feature vectors
+ List baseline = new LinkedList<>();
+ for (String similarPath : children) {
+ String query = "select [jcr:path] from [nt:base] where similar(., '" + similarPath + "')";
+
+ Iterator result = executeQuery(query, "JCR-SQL2").iterator();
+ List current = new LinkedList<>();
+ while (result.hasNext()) {
+ String next = result.next();
+ current.add(next);
+ }
+ assertNotEquals(baseline, current);
+ baseline.clear();
+ baseline.addAll(current);
+ }
+ }
+
+ /**
+ * To disable similarity for binaries the index type should not be in present as value for FulltextIndexConstants.INDEX_SIMILARITY_BINARIES.
+ * In this case index type is lucene but indexSimilarityBinaries is set to elasticsearch
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRepSimilarWithBinaryFeatureVectorsWithIndexSimilarityBinariesDefinedAsElasticsearch() throws Exception {
+
+ IndexDefinitionBuilder idxb = new LuceneIndexDefinitionBuilder().noAsync().indexSimilarityBinaries("elasticsearch");
+ idxb.indexRule("nt:base").property("fv").useInSimilarity().nodeScopeIndex().propertyIndex();
+
+
+ Tree idx = root.getTree("/").getChild("oak:index").addChild("test1");
+ idxb.build(idx);
+ root.commit();
+
+ Tree test = root.getTree("/").addChild("test");
+
+ URI uri = getClass().getResource("/org/apache/jackrabbit/oak/query/fvs.csv").toURI();
+ File file = new File(uri);
+
+ Collection children = new LinkedList<>();
+ for (String line : IOUtils.readLines(new FileInputStream(file), Charset.defaultCharset())) {
+ String[] split = line.split(",");
+ List values = new LinkedList<>();
+ int i = 0;
+ for (String s : split) {
+ if (i > 0) {
+ values.add(Double.parseDouble(s));
+ }
+ i++;
+ }
+
+ byte[] bytes = SimSearchUtils.toByteArray(values);
+ List actual = SimSearchUtils.toDoubles(bytes);
+ assertEquals(values, actual);
+
+ Blob blob = root.createBlob(new ByteArrayInputStream(bytes));
+ String name = split[0];
+ Tree child = test.addChild(name);
+ child.setProperty("fv", blob, Type.BINARY);
+ children.add(child.getPath());
+ }
+ root.commit();
+
+ // check that similarity changes across different feature vectors
+ for (String similarPath : children) {
+ String query = "select [jcr:path] from [nt:base] where similar(., '" + similarPath + "')";
+
+ Iterator result = executeQuery(query, "JCR-SQL2").iterator();
+ List current = new LinkedList<>();
+ while (result.hasNext()) {
+ String next = result.next();
+ current.add(next);
+ }
+ assertEquals("binary data for similarity should not be indexed", 0, current.size());
+ }
+ }
+
@Test
public void testRepSimilarWithStringFeatureVectors() throws Exception {
@@ -3032,6 +3148,97 @@ public void testRepSimilarWithStringFeatureVectors() throws Exception {
}
}
+ @Test
+ public void testRepSimilarWithStringFeatureVectorsWithIndexSimilarityStringsDefinedAsLucene() throws Exception {
+
+ IndexDefinitionBuilder idxb = new LuceneIndexDefinitionBuilder().noAsync().indexSimilarityStrings("lucene");
+ idxb.indexRule("nt:base").property("fv").useInSimilarity().nodeScopeIndex().propertyIndex();
+
+ Tree idx = root.getTree("/").getChild("oak:index").addChild("test1");
+ idxb.build(idx);
+ root.commit();
+
+ Tree test = root.getTree("/").addChild("test");
+
+ URI uri = getClass().getResource("/org/apache/jackrabbit/oak/query/fvs.csv").toURI();
+ File file = new File(uri);
+
+ Collection children = new LinkedList<>();
+
+ for (String line : IOUtils.readLines(new FileInputStream(file), Charset.defaultCharset())) {
+ int i1 = line.indexOf(',');
+ String name = line.substring(0, i1);
+ String value = line.substring(i1 + 1);
+ Tree child = test.addChild(name);
+ child.setProperty("fv", value, Type.STRING);
+ children.add(child.getPath());
+ }
+ root.commit();
+
+ // check that similarity changes across different feature vectors
+ List baseline = new LinkedList<>();
+ for (String similarPath : children) {
+ String query = "select [jcr:path] from [nt:base] where similar(., '" + similarPath + "')";
+
+ Iterator result = executeQuery(query, "JCR-SQL2").iterator();
+ List current = new LinkedList<>();
+ while (result.hasNext()) {
+ String next = result.next();
+ current.add(next);
+ }
+ assertNotEquals(baseline, current);
+ baseline.clear();
+ baseline.addAll(current);
+ }
+ }
+
+ /**
+ * To disable similarity for strings the index type should not be in present as value for FulltextIndexConstants.INDEX_SIMILARITY_STRINGS.
+ * In this case index type is lucene but indexSimilarityStrings is set to elasticsearch
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRepSimilarWithStringFeatureVectorsWithIndexSimilarityStringsDefinedAsElasticsearch() throws Exception {
+
+ IndexDefinitionBuilder idxb = new LuceneIndexDefinitionBuilder().noAsync().indexSimilarityStrings("elasticsearch");
+ idxb.indexRule("nt:base").property("fv").useInSimilarity().nodeScopeIndex().propertyIndex();
+
+ Tree idx = root.getTree("/").getChild("oak:index").addChild("test1");
+ idxb.build(idx);
+ root.commit();
+
+ Tree test = root.getTree("/").addChild("test");
+
+ URI uri = getClass().getResource("/org/apache/jackrabbit/oak/query/fvs.csv").toURI();
+ File file = new File(uri);
+
+ Collection children = new LinkedList<>();
+
+ for (String line : IOUtils.readLines(new FileInputStream(file), Charset.defaultCharset())) {
+ int i1 = line.indexOf(',');
+ String name = line.substring(0, i1);
+ String value = line.substring(i1 + 1);
+ Tree child = test.addChild(name);
+ child.setProperty("fv", value, Type.STRING);
+ children.add(child.getPath());
+ }
+ root.commit();
+
+ // check that similarity changes across different feature vectors
+ for (String similarPath : children) {
+ String query = "select [jcr:path] from [nt:base] where similar(., '" + similarPath + "')";
+
+ Iterator result = executeQuery(query, "JCR-SQL2").iterator();
+ List current = new LinkedList<>();
+ while (result.hasNext()) {
+ String next = result.next();
+ current.add(next);
+ }
+ assertEquals("String data for similarity should not be indexed", 0, current.size());
+ }
+ }
+
@Test
public void testRepSimilarWithBinaryFeatureVectorsAndRerank() throws Exception {
diff --git a/oak-parent/pom.xml b/oak-parent/pom.xml
index 67846307109..de1557c0300 100644
--- a/oak-parent/pom.xml
+++ b/oak-parent/pom.xml
@@ -393,11 +393,12 @@
org.apache.maven.plugins
maven-site-plugin
- 3.7.1
+ 3.12.0
false
true
true
+ false
diff --git a/oak-run-commons/src/test/java/org/apache/jackrabbit/oak/index/indexer/document/flatfile/FlatFileStoreTest.java b/oak-run-commons/src/test/java/org/apache/jackrabbit/oak/index/indexer/document/flatfile/FlatFileStoreTest.java
index 18bc33e75de..eb7f1a26728 100644
--- a/oak-run-commons/src/test/java/org/apache/jackrabbit/oak/index/indexer/document/flatfile/FlatFileStoreTest.java
+++ b/oak-run-commons/src/test/java/org/apache/jackrabbit/oak/index/indexer/document/flatfile/FlatFileStoreTest.java
@@ -23,6 +23,7 @@
import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.oak.index.indexer.document.CompositeException;
import org.apache.jackrabbit.oak.index.indexer.document.NodeStateEntry;
+import org.apache.jackrabbit.oak.index.indexer.document.NodeStateEntry.NodeStateEntryBuilder;
import org.apache.jackrabbit.oak.index.indexer.document.NodeStateEntryTraverser;
import org.apache.jackrabbit.oak.index.indexer.document.NodeStateEntryTraverserFactory;
import org.apache.jackrabbit.oak.plugins.document.mongo.DocumentStoreSplitter;
@@ -397,7 +398,11 @@ public void resumePreviousUnfinishedDownloadAndMerge() throws Exception {
assertContainsMergeFolder(spyBuilder.getFlatFileStoreDir(), true);
List sortedPaths = TestUtils.sortPaths(mongoDocs.stream().map(md -> md.path).collect(Collectors.toList()));
- assertEquals(mongoDocs.size(), nsetf.getTotalProvidedDocCount());
+ // with multi-threaded download and multiple threads,
+ // we can't expect that each entry is downloaded exactly once,
+ // as there could be some overlap (the range check happends
+ // _after_ retrieving the entry)
+ assertTrue(mongoDocs.size() <= nsetf.getTotalProvidedDocCount());
assertEquals(sortedPaths, entryPaths);
} finally {
System.clearProperty(OAK_INDEXER_SORT_STRATEGY_TYPE);
@@ -479,7 +484,8 @@ public NodeStateEntryTraverser create(MongoDocumentTraverser.TraversingRange ran
String traverserId = getId();
return new Iterator() {
- NodeStateEntry lastReturnedDoc;
+ // ensure we don't get a NullPointerException in logger.debug below
+ NodeStateEntry lastReturnedDoc = new NodeStateEntryBuilder(null, "/").build();
@Override
public boolean hasNext() {
@@ -488,7 +494,8 @@ public boolean hasNext() {
@Override
public NodeStateEntry next() {
- if (providedDocuments.get() == breakAfterDelivering.get()) {
+ // multiple threads could fail at the same time, that's fine
+ if (providedDocuments.get() >= breakAfterDelivering.get()) {
logger.debug("{} Breaking after getting docs with id {}", traverserId, lastReturnedDoc.getId());
throw new IllegalStateException(EXCEPTION_MESSAGE);
}
diff --git a/oak-run/pom.xml b/oak-run/pom.xml
index 252a2eda924..b1997972909 100644
--- a/oak-run/pom.xml
+++ b/oak-run/pom.xml
@@ -31,7 +31,7 @@
Oak Runnable Jar
- 8.2.0.v20160908
+ 9.4.46.v20220331
2.4.17