Eliminate AbstractRaftRPC 88/114388/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 7 Nov 2024 11:18:31 +0000 (12:18 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 7 Nov 2024 11:18:31 +0000 (12:18 +0100)
The RaftRPC/AbstractRaftRPC split is artificial, let's merge the two
classes, which allows us to seal the entire hierarchy.

Change-Id: I2b50200e7ab286881c63865940db5d866dbda942
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AbstractRaftRPC.java [deleted file]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntries.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntriesReply.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshot.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshotReply.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RaftRPC.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVote.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVoteReply.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java

diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AbstractRaftRPC.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AbstractRaftRPC.java
deleted file mode 100644 (file)
index 038ad48..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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();
-}
index 29b404231a660ba558f886dcff165b8c60d14da9..6b5fe03e341b5e9c03dd4757ae83b604a970c6ae 100644 (file)
@@ -25,7 +25,7 @@ import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEnt
 /**
  * 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;
 
index 033a19a7b26e758a30430b902085649af4c886ef..ebc38450e3aac9bf60bedf41f932e187d5d5177b 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.controller.cluster.raft.RaftVersions;
 /**
  * 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;
 
index 85ff4193a8cbbef1c2bf8941d5dc404dfbe5fe83..89855911ca2e1a38c0aa33ef83ddf20c3d395a1b 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPay
 /**
  * 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;
 
index ed8b2800816f29a42c46b34adfa1aa5ca3004067..7b26a4d18ac51da95a3aaeb84c90546d2c8d1425 100644 (file)
@@ -7,7 +7,7 @@
  */
 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;
 
index 4a5c7b8b93ba66f9214fe464035ab4ac9bcf13b7..1520359d924dbf6d58b4fa64afba1d1e0e98e6ca 100644 (file)
@@ -5,7 +5,6 @@
  * 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;
@@ -14,11 +13,35 @@ import org.apache.pekko.dispatch.ControlMessage;
 /**
  * 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();
 }
index 2b33a12950620accf369300b23074710c8b5b3c2..61a621d8324dbea89ecff6d8708c8bc268479d55 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.cluster.raft.messages;
 /**
  * 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;
 
index 01fd9abe2e1266572122e155630e4eca82cfb4d1..08bcaaa5aff121ef9f20843f1e8a595d767c1ec5 100644 (file)
@@ -7,7 +7,7 @@
  */
 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;
 
index 5b9ed1f1701ff1709872a2509eb102606f1975d3..316a148be67497e44602d69472bfe1e6ba23933a 100644 (file)
@@ -1073,17 +1073,11 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest<Follower> {
     }
 
     @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));
     }