+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.raft.messages;
-
-public abstract class AbstractRaftRPC implements RaftRPC {
- @java.io.Serial
- private static final long serialVersionUID = -6061342433962854822L;
-
- // term
- private final long term;
-
- AbstractRaftRPC(final long term) {
- this.term = term;
- }
-
- @Override
- public final long getTerm() {
- return term;
- }
-
- // All implementations must use Externalizable Proxy pattern
- @java.io.Serial
- abstract Object writeReplace();
-}
/**
* Invoked by leader to replicate log entries (§5.3); also used as heartbeat (§5.2).
*/
-public final class AppendEntries extends AbstractRaftRPC {
+public final class AppendEntries extends RaftRPC {
@java.io.Serial
private static final long serialVersionUID = 1L;
/**
* Reply for the AppendEntries message.
*/
-public final class AppendEntriesReply extends AbstractRaftRPC {
+public final class AppendEntriesReply extends RaftRPC {
@java.io.Serial
private static final long serialVersionUID = -7487547356392536683L;
/**
* Message sent from a leader to install a snapshot chunk on a follower.
*/
-public final class InstallSnapshot extends AbstractRaftRPC {
+public final class InstallSnapshot extends RaftRPC {
@java.io.Serial
private static final long serialVersionUID = 1L;
*/
package org.opendaylight.controller.cluster.raft.messages;
-public final class InstallSnapshotReply extends AbstractRaftRPC {
+public final class InstallSnapshotReply extends RaftRPC {
@java.io.Serial
private static final long serialVersionUID = 642227896390779503L;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.controller.cluster.raft.messages;
import java.io.Serializable;
/**
* Interface implemented by all requests exchanged in the Raft protocol.
*/
-public interface RaftRPC extends Serializable, ControlMessage {
+public abstract sealed class RaftRPC implements Serializable, ControlMessage
+ permits AppendEntries, AppendEntriesReply,
+ InstallSnapshot, InstallSnapshotReply,
+ RequestVote, RequestVoteReply {
+ @java.io.Serial
+ private static final long serialVersionUID = 1L;
+
+ // TODO: signed long, e.g. we only support up to 63 bit terms. We really should support the full range, but that
+ // requires a complete audit of users. The safest way to do that is to make 'UnsignedLong getTerm()' and
+ // have a more efficient 'long term()', safe users are migrated to? Needs some careful experimentation.
+ private final long term;
+
+ RaftRPC(final long term) {
+ this.term = term;
+ }
+
/**
* Return the term in which this call is being made.
*
* @return The term ID
*/
- long getTerm();
+ public final long getTerm() {
+ return term;
+ }
+
+ @Override
+ public abstract String toString();
+
+ // All implementations must use Externalizable Proxy pattern
+ @java.io.Serial
+ abstract Object writeReplace();
}
/**
* Invoked by candidates to gather votes (§5.2).
*/
-public final class RequestVote extends AbstractRaftRPC {
+public final class RequestVote extends RaftRPC {
@java.io.Serial
private static final long serialVersionUID = -6967509186297108657L;
*/
package org.opendaylight.controller.cluster.raft.messages;
-public final class RequestVoteReply extends AbstractRaftRPC {
+public final class RequestVoteReply extends RaftRPC {
@java.io.Serial
private static final long serialVersionUID = 8427899326488775660L;
}
@Test
+ // TODO: parameterized with all possible RaftRPCs
public void testElectionScheduledWhenAnyRaftRPCReceived() {
MockRaftActorContext context = createActorContext();
follower = createBehavior(context);
- follower.handleMessage(leaderActor, new RaftRPC() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public long getTerm() {
- return 100;
- }
- });
+ follower.handleMessage(leaderActor, new RequestVoteReply(100, false));
verify(follower).scheduleElection(any(FiniteDuration.class));
}