This is an automated email from the ASF dual-hosted git repository.

baedke pushed a commit to branch OAK-11617-2
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/OAK-11617-2 by this push:
     new e8a7c445b0 OAK-11617: Provide oak-run commands to analyze and fix 
inconsistencies in the namespace registry
e8a7c445b0 is described below

commit e8a7c445b00becd6a98ad7a18763a6124b7d235a
Author: Manfred Baedke <[email protected]>
AuthorDate: Wed Jul 2 13:18:56 2025 +0200

    OAK-11617: Provide oak-run commands to analyze and fix inconsistencies in 
the namespace registry
    
    Multiple invocations of consistency check fixed; added test case.
---
 .../plugins/name/ReadOnlyNamespaceRegistry.java    | 14 ++--
 .../oak/plugins/name/NamespaceRegistryTest.java    | 75 ++++++++++++++++------
 2 files changed, 63 insertions(+), 26 deletions(-)

diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
index 63dce06a57..8bf13a7848 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
@@ -50,14 +50,17 @@ public class ReadOnlyNamespaceRegistry
 
     private static volatile boolean CONSISTENCY_CHECKED;
 
+    protected final Root root;
     protected final Tree namespaces;
     protected final Tree nsdata;
 
     public ReadOnlyNamespaceRegistry(Root root) {
+        this.root = root;
         this.namespaces = root.getTree(NAMESPACES_PATH);
         this.nsdata = namespaces.getChild(REP_NSDATA);
         if (!CONSISTENCY_CHECKED) {
             checkConsistency(root);
+            CONSISTENCY_CHECKED = true;
         }
     }
 
@@ -127,16 +130,15 @@ public class ReadOnlyNamespaceRegistry
                 "No namespace prefix registered for URI " + uri);
     }
 
+    public boolean checkConsistency() throws IllegalStateException {
+        return checkConsistency(root);
+    }
+
     public boolean checkConsistency(Root root) throws IllegalStateException {
-        NamespaceRegistryModel model = createNamespaceRegistryModel(root);
+        NamespaceRegistryModel model = NamespaceRegistryModel.create(root);
         if (model == null) {
             LOG.warn("Consistency check skipped because there is no namespace 
registry.");
         }
         return model == null || model.isConsistent();
     }
-
-    public NamespaceRegistryModel createNamespaceRegistryModel(Root root) {
-        return NamespaceRegistryModel.create(root);
-    }
-
 }
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryTest.java
index d49bdcd46d..de7d14b736 100755
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryTest.java
@@ -26,19 +26,30 @@ import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyBuilder;
 import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
 
+import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
 
 import java.io.ByteArrayOutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Objects;
 
 import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_NSDATA;
 import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_PREFIXES;
 import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_URIS;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 public class NamespaceRegistryTest {
 
@@ -55,24 +66,16 @@ public class NamespaceRegistryTest {
                 .with(new NamespaceEditorProvider())
                 .createContentSession()) {
             Root root = session.getLatestRoot();
-            ReadWriteNamespaceRegistry registry = new 
ReadWriteNamespaceRegistry(root) {
-                @Override
-                protected Root getWriteRoot() {
-                    return session.getLatestRoot();
-                }
-                @Override
-                protected void refresh() {
-                    root.refresh();
-                }
-            };
+            ReadWriteNamespaceRegistry registry = new 
TestNamespaceRegistry(root);
             Tree namespaces = root.getTree("/jcr:system/rep:namespaces");
             Tree nsdata = namespaces.getChild(REP_NSDATA);
             PropertyState prefixProp = nsdata.getProperty(REP_PREFIXES);
             PropertyState namespaceProp = nsdata.getProperty(REP_URIS);
 
             // Check the initial state of the namespace registry
-            assertTrue(registry.checkConsistency(root));
-            NamespaceRegistryModel model = 
registry.createNamespaceRegistryModel(root);
+            assertTrue(registry.checkConsistency());
+            NamespaceRegistryModel model = NamespaceRegistryModel.create(root);
+            assertNotNull(model);
             assertTrue(model.isConsistent());
             assertTrue(model.isFixable());
 
@@ -92,7 +95,8 @@ public class NamespaceRegistryTest {
 
             // Now it cannot be fixed automatically
             assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
+            model = NamespaceRegistryModel.create(root);
+            assertNotNull(model);
             assertFalse(model.isConsistent());
             assertFalse(model.isFixable());
 
@@ -123,7 +127,8 @@ public class NamespaceRegistryTest {
 
             // This is inconsistent, but can be fixed automatically
             assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
+            model = NamespaceRegistryModel.create(root);
+            assertNotNull(model);
             assertFalse(model.isConsistent());
             assertTrue(model.isFixable());
 
@@ -152,7 +157,8 @@ public class NamespaceRegistryTest {
 
             // Now it again cannot be fixed automatically
             assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
+            model = NamespaceRegistryModel.create(root);
+            assertNotNull(model);
             assertFalse(model.isConsistent());
             assertFalse(model.isFixable());
 
@@ -169,7 +175,7 @@ public class NamespaceRegistryTest {
 
             // Now it can be fixed automatically again
             assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
+            model = NamespaceRegistryModel.create(root);
             assertFalse(model.isConsistent());
             assertTrue(model.isFixable());
 
@@ -188,7 +194,8 @@ public class NamespaceRegistryTest {
 
             // Can still be fixed automatically
             assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
+            model = NamespaceRegistryModel.create(root);
+            assertNotNull(model);
             assertFalse(model.isConsistent());
             assertTrue(model.isFixable());
 
@@ -207,7 +214,7 @@ public class NamespaceRegistryTest {
 
             // Can still be fixed automatically
             assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
+            model = NamespaceRegistryModel.create(root);
             assertFalse(model.isConsistent());
             assertTrue(model.isFixable());
 
@@ -227,7 +234,8 @@ public class NamespaceRegistryTest {
 
             // Cannot be fixed automatically
             assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
+            model = NamespaceRegistryModel.create(root);
+            assertNotNull(model);
             assertFalse(model.isConsistent());
             assertFalse(model.isFixable());
 
@@ -247,7 +255,7 @@ public class NamespaceRegistryTest {
             assertFalse(registry.checkConsistency(root));
             model.apply(root);
             assertTrue(registry.checkConsistency(root));
-            
assertTrue(registry.createNamespaceRegistryModel(root).isConsistent());
+            
assertTrue(Objects.requireNonNull(NamespaceRegistryModel.create(root)).isConsistent());
 
             assertEquals(0, model.getDanglingPrefixes().size());
             assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
@@ -260,4 +268,31 @@ public class NamespaceRegistryTest {
             assertEquals("bar2", registry.getPrefix("urn:bar2"));
         }
     }
+
+    @Test
+    public void testConsistencyCheckInvocationCount() throws Exception {
+        Oak oak = new Oak()
+                .with(new OpenSecurityProvider())
+                .with(new InitialContent())
+                .with(new NamespaceEditorProvider());
+        try (ContentSession session = oak.createContentSession()) {
+            Root root = session.getLatestRoot();
+            ReadWriteNamespaceRegistry registry = new 
TestNamespaceRegistry(root);
+            ReadWriteNamespaceRegistry spy = spy(registry);
+            verify(spy, times(0)).checkConsistency(any(Root.class));
+            new TestNamespaceRegistry(root);
+            verify(spy, times(0)).checkConsistency(any(Root.class));
+        }
+    }
+
+    static class TestNamespaceRegistry extends ReadWriteNamespaceRegistry {
+        public TestNamespaceRegistry(Root root) {
+            super(root);
+        }
+
+        @Override
+        protected Root getWriteRoot() {
+            return root;
+        }
+    }
 }

Reply via email to