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 mr...@apache.org on 2014/12/01 09:46:30 UTC

svn commit: r1642648 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/document/ test/java/org/apache/jackrabbit/oak/plugins/document/

Author: mreutegg
Date: Mon Dec  1 08:46:30 2014
New Revision: 1642648

URL: http://svn.apache.org/r1642648
Log:
OAK-2308: Incorrect recovery of _lastRev for branch commit

Test and fix

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java?rev=1642648&r1=1642647&r2=1642648&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java Mon Dec  1 08:46:30 2014
@@ -289,7 +289,8 @@ public class LastRevRecoveryAgent {
         // if found then lastRev needs to be fixed
         for (Revision rev : revs) {
             if (rev.compareRevisionTime(currentLastRev) > 0) {
-                if (doc.isCommitted(rev)) {
+                rev = doc.getCommitRevision(rev);
+                if (rev != null) {
                     return rev;
                 }
             } else {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java?rev=1642648&r1=1642647&r2=1642648&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java Mon Dec  1 08:46:30 2014
@@ -545,6 +545,26 @@ public final class NodeDocument extends 
     }
 
     /**
+     * Returns the commit revision for the change with the given revision.
+     *
+     * @param revision the revision of a change.
+     * @return the commit revision of the change or {@code null} if the change
+     *          is not committed or unknown.
+     */
+    @CheckForNull
+    public Revision getCommitRevision(@Nonnull Revision revision) {
+        NodeDocument commitRoot = getCommitRoot(checkNotNull(revision));
+        if (commitRoot == null) {
+            return null;
+        }
+        String value = commitRoot.getCommitValue(revision);
+        if (Utils.isCommitted(value)) {
+            return Utils.resolveCommitRevision(revision, value);
+        }
+        return null;
+    }
+
+    /**
      * Returns <code>true</code> if this document contains an entry for the
      * given <code>revision</code> in the {@link #REVISIONS} map. Please note
      * that an entry in the {@link #REVISIONS} map does not necessarily mean

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1642648&r1=1642647&r2=1642648&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java Mon Dec  1 08:46:30 2014
@@ -677,6 +677,52 @@ public class DocumentNodeStoreTest {
         store.dispose();
     }
 
+    // OAK-2308
+    @Test
+    public void recoverBranchCommit() throws Exception {
+        Clock clock = new Clock.Virtual();
+        clock.waitUntil(System.currentTimeMillis());
+
+        MemoryDocumentStore docStore = new MemoryDocumentStore();
+
+        DocumentNodeStore store1 = new DocumentMK.Builder()
+                .setDocumentStore(docStore)
+                .setAsyncDelay(0).clock(clock).getNodeStore();
+
+        NodeBuilder builder = store1.getRoot().builder();
+        builder.child("test");
+        merge(store1, builder);
+        // make sure all _lastRevs are written back
+        store1.runBackgroundOperations();
+
+        builder = store1.getRoot().builder();
+        NodeBuilder node = builder.getChildNode("test").child("node");
+        String id = Utils.getIdFromPath("/test/node");
+        int i = 0;
+        // force creation of a branch
+        while (docStore.find(NODES, id) == null) {
+            node.setProperty("foo", i++);
+        }
+        merge(store1, builder);
+
+        // wait until lease expires
+        clock.waitUntil(clock.getTime() + store1.getClusterInfo().getLeaseTime() + 1000);
+        // run recovery for this store
+        LastRevRecoveryAgent agent = store1.getLastRevRecoveryAgent();
+        assertTrue(agent.isRecoveryNeeded());
+        agent.recover(store1.getClusterId());
+
+        // start a second store
+        DocumentNodeStore store2 = new DocumentMK.Builder()
+                .setDocumentStore(docStore)
+                .setAsyncDelay(0).clock(clock).getNodeStore();
+        // must see /test/node
+        assertTrue(store2.getRoot().getChildNode("test").getChildNode("node").exists());
+
+        store2.dispose();
+        store1.dispose();
+    }
+
     private static void merge(NodeStore store, NodeBuilder root)
             throws CommitFailedException {
         store.merge(root, EmptyHook.INSTANCE, CommitInfo.EMPTY);