Forráskód Böngészése

ZOOKEEPER-4846: Failure to reload database due to missing ACL

ZOOKEEPER-4846. Fix ACL reference on existing znode when trying to create
Reviewers: cnauroth, eolivelli, ztzg
Author: anmolnar
Closes #2222 from anmolnar/ZOOKEEPER-4846
Andor Molnár 2 hónapja
szülő
commit
8532163df1

+ 3 - 2
zookeeper-server/src/main/java/org/apache/zookeeper/server/DataTree.java

@@ -462,8 +462,9 @@ public class DataTree {
             // we did for the global sessions.
             Long acls = aclCache.convertAcls(acl);
 
-            Set<String> children = parent.getChildren();
-            if (children.contains(childName)) {
+            DataNode existingChild = nodes.get(path);
+            if (existingChild != null) {
+                existingChild.acl = acls;
                 throw new NodeExistsException();
             }
 

+ 16 - 0
zookeeper-server/src/test/java/org/apache/zookeeper/server/DataTreeTest.java

@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -631,6 +632,21 @@ public class DataTreeTest extends ZKTestCase {
         }
     }
 
+    @Test
+    public void testCreateNodeFixMissingACL() throws Exception {
+        DataTree dt = new DataTree();
+        ReferenceCountedACLCache aclCache = dt.getReferenceCountedAclCache();
+
+        dt.createNode("/the_parent", new byte[0], ZooDefs.Ids.CREATOR_ALL_ACL, -1, 1, 1, 0);
+        Long aclId = dt.getNode("/the_parent").acl;
+        aclCache.removeUsage(aclId);
+        aclCache.purgeUnused();
+        // try to re-create the parent -> throws NodeExistsException, but fixes the deleted ACL
+        assertThrows(NodeExistsException.class, () ->
+            dt.createNode("/the_parent", new byte[0], ZooDefs.Ids.CREATOR_ALL_ACL, -1, 1, 1, 0));
+        dt.createNode("/the_parent/the_child", new byte[0], ZooDefs.Ids.CREATOR_ALL_ACL, -1, 2, 2, 2);
+    }
+
     private DataTree buildDataTreeForTest() {
         final DataTree dt = new DataTree();
         assertEquals(dt.lastProcessedZxid, 0);