Bug 3020: Add leader version to LeaderStateChanged 84/19184/3
authorTom Pantelis <tpanteli@brocade.com>
Fri, 24 Apr 2015 22:26:22 +0000 (18:26 -0400)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 6 Jun 2015 18:59:41 +0000 (18:59 +0000)
Added the leader's payload version to the LeaderStateChanged message and
modified the raft code to set it.

Change-Id: I9a34f90641a2962418d234bb56e55f2df5207e5b
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
15 files changed:
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractLeader.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehavior.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/DelegatingRaftActorBehavior.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/RaftActorBehavior.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActor.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/notifications/LeaderStateChanged.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ShardLeaderStateChanged.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/RoleChangeNotifierTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardManagerTest.java

index 0b3fca090cfbfeed1ca89282a406587648848730..ebc157bc1729aff08199b5d6fe4a17b04afdc552 100644 (file)
@@ -303,9 +303,11 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
 
         // it can happen that the state has not changed but the leader has changed.
         Optional<ActorRef> roleChangeNotifier = getRoleChangeNotifier();
-        if(!Objects.equal(oldBehaviorLeaderId, currentBehavior.getLeaderId())) {
+        if(!Objects.equal(oldBehaviorLeaderId, currentBehavior.getLeaderId()) ||
+           oldBehaviorState.getLeaderPayloadVersion() != currentBehavior.getLeaderPayloadVersion()) {
             if(roleChangeNotifier.isPresent()) {
-                roleChangeNotifier.get().tell(newLeaderStateChanged(getId(), currentBehavior.getLeaderId()), getSelf());
+                roleChangeNotifier.get().tell(newLeaderStateChanged(getId(), currentBehavior.getLeaderId(),
+                        currentBehavior.getLeaderPayloadVersion()), getSelf());
             }
 
             onLeaderChanged(oldBehaviorLeaderId, currentBehavior.getLeaderId());
@@ -318,8 +320,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
         }
     }
 
-    protected LeaderStateChanged newLeaderStateChanged(String memberId, String leaderId) {
-        return new LeaderStateChanged(memberId, leaderId);
+    protected LeaderStateChanged newLeaderStateChanged(String memberId, String leaderId, short leaderPayloadVersion) {
+        return new LeaderStateChanged(memberId, leaderId, leaderPayloadVersion);
     }
 
     @Override
@@ -633,10 +635,12 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
     private static class BehaviorStateHolder {
         private RaftActorBehavior behavior;
         private String leaderId;
+        private short leaderPayloadVersion;
 
         void init(RaftActorBehavior behavior) {
             this.behavior = behavior;
             this.leaderId = behavior != null ? behavior.getLeaderId() : null;
+            this.leaderPayloadVersion = behavior != null ? behavior.getLeaderPayloadVersion() : -1;
         }
 
         RaftActorBehavior getBehavior() {
@@ -646,5 +650,9 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
         String getLeaderId() {
             return leaderId;
         }
+
+        short getLeaderPayloadVersion() {
+            return leaderPayloadVersion;
+        }
     }
 }
index 2eb3b32c6f13d0c01db85fe7fa141a1eb6c2aac9..de1e1d11ff0c2045e3056336a4bef5344d21a240 100644 (file)
@@ -93,6 +93,8 @@ public abstract class AbstractLeader extends AbstractRaftActorBehavior {
     public AbstractLeader(RaftActorContext context) {
         super(context, RaftState.Leader);
 
+        setLeaderPayloadVersion(context.getPayloadVersion());
+
         final Builder<String, FollowerLogInformation> ftlBuilder = ImmutableMap.builder();
         for (String followerId : context.getPeerAddresses().keySet()) {
             FollowerLogInformation followerLogInformation =
index 9e4ae6f6a5f6ea912964cec51e060de673e691a7..fc2f137e886085b9f8de644a2a1ae2b660281fa3 100644 (file)
@@ -61,6 +61,8 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
      */
     protected String leaderId = null;
 
+    private short leaderPayloadVersion = -1;
+
     private long replicatedToAllIndex = -1;
 
     private final String logName;
@@ -420,6 +422,15 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
         return leaderId;
     }
 
+    @Override
+    public short getLeaderPayloadVersion() {
+        return leaderPayloadVersion;
+    }
+
+    public void setLeaderPayloadVersion(short leaderPayloadVersion) {
+        this.leaderPayloadVersion = leaderPayloadVersion;
+    }
+
     protected RaftActorBehavior switchBehavior(RaftActorBehavior behavior) {
         LOG.info("{} :- Switching from behavior {} to {}", logName(), this.state(), behavior.state());
         try {
index 776dae73fac5d1154b40781bd58c0d06f0370b3a..64bdc4a504efd8f78f56bdb5debd3c1a2e251178 100644 (file)
@@ -55,4 +55,9 @@ public class DelegatingRaftActorBehavior implements RaftActorBehavior {
     public long getReplicatedToAllIndex() {
         return delegate.getReplicatedToAllIndex();
     }
+
+    @Override
+    public short getLeaderPayloadVersion() {
+        return delegate.getLeaderPayloadVersion();
+    }
 }
index 150f300a4680aee0499e962efac85505e671c527..d16ddabddee988df72c90866a05486312ecc48d9 100644 (file)
@@ -120,6 +120,8 @@ public class Follower extends AbstractRaftActorBehavior {
         // If we got here then we do appear to be talking to the leader
         leaderId = appendEntries.getLeaderId();
 
+        setLeaderPayloadVersion(appendEntries.getPayloadVersion());
+
         // 2. Reply false if log doesn’t contain an entry at prevLogIndex
         // whose term matches prevLogTerm (§5.3)
 
index b766e0ce39fe9be1b847f54c625c802d036a7a0a..a4f7a42640500942691de396a5af0230808f69c6 100644 (file)
@@ -62,4 +62,9 @@ public interface RaftActorBehavior extends AutoCloseable{
      * @return
      */
     long getReplicatedToAllIndex();
+
+    /**
+     * Returns the leader's payload data version.
+     */
+    short getLeaderPayloadVersion();
 }
index a6853caf9ea78fbbd45421a049858ec948e24678..d72d40416f3b3288a1b3f2b1aaa97f48c473af82 100644 (file)
@@ -29,6 +29,8 @@ import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payloa
 
 public class MockRaftActor extends RaftActor implements RaftActorRecoveryCohort, RaftActorSnapshotCohort {
 
+    public static final short PAYLOAD_VERSION = 5;
+
     final RaftActor actorDelegate;
     final RaftActorRecoveryCohort recoveryCohortDelegate;
     final RaftActorSnapshotCohort snapshotCohortDelegate;
@@ -70,7 +72,7 @@ public class MockRaftActor extends RaftActor implements RaftActorRecoveryCohort,
 
     public MockRaftActor(String id, Map<String, String> peerAddresses, Optional<ConfigParams> config,
                          DataPersistenceProvider dataPersistenceProvider) {
-        super(id, peerAddresses, config, (short) 0);
+        super(id, peerAddresses, config, PAYLOAD_VERSION);
         state = new ArrayList<>();
         this.actorDelegate = mock(RaftActor.class);
         this.recoveryCohortDelegate = mock(RaftActorRecoveryCohort.class);
index 45c2e0d0adf6094a1e9800cf78a05d20653968c5..fb9541c8d9dd598961522ac08a476a7ffb744bb6 100644 (file)
@@ -418,15 +418,18 @@ public class RaftActorTest extends AbstractActorTest {
                     notifierActor, LeaderStateChanged.class);
 
             assertEquals(raftRoleChanged.getMemberId(), leaderStateChange.getLeaderId());
+            assertEquals(MockRaftActor.PAYLOAD_VERSION, leaderStateChange.getLeaderPayloadVersion());
 
             notifierActor.underlyingActor().clear();
 
             MockRaftActor raftActor = raftActorRef.underlyingActor();
             final String newLeaderId = "new-leader";
+            final short newLeaderVersion = 6;
             Follower follower = new Follower(raftActor.getRaftActorContext()) {
                 @Override
                 public RaftActorBehavior handleMessage(ActorRef sender, Object message) {
                     leaderId = newLeaderId;
+                    setLeaderPayloadVersion(newLeaderVersion);
                     return this;
                 }
             };
@@ -448,6 +451,15 @@ public class RaftActorTest extends AbstractActorTest {
             leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
             assertEquals(persistenceId, leaderStateChange.getMemberId());
             assertEquals(newLeaderId, leaderStateChange.getLeaderId());
+            assertEquals(newLeaderVersion, leaderStateChange.getLeaderPayloadVersion());
+
+            notifierActor.underlyingActor().clear();
+
+            raftActor.handleCommand("any");
+
+            Uninterruptibles.sleepUninterruptibly(505, TimeUnit.MILLISECONDS);
+            leaderStateChange = MessageCollectorActor.getFirstMatching(notifierActor, LeaderStateChanged.class);
+            assertNull(leaderStateChange);
         }};
     }
 
index 443ebc31a4ae49380f92d3bfa341879882d137e5..ce1b46e9fd0d400e8467f091fd4621eb3548bbfc 100644 (file)
@@ -401,7 +401,9 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest {
         // before the new behavior was created (1 in this case)
         // This will not work for a Candidate because as soon as a Candidate
         // is created it increments the term
-        AppendEntries appendEntries = new AppendEntries(1, "leader-1", 2, 1, entries, 4, -1, (short)0);
+        short leaderPayloadVersion = 10;
+        String leaderId = "leader-1";
+        AppendEntries appendEntries = new AppendEntries(1, leaderId, 2, 1, entries, 4, -1, leaderPayloadVersion);
 
         follower = createBehavior(context);
 
@@ -413,6 +415,9 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest {
         assertEquals("Entry 3", entries.get(0), log.get(3));
         assertEquals("Entry 4", entries.get(1), log.get(4));
 
+        assertEquals("getLeaderPayloadVersion", leaderPayloadVersion, newBehavior.getLeaderPayloadVersion());
+        assertEquals("getLeaderId", leaderId, newBehavior.getLeaderId());
+
         expectAndVerifyAppendEntriesReply(1, true, context.getId(), 1, 4);
     }
 
index ccde8bfb226fb4cb3b3dcbaa333139de1eb00524..07548d6a9248b450e9ee478fabbe6dd7d357829e 100644 (file)
@@ -58,6 +58,7 @@ public class LeaderTest extends AbstractLeaderTest {
             Props.create(ForwardMessageToBehaviorActor.class), actorFactory.generateActorId("follower"));
 
     private Leader leader;
+    private final short payloadVersion = 5;
 
     @Override
     @After
@@ -967,6 +968,7 @@ public class LeaderTest extends AbstractLeaderTest {
         configParams.setElectionTimeoutFactor(100000);
         MockRaftActorContext context = new MockRaftActorContext(id, getSystem(), actorRef);
         context.setConfigParams(configParams);
+        context.setPayloadVersion(payloadVersion);
         return context;
     }
 
@@ -1360,6 +1362,8 @@ public class LeaderTest extends AbstractLeaderTest {
 
         leader = new Leader(leaderActorContext);
 
+        assertEquals(payloadVersion, leader.getLeaderPayloadVersion());
+
         short payloadVersion = 5;
         AppendEntriesReply reply = new AppendEntriesReply(FOLLOWER_ID, 1, true, 2, 1, payloadVersion);
 
index 23c95ecc99c0dea3ca144092018fd303d6dd7511..359e2b221b55105c685c7ce4362b89b9fc86e628 100644 (file)
@@ -20,10 +20,12 @@ import javax.annotation.Nullable;
 public class LeaderStateChanged {
     private final String memberId;
     private final String leaderId;
+    private final short leaderPayloadVersion;
 
-    public LeaderStateChanged(@Nonnull String memberId, @Nullable String leaderId) {
+    public LeaderStateChanged(@Nonnull String memberId, @Nullable String leaderId, short leaderPayloadVersion) {
         this.memberId = Preconditions.checkNotNull(memberId);
         this.leaderId = leaderId;
+        this.leaderPayloadVersion = leaderPayloadVersion;
     }
 
     public @Nonnull String getMemberId() {
@@ -34,11 +36,15 @@ public class LeaderStateChanged {
         return leaderId;
     }
 
+    public short getLeaderPayloadVersion() {
+        return leaderPayloadVersion;
+    }
+
     @Override
     public String toString() {
         StringBuilder builder = new StringBuilder();
         builder.append("LeaderStateChanged [memberId=").append(memberId).append(", leaderId=").append(leaderId)
-                .append("]");
+                .append(", leaderPayloadVersion=").append(leaderPayloadVersion).append("]");
         return builder.toString();
     }
 }
index 71afb5c9b7394215406926306f7555b034231b47..c8f2b1b8d98a45e86a827bb7613fb94f850b4243 100644 (file)
@@ -278,9 +278,10 @@ public class Shard extends RaftActor {
     }
 
     @Override
-    protected LeaderStateChanged newLeaderStateChanged(String memberId, String leaderId) {
+    protected LeaderStateChanged newLeaderStateChanged(String memberId, String leaderId, short leaderPayloadVersion) {
         return new ShardLeaderStateChanged(memberId, leaderId,
-                isLeader() ? Optional.<DataTree>of(store.getDataTree()) : Optional.<DataTree>absent());
+                isLeader() ? Optional.<DataTree>of(store.getDataTree()) : Optional.<DataTree>absent(),
+                leaderPayloadVersion);
     }
 
     private void onDatastoreContext(DatastoreContext context) {
index d9a55ab1e98e7c0f752e73035d8f25494e9f34d1..20b7d818e315fc60b018e0c6e79082a11036b1e7 100644 (file)
@@ -25,8 +25,8 @@ public class ShardLeaderStateChanged extends LeaderStateChanged {
     private final Optional<DataTree> localShardDataTree;
 
     public ShardLeaderStateChanged(@Nonnull String memberId, @Nonnull String leaderId,
-            @Nonnull Optional<DataTree> localShardDataTree) {
-        super(memberId, leaderId);
+            @Nonnull Optional<DataTree> localShardDataTree, short leaderPayloadVersion) {
+        super(memberId, leaderId, leaderPayloadVersion);
         this.localShardDataTree = Preconditions.checkNotNull(localShardDataTree);
     }
 
index 1ab03b216cdf09075d5747b7a76bf7e579bb9c38..de852c0887d49d9cd3224c7a3ea659100ffb6328 100644 (file)
@@ -81,7 +81,7 @@ public class RoleChangeNotifierTest extends AbstractActorTest  {
             TestActorRef<RoleChangeNotifier> notifierTestActorRef = TestActorRef.create(
                 getSystem(), RoleChangeNotifier.getProps(actorId), actorId);
 
-            notifierTestActorRef.tell(new LeaderStateChanged("member1", "leader1"), ActorRef.noSender());
+            notifierTestActorRef.tell(new LeaderStateChanged("member1", "leader1", (short)5), ActorRef.noSender());
 
             // listener registers after the sate has been changed, ensure we sent the latest state change after a reply
             notifierTestActorRef.tell(new RegisterRoleChangeListener(), getRef());
@@ -91,12 +91,14 @@ public class RoleChangeNotifierTest extends AbstractActorTest  {
             LeaderStateChanged leaderStateChanged = expectMsgClass(LeaderStateChanged.class);
             assertEquals("getMemberId", "member1", leaderStateChanged.getMemberId());
             assertEquals("getLeaderId", "leader1", leaderStateChanged.getLeaderId());
+            assertEquals("getLeaderPayloadVersion", 5, leaderStateChanged.getLeaderPayloadVersion());
 
-            notifierTestActorRef.tell(new LeaderStateChanged("member1", "leader2"), ActorRef.noSender());
+            notifierTestActorRef.tell(new LeaderStateChanged("member1", "leader2", (short)6), ActorRef.noSender());
 
             leaderStateChanged = expectMsgClass(LeaderStateChanged.class);
             assertEquals("getMemberId", "member1", leaderStateChanged.getMemberId());
             assertEquals("getLeaderId", "leader2", leaderStateChanged.getLeaderId());
+            assertEquals("getLeaderPayloadVersion", 6, leaderStateChanged.getLeaderPayloadVersion());
         }};
     }
 }
index ae8db2b5f5d2a4727dd063a51fe90cafbc609460..e95993de24bbe80b4c3f7bc7a6bc3fdf74816b8f 100644 (file)
@@ -156,7 +156,8 @@ public class ShardManagerTest extends AbstractActorTest {
             shardManager.tell(new ActorInitialized(), mockShardActor);
 
             DataTree mockDataTree = mock(DataTree.class);
-            shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree)), getRef());
+            shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree),
+                    DataStoreVersions.CURRENT_VERSION), getRef());
 
             MessageCollectorActor.expectFirstMatching(mockShardActor, RegisterRoleChangeListener.class);
             shardManager.tell((new RoleChangeNotification(memberId, RaftState.Candidate.name(),
@@ -183,7 +184,7 @@ public class ShardManagerTest extends AbstractActorTest {
             String memberId1 = "member-1-shard-default-" + shardMrgIDSuffix;
             shardManager.tell(new RoleChangeNotification(memberId1,
                     RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor);
-            shardManager.tell(new LeaderStateChanged(memberId1, memberId2), mockShardActor);
+            shardManager.tell(new LeaderStateChanged(memberId1, memberId2, DataStoreVersions.CURRENT_VERSION), mockShardActor);
 
             shardManager.tell(new FindPrimary(Shard.DEFAULT_NAME, false), getRef());
 
@@ -205,7 +206,8 @@ public class ShardManagerTest extends AbstractActorTest {
             String memberId1 = "member-1-shard-default-" + shardMrgIDSuffix;
             shardManager.tell(new RoleChangeNotification(memberId1,
                     RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor);
-            shardManager.tell(new ShardLeaderStateChanged(memberId1, memberId2, Optional.<DataTree>absent()), mockShardActor);
+            shardManager.tell(new ShardLeaderStateChanged(memberId1, memberId2, Optional.<DataTree>absent(),
+                    DataStoreVersions.CURRENT_VERSION), mockShardActor);
 
             shardManager.tell(new FindPrimary(Shard.DEFAULT_NAME, false), getRef());
 
@@ -257,7 +259,8 @@ public class ShardManagerTest extends AbstractActorTest {
             expectMsgClass(duration("5 seconds"), NoShardLeaderException.class);
 
             DataTree mockDataTree = mock(DataTree.class);
-            shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree)), mockShardActor);
+            shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree),
+                    DataStoreVersions.CURRENT_VERSION), mockShardActor);
 
             shardManager.tell(new FindPrimary(Shard.DEFAULT_NAME, false), getRef());
 
@@ -292,7 +295,8 @@ public class ShardManagerTest extends AbstractActorTest {
             expectNoMsg(FiniteDuration.create(150, TimeUnit.MILLISECONDS));
 
             DataTree mockDataTree = mock(DataTree.class);
-            shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree)), mockShardActor);
+            shardManager.tell(new ShardLeaderStateChanged(memberId, memberId, Optional.of(mockDataTree),
+                    DataStoreVersions.CURRENT_VERSION), mockShardActor);
 
             LocalPrimaryShardFound primaryFound = expectMsgClass(duration("5 seconds"), LocalPrimaryShardFound.class);
             assertTrue("Unexpected primary path " +  primaryFound.getPrimaryPath(),
@@ -390,7 +394,7 @@ public class ShardManagerTest extends AbstractActorTest {
 
             String memberId2 = "member-2-shard-astronauts-" + shardMrgIDSuffix;
             shardManager2.tell(new ShardLeaderStateChanged(memberId2, memberId2,
-                    Optional.of(mock(DataTree.class))), mockShardActor2);
+                    Optional.of(mock(DataTree.class)), DataStoreVersions.CURRENT_VERSION), mockShardActor2);
             shardManager2.tell(new RoleChangeNotification(memberId2,
                     RaftState.Candidate.name(), RaftState.Leader.name()), mockShardActor2);
 
@@ -457,10 +461,11 @@ public class ShardManagerTest extends AbstractActorTest {
             String memberId2 = "member-2-shard-default-" + shardMrgIDSuffix;
             String memberId1 = "member-1-shard-default-" + shardMrgIDSuffix;
             shardManager1.tell(new ShardLeaderStateChanged(memberId1, memberId2,
-                Optional.of(mock(DataTree.class))), mockShardActor1);
+                Optional.of(mock(DataTree.class)), DataStoreVersions.CURRENT_VERSION), mockShardActor1);
             shardManager1.tell(new RoleChangeNotification(memberId1,
                 RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor1);
-            shardManager2.tell(new ShardLeaderStateChanged(memberId2, memberId2, Optional.of(mock(DataTree.class))),
+            shardManager2.tell(new ShardLeaderStateChanged(memberId2, memberId2, Optional.of(mock(DataTree.class)),
+                    DataStoreVersions.CURRENT_VERSION),
                 mockShardActor2);
             shardManager2.tell(new RoleChangeNotification(memberId2,
                 RaftState.Candidate.name(), RaftState.Leader.name()), mockShardActor2);
@@ -538,10 +543,11 @@ public class ShardManagerTest extends AbstractActorTest {
             String memberId2 = "member-2-shard-default-" + shardMrgIDSuffix;
             String memberId1 = "member-1-shard-default-" + shardMrgIDSuffix;
             shardManager1.tell(new ShardLeaderStateChanged(memberId1, memberId2,
-                Optional.of(mock(DataTree.class))), mockShardActor1);
+                Optional.of(mock(DataTree.class)), DataStoreVersions.CURRENT_VERSION), mockShardActor1);
             shardManager1.tell(new RoleChangeNotification(memberId1,
                 RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor1);
-            shardManager2.tell(new ShardLeaderStateChanged(memberId2, memberId2, Optional.of(mock(DataTree.class))),
+            shardManager2.tell(new ShardLeaderStateChanged(memberId2, memberId2, Optional.of(mock(DataTree.class)),
+                    DataStoreVersions.CURRENT_VERSION),
                 mockShardActor2);
             shardManager2.tell(new RoleChangeNotification(memberId2,
                 RaftState.Candidate.name(), RaftState.Leader.name()), mockShardActor2);
@@ -567,8 +573,8 @@ public class ShardManagerTest extends AbstractActorTest {
 
             assertNull("Expected primaryShardInfoCache entry removed", primaryShardInfoCache.getIfPresent("default"));
 
-            shardManager1.tell(new ShardLeaderStateChanged(memberId1, memberId1, Optional.of(mock(DataTree.class))),
-                mockShardActor1);
+            shardManager1.tell(new ShardLeaderStateChanged(memberId1, memberId1, Optional.of(mock(DataTree.class)),
+                    DataStoreVersions.CURRENT_VERSION), mockShardActor1);
             shardManager1.tell(new RoleChangeNotification(memberId1,
                 RaftState.Follower.name(), RaftState.Leader.name()), mockShardActor1);
 
@@ -683,7 +689,7 @@ public class ShardManagerTest extends AbstractActorTest {
                 verify(ready, never()).countDown();
 
                 shardManager.underlyingActor().onReceiveCommand(new ShardLeaderStateChanged(memberId, memberId,
-                        Optional.of(mock(DataTree.class))));
+                        Optional.of(mock(DataTree.class)), DataStoreVersions.CURRENT_VERSION));
 
                 verify(ready, times(1)).countDown();
 
@@ -705,7 +711,8 @@ public class ShardManagerTest extends AbstractActorTest {
                 shardManager.underlyingActor().onReceiveCommand(MockClusterWrapper.createMemberUp("member-2", getRef().path().toString()));
 
                 shardManager.underlyingActor().onReceiveCommand(new ShardLeaderStateChanged(memberId,
-                        "member-2-shard-default-" + shardMrgIDSuffix, Optional.of(mock(DataTree.class))));
+                        "member-2-shard-default-" + shardMrgIDSuffix, Optional.of(mock(DataTree.class)),
+                        DataStoreVersions.CURRENT_VERSION));
 
                 verify(ready, times(1)).countDown();
 
@@ -725,7 +732,8 @@ public class ShardManagerTest extends AbstractActorTest {
                 verify(ready, never()).countDown();
 
                 shardManager.underlyingActor().onReceiveCommand(new ShardLeaderStateChanged(memberId,
-                        "member-2-shard-default-" + shardMrgIDSuffix, Optional.of(mock(DataTree.class))));
+                        "member-2-shard-default-" + shardMrgIDSuffix, Optional.of(mock(DataTree.class)),
+                        DataStoreVersions.CURRENT_VERSION));
 
                 shardManager.underlyingActor().onReceiveCommand(MockClusterWrapper.createMemberUp("member-2", getRef().path().toString()));