Author: mreutegg
Date: Tue Jan 14 10:50:10 2014
New Revision: 1558006

URL: http://svn.apache.org/r1558006
Log:
OAK-1320: Inconsistent state in Mongo/KernelRootBuilder

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootBuilder.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootBuilder.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootBuilder.java?rev=1558006&r1=1558005&r2=1558006&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootBuilder.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootBuilder.java
 Tue Jan 14 10:50:10 2014
@@ -145,7 +145,19 @@ class KernelRootBuilder extends MemoryNo
      */
     NodeState merge(CommitHook hook, CommitInfo info) throws 
CommitFailedException {
         purge();
-        branch.merge(hook, info);
+        boolean success = false;
+        try {
+            branch.merge(hook, info);
+            success = true;
+        } finally {
+            if (!success) {
+                // need to adjust base and head of this builder
+                // in case branch.merge() did a rebase and then
+                // a commit hook failed the merge
+                super.reset(branch.getHead());
+                this.base = branch.getBase();
+            }
+        }
         return reset();
     }
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java?rev=1558006&r1=1558005&r2=1558006&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java
 Tue Jan 14 10:50:10 2014
@@ -142,7 +142,19 @@ class MongoRootBuilder extends MemoryNod
      */
     NodeState merge(CommitHook hook, CommitInfo info) throws 
CommitFailedException {
         purge();
-        branch.merge(hook, info);
+        boolean success = false;
+        try {
+            branch.merge(hook, info);
+            success = true;
+        } finally {
+            if (!success) {
+                // need to adjust base and head of this builder
+                // in case branch.merge() did a rebase and then
+                // a commit hook failed the merge
+                super.reset(branch.getHead());
+                this.base = branch.getBase();
+            }
+        }
         return reset();
     }
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java?rev=1558006&r1=1558005&r2=1558006&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/NodeStoreTest.java
 Tue Jan 14 10:50:10 2014
@@ -19,11 +19,12 @@
 package org.apache.jackrabbit.oak.kernel;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static junit.framework.Assert.assertFalse;
 import static org.apache.jackrabbit.oak.api.Type.LONG;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.junit.runners.Parameterized.Parameters;
 
 import java.util.ArrayList;
@@ -446,6 +447,34 @@ public class NodeStoreTest {
         compareAgainstBaseState(KernelNodeState.MAX_CHILD_NODE_NAMES);
     }
 
+    @Test // OAK-1320
+    public void rebaseWithFailedMerge() throws CommitFailedException {
+        NodeBuilder rootBuilder = store.getRoot().builder();
+        rootBuilder.child("foo");
+
+        // commit something in between to force rebase
+        NodeBuilder b = store.getRoot().builder();
+        b.child("bar");
+        store.merge(b, EmptyHook.INSTANCE, null);
+
+        try {
+            store.merge(rootBuilder, new CommitHook() {
+                @Nonnull
+                @Override
+                public NodeState processCommit(NodeState before, NodeState 
after)
+                        throws CommitFailedException {
+                    throw new CommitFailedException("", 0, "commit rejected");
+                }
+            }, null);
+            fail("must throw CommitFailedException");
+        } catch (CommitFailedException e) {
+            // expected
+        }
+        // merge again
+        NodeState root = store.merge(rootBuilder, EmptyHook.INSTANCE, null);
+        assertTrue(root.hasChildNode("bar"));
+    }
+
     private void compareAgainstBaseState(int childNodeCount) throws 
CommitFailedException {
         NodeState before = store.getRoot();
         NodeBuilder builder = before.builder();


Reply via email to