Added a raftVersion field to AppendEntriesReply and modified
AbstractLeader to store the raftVersion in the FollowerLogInformation.
This will enable sending the appropriate serialized version for
subsequent messages sent to the follower.
The raftVersion in the FollowerLogInformation is initialized to
0 (HELIUM_VERSION) so we assume the oldest version for backwards
compatibility until we get the first AppendEntriesReply with the
follower's actual version.
Since we're adding a new field to AppendEntriesReply this won't break
backwards compatibility as Java serialization handles that. The
raftVersion will be set to 0 if sent from a pre-boron version.
Change-Id: I4519c4f314674840f2578848b2888c3e8467dd21
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
* Sets the payload data version of the follower.
*/
void setPayloadVersion(short payloadVersion);
* Sets the payload data version of the follower.
*/
void setPayloadVersion(short payloadVersion);
+
+ /**
+ * @return the raft version of the follower.
+ */
+ short getRaftVersion();
+
+ /**
+ * Sets the raft version of the follower.
+ */
+ void setRaftVersion(short payloadVersion);
private short payloadVersion = -1;
private short payloadVersion = -1;
+ // Assume the HELIUM_VERSION version initially for backwards compatibility until we obtain the follower's
+ // actual version via AppendEntriesReply. Although we no longer support the Helium version, a pre-Boron
+ // follower will not have the version field in AppendEntriesReply so it will be set to 0 which is
+ // HELIUM_VERSION.
+ private short raftVersion = RaftVersions.HELIUM_VERSION;
+
private final PeerInfo peerInfo;
public FollowerLogInformationImpl(PeerInfo peerInfo, long matchIndex, RaftActorContext context) {
private final PeerInfo peerInfo;
public FollowerLogInformationImpl(PeerInfo peerInfo, long matchIndex, RaftActorContext context) {
this.payloadVersion = payloadVersion;
}
this.payloadVersion = payloadVersion;
}
+ @Override
+ public short getRaftVersion() {
+ return raftVersion;
+ }
+
+ @Override
+ public void setRaftVersion(short raftVersion) {
+ this.raftVersion = raftVersion;
+ }
+
@Override
public String toString() {
return "FollowerLogInformationImpl [id=" + getId() + ", nextIndex=" + nextIndex + ", matchIndex=" + matchIndex
@Override
public String toString() {
return "FollowerLogInformationImpl [id=" + getId() + ", nextIndex=" + nextIndex + ", matchIndex=" + matchIndex
public interface RaftVersions {
short HELIUM_VERSION = 0;
short LITHIUM_VERSION = 1;
public interface RaftVersions {
short HELIUM_VERSION = 0;
short LITHIUM_VERSION = 1;
- short CURRENT_VERSION = LITHIUM_VERSION;
+ short BORON_VERSION = 3;
+ short CURRENT_VERSION = BORON_VERSION;
followerLogInformation.markFollowerActive();
followerLogInformation.setPayloadVersion(appendEntriesReply.getPayloadVersion());
followerLogInformation.markFollowerActive();
followerLogInformation.setPayloadVersion(appendEntriesReply.getPayloadVersion());
+ followerLogInformation.setRaftVersion(appendEntriesReply.getRaftVersion());
boolean updated = false;
if (appendEntriesReply.isSuccess()) {
boolean updated = false;
if (appendEntriesReply.isSuccess()) {
package org.opendaylight.controller.cluster.raft.messages;
package org.opendaylight.controller.cluster.raft.messages;
+import org.opendaylight.controller.cluster.raft.RaftVersions;
+
/**
* Reply for the AppendEntriesRpc message
*/
/**
* Reply for the AppendEntriesRpc message
*/
private final short payloadVersion;
private final short payloadVersion;
+ private final short raftVersion = RaftVersions.CURRENT_VERSION;
+
private final boolean forceInstallSnapshot;
public AppendEntriesReply(String followerId, long term, boolean success, long logLastIndex, long logLastTerm,
private final boolean forceInstallSnapshot;
public AppendEntriesReply(String followerId, long term, boolean success, long logLastIndex, long logLastTerm,
+ public short getRaftVersion() {
+ return raftVersion;
+ }
+
public boolean isForceInstallSnapshot() {
return forceInstallSnapshot;
}
public boolean isForceInstallSnapshot() {
return forceInstallSnapshot;
}
public String toString() {
return "AppendEntriesReply [term=" + getTerm() + ", success=" + success + ", followerId=" + followerId
+ ", logLastIndex=" + logLastIndex + ", logLastTerm=" + logLastTerm + ", forceInstallSnapshot="
public String toString() {
return "AppendEntriesReply [term=" + getTerm() + ", success=" + success + ", followerId=" + followerId
+ ", logLastIndex=" + logLastIndex + ", logLastTerm=" + logLastTerm + ", forceInstallSnapshot="
- + forceInstallSnapshot + ", payloadVersion=" + payloadVersion + "]";
+ + forceInstallSnapshot + ", payloadVersion=" + payloadVersion + ", raftVersion=" + raftVersion + "]";
import org.opendaylight.controller.cluster.raft.RaftActorContext;
import org.opendaylight.controller.cluster.raft.RaftActorLeadershipTransferCohort;
import org.opendaylight.controller.cluster.raft.RaftState;
import org.opendaylight.controller.cluster.raft.RaftActorContext;
import org.opendaylight.controller.cluster.raft.RaftActorLeadershipTransferCohort;
import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.RaftVersions;
import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
import org.opendaylight.controller.cluster.raft.SerializationUtils;
import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
import org.opendaylight.controller.cluster.raft.SerializationUtils;
leader = new Leader(leaderActorContext);
leader = new Leader(leaderActorContext);
+ FollowerLogInformation followerInfo = leader.getFollower(FOLLOWER_ID);
+
assertEquals(payloadVersion, leader.getLeaderPayloadVersion());
assertEquals(payloadVersion, leader.getLeaderPayloadVersion());
+ assertEquals(RaftVersions.HELIUM_VERSION, followerInfo.getRaftVersion());
short payloadVersion = 5;
AppendEntriesReply reply = new AppendEntriesReply(FOLLOWER_ID, 1, true, 2, 1, payloadVersion);
short payloadVersion = 5;
AppendEntriesReply reply = new AppendEntriesReply(FOLLOWER_ID, 1, true, 2, 1, payloadVersion);
assertEquals(2, applyState.getReplicatedLogEntry().getIndex());
assertEquals(2, applyState.getReplicatedLogEntry().getIndex());
- FollowerLogInformation followerInfo = leader.getFollower(FOLLOWER_ID);
+ assertEquals(2, followerInfo.getMatchIndex());
+ assertEquals(3, followerInfo.getNextIndex());
assertEquals(payloadVersion, followerInfo.getPayloadVersion());
assertEquals(payloadVersion, followerInfo.getPayloadVersion());
+ assertEquals(RaftVersions.CURRENT_VERSION, followerInfo.getRaftVersion());