Ensure all active nodes are in contention before relinquishing a partition

Change-Id: I846f810547b286736d26d319f315048398334a83
(cherry picked from commit 783d3d24d6ad1360615efa773efb2f5675150543)
diff --git a/core/store/dist/src/main/java/org/onosproject/store/intent/impl/IntentPartitionManager.java b/core/store/dist/src/main/java/org/onosproject/store/intent/impl/IntentPartitionManager.java
index 3080143..2d09bcf 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/intent/impl/IntentPartitionManager.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/intent/impl/IntentPartitionManager.java
@@ -200,8 +200,12 @@
 
         for (int i = 0; i < relinquish; i++) {
             String topic = myPartitions.get(i);
-            leadershipService.withdraw(topic);
-            executor.schedule(() -> recontest(topic), BACKOFF_TIME, TimeUnit.SECONDS);
+            // Wait till all active nodes are in contention for partition ownership.
+            // This avoids too many relinquish/reclaim cycles.
+            if (leadershipService.getCandidates(topic).size() == activeNodes) {
+                leadershipService.withdraw(topic);
+                executor.schedule(() -> recontest(topic), BACKOFF_TIME, TimeUnit.SECONDS);
+            }
         }
     }
 
diff --git a/core/store/dist/src/test/java/org/onosproject/store/intent/impl/IntentPartitionManagerTest.java b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/IntentPartitionManagerTest.java
index 89ee8d3..fb44abd 100644
--- a/core/store/dist/src/test/java/org/onosproject/store/intent/impl/IntentPartitionManagerTest.java
+++ b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/IntentPartitionManagerTest.java
@@ -116,6 +116,11 @@
                                                               allNodes))
                                     .anyTimes();
         }
+        for (int i = 0; i < IntentPartitionManager.NUM_PARTITIONS; i++) {
+            expect(leadershipService.getCandidates(ELECTION_PREFIX + i))
+            .andReturn(Arrays.asList(MY_NODE_ID, OTHER_NODE_ID))
+            .anyTimes();
+        }
     }
 
     /**