Author: catholicon
Date: Thu Dec 22 22:23:25 2016
New Revision: 1775757

URL: http://svn.apache.org/viewvc?rev=1775757&view=rev
Log:
OAK-5337: LastRevRecoveryAgent should avoid recovering documents from its own 
cluster id if the instance is running

Skip self-clusterId while filtering cluster candidates that "might" need 
recovery

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgent.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgentTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevSingleNodeRecoveryTest.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=1775757&r1=1775756&r2=1775757&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
 Thu Dec 22 22:23:25 2016
@@ -437,7 +437,9 @@ public class LastRevRecoveryAgent {
 
     /**
      * Gets the _lastRev recovery candidate cluster nodes. This also includes
-     * cluster nodes that are currently being recovered.
+     * cluster nodes that are currently being recovered. The method would not
+     * return self as a candidate for recovery even if it has failed to update
+     * lease in time
      *
      * @return the recovery candidate nodes.
      */
@@ -446,7 +448,7 @@ public class LastRevRecoveryAgent {
                 new Predicate<ClusterNodeInfoDocument>() {
             @Override
             public boolean apply(ClusterNodeInfoDocument input) {
-                return missingLastRevUtil.isRecoveryNeeded(input);
+                return nodeStore.getClusterId() != input.getClusterId() && 
missingLastRevUtil.isRecoveryNeeded(input);
             }
         }), new Function<ClusterNodeInfoDocument, Integer>() {
             @Override

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgentTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgentTest.java?rev=1775757&r1=1775756&r2=1775757&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgentTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgentTest.java
 Thu Dec 22 22:23:25 2016
@@ -115,10 +115,11 @@ public class LastRevRecoveryAgentTest {
     }
 
     @After
-    public void tearDown(){
+    public void tearDown() throws Exception {
         ds1.dispose();
         ds2.dispose();
         sharedStore.dispose();
+        fixture.dispose();
         ClusterNodeInfo.resetClockToDefault();
         Revision.resetClockToDefault();
     }
@@ -163,6 +164,48 @@ public class LastRevRecoveryAgentTest {
         assertEquals(zlastRev2, getDocument(ds1, "/").getLastRev().get(c2Id));
     }
 
+    //OAK-5337
+    @Test
+    public void testSelfRecovery() throws Exception{
+        //1. Create base structure /x/y
+        NodeBuilder b1 = ds1.getRoot().builder();
+        b1.child("x").child("y");
+        merge(ds1, b1);
+        ds1.runBackgroundOperations();
+
+        //2. Add a new node /x/y/z in C1
+        b1 = ds1.getRoot().builder();
+        b1.child("x").child("y").child("z");
+        merge(ds1, b1);
+
+        long leaseTime = ds1.getClusterInfo().getLeaseTime();
+
+        clock.waitUntil(clock.getTime() + leaseTime + 10);
+
+        //Renew the lease for C2
+        ds2.getClusterInfo().renewLease();
+        //C1 needs recovery from lease timeout pov
+        assertTrue(ds1.getLastRevRecoveryAgent().isRecoveryNeeded());
+
+        Iterable<Integer> cids = 
ds1.getLastRevRecoveryAgent().getRecoveryCandidateNodes();
+        //.. but, it won't be returned while we iterate candidate nodes from 
self
+        assertEquals(0, Iterables.size(cids));
+
+        cids = ds2.getLastRevRecoveryAgent().getRecoveryCandidateNodes();
+        //... checking that from other node still reports
+        assertEquals(1, Iterables.size(cids));
+        assertEquals(c1Id, Iterables.get(cids, 0).intValue());
+
+        ds2.runBackgroundOperations();
+        
assertFalse(ds2.getRoot().getChildNode("x").getChildNode("y").hasChildNode("z"));
+
+        // yet, calling recover with self-cluster-id still works (useful for 
startup LRRA)
+        ds1.getLastRevRecoveryAgent().recover(Iterables.get(cids, 0));
+
+        ds2.runBackgroundOperations();
+        
assertTrue(ds2.getRoot().getChildNode("x").getChildNode("y").hasChildNode("z"));
+    }
+
     @Test
     public void testRepeatedRecovery() throws Exception {
         //1. Create base structure /x/y

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevSingleNodeRecoveryTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevSingleNodeRecoveryTest.java?rev=1775757&r1=1775756&r2=1775757&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevSingleNodeRecoveryTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevSingleNodeRecoveryTest.java
 Thu Dec 22 22:23:25 2016
@@ -20,6 +20,7 @@
 package org.apache.jackrabbit.oak.plugins.document;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.util.Collection;
@@ -173,10 +174,13 @@ public class LastRevSingleNodeRecoveryTe
         clock.waitUntil(clock.getTime() + mk.getClusterInfo().getLeaseTime() + 
1000);
 
         LastRevRecoveryAgent recoveryAgent = 
mk.getNodeStore().getLastRevRecoveryAgent();
-        Iterable<Integer> cids = recoveryAgent.getRecoveryCandidateNodes();
 
-        assertEquals(1, Iterables.size(cids));
-        assertEquals(Integer.valueOf(1), Iterables.get(cids, 0));
+        // Post OAK-5337, a cluster node won't report itself as a candidate 
for recovery
+        // Recovery agent would still detect that recovery is required and 
calling
+        // recover on self would recover too (testLastRevRestore)
+        assertTrue(recoveryAgent.isRecoveryNeeded());
+        Iterable<Integer> cids = recoveryAgent.getRecoveryCandidateNodes();
+        assertEquals(0, Iterables.size(cids));
     }
     
     private void setupScenario() throws InterruptedException {


Reply via email to