You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2026/04/28 08:22:10 UTC

(jackrabbit-oak) 01/01: OAK-12196 Improve logging for diff.index

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

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

commit 9b5b4f5fafff5aedd29ba4ef96cf521cb5790c0d
Author: Thomas Mueller <mu...@adobe.com>
AuthorDate: Tue Apr 28 10:21:52 2026 +0200

    OAK-12196 Improve logging for diff.index
---
 .../jackrabbit/oak/plugins/index/IndexUpdate.java  | 17 +++++++
 .../oak/plugins/index/IndexUpdateTest.java         | 53 ++++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
index 058d8f8b16..75df48aa36 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
@@ -37,6 +37,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.jackrabbit.JcrConstants;
@@ -87,6 +88,15 @@ public class IndexUpdate implements Editor, PathSource {
     // this is the last time such a message was logged (if any).
     private static final AtomicLong lastMissingProviderMessageTime = new AtomicLong();
 
+    // Names of diff index nodes (e.g. "diff.index", "diff.index.optimizer") for which a
+    // detection message has already been logged in this JVM. They legitimately use
+    // jcr:primaryType=nt:unstructured, so their presence is reported once at INFO.
+    private static final Set<String> diffIndexesDetected = ConcurrentHashMap.newKeySet();
+
+    static void resetDiffIndexesDetectedForTest() {
+        diffIndexesDetected.clear();
+    }
+
     /**
      * <p>
      * The value of this flag determines the behavior of the IndexUpdate when
@@ -314,6 +324,13 @@ public class IndexUpdate implements Editor, PathSource {
                  and skip further execution for invalid nodetype of index definition.
                  */
                 if (!IndexConstants.INDEX_DEFINITIONS_NODE_TYPE.equals(primaryType)) {
+                    if (DiffIndexMerger.DIFF_INDEX.equals(name)
+                            || DiffIndexMerger.DIFF_INDEX_OPTIMIZER.equals(name)) {
+                        if (diffIndexesDetected.add(name)) {
+                            log.info("index {} is detected", name);
+                        }
+                        continue;
+                    }
                     // It is a cyclic counter which reset back to 0 after INDEX_JCR_TYPE_INVALID_LOG_LIMITER
                     // This is to sparsely log this warning.
                     if ((cyclicExecutionCount >= INDEX_JCR_TYPE_INVALID_LOG_LIMITER)) {
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
index 03484055f4..f916e536a7 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
@@ -1076,6 +1076,59 @@ public class IndexUpdateTest {
  
     }    
 
+    /*
+     * OAK-12196: diff.index and diff.index.optimizer legitimately use
+     * jcr:primaryType=nt:unstructured. They should be reported once at INFO,
+     * not repeatedly at WARN.
+     */
+    @Test
+    public void testDiffIndexLoggedOnceAtInfo() throws Exception {
+        IndexUpdate.resetDiffIndexesDetectedForTest();
+
+        LogCustomizer customLogs = LogCustomizer.forLogger(IndexUpdate.class.getName())
+                .enable(Level.INFO).create();
+        try {
+            customLogs.starting();
+
+            NodeBuilder oakIndex = builder.child(INDEX_DEFINITIONS_NAME);
+            oakIndex.child("diff.index")
+                    .setProperty(org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE,
+                            org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED, Type.NAME)
+                    .setProperty(TYPE_PROPERTY_NAME, "diff");
+            oakIndex.child("diff.index.optimizer")
+                    .setProperty(org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE,
+                            org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED, Type.NAME)
+                    .setProperty(TYPE_PROPERTY_NAME, "diff");
+
+            NodeState before = root;
+            NodeState after = builder.getNodeState();
+            NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+
+            // run a second commit; the INFO messages must NOT be repeated
+            NodeBuilder b2 = indexed.builder();
+            b2.child("anyContent").setProperty("foo", "bar");
+            HOOK.processCommit(indexed, b2.getNodeState(), CommitInfo.EMPTY);
+
+            List<String> logs = customLogs.getLogs();
+            List<String> detected = logs.stream()
+                    .filter(s -> s.contains("is detected"))
+                    .collect(java.util.stream.Collectors.toList());
+            assertEquals("expected each diff index name to be reported once, got: " + detected,
+                    2, detected.size());
+            assertThat(detected, IsCollectionContaining.hasItems(
+                    "index diff.index is detected",
+                    "index diff.index.optimizer is detected"));
+
+            for (String entry : logs) {
+                assertFalse("WARN about jcr:primaryType must not fire for diff.index nodes: " + entry,
+                        entry.contains("jcr:primaryType of index"));
+            }
+        } finally {
+            customLogs.finished();
+            IndexUpdate.resetDiffIndexesDetectedForTest();
+        }
+    }
+
     private static void markCorrupt(NodeBuilder builder, String indexName) {
         builder.getChildNode(INDEX_DEFINITIONS_NAME).getChildNode(indexName)
                 .setProperty(IndexConstants.CORRUPT_PROPERTY_NAME, ISO8601.format(Calendar.getInstance()));