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 da...@apache.org on 2024/02/05 12:49:30 UTC

(jackrabbit-oak) 01/01: OAK-10633 : make embedded verification configurable in detailedGC

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

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

commit cac501632cea5486f95a28502abc462830d4db23
Author: Rishabh Kumar <di...@adobe.com>
AuthorDate: Mon Feb 5 18:19:05 2024 +0530

    OAK-10633 :  make embedded verification configurable in detailedGC
---
 .../jackrabbit/oak/run/RevisionsCommand.java       |  6 ++-
 .../oak/plugins/document/Configuration.java        | 10 +++++
 .../oak/plugins/document/DocumentNodeStore.java    |  3 +-
 .../plugins/document/DocumentNodeStoreBuilder.java | 21 +++++++++
 .../plugins/document/DocumentNodeStoreService.java | 22 +++++++++-
 .../plugins/document/VersionGarbageCollector.java  |  2 +-
 .../document/rdb/RDBDocumentNodeStoreBuilder.java  | 22 ++++++++++
 .../oak/plugins/document/util/Utils.java           | 11 +++++
 .../DocumentNodeStoreServiceConfigurationTest.java | 10 +++++
 .../mongo/MongoDocumentNodeStoreBuilderTest.java   | 12 +++++
 .../rdb/RDBDocumentNodeStoreBuilderTest.java       | 16 +++++++
 .../oak/plugins/document/util/UtilsTest.java       | 51 ++++++++++++++++++++++
 12 files changed, 181 insertions(+), 5 deletions(-)

diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/RevisionsCommand.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/RevisionsCommand.java
index b01c0512a0..5c6aba2e7e 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/RevisionsCommand.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/RevisionsCommand.java
@@ -62,6 +62,7 @@ import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreHelper
 import static org.apache.jackrabbit.oak.plugins.document.FormatVersion.versionOf;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.getRootDocument;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isDetailedGCEnabled;
+import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isEmbeddedVerificationEnabled;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.timestampToString;
 import static org.apache.jackrabbit.oak.run.Utils.asCloseable;
 import static org.apache.jackrabbit.oak.run.Utils.createDocumentMKBuilder;
@@ -261,6 +262,9 @@ public class RevisionsCommand implements Command {
         if (options.isDetailedGCEnabled()) {
             builder.setDetailedGCEnabled(true);
         }
+        if (options.isEmbeddedVerificationEnabled()) {
+            builder.setEmbeddedVerificationEnabled(true);
+        }
         // set it read-only before the DocumentNodeStore is created
         // this prevents the DocumentNodeStore from writing a new
         // clusterId to the clusterNodes and nodes collections
@@ -271,7 +275,7 @@ public class RevisionsCommand implements Command {
         System.out.println("DryRun is enabled : " + options.isDryRun());
         System.out.println("EmbeddedVerification is enabled : " + options.isEmbeddedVerificationEnabled());
         VersionGarbageCollector gc = createVersionGC(builder.build(), gcSupport, isDetailedGCEnabled(builder),
-                options.isDryRun(), options.isEmbeddedVerificationEnabled());
+                options.isDryRun(), isEmbeddedVerificationEnabled(builder));
 
         VersionGCOptions gcOptions = gc.getOptions();
         gcOptions = gcOptions.withDelayFactor(options.getDelay());
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
index 52bf2ecc30..942c3f8e62 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
@@ -33,6 +33,7 @@ import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilde
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_UPDATE_LIMIT;
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_DETAILED_GC_ENABLED;
+import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_EMBEDDED_VERIFICATION_ENABLED;
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_THROTTLING_ENABLED;
 
 @ObjectClassDefinition(
@@ -298,4 +299,13 @@ import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreServic
                     ". Note that this value can be overridden via framework " +
                     "property 'oak.documentstore.detailedGCEnabled'")
     boolean detailedGCEnabled() default DEFAULT_DETAILED_GC_ENABLED;
+
+    @AttributeDefinition(
+            name = "Document Node Store Embedded Verification for Detailed GC",
+            description = "Boolean value indicating whether Embedded Verification (i.e. verify the document after " +
+                    "applying changes in memory before any database calls) for Detailed GC should be enabled for " +
+                    "document node store or not. The Default value is " + DEFAULT_EMBEDDED_VERIFICATION_ENABLED +
+                    ". Note that this value can be overridden via framework " +
+                    "property 'oak.documentstore.embeddedVerificationEnabled'")
+    boolean embeddedVerificationEnabled() default DEFAULT_EMBEDDED_VERIFICATION_ENABLED;
 }
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
index e4e04fb759..fc0147b3fb 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
@@ -39,6 +39,7 @@ import static org.apache.jackrabbit.oak.plugins.document.util.Utils.alignWithExt
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.getIdFromPath;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.getModuleVersion;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isDetailedGCEnabled;
+import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isEmbeddedVerificationEnabled;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isThrottlingEnabled;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.pathToId;
 import static org.apache.jackrabbit.oak.spi.observation.ChangeSet.COMMIT_CONTEXT_OBSERVATION_CHANGESET;
@@ -642,7 +643,7 @@ public final class DocumentNodeStore
         this.branches = new UnmergedBranches();
         this.asyncDelay = builder.getAsyncDelay();
         this.versionGarbageCollector = new VersionGarbageCollector(
-                this, builder.createVersionGCSupport(), isDetailedGCEnabled(builder), false, false);
+                this, builder.createVersionGCSupport(), isDetailedGCEnabled(builder), false, isEmbeddedVerificationEnabled(builder));
         this.versionGarbageCollector.setStatisticsProvider(builder.getStatisticsProvider());
         this.versionGarbageCollector.setGCMonitor(builder.getGCMonitor());
         this.journalGarbageCollector = new JournalGarbageCollector(
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
index d894aa27e4..5402e06281 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
@@ -126,6 +126,7 @@ public class DocumentNodeStoreBuilder<T extends DocumentNodeStoreBuilder<T>> {
     private Feature prefetchFeature;
     private Feature docStoreThrottlingFeature;
     private Feature docStoreDetailedGCFeature;
+    private Feature docStoreEmbeddedVerificationFeature;
     private Weigher<CacheValue, CacheValue> weigher = new EmpiricalWeigher();
     private long memoryCacheSize = DEFAULT_MEMORY_CACHE_SIZE;
     private int nodeCachePercentage = DEFAULT_NODE_CACHE_PERCENTAGE;
@@ -165,6 +166,7 @@ public class DocumentNodeStoreBuilder<T extends DocumentNodeStoreBuilder<T>> {
     private boolean clusterInvisible;
     private boolean throttlingEnabled;
     private boolean detailedGCEnabled;
+    private boolean embeddedVerificationEnabled;
     private long suspendTimeoutMillis = DEFAULT_SUSPEND_TIMEOUT;
 
     /**
@@ -297,6 +299,15 @@ public class DocumentNodeStoreBuilder<T extends DocumentNodeStoreBuilder<T>> {
         return this.detailedGCEnabled;
     }
 
+    public T setEmbeddedVerificationEnabled(boolean b) {
+        this.embeddedVerificationEnabled = b;
+        return thisBuilder();
+    }
+
+    public boolean isEmbeddedVerificationEnabled() {
+        return this.embeddedVerificationEnabled;
+    }
+
 
     public T setReadOnlyMode() {
         this.isReadOnlyMode = true;
@@ -337,6 +348,16 @@ public class DocumentNodeStoreBuilder<T extends DocumentNodeStoreBuilder<T>> {
         return docStoreDetailedGCFeature;
     }
 
+    public T setDocStoreEmbeddedVerificationFeature(@Nullable Feature getDocStoreEmbeddedVerification) {
+        this.docStoreEmbeddedVerificationFeature = getDocStoreEmbeddedVerification;
+        return thisBuilder();
+    }
+
+    @Nullable
+    public Feature getDocStoreEmbeddedVerificationFeature() {
+        return docStoreEmbeddedVerificationFeature;
+    }
+
     public T setLeaseFailureHandler(LeaseFailureHandler leaseFailureHandler) {
         this.leaseFailureHandler = leaseFailureHandler;
         return thisBuilder();
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
index d1c5e1ae72..e06c567483 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
@@ -139,6 +139,7 @@ public class DocumentNodeStoreService {
     static final boolean DEFAULT_SO_KEEP_ALIVE = true;
     static final boolean DEFAULT_THROTTLING_ENABLED = false;
     static final boolean DEFAULT_DETAILED_GC_ENABLED = false;
+    static final boolean DEFAULT_EMBEDDED_VERIFICATION_ENABLED = true;
     static final int DEFAULT_MONGO_LEASE_SO_TIMEOUT_MILLIS = 30000;
     static final String DEFAULT_PERSISTENT_CACHE = "cache";
     static final String DEFAULT_JOURNAL_CACHE = "diff-cache";
@@ -185,7 +186,12 @@ public class DocumentNodeStoreService {
     /**
      * Feature toggle name to enable detailed GC for Mongo Document Store
      */
-    private static final String FT_NAME_DEATILED_GC = "FT_DETAILED_GC_OAK-10199";
+    private static final String FT_NAME_DETAILED_GC = "FT_DETAILED_GC_OAK-10199";
+
+    /**
+     * Feature toggle name to enable embedded verification for detailed GC mode for Mongo Document Store
+     */
+    private static final String FT_NAME_EMBEDDED_VERIFICATION = "FT_EMBEDDED_VERIFICATION_OAK-10633";
 
     // property name constants - values can come from framework properties or OSGi config
     public static final String CUSTOM_BLOB_STORE = "customBlobStore";
@@ -223,6 +229,7 @@ public class DocumentNodeStoreService {
     private Feature prefetchFeature;
     private Feature docStoreThrottlingFeature;
     private Feature docStoreDetailedGCFeature;
+    private Feature docStoreEmbeddedVerificationFeature;
     private ComponentContext context;
     private Whiteboard whiteboard;
     private long deactivationTimestamp = 0;
@@ -257,7 +264,8 @@ public class DocumentNodeStoreService {
         documentStoreType = DocumentStoreType.fromString(this.config.documentStoreType());
         prefetchFeature = Feature.newFeature(FT_NAME_PREFETCH, whiteboard);
         docStoreThrottlingFeature = Feature.newFeature(FT_NAME_DOC_STORE_THROTTLING, whiteboard);
-        docStoreDetailedGCFeature = Feature.newFeature(FT_NAME_DEATILED_GC, whiteboard);
+        docStoreDetailedGCFeature = Feature.newFeature(FT_NAME_DETAILED_GC, whiteboard);
+        docStoreEmbeddedVerificationFeature = Feature.newFeature(FT_NAME_EMBEDDED_VERIFICATION, whiteboard);
 
         registerNodeStoreIfPossible();
     }
@@ -474,8 +482,10 @@ public class DocumentNodeStoreService {
                 setPrefetchFeature(prefetchFeature).
                 setDocStoreThrottlingFeature(docStoreThrottlingFeature).
                 setDocStoreDetailedGCFeature(docStoreDetailedGCFeature).
+                setDocStoreEmbeddedVerificationFeature(docStoreEmbeddedVerificationFeature).
                 setThrottlingEnabled(config.throttlingEnabled()).
                 setDetailedGCEnabled(config.detailedGCEnabled()).
+                setEmbeddedVerificationEnabled(config.embeddedVerificationEnabled()).
                 setSuspendTimeoutMillis(config.suspendTimeoutMillis()).
                 setLeaseFailureHandler(new LeaseFailureHandler() {
 
@@ -621,6 +631,14 @@ public class DocumentNodeStoreService {
             docStoreThrottlingFeature.close();
         }
 
+        if (docStoreDetailedGCFeature != null) {
+            docStoreDetailedGCFeature.close();
+        }
+
+        if (docStoreEmbeddedVerificationFeature != null) {
+            docStoreEmbeddedVerificationFeature.close();
+        }
+
         unregisterNodeStore();
     }
 
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
index aca0b2a746..73565b29fc 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
@@ -160,7 +160,7 @@ public class VersionGarbageCollector {
         this.ds = gcSupport.getDocumentStore();
         this.detailedGCEnabled = detailedGCEnabled;
         this.isDetailedGCDryRun = isDetailedGCDryRun;
-        this.embeddedVerification = embeddedVerification; //TODO: make this "configurable" for actual detailedGC
+        this.embeddedVerification = embeddedVerification;
         this.options = new VersionGCOptions();
     }
 
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
index 92aa40af86..d4ba9aa87e 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
@@ -138,4 +138,26 @@ public class RDBDocumentNodeStoreBuilder
     public Feature getDocStoreDetailedGCFeature() {
         return null;
     }
+
+    @Override
+    public boolean isEmbeddedVerificationEnabled() {
+        return false;
+    }
+
+    @Override
+    public RDBDocumentNodeStoreBuilder setEmbeddedVerificationEnabled(boolean b) {
+        // embeddedVerification is non supported for RDB since detailedGC is not.
+        return thisBuilder();
+    }
+
+    @Override
+    public RDBDocumentNodeStoreBuilder setDocStoreEmbeddedVerificationFeature(@Nullable Feature getDocStoreEmbeddedVerification) {
+        return thisBuilder();
+    }
+
+    @Override
+    @Nullable
+    public Feature getDocStoreEmbeddedVerificationFeature() {
+        return null;
+    }
 }
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
index 85bb1225fb..60690f88aa 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
@@ -915,6 +915,17 @@ public class Utils {
         return builder.isDetailedGCEnabled() || (docStoreDetailedGCFeature != null && docStoreDetailedGCFeature.isEnabled());
     }
 
+    /**
+     * Check whether embedded verification for detailed GC mode is enabled or not for document store.
+     *
+     * @param builder instance for DocumentNodeStoreBuilder
+     * @return true if embedded verification is enabled else false
+     */
+    public static boolean isEmbeddedVerificationEnabled(final DocumentNodeStoreBuilder<?> builder) {
+        final Feature docStoreEmbeddedVerificationFeature = builder.getDocStoreEmbeddedVerificationFeature();
+        return builder.isEmbeddedVerificationEnabled() || (docStoreEmbeddedVerificationFeature != null && docStoreEmbeddedVerificationFeature.isEnabled());
+    }
+
     /**
      * Returns true if all the revisions in the {@code a} greater or equals
      * to their counterparts in {@code b}. If {@code b} contains revisions
diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
index b3d5d69fb3..d2013c825f 100644
--- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
+++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
@@ -34,6 +34,7 @@ import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.ComponentContext;
 
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_DETAILED_GC_ENABLED;
+import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_EMBEDDED_VERIFICATION_ENABLED;
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_THROTTLING_ENABLED;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -86,6 +87,7 @@ public class DocumentNodeStoreServiceConfigurationTest {
         assertEquals("STRICT", config.leaseCheckMode());
         assertEquals(DEFAULT_THROTTLING_ENABLED, config.throttlingEnabled());
         assertEquals(DEFAULT_DETAILED_GC_ENABLED, config.detailedGCEnabled());
+        assertEquals(DEFAULT_EMBEDDED_VERIFICATION_ENABLED, config.embeddedVerificationEnabled());
         assertEquals(CommitQueue.DEFAULT_SUSPEND_TIMEOUT, config.suspendTimeoutMillis());
     }
 
@@ -113,6 +115,14 @@ public class DocumentNodeStoreServiceConfigurationTest {
         assertEquals(detailedGCDocStore, config.detailedGCEnabled());
     }
 
+    @Test
+    public void embeddedVerificationEnabled() throws Exception {
+        boolean embeddedVerificationEnabled = false;
+        addConfigurationEntry(preset, "embeddedVerificationEnabled", embeddedVerificationEnabled);
+        Configuration config = createConfiguration();
+        assertEquals(embeddedVerificationEnabled, config.embeddedVerificationEnabled());
+    }
+
     @Test
     public void presetSocketKeepAlive() throws Exception {
         boolean keepAlive = !DocumentNodeStoreService.DEFAULT_SO_KEEP_ALIVE;
diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java
index a08abe05d3..5109726b6b 100644
--- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java
+++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java
@@ -60,6 +60,18 @@ public class MongoDocumentNodeStoreBuilderTest {
         assertNull(builder.getDocStoreDetailedGCFeature());
     }
 
+    @Test
+    public void embeddedVerificationEnabled() {
+        MongoDocumentNodeStoreBuilder builder = new MongoDocumentNodeStoreBuilder();
+        assertFalse(builder.isEmbeddedVerificationEnabled());
+    }
+
+    @Test
+    public void embeddedVerificationFeatureToggleEnabled() {
+        MongoDocumentNodeStoreBuilder builder = new MongoDocumentNodeStoreBuilder();
+        assertNull(builder.getDocStoreEmbeddedVerificationFeature());
+    }
+
     @Test
     public void collectionCompressionDisabled() {
         MongoDocumentNodeStoreBuilder builder = new MongoDocumentNodeStoreBuilder();
diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java
index d821b1f785..dc61e6aae3 100755
--- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java
+++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java
@@ -75,4 +75,20 @@ public class RDBDocumentNodeStoreBuilderTest {
         builder.setDocStoreDetailedGCFeature(docStoreDetailedGCFeature);
         assertNull(builder.getDocStoreDetailedGCFeature());
     }
+
+    @Test
+    public void embeddedVerificationDisabled() {
+        RDBDocumentNodeStoreBuilder builder = new RDBDocumentNodeStoreBuilder();
+        builder.setEmbeddedVerificationEnabled(true);
+        assertFalse(builder.isEmbeddedVerificationEnabled());
+    }
+
+    @Test
+    public void embeddedVerificationFeatureToggleDisabled() {
+        RDBDocumentNodeStoreBuilder builder = new RDBDocumentNodeStoreBuilder();
+        Feature embeddedVerificationFeature = mock(Feature.class);
+        when(embeddedVerificationFeature.isEnabled()).thenReturn(true);
+        builder.setDocStoreEmbeddedVerificationFeature(embeddedVerificationFeature);
+        assertNull(builder.getDocStoreEmbeddedVerificationFeature());
+    }
 }
diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
index cddaf79a61..72f17dd638 100644
--- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
+++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
@@ -58,6 +58,7 @@ import org.slf4j.event.Level;
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.newDocumentNodeStoreBuilder;
 import static org.apache.jackrabbit.oak.plugins.document.rdb.RDBDocumentNodeStoreBuilder.newRDBDocumentNodeStoreBuilder;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isDetailedGCEnabled;
+import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isEmbeddedVerificationEnabled;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isThrottlingEnabled;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.is;
@@ -235,6 +236,56 @@ public class UtilsTest {
         assertFalse("Detailed GC is disabled for RDB Document Store", detailedGCEnabled);
     }
 
+    @Test
+    public void embeddedVerificationEnabledDefaultValue() {
+        boolean embeddedVerificationEnabled = isEmbeddedVerificationEnabled(newDocumentNodeStoreBuilder());
+        assertFalse("Embedded Verification is enabled by default", embeddedVerificationEnabled);
+    }
+
+    @Test
+    public void embeddedVerificationExplicitlyDisabled() {
+        DocumentNodeStoreBuilder<?> builder = newDocumentNodeStoreBuilder();
+        builder.setEmbeddedVerificationEnabled(false);
+        Feature docStoreEmbeddedVerificationFeature = mock(Feature.class);
+        when(docStoreEmbeddedVerificationFeature.isEnabled()).thenReturn(false);
+        builder.setDocStoreEmbeddedVerificationFeature(docStoreEmbeddedVerificationFeature);
+        boolean embeddedVerificationEnabled = isEmbeddedVerificationEnabled(builder);
+        assertFalse("Embedded Verification is disabled explicitly", embeddedVerificationEnabled);
+    }
+
+    @Test
+    public void embeddedVerificationEnabledViaConfiguration() {
+        DocumentNodeStoreBuilder<?> builder = newDocumentNodeStoreBuilder();
+        builder.setEmbeddedVerificationEnabled(true);
+        Feature docStoreEmbeddedVerificationFeature = mock(Feature.class);
+        when(docStoreEmbeddedVerificationFeature.isEnabled()).thenReturn(false);
+        builder.setDocStoreEmbeddedVerificationFeature(docStoreEmbeddedVerificationFeature);
+        boolean embeddedVerificationEnabled = isEmbeddedVerificationEnabled(builder);
+        assertTrue("Embedded Verification is enabled via configuration", embeddedVerificationEnabled);
+    }
+
+    @Test
+    public void embeddedVerificationEnabledViaFeatureToggle() {
+        DocumentNodeStoreBuilder<?> builder = newDocumentNodeStoreBuilder();
+        builder.setEmbeddedVerificationEnabled(false);
+        Feature docStoreEmbeddedVerificationFeature = mock(Feature.class);
+        when(docStoreEmbeddedVerificationFeature.isEnabled()).thenReturn(true);
+        builder.setDocStoreEmbeddedVerificationFeature(docStoreEmbeddedVerificationFeature);
+        boolean embeddedVerificationEnabled = isEmbeddedVerificationEnabled(builder);
+        assertTrue("Embedded Verification is enabled via Feature Toggle", embeddedVerificationEnabled);
+    }
+
+    @Test
+    public void embeddedVerificationDisabledForRDB() {
+        DocumentNodeStoreBuilder<?> builder = newRDBDocumentNodeStoreBuilder();
+        builder.setEmbeddedVerificationEnabled(true);
+        Feature docStoreEmbeddedVerificationFeature = mock(Feature.class);
+        when(docStoreEmbeddedVerificationFeature.isEnabled()).thenReturn(true);
+        builder.setDocStoreEmbeddedVerificationFeature(docStoreEmbeddedVerificationFeature);
+        boolean embeddedVerificationEnabled = isEmbeddedVerificationEnabled(builder);
+        assertFalse("Embedded Verification is disabled for RDB Document Store", embeddedVerificationEnabled);
+    }
+
     @Test
     public void getDepthFromId() throws Exception{
         assertEquals(1, Utils.getDepthFromId("1:/x"));