This is an automated email from the ASF dual-hosted git repository.

pjfanning pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko.git


The following commit(s) were added to refs/heads/main by this push:
     new 0c1de3363f remove the Akka 2.6.4 rolling-migration manifests from 
ClusterMessageSerializer (#3516)
0c1de3363f is described below

commit 0c1de3363f1617bdef8dd7faf46008d23869ae20
Author: PJ Fanning <[email protected]>
AuthorDate: Sun Sep 6 09:00:55 2026 +0100

    remove the Akka 2.6.4 rolling-migration manifests from 
ClusterMessageSerializer (#3516)
    
    Motivation:
    The Old* and *Pre2523 manifest vals were kept "for one version iteration
    from Akka 2.6.4" to allow rolling migration to short manifests, removable
    "in Akka 2.6.6 or later". No peer a Pekko node can talk to emits them:
    Pekko has always emitted the short manifests, and an actual old Akka node
    would emit akka.cluster.* strings, which these org.apache.pekko.cluster.*
    constants (renamed in the fork) can never match. Each dead branch was a
    wire-reachable deserialization path.
    
    Modification:
    Remove the vals, their fromBinary cases, and the two heartbeat
    deserializers only those cases used. Replace the spec's old-manifest
    round-trip tests and their now-unused helpers with a test asserting every
    removed manifest is rejected as unknown.
    
    Result:
    The class-based manifests are refused with "Unknown manifest". Short
    manifests are unchanged.
    
    Tests:
    - sbt "cluster/testOnly 
org.apache.pekko.cluster.protobuf.ClusterMessageSerializerSpec" - 8 passed
    - the new rejection test fails without the production change (the manifest
      routes to deserializeJoin and raises InvalidProtocolBufferException)
    - sbt "cluster/mimaReportBinaryIssues" - no issues
    - sbt "cluster/scalafmtCheckAll" - clean
    
    References:
    None - removes dead Akka 2.6.4 compatibility code
---
 .../protobuf/ClusterMessageSerializer.scala        |  40 +-------
 .../protobuf/ClusterMessageSerializerSpec.scala    | 105 +++++----------------
 2 files changed, 26 insertions(+), 119 deletions(-)

diff --git 
a/cluster/src/main/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializer.scala
 
b/cluster/src/main/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializer.scala
index 23a6f77ff0..b4e5db8f6e 100644
--- 
a/cluster/src/main/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializer.scala
+++ 
b/cluster/src/main/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializer.scala
@@ -40,22 +40,6 @@ import com.typesafe.config.{ Config, ConfigFactory, 
ConfigRenderOptions }
  */
 @InternalApi
 private[pekko] object ClusterMessageSerializer {
-  // Kept for one version iteration from Akka 2.6.4 to allow rolling migration 
to short manifests
-  // can be removed in Akka 2.6.6 or later.
-  val OldJoinManifest = s"org.apache.pekko.cluster.InternalClusterAction$$Join"
-  val OldWelcomeManifest = 
s"org.apache.pekko.cluster.InternalClusterAction$$Welcome"
-  val OldLeaveManifest = s"org.apache.pekko.cluster.ClusterUserAction$$Leave"
-  val OldDownManifest = s"org.apache.pekko.cluster.ClusterUserAction$$Down"
-  val OldInitJoinManifest = 
s"org.apache.pekko.cluster.InternalClusterAction$$InitJoin$$"
-  val OldInitJoinAckManifest = 
s"org.apache.pekko.cluster.InternalClusterAction$$InitJoinAck"
-  val OldInitJoinNackManifest = 
s"org.apache.pekko.cluster.InternalClusterAction$$InitJoinNack"
-  val HeartBeatManifestPre2523 = 
s"org.apache.pekko.cluster.ClusterHeartbeatSender$$Heartbeat"
-  val HeartBeatRspManifest2523 = 
s"org.apache.pekko.cluster.ClusterHeartbeatSender$$HeartbeatRsp"
-  val OldExitingConfirmedManifest = 
s"org.apache.pekko.cluster.InternalClusterAction$$ExitingConfirmed"
-  val OldGossipStatusManifest = "org.apache.pekko.cluster.GossipStatus"
-  val OldGossipEnvelopeManifest = "org.apache.pekko.cluster.GossipEnvelope"
-  val OldClusterRouterPoolManifest = 
"org.apache.pekko.cluster.routing.ClusterRouterPool"
-
   // is handled on the deserializing side in Akka 2.6.2 and then on the 
serializing side in Akka 2.6.3
   val JoinManifest = "J"
   val WelcomeManifest = "W"
@@ -139,21 +123,7 @@ final class ClusterMessageSerializer(val system: 
ExtendedActorSystem)
     case DownManifest              => deserializeDown(bytes)
     case ExitingConfirmedManifest  => deserializeExitingConfirmed(bytes)
     case ClusterRouterPoolManifest => deserializeClusterRouterPool(bytes)
-    // needs to stay in Akka 2.6.5 to be able to talk to an Akka 2.5.{3,4} 
node during rolling upgrade
-    case HeartBeatManifestPre2523     => deserializeHeartBeatAsAddress(bytes)
-    case HeartBeatRspManifest2523     => 
deserializeHeartBeatRspAsUniqueAddress(bytes)
-    case OldGossipStatusManifest      => deserializeGossipStatus(bytes)
-    case OldGossipEnvelopeManifest    => deserializeGossipEnvelope(bytes)
-    case OldInitJoinManifest          => deserializeInitJoin(bytes)
-    case OldInitJoinAckManifest       => deserializeInitJoinAck(bytes)
-    case OldInitJoinNackManifest      => deserializeInitJoinNack(bytes)
-    case OldJoinManifest              => deserializeJoin(bytes)
-    case OldWelcomeManifest           => deserializeWelcome(bytes)
-    case OldLeaveManifest             => deserializeLeave(bytes)
-    case OldDownManifest              => deserializeDown(bytes)
-    case OldExitingConfirmedManifest  => deserializeExitingConfirmed(bytes)
-    case OldClusterRouterPoolManifest => deserializeClusterRouterPool(bytes)
-    case _                            => throw new 
IllegalArgumentException(s"Unknown manifest [$manifest]")
+    case _                         => throw new 
IllegalArgumentException(s"Unknown manifest [$manifest]")
   }
 
   def compress(msg: MessageLite): Array[Byte] = {
@@ -323,14 +293,6 @@ final class ClusterMessageSerializer(val system: 
ExtendedActorSystem)
     InternalClusterAction.ExitingConfirmed(uniqueAddressFromBinary(bytes))
   }
 
-  private def deserializeHeartBeatRspAsUniqueAddress(bytes: Array[Byte]): 
ClusterHeartbeatSender.HeartbeatRsp = {
-    ClusterHeartbeatSender.HeartbeatRsp(uniqueAddressFromBinary(bytes), -1, -1)
-  }
-
-  private def deserializeHeartBeatAsAddress(bytes: Array[Byte]): 
ClusterHeartbeatSender.Heartbeat = {
-    ClusterHeartbeatSender.Heartbeat(addressFromBinary(bytes), -1, -1)
-  }
-
   def deserializeHeartBeat(bytes: Array[Byte]): 
ClusterHeartbeatSender.Heartbeat = {
     val hb = cm.Heartbeat.parseFrom(bytes)
     ClusterHeartbeatSender.Heartbeat(addressFromProto(hb.getFrom), 
hb.getSequenceNr, hb.getCreationTime)
diff --git 
a/cluster/src/test/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializerSpec.scala
 
b/cluster/src/test/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializerSpec.scala
index ec993a6ead..14d0974e40 100644
--- 
a/cluster/src/test/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializerSpec.scala
+++ 
b/cluster/src/test/scala/org/apache/pekko/cluster/protobuf/ClusterMessageSerializerSpec.scala
@@ -56,26 +56,6 @@ class ClusterMessageSerializerSpec extends 
PekkoSpec("pekko.actor.provider = clu
     }
   }
 
-  private def roundtripWithManifest[T <: AnyRef](obj: T, manifest: String): T 
= {
-    val blob = serializer.toBinary(obj)
-    serializer.fromBinary(blob, manifest).asInstanceOf[T]
-  }
-
-  private def checkDeserializationWithManifest(obj: AnyRef, 
deserializationManifest: String): Unit = {
-    (obj, roundtripWithManifest(obj, deserializationManifest)) match {
-      case (env: GossipEnvelope, env2: GossipEnvelope) =>
-        env2.from should ===(env.from)
-        env2.to should ===(env.to)
-        env2.gossip should ===(env.gossip)
-        env.gossip.members.foreach { m1 =>
-          val m2 = env.gossip.members.find(_.uniqueAddress == 
m1.uniqueAddress).get
-          checkSameMember(m1, m2)
-        }
-      case (_, ref) =>
-        ref should ===(obj)
-    }
-  }
-
   private def checkSameMember(m1: Member, m2: Member): Unit = {
     m1.uniqueAddress should ===(m2.uniqueAddress)
     m1.status should ===(m2.status)
@@ -138,50 +118,32 @@ class ClusterMessageSerializerSpec extends 
PekkoSpec("pekko.actor.provider = clu
       checkSerialization(InternalClusterAction.Welcome(uniqueAddress, g2))
     }
 
-    // can be removed in Akka 2.6.3 only checks deserialization with new not 
yet in effect manifests for Akka 2.6.2
-    "be de-serializable with class manifests from Akka 2.6.4 and earlier 
nodes" in {
+    "reject the class-based manifests that Akka 2.6.4 and earlier nodes sent" 
in {
+      // these were kept "for one version iteration from Akka 2.6.4" to allow 
rolling
+      // migration to the short manifests; nothing a Pekko node can talk to 
emits them,
+      // so they must be refused as unknown rather than kept as wire-reachable 
paths
       val address = Address("pekko", "system", "some.host.org", 4711)
-      val uniqueAddress = UniqueAddress(address, 17L)
-      val address2 = Address("pekko", "system", "other.host.org", 4711)
-      val uniqueAddress2 = UniqueAddress(address2, 18L)
-      checkDeserializationWithManifest(
-        InternalClusterAction.Join(uniqueAddress, Set("foo", "bar", "dc-A"), 
Version.Zero),
-        ClusterMessageSerializer.OldJoinManifest)
-      checkDeserializationWithManifest(ClusterUserAction.Leave(address), 
ClusterMessageSerializer.LeaveManifest)
-      checkDeserializationWithManifest(ClusterUserAction.Down(address), 
ClusterMessageSerializer.DownManifest)
-      checkDeserializationWithManifest(
-        InternalClusterAction.InitJoin(ConfigFactory.empty),
-        ClusterMessageSerializer.OldInitJoinManifest)
-      checkDeserializationWithManifest(
-        InternalClusterAction.InitJoinAck(address, 
CompatibleConfig(ConfigFactory.empty)),
-        ClusterMessageSerializer.OldInitJoinAckManifest)
-      checkDeserializationWithManifest(
-        InternalClusterAction.InitJoinNack(address),
-        ClusterMessageSerializer.OldInitJoinNackManifest)
-      checkDeserializationWithManifest(
-        InternalClusterAction.ExitingConfirmed(uniqueAddress),
-        ClusterMessageSerializer.OldExitingConfirmedManifest)
-
-      val node1 = VectorClock.Node("node1")
-      val node2 = VectorClock.Node("node2")
-      val node3 = VectorClock.Node("node3")
-      val node4 = VectorClock.Node("node4")
-      val g1 = (Gossip(SortedSet(a1, b1, c1, d1)) :+ node1 :+ 
node2).seen(a1.uniqueAddress).seen(b1.uniqueAddress)
-      val g2 = (g1 :+ node3 :+ 
node4).seen(a1.uniqueAddress).seen(c1.uniqueAddress)
-      val reachability3 = Reachability.empty
-        .unreachable(a1.uniqueAddress, e1.uniqueAddress)
-        .unreachable(b1.uniqueAddress, e1.uniqueAddress)
-      checkDeserializationWithManifest(
-        GossipEnvelope(a1.uniqueAddress, uniqueAddress2, g1),
-        ClusterMessageSerializer.OldGossipEnvelopeManifest)
-
-      checkDeserializationWithManifest(
-        GossipStatus(a1.uniqueAddress, g1.version, g1.seenDigest),
-        ClusterMessageSerializer.OldGossipStatusManifest)
-
-      checkDeserializationWithManifest(
-        InternalClusterAction.Welcome(uniqueAddress, g2),
-        ClusterMessageSerializer.OldWelcomeManifest)
+      val bytes = serializer.toBinary(ClusterUserAction.Leave(address))
+      Seq(
+        "org.apache.pekko.cluster.InternalClusterAction$Join",
+        "org.apache.pekko.cluster.InternalClusterAction$Welcome",
+        "org.apache.pekko.cluster.ClusterUserAction$Leave",
+        "org.apache.pekko.cluster.ClusterUserAction$Down",
+        "org.apache.pekko.cluster.InternalClusterAction$InitJoin$",
+        "org.apache.pekko.cluster.InternalClusterAction$InitJoinAck",
+        "org.apache.pekko.cluster.InternalClusterAction$InitJoinNack",
+        "org.apache.pekko.cluster.ClusterHeartbeatSender$Heartbeat",
+        "org.apache.pekko.cluster.ClusterHeartbeatSender$HeartbeatRsp",
+        "org.apache.pekko.cluster.InternalClusterAction$ExitingConfirmed",
+        "org.apache.pekko.cluster.GossipStatus",
+        "org.apache.pekko.cluster.GossipEnvelope",
+        "org.apache.pekko.cluster.routing.ClusterRouterPool").foreach { 
manifest =>
+        withClue(s"manifest [$manifest]: ") {
+          intercept[IllegalArgumentException] {
+            serializer.fromBinary(bytes, manifest)
+          }.getMessage should include("Unknown manifest")
+        }
+      }
     }
 
     "reject gossip that refers to a lookup table entry it did not send" in {
@@ -300,23 +262,6 @@ class ClusterMessageSerializerSpec extends 
PekkoSpec("pekko.actor.provider = clu
     }
   }
 
-  // support for deserializing a new format with a string based manifest was 
added in Akka 2.5.23 but the next step
-  // was never done, meaning that 2.6.4 still emits the old format
-  "Rolling upgrades for heart beat message changes in Akka 2.5.23" must {
-
-    "deserialize heart beats represented by just an address Address to support 
versions prior to Akka 2.6.5" in {
-      val serialized = 
serializer.addressToProto(a1.address).build().toByteArray
-      val deserialized = serializer.fromBinary(serialized, 
ClusterMessageSerializer.HeartBeatManifestPre2523)
-      deserialized should ===(ClusterHeartbeatSender.Heartbeat(a1.address, -1, 
-1))
-    }
-
-    "deserialize heart beat responses as UniqueAddress to support versions 
prior to 2.5.23" in {
-      val serialized = 
serializer.uniqueAddressToProto(a1.uniqueAddress).build().toByteArray
-      val deserialized = serializer.fromBinary(serialized, 
ClusterMessageSerializer.HeartBeatRspManifest2523)
-      deserialized should 
===(ClusterHeartbeatSender.HeartbeatRsp(a1.uniqueAddress, -1, -1))
-    }
-  }
-
   "Cluster router pool" must {
     "be serializable with no role" in {
       checkSerialization(


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to