From 227c3a1567e278bbdb1abdb496b433aa6685d58c Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 00:31:26 +0300 Subject: [PATCH 01/47] raw --- .../discovery/DiscoveryMessageFactory.java | 12 + .../persistence/tree/io/BPlusMetaIO.java | 3 +- .../serializer/RecordDataV1Serializer.java | 3 +- .../ignite/lang/IgniteProductVersion.java | 121 ++++--- .../ignite/spi/discovery/tcp/ClientImpl.java | 6 +- .../ignite/spi/discovery/tcp/ServerImpl.java | 24 +- .../tcp/internal/TcpDiscoveryNode.java | 202 ++++++----- .../ClusterNodeCollectionMessage.java | 77 +++++ .../tcp/messages/ClusterNodeMessage.java | 274 +++++++++++++++ .../messages/IgniteProductVersionMessage.java | 152 +++++++++ .../TcpDiscoveryNodeAddedMessage.java | 314 ++++++++++++++++-- 11 files changed, 985 insertions(+), 203 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java create mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java create mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 753f00569c5cf..7a799ad101ab3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -17,7 +17,10 @@ package org.apache.ignite.internal.managers.discovery; +import org.apache.ignite.internal.codegen.ClusterNodeCollectionMessageSerializer; +import org.apache.ignite.internal.codegen.ClusterNodeMessageSerializer; import org.apache.ignite.internal.codegen.DiscoveryDataPacketSerializer; +import org.apache.ignite.internal.codegen.IgniteProductVersionMessageSerializer; import org.apache.ignite.internal.codegen.InetAddressMessageSerializer; import org.apache.ignite.internal.codegen.InetSocketAddressMessageSerializer; import org.apache.ignite.internal.codegen.NodeSpecificDataSerializer; @@ -37,6 +40,7 @@ import org.apache.ignite.internal.codegen.TcpDiscoveryLoopbackProblemMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryMetricsUpdateMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryNodeAddFinishedMessageSerializer; +import org.apache.ignite.internal.codegen.TcpDiscoveryNodeAddedMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryNodeFailedMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryNodeFullMetricsMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryNodeLeftMessageSerializer; @@ -48,6 +52,9 @@ import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; +import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeCollectionMessage; +import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeMessage; +import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; import org.apache.ignite.spi.discovery.tcp.messages.InetAddressMessage; import org.apache.ignite.spi.discovery.tcp.messages.InetSocketAddressMessage; import org.apache.ignite.spi.discovery.tcp.messages.NodeSpecificData; @@ -67,6 +74,7 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryLoopbackProblemMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFullMetricsMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeLeftMessage; @@ -80,6 +88,9 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { /** {@inheritDoc} */ @Override public void registerAll(MessageFactory factory) { + factory.register((short)-110, ClusterNodeCollectionMessage::new, new ClusterNodeCollectionMessageSerializer()); + factory.register((short)-109, ClusterNodeMessage::new, new ClusterNodeMessageSerializer()); + factory.register((short)-108, IgniteProductVersionMessage::new, new IgniteProductVersionMessageSerializer()); factory.register((short)-107, NodeSpecificData::new, new NodeSpecificDataSerializer()); factory.register((short)-106, DiscoveryDataPacket::new, new DiscoveryDataPacketSerializer()); factory.register((short)-105, TcpDiscoveryNodeFullMetricsMessage::new, @@ -110,5 +121,6 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { factory.register((short)17, TcpDiscoveryNodeFailedMessage::new, new TcpDiscoveryNodeFailedMessageSerializer()); factory.register((short)18, TcpDiscoveryStatusCheckMessage::new, new TcpDiscoveryStatusCheckMessageSerializer()); factory.register((short)19, TcpDiscoveryNodeAddFinishedMessage::new, new TcpDiscoveryNodeAddFinishedMessageSerializer()); + factory.register((short)20, TcpDiscoveryNodeAddedMessage::new, new TcpDiscoveryNodeAddedMessageSerializer()); } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java index edcfefc4f8890..7ab88b3809182 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java @@ -23,6 +23,7 @@ import org.apache.ignite.internal.pagemem.PageUtils; import org.apache.ignite.internal.util.GridStringBuilder; import org.apache.ignite.lang.IgniteProductVersion; +import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; /** * IO routines for B+Tree meta pages. @@ -303,7 +304,7 @@ public IgniteProductVersion createdVersion(long pageAddr) { PageUtils.getByte(pageAddr, CREATED_VER_OFFSET + 1), PageUtils.getByte(pageAddr, CREATED_VER_OFFSET + 2), PageUtils.getLong(pageAddr, CREATED_VER_OFFSET + 3), - PageUtils.getBytes(pageAddr, CREATED_VER_OFFSET + 11, IgniteProductVersion.REV_HASH_SIZE)); + PageUtils.getBytes(pageAddr, CREATED_VER_OFFSET + 11, IgniteProductVersionMessage.REV_HASH_SIZE)); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java index de920fddadf31..5fb2d97a02d13 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java @@ -120,6 +120,7 @@ import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteProductVersion; +import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; import org.apache.ignite.spi.encryption.EncryptionSpi; import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi; import org.jetbrains.annotations.Nullable; @@ -850,7 +851,7 @@ WALRecord readPlainRecord(RecordType type, ByteBufferBackedDataInput in, long flags = in.readLong(); - byte[] revHash = new byte[IgniteProductVersion.REV_HASH_SIZE]; + byte[] revHash = new byte[IgniteProductVersionMessage.REV_HASH_SIZE]; byte maj = in.readByte(); byte min = in.readByte(); byte maint = in.readByte(); diff --git a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java index 1c78694550bd5..3efda7095caa4 100644 --- a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java +++ b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java @@ -27,6 +27,7 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.IgniteVersionUtils; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; import org.jetbrains.annotations.NotNull; /** @@ -41,39 +42,26 @@ public class IgniteProductVersion implements Comparable, E /** */ private static final long serialVersionUID = 0L; - /** Size of the {@link #revHash }*/ - public static final int REV_HASH_SIZE = 20; - /** Size in bytes of serialized: 3 bytes (maj, min, maintenance version), 8 bytes - timestamp */ - public static final int SIZE_IN_BYTES = 3 + 8 + REV_HASH_SIZE; + public static final int SIZE_IN_BYTES = 3 + 8 + IgniteProductVersionMessage.REV_HASH_SIZE; /** Regexp parse pattern. */ private static final Pattern VER_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)([-.]([^0123456789][^-]+)(-SNAPSHOT)?)?(-(\\d+))?(-([\\da-f]+))?"); - /** Major version number. */ - private byte major; - - /** Minor version number. */ - private byte minor; - - /** Maintenance version number. */ - private byte maintenance; - - /** Stage of development. */ - private String stage; - - /** Revision timestamp. */ - private long revTs; - - /** Revision hash. */ - private byte[] revHash; + /** The values holding message. */ + private IgniteProductVersionMessage productVerMsg; /** * Empty constructor required by {@link Externalizable}. */ public IgniteProductVersion() { - // No-op. + productVerMsg = new IgniteProductVersionMessage(); + } + + /** @param productVerMsg Product version message. */ + public IgniteProductVersion(IgniteProductVersionMessage productVerMsg) { + this.productVerMsg = productVerMsg; } /** @@ -96,17 +84,17 @@ public IgniteProductVersion(byte major, byte minor, byte maintenance, long revTs * @param revHash Revision hash. */ public IgniteProductVersion(byte major, byte minor, byte maintenance, String stage, long revTs, byte[] revHash) { - if (revHash != null && revHash.length != REV_HASH_SIZE) { + productVerMsg = new IgniteProductVersionMessage(major, minor, maintenance, stage, revTs, revHash); + + if (revHash != null && revHash.length != IgniteProductVersionMessage.REV_HASH_SIZE) { throw new IllegalArgumentException("Invalid length for SHA1 hash (must be " - + REV_HASH_SIZE + "): " + revHash.length); + + IgniteProductVersionMessage.REV_HASH_SIZE + "): " + revHash.length); } + } - this.major = major; - this.minor = minor; - this.maintenance = maintenance; - this.stage = stage; - this.revTs = revTs; - this.revHash = revHash != null ? revHash : new byte[REV_HASH_SIZE]; + /** @return {@link IgniteProductVersionMessage}. */ + public IgniteProductVersionMessage message() { + return productVerMsg; } /** @@ -115,7 +103,7 @@ public IgniteProductVersion(byte major, byte minor, byte maintenance, String sta * @return Major version number. */ public byte major() { - return major; + return productVerMsg.major(); } /** @@ -124,7 +112,7 @@ public byte major() { * @return Minor version number. */ public byte minor() { - return minor; + return productVerMsg.minor(); } /** @@ -133,14 +121,14 @@ public byte minor() { * @return Maintenance version number. */ public byte maintenance() { - return maintenance; + return productVerMsg.maintenance(); } /** * @return Stage of development. */ public String stage() { - return stage; + return productVerMsg.stage(); } /** @@ -149,7 +137,7 @@ public String stage() { * @return Revision timestamp. */ public long revisionTimestamp() { - return revTs; + return productVerMsg.revisionTimestamp(); } /** @@ -158,7 +146,7 @@ public long revisionTimestamp() { * @return Revision hash. */ public byte[] revisionHash() { - return revHash; + return productVerMsg.revisionHash(); } /** @@ -167,7 +155,7 @@ public byte[] revisionHash() { * @return Release date. */ public Date releaseDate() { - return new Date(revTs * 1000); + return new Date(revisionTimestamp() * 1000); } /** @@ -178,31 +166,31 @@ public Date releaseDate() { */ public boolean greaterThanEqual(int major, int minor, int maintenance) { // NOTE: Unknown version is less than any other version. - if (major == this.major) - return minor == this.minor ? this.maintenance >= maintenance : this.minor > minor; + if (major == major()) + return minor == minor() ? maintenance() >= maintenance : minor() > minor; else - return this.major > major; + return major() > major; } /** {@inheritDoc} */ @Override public int compareTo(@NotNull IgniteProductVersion o) { // NOTE: Unknown version is less than any other version. - int res = Integer.compare(major, o.major); + int res = Integer.compare(major(), o.major()); if (res != 0) return res; - res = Integer.compare(minor, o.minor); + res = Integer.compare(minor(), o.minor()); if (res != 0) return res; - res = Integer.compare(maintenance, o.maintenance); + res = Integer.compare(maintenance(), o.maintenance()); if (res != 0) return res; - return Long.compare(revTs, o.revTs); + return Long.compare(revisionTimestamp(), o.revisionTimestamp()); } /** @@ -210,17 +198,17 @@ public boolean greaterThanEqual(int major, int minor, int maintenance) { * @return Compare result. */ public int compareToIgnoreTimestamp(@NotNull IgniteProductVersion o) { - int res = Integer.compare(major, o.major); + int res = Integer.compare(major(), o.major()); if (res != 0) return res; - res = Integer.compare(minor, o.minor); + res = Integer.compare(minor(), o.minor()); if (res != 0) return res; - return Integer.compare(maintenance, o.maintenance); + return Integer.compare(maintenance(), o.maintenance()); } /** {@inheritDoc} */ @@ -233,47 +221,50 @@ public int compareToIgnoreTimestamp(@NotNull IgniteProductVersion o) { IgniteProductVersion that = (IgniteProductVersion)o; - return revTs == that.revTs && maintenance == that.maintenance && minor == that.minor && major == that.major; + return revisionTimestamp() == that.revisionTimestamp() && maintenance() == that.maintenance() + && minor() == that.minor() && major() == that.major(); } /** {@inheritDoc} */ @Override public int hashCode() { - int res = major; + int res = major(); - res = 31 * res + minor; - res = 31 * res + maintenance; - res = 31 * res + (int)(revTs ^ (revTs >>> 32)); + res = 31 * res + minor(); + res = 31 * res + maintenance(); + res = 31 * res + (int)(revisionTimestamp() ^ (revisionTimestamp() >>> 32)); return res; } /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { - out.writeByte(major); - out.writeByte(minor); - out.writeByte(maintenance); - out.writeLong(revTs); - U.writeByteArray(out, revHash); + out.writeByte(major()); + out.writeByte(minor()); + out.writeByte(maintenance()); + out.writeLong(revisionTimestamp()); + U.writeByteArray(out, revisionHash()); } /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - major = in.readByte(); - minor = in.readByte(); - maintenance = in.readByte(); - revTs = in.readLong(); - revHash = U.readByteArray(in); + assert productVerMsg != null; + + productVerMsg.major(in.readByte()); + productVerMsg.minor(in.readByte()); + productVerMsg.maintenance(in.readByte()); + productVerMsg.revisionTimestamp(in.readLong()); + productVerMsg.revisionHash(U.readByteArray(in)); } /** {@inheritDoc} */ @Override public String toString() { - String revTsStr = IgniteVersionUtils.formatBuildTimeStamp(revTs * 1000); + String revTsStr = IgniteVersionUtils.formatBuildTimeStamp(revisionTimestamp() * 1000); - String hash = U.byteArray2HexString(revHash).toLowerCase(); + String hash = U.byteArray2HexString(revisionHash()).toLowerCase(); hash = hash.length() > 8 ? hash.substring(0, 8) : hash; - return major + "." + minor + "." + maintenance + "#" + revTsStr + "-sha1:" + hash; + return major() + "." + minor() + "." + maintenance() + "#" + revTsStr + "-sha1:" + hash; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 2e96845ff0332..fe702517dbe33 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2160,8 +2160,12 @@ protected void processDiscoveryMessage(TcpDiscoveryAbstractMessage msg) { if (msg instanceof TraceableMessage) tracing.messages().beforeSend((TraceableMessage)msg); - if (msg instanceof TcpDiscoveryNodeAddedMessage) + if (msg instanceof TcpDiscoveryNodeAddedMessage) { + ((TcpDiscoveryNodeAddedMessage)msg) + .finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); + processNodeAddedMessage((TcpDiscoveryNodeAddedMessage)msg); + } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) processNodeAddFinishedMessage((TcpDiscoveryNodeAddFinishedMessage)msg); else if (msg instanceof TcpDiscoveryNodeLeftMessage) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 2f6d431fa9a4b..3b16c46392645 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1877,7 +1877,7 @@ private void prepareNodeAddedMessage( nodeAddedMsg.topology(topToSnd); - Collection msgs0 = null; + List msgs0 = null; if (msgs != null) { msgs0 = new ArrayList<>(msgs.size()); @@ -2482,6 +2482,8 @@ void add(TcpDiscoveryAbstractMessage msg) { // Do not need this data for client reconnect. if (addedMsg.gridDiscoveryData() != null) addedMsg.clearDiscoveryData(); + + addedMsg.prepareMarshal(spi.marshaller()); } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; @@ -2644,6 +2646,8 @@ private TcpDiscoveryAbstractMessage prepare(TcpDiscoveryAbstractMessage msg, UUI msg0.topology(addedMsg.clientTopology()); + msg0.prepareMarshal(spi.marshaller()); + return msg0; } } @@ -3141,8 +3145,12 @@ else if (msg instanceof TcpDiscoveryClientReconnectMessage) { sendMessageAcrossRing(msg); } - else if (msg instanceof TcpDiscoveryNodeAddedMessage) + else if (msg instanceof TcpDiscoveryNodeAddedMessage) { + ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(spi.marshaller(), + U.resolveClassLoader(spi.ignite().configuration())); + processNodeAddedMessage((TcpDiscoveryNodeAddedMessage)msg); + } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) processNodeAddFinishedMessage((TcpDiscoveryNodeAddFinishedMessage)msg); @@ -3254,6 +3262,8 @@ private void sendMessageToClients(TcpDiscoveryAbstractMessage msg) { } } + ((TcpDiscoveryNodeAddedMessage)msg).prepareMarshal(spi.marshaller()); + // TODO Investigate possible optimizations: https://issues.apache.org/jira/browse/IGNITE-27722 clientMsgWorker.addMessage(msg); } @@ -4863,8 +4873,11 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { else if (!locNodeId.equals(node.id()) && ring.node(node.id()) != null) { // Local node already has node from message in local topology. // Just pass it to coordinator via the ring. - if (sendMessageToRemotes(msg)) + if (sendMessageToRemotes(msg)) { + msg.prepareMarshal(spi.marshaller()); + sendMessageAcrossRing(msg); + } if (log.isDebugEnabled()) { log.debug("Local node already has node being added. Passing TcpDiscoveryNodeAddedMessage to " + @@ -5087,8 +5100,11 @@ else if (spiState == CONNECTING) processMessageFailedNodes(msg); } - if (sendMessageToRemotes(msg)) + if (sendMessageToRemotes(msg)) { + msg.prepareMarshal(spi.marshaller()); + sendMessageAcrossRing(msg); + } } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java index 89f1f492e9272..2b4ffc06b8f2b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java @@ -36,6 +36,7 @@ import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.IgniteNodeAttributes; import org.apache.ignite.internal.managers.discovery.IgniteClusterNode; +import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; import org.apache.ignite.internal.util.lang.GridMetadataAwareAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -46,6 +47,7 @@ import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeMessage; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_NODE_CONSISTENT_ID; @@ -62,23 +64,8 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite /** */ private static final long serialVersionUID = 0L; - /** Node ID. */ - private volatile UUID id; - - /** Consistent ID. */ - @GridToStringInclude - private Object consistentId; - - /** Node attributes. */ - @GridToStringExclude - private Map attrs; - - /** Internal discovery addresses as strings. */ - @GridToStringInclude - private Collection addrs; - - /** Internal discovery host names as strings. */ - private Collection hostNames; + /** Values holding message of {@link ClusterNode}. */ + private ClusterNodeMessage clusterNodeMsg; /** */ @GridToStringInclude @@ -88,17 +75,10 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite @GridToStringInclude private int discPort; - /** Node metrics. */ - @GridToStringExclude - private volatile ClusterMetrics metrics; - /** Node cache metrics. */ @GridToStringExclude private volatile Map cacheMetrics; - /** Node order in the topology. */ - private volatile long order; - /** Node order in the topology (internal). */ private volatile long intOrder; @@ -118,12 +98,6 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite @GridToStringExclude private boolean visible; - /** Grid local node flag (transient). */ - private boolean loc; - - /** Version. */ - private IgniteProductVersion ver; - /** Alive check time (used by clients). */ @GridToStringExclude private transient volatile long aliveCheckTimeNanos; @@ -148,7 +122,12 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite * Public default no-arg constructor for {@link Externalizable} interface. */ public TcpDiscoveryNode() { - // No-op. + clusterNodeMsg = new ClusterNodeMessage(); + } + + /** */ + public TcpDiscoveryNode(ClusterNodeMessage msg) { + clusterNodeMsg = msg; } /** @@ -162,7 +141,8 @@ public TcpDiscoveryNode() { * @param ver Version. * @param consistentId Node consistent ID. */ - public TcpDiscoveryNode(UUID id, + public TcpDiscoveryNode( + UUID id, Collection addrs, Collection hostNames, int discPort, @@ -174,21 +154,23 @@ public TcpDiscoveryNode(UUID id, assert metricsProvider != null; assert ver != null; - this.id = id; - List sortedAddrs = new ArrayList<>(addrs); - Collections.sort(sortedAddrs); - this.addrs = sortedAddrs; - this.hostNames = hostNames; - this.discPort = discPort; - this.metricsProvider = metricsProvider; - this.ver = ver; + clusterNodeMsg = new ClusterNodeMessage(); + id(id); + clusterNodeMsg.consistentId(consistentId != null ? consistentId : U.consistentId(sortedAddrs, discPort)); + clusterNodeMsg.addresses(sortedAddrs); + clusterNodeMsg.hostNames(hostNames); + version(ver); + + ClusterMetrics metrics = metricsProvider.metrics(); - this.consistentId = consistentId != null ? consistentId : U.consistentId(sortedAddrs, discPort); + if (metrics != null) + setMetrics(metrics); - metrics = metricsProvider.metrics(); + this.metricsProvider = metricsProvider; + this.discPort = discPort; cacheMetrics = metricsProvider.cacheMetrics(); sockAddrs = U.toSocketAddresses(this, discPort); } @@ -208,13 +190,18 @@ public void lastSuccessfulAddress(InetSocketAddress lastSuccessfulAddr) { } /** {@inheritDoc} */ - @Override public UUID id() { - return id; + @Override public synchronized UUID id() { + return clusterNodeMsg.id(); + } + + /** */ + private synchronized void id(UUID id) { + clusterNodeMsg.id(id); } /** {@inheritDoc} */ @Override public Object consistentId() { - return consistentId; + return clusterNodeMsg.consistentId(); } /** @@ -223,13 +210,13 @@ public void lastSuccessfulAddress(InetSocketAddress lastSuccessfulAddr) { * @param consistentId Consistent globally unique node ID. */ @Override public void setConsistentId(Serializable consistentId) { - this.consistentId = consistentId; + clusterNodeMsg.consistentId(consistentId); - final Map map = new HashMap<>(attrs); + Map map = new HashMap<>(clusterNodeMsg.attributes()); map.put(ATTR_NODE_CONSISTENT_ID, consistentId); - attrs = Collections.unmodifiableMap(map); + clusterNodeMsg.attributes(Collections.unmodifiableMap(map)); } /** {@inheritDoc} */ @@ -238,13 +225,13 @@ public void lastSuccessfulAddress(InetSocketAddress lastSuccessfulAddr) { if (IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS.equals(name)) return null; - return (T)attrs.get(name); + return (T)clusterNodeMsg.attributes().get(name); } /** {@inheritDoc} */ @Override public Map attributes() { // Even though discovery SPI removes this attribute after authentication, keep this check for safety. - return F.view(attrs, new IgnitePredicate() { + return F.view(clusterNodeMsg.attributes(), new IgnitePredicate<>() { @Override public boolean apply(String s) { return !IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS.equals(s); } @@ -257,7 +244,7 @@ public void lastSuccessfulAddress(InetSocketAddress lastSuccessfulAddr) { * @param attrs Node attributes. */ public void setAttributes(Map attrs) { - this.attrs = U.sealMap(attrs); + clusterNodeMsg.attributes(U.sealMap(attrs)); } /** @@ -266,27 +253,29 @@ public void setAttributes(Map attrs) { * @return Node attributes without filtering. */ public Map getAttributes() { - return attrs; + return clusterNodeMsg.attributes(); } /** {@inheritDoc} */ - @Override public ClusterMetrics metrics() { + @Override public synchronized ClusterMetrics metrics() { if (metricsProvider != null) { - ClusterMetrics metrics0 = metricsProvider.metrics(); + ClusterMetrics metrics = metricsProvider.metrics(); - metrics = metrics0; + setMetrics(metrics); - return metrics0; + return metrics; } - return metrics; + assert clusterNodeMsg.clusterMetricsMessage() != null; + + return new ClusterMetricsSnapshot(clusterNodeMsg.clusterMetricsMessage()); } /** {@inheritDoc} */ - @Override public void setMetrics(ClusterMetrics metrics) { + @Override public synchronized void setMetrics(ClusterMetrics metrics) { assert metrics != null; - this.metrics = metrics; + clusterNodeMsg.clusterMetricsMessage(new NodeMetricsMessage(metrics)); } /** {@inheritDoc} */ @@ -326,22 +315,22 @@ public void internalOrder(long intOrder) { /** * @return Order. */ - @Override public long order() { - return order; + @Override public synchronized long order() { + return clusterNodeMsg.order(); } /** * @param order Order of the node. */ - public void order(long order) { + public synchronized void order(long order) { assert order > 0 : "Order is invalid: " + this; - this.order = order; + clusterNodeMsg.order(order); } /** {@inheritDoc} */ @Override public IgniteProductVersion version() { - return ver; + return new IgniteProductVersion(clusterNodeMsg.productVersionMessage()); } /** @@ -350,29 +339,29 @@ public void order(long order) { public void version(IgniteProductVersion ver) { assert ver != null; - this.ver = ver; + clusterNodeMsg.productVersionMessage(ver.message()); } /** {@inheritDoc} */ @Override public Collection addresses() { - return addrs; + return clusterNodeMsg.addresses(); } /** {@inheritDoc} */ @Override public boolean isLocal() { - return loc; + return clusterNodeMsg.local(); } /** * @param loc Grid local node flag. */ public void local(boolean loc) { - this.loc = loc; + clusterNodeMsg.local(loc); } /** {@inheritDoc} */ @Override public Collection hostNames() { - return hostNames; + return clusterNodeMsg.hostNames(); } /** @@ -463,9 +452,9 @@ public void visible(boolean visible) { /** {@inheritDoc} */ @Override public boolean isClient() { if (!cacheCliInit) { - Boolean clientModeAttr = ((ClusterNode)this).attribute(IgniteNodeAttributes.ATTR_CLIENT_MODE); + Boolean clientModeAttr = attribute(IgniteNodeAttributes.ATTR_CLIENT_MODE); - cacheCli = clientModeAttr != null && clientModeAttr; + clusterNodeMsg.client(cacheCli = clientModeAttr != null && clientModeAttr); cacheCliInit = true; } @@ -520,7 +509,7 @@ public void clientRouterNodeId(UUID clientRouterNodeId) { * @param newId New node ID. */ public void onClientDisconnected(UUID newId) { - id = newId; + id(newId); } /** @@ -528,11 +517,10 @@ public void onClientDisconnected(UUID newId) { * @return Copy of local node for client reconnect request. */ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { - TcpDiscoveryNode node = new TcpDiscoveryNode( - id, addrs, hostNames, discPort, metricsProvider, ver, null - ); + TcpDiscoveryNode node = new TcpDiscoveryNode(id(), clusterNodeMsg.addresses(), hostNames(), discPort, + metricsProvider, version(), null); - node.attrs = Collections.unmodifiableMap(new HashMap<>(nodeAttrs)); + node.clusterNodeMsg.attributes(Collections.unmodifiableMap(new HashMap<>(nodeAttrs))); node.clientRouterNodeId = clientRouterNodeId; return node; @@ -556,16 +544,16 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { - U.writeUuid(out, id); - U.writeMap(out, attrs); - U.writeCollection(out, addrs); - U.writeCollection(out, hostNames); + U.writeUuid(out, id()); + U.writeMap(out, clusterNodeMsg.attributes()); + U.writeCollection(out, clusterNodeMsg.addresses()); + U.writeCollection(out, clusterNodeMsg.hostNames()); out.writeInt(discPort); // Cluster metrics byte[] mtr = null; - ClusterMetrics metrics = this.metrics; + ClusterMetrics metrics = metrics(); if (metrics != null) mtr = ClusterMetricsSnapshot.serialize(metrics); @@ -575,28 +563,30 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { // Legacy: Number of cache metrics out.writeInt(0); - out.writeLong(order); + out.writeLong(order()); out.writeLong(intOrder); - out.writeObject(ver); + out.writeObject(version()); U.writeUuid(out, clientRouterNodeId); } /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - id = U.readUuid(in); + assert clusterNodeMsg != null; + + id(U.readUuid(in)); - attrs = U.sealMap(U.readMap(in)); - addrs = U.readCollection(in); - hostNames = U.readCollection(in); + clusterNodeMsg.attributes(U.sealMap(U.readMap(in))); + clusterNodeMsg.addresses(U.readCollection(in)); + clusterNodeMsg.hostNames(U.readCollection(in)); discPort = in.readInt(); - Object consistentIdAttr = attrs.get(ATTR_NODE_CONSISTENT_ID); + Object consistentIdAttr = clusterNodeMsg.attributes().get(ATTR_NODE_CONSISTENT_ID); // Cluster metrics byte[] mtr = U.readByteArray(in); if (mtr != null) - metrics = ClusterMetricsSnapshot.deserialize(mtr, 0); + setMetrics(ClusterMetricsSnapshot.deserialize(mtr, 0)); // Legacy: Cache metrics int size = in.readInt(); @@ -606,20 +596,22 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { in.readObject(); } - order = in.readLong(); + order(in.readLong()); intOrder = in.readLong(); - ver = (IgniteProductVersion)in.readObject(); + version((IgniteProductVersion)in.readObject()); clientRouterNodeId = U.readUuid(in); if (clientRouterNodeId() != null) - consistentId = consistentIdAttr != null ? consistentIdAttr : id; - else - consistentId = consistentIdAttr != null ? consistentIdAttr : U.consistentId(addrs, discPort); + clusterNodeMsg.consistentId(consistentIdAttr != null ? consistentIdAttr : id()); + else { + clusterNodeMsg.consistentId(consistentIdAttr != null ? consistentIdAttr + : U.consistentId(clusterNodeMsg.addresses(), discPort)); + } } /** {@inheritDoc} */ @Override public int hashCode() { - return id.hashCode(); + return id().hashCode(); } /** {@inheritDoc} */ @@ -638,14 +630,16 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { * @param node to copy data from */ public TcpDiscoveryNode(ClusterNode node) { - this.id = node.id(); - this.consistentId = node.consistentId(); - this.addrs = node.addresses(); - this.hostNames = node.hostNames(); - this.order = node.order(); - this.ver = node.version(); - this.clientRouterNodeId = node.isClient() ? node.id() : null; - - attrs = Collections.singletonMap(ATTR_NODE_CONSISTENT_ID, consistentId); + clusterNodeMsg = new ClusterNodeMessage(); + + id(node.id()); + clusterNodeMsg.consistentId(node.consistentId()); + clusterNodeMsg.addresses(node.addresses()); + clusterNodeMsg.hostNames(node.hostNames()); + order(node.order()); + version(node.version()); + clusterNodeMsg.attributes(Collections.singletonMap(ATTR_NODE_CONSISTENT_ID, clusterNodeMsg.consistentId())); + + clientRouterNodeId = node.isClient() ? node.id() : null; } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java new file mode 100644 index 0000000000000..35304fd68bd96 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.discovery.tcp.messages; + +import java.util.Collection; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; + +/** + * Container message for a collection of {@link ClusterNodeMessage}. + *
+ * Requires pre- and post- marshalling. + * + * @see #prepareMarshal(Marshaller) + * @see #prepareMarshal(Marshaller) + */ +public class ClusterNodeCollectionMessage implements Message { + /** The collection of wrapped {@link ClusterNodeMessage}. */ + @Order(value = 0, method = "clusterNodeMessages") + private Collection clusterNodeMsgs; + + /** Constructor for {@link DiscoveryMessageFactory}. */ + public ClusterNodeCollectionMessage() { + // No-op. + } + + /** @param clusterNodeMsgs Holder messages of {@link ClusterNode}. */ + public ClusterNodeCollectionMessage(Collection clusterNodeMsgs) { + this.clusterNodeMsgs = clusterNodeMsgs; + } + + /** @param marsh Marshalled. */ + public void prepareMarshal(Marshaller marsh) { + clusterNodeMsgs.forEach(msg -> msg.prepareMarshal(marsh)); + } + + /** + * @param marsh Marshalled. + * @param clsLdr Class loader. + */ + public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + clusterNodeMsgs.forEach(msg -> msg.finishUnmarshal(marsh, clsLdr)); + } + + /** @return Holder messages of {@link ClusterNode}. */ + public Collection clusterNodeMessages() { + return clusterNodeMsgs; + } + + /** @param clusterNodeMsgs Holder messages of {@link ClusterNode}. */ + public void clusterNodeMessages(Collection clusterNodeMsgs) { + this.clusterNodeMsgs = clusterNodeMsgs; + } + + /** {@inheritDoc} */ + @Override public short directType() { + return 115; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java new file mode 100644 index 0000000000000..510c7ac0ff33e --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java @@ -0,0 +1,274 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.discovery.tcp.messages; + +import java.util.Collection; +import java.util.Map; +import java.util.UUID; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; +import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; + +/** + * Message for {@link ClusterNode}. Requites pre- and post- serialization with the class loader. + *
+ * Requires pre- and -post marshalling. + * + * @see #prepareMarshal(Marshaller) + * @see #finishUnmarshal(Marshaller, ClassLoader) + */ +public class ClusterNodeMessage implements Message { + /** Node ID. */ + @Order(0) + private UUID id; + + /** Internal discovery addresses as strings. */ + @Order(value = 1, method = "addresses") + private Collection addrs; + + /** Internal discovery host names as strings. */ + @Order(2) + private Collection hostNames; + + /** */ + @Order(value = 3, method = "clusterMetricsMessage") + private NodeMetricsMessage clusterMetricsMsg; + + /** */ + @Order(value = 4) + private long order; + + /** */ + @Order(value = 5, method = "productVersionMessage") + private IgniteProductVersionMessage productVerMsg; + + /** Grid local node flag (transient). */ + @Order(value = 6, method = "local") + private boolean loc; + + /** */ + @Order(7) + private boolean client; + + /** */ + @Order(8) + private String dataCenterId; + + /** Consistent ID. */ + private Object consistentId; + + /** */ + private byte[] consistentIdBytes; + + /** Node attributes. */ + private Map attrs; + + /** */ + private byte[] attrsBytes; + + /** Constructor for {@link DiscoveryMessageFactory}. */ + public ClusterNodeMessage() { + // No-op. + } + + /** @param clusterNode Cluster node. */ + public ClusterNodeMessage(ClusterNode clusterNode) { + id = clusterNode.id(); + addrs = clusterNode.addresses(); + hostNames = clusterNode.hostNames(); + if (clusterNode.metrics() != null) + clusterMetricsMsg = new NodeMetricsMessage(clusterNode.metrics()); + order = clusterNode.order(); + productVerMsg = new IgniteProductVersionMessage(clusterNode.version()); + loc = clusterNode.isLocal(); + client = clusterNode.isClient(); + dataCenterId = clusterNode.dataCenterId(); + attrs = clusterNode.attributes(); + } + + /** @param marsh Marshalled. */ + public void prepareMarshal(Marshaller marsh) { + if (F.isEmpty(attrs) && attrsBytes == null) { + try { + attrsBytes = U.marshal(marsh, attrs); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal cluster node attributes.", e); + } + } + + if (consistentId != null && consistentIdBytes == null) { + try { + consistentIdBytes = U.marshal(marsh, consistentId); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal cluster node's consistent id.", e); + } + } + } + + /** + * @param marsh Marshalled. + * @param clsLdr Class loader. + */ + public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + if (attrsBytes != null && F.isEmpty(attrs)) { + try { + attrs = U.unmarshal(marsh, attrsBytes, clsLdr); + + attrsBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal cluster node attributes.", e); + } + } + + if (consistentIdBytes != null && consistentId == null) { + try { + consistentId = U.unmarshal(marsh, consistentIdBytes, clsLdr); + + consistentIdBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to cluster node's consistent id.", e); + } + } + } + + /** @return Addresses. */ + public Collection addresses() { + return addrs; + } + + /** @param addrs Addresses. */ + public void addresses(Collection addrs) { + this.addrs = addrs; + } + + /** @return Node metrics message. */ + public NodeMetricsMessage clusterMetricsMessage() { + return clusterMetricsMsg; + } + + /** @param clusterMetricsMsg Node metrics message. */ + public void clusterMetricsMessage(NodeMetricsMessage clusterMetricsMsg) { + this.clusterMetricsMsg = clusterMetricsMsg; + } + + /** @return Client flag. */ + public boolean client() { + return client; + } + + /** @param client Client flag. */ + public void client(boolean client) { + this.client = client; + } + + /** @return Datacenter id. */ + public String dataCenterId() { + return dataCenterId; + } + + /** @param dataCenterId Datacenter id. */ + public void dataCenterId(String dataCenterId) { + this.dataCenterId = dataCenterId; + } + + /** @return Host names. */ + public Collection hostNames() { + return hostNames; + } + + /** @param hostNames Host names. */ + public void hostNames(Collection hostNames) { + this.hostNames = hostNames; + } + + /** @return Node id. */ + public UUID id() { + return id; + } + + /** @param id Node id. */ + public void id(UUID id) { + this.id = id; + } + + /** @return Node order. */ + public long order() { + return order; + } + + /** @param order Node order. */ + public void order(long order) { + this.order = order; + } + + /** @return Local node flag. */ + public boolean local() { + return loc; + } + + /** @param loc Local node flag. */ + public void local(boolean loc) { + this.loc = loc; + } + + /** @return Product version. */ + public IgniteProductVersionMessage productVersionMessage() { + return productVerMsg; + } + + /** @param productVerMsg Product version. */ + public void productVersionMessage(IgniteProductVersionMessage productVerMsg) { + this.productVerMsg = productVerMsg; + } + + /** @return Node consistent id. */ + public Object consistentId() { + return consistentId; + } + + /** @param consistentId Node consistent id. */ + public void consistentId(Object consistentId) { + this.consistentId = consistentId; + } + + /** @return Node's attributes. */ + public Map attributes() { + return attrs; + } + + /** @param attrs Node's attributes. */ + public void attributes(Map attrs) { + this.attrs = attrs; + } + + /** {@inheritDoc} */ + @Override public short directType() { + return -109; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java new file mode 100644 index 0000000000000..bdf1da1e1b8aa --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.discovery.tcp.messages; + +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; +import org.apache.ignite.lang.IgniteProductVersion; +import org.apache.ignite.plugin.extensions.communication.Message; + +/** Message for {@link IgniteProductVersion}.*/ +public class IgniteProductVersionMessage implements Message { + /** Size of the {@link #revHash }*/ + public static final int REV_HASH_SIZE = 20; + + /** Major version number. */ + @Order(0) + private byte major; + + /** Minor version number. */ + @Order(1) + private byte minor; + + /** Maintenance version number. */ + @Order(2) + private byte maintenance; + + /** Stage of development. */ + @Order(3) + private String stage; + + /** Revision timestamp. */ + @Order(value = 4, method = "revisionTimestamp") + private long revTs; + + /** Revision hash. */ + @Order(value = 5, method = "revisionHash") + private byte[] revHash; + + /** Constructor for {@link DiscoveryMessageFactory}. */ + public IgniteProductVersionMessage() { + // No-op. + } + + /** + * @param major Major version. + * @param minor Minor version. + * @param maintenance Maintenance. + * @param stage Stage. + * @param revTs Revision timestamp. + * @param revHash Revision hash. + */ + public IgniteProductVersionMessage(byte major, byte minor, byte maintenance, String stage, long revTs, byte[] revHash) { + this.major = major; + this.minor = minor; + this.maintenance = maintenance; + this.stage = stage; + this.revTs = revTs; + this.revHash = revHash != null ? revHash : new byte[REV_HASH_SIZE]; + } + + /** @param ver Product version. */ + public IgniteProductVersionMessage(IgniteProductVersion ver) { + this( + ver.major(), + ver.minor(), + ver.maintenance(), + ver.stage(), + ver.revisionTimestamp(), + ver.revisionHash() + ); + } + + /** @return Maintenance. */ + public byte maintenance() { + return maintenance; + } + + /** @param maintenance Maintenance. */ + public void maintenance(byte maintenance) { + this.maintenance = maintenance; + } + + /** @return Major version. */ + public byte major() { + return major; + } + + /** @param major Major version. */ + public void major(byte major) { + this.major = major; + } + + /** @return Minor version. */ + public byte minor() { + return minor; + } + + /** @param minor Minor version. */ + public void minor(byte minor) { + this.minor = minor; + } + + /** @return Revision hash. */ + public byte[] revisionHash() { + return revHash; + } + + /** @param revHash Revision hash. */ + public void revisionHash(byte[] revHash) { + this.revHash = revHash; + } + + /** @return Revision timestamp. */ + public long revisionTimestamp() { + return revTs; + } + + /** @param revTs Revision timestamp. */ + public void revisionTimestamp(long revTs) { + this.revTs = revTs; + } + + /** @return Statge. */ + public String stage() { + return stage; + } + + /** @param stage Stage. */ + public void stage(String stage) { + this.stage = stage; + } + + /** {@inheritDoc} */ + @Override public short directType() { + return -108; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index 36540d8b7dfc1..e445617fd87e7 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -17,12 +17,24 @@ package org.apache.ignite.spi.discovery.tcp.messages; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; import org.jetbrains.annotations.Nullable; @@ -31,35 +43,66 @@ * Message telling nodes that new node should be added to topology. * When newly added node receives the message it connects to its next and finishes * join process. + *
+ * Requires pre- and post- marshalling. + * @see #prepareMarshal(Marshaller) + * @see #finishUnmarshal(Marshaller, ClassLoader) */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage { +public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { /** */ private static final long serialVersionUID = 0L; - /** Added node. */ - private final TcpDiscoveryNode node; - /** */ + @Order(value = 6, method = "gridDiscoveryData") private DiscoveryDataPacket dataPacket; - /** Pending messages from previous node. */ - private Collection msgs; + /** Start time of the first grid node. */ + @Order(7) + private long gridStartTime; + + /** Topology snapshots history. */ + @Order(value = 8, method = "topologyHistoryMessages") + private @Nullable Map topHistMsgs; + + /** {@link TcpDiscoveryAbstractMessage} pending messages from previous node which is a {@link Message}. */ + @Order(value = 9, method = "pendingMessages") + private Map pendingMsgs; + + /** Added node. */ + private TcpDiscoveryNode node; + + /** Marshalled {@link #node}. */ + private byte[] nodeBytes; /** Current topology. Initialized by coordinator. */ @GridToStringInclude private Collection top; + /** Marshalled {@link #top}. */ + private byte[] topBytes; + /** */ @GridToStringInclude private transient Collection clientTop; - /** Topology snapshots history. */ - private Map> topHist; + /** Marshalled {@link #clientTop}. */ + private byte[] clientTopBytes; - /** Start time of the first grid node. */ - private final long gridStartTime; + /** + * TODO: Remove after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 + * Java-serializable pending messages from previous node. + */ + private Map serializablePendingMsgs; + + /** Marshalled {@link #serializablePendingMsgs}. */ + private byte[] serializablePendingMsgsBytes; + + /** Constructor for {@link DiscoveryMessageFactory}. */ + public TcpDiscoveryNodeAddedMessage() { + // No-op. + } /** * Constructor. @@ -69,7 +112,8 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM * @param dataPacket container for collecting discovery data across the cluster. * @param gridStartTime Start time of the first grid node. */ - public TcpDiscoveryNodeAddedMessage(UUID creatorNodeId, + public TcpDiscoveryNodeAddedMessage( + UUID creatorNodeId, TcpDiscoveryNode node, DiscoveryDataPacket dataPacket, long gridStartTime @@ -90,13 +134,113 @@ public TcpDiscoveryNodeAddedMessage(UUID creatorNodeId, public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { super(msg); - this.node = msg.node; - this.msgs = msg.msgs; - this.top = msg.top; - this.clientTop = msg.clientTop; - this.topHist = msg.topHist; - this.dataPacket = msg.dataPacket; - this.gridStartTime = msg.gridStartTime; + node = msg.node; + pendingMsgs = msg.pendingMsgs; + serializablePendingMsgs = msg.serializablePendingMsgs; + top = msg.top; + clientTop = msg.clientTop; + topHistMsgs = msg.topHistMsgs; + dataPacket = msg.dataPacket; + gridStartTime = msg.gridStartTime; + } + + /** + * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 + * @param marsh marshaller. + */ + public void prepareMarshal(Marshaller marsh) { + if (!F.isEmpty(topHistMsgs)) + topHistMsgs.values().forEach(m -> m.prepareMarshal(marsh)); + + if (node == null && nodeBytes == null) { + try { + nodeBytes = U.marshal(marsh, node); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal cluster node.", e); + } + } + + if (top != null && topBytes == null) { + try { + topBytes = U.marshal(marsh, top); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal topology nodes.", e); + } + } + + if (clientTop != null && clientTopBytes == null) { + try { + clientTopBytes = U.marshal(marsh, clientTop); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal client topology nodes.", e); + } + } + + if (serializablePendingMsgs != null && serializablePendingMsgsBytes == null) { + try { + serializablePendingMsgsBytes = U.marshal(marsh, serializablePendingMsgs); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal serializable pending messages.", e); + } + } + } + + /** + * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 + * @param marsh Marshaller. + * @param clsLdr Class loader. + */ + public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + if (!F.isEmpty(topHistMsgs)) + topHistMsgs.values().forEach(m -> m.finishUnmarshal(marsh, clsLdr)); + + if (nodeBytes != null && node == null) { + try { + node = U.unmarshal(marsh, nodeBytes, clsLdr); + + nodeBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal cluster node.", e); + } + } + + if (topBytes != null && top == null) { + try { + top = U.unmarshal(marsh, topBytes, clsLdr); + + topBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal topology nodes.", e); + } + } + + if (clientTopBytes != null && clientTop == null) { + try { + clientTop = U.unmarshal(marsh, clientTopBytes, clsLdr); + + clientTopBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal client topology nodes.", e); + } + } + + if (serializablePendingMsgsBytes != null && serializablePendingMsgs == null) { + try { + serializablePendingMsgs = U.unmarshal(marsh, serializablePendingMsgsBytes, clsLdr); + + serializablePendingMsgsBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal serializable pending messages.", e); + } + } } /** @@ -109,23 +253,89 @@ public TcpDiscoveryNode node() { } /** + * @return Pending messages. + * @see #messages() + */ + public Map pendingMessages() { + return pendingMsgs; + } + + /** + * @param pendingMsgs Pending messages. + * @see #messages(List) + */ + public void pendingMessages(Map pendingMsgs) { + this.pendingMsgs = pendingMsgs; + } + + /** + * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Gets pending messages sent to new node by its previous. * * @return Pending messages from previous node. */ - @Nullable public Collection messages() { - return msgs; + @Nullable public List messages() { + assert serializablePendingMsgs == null; + + if (F.isEmpty(pendingMsgs) && F.isEmpty(serializablePendingMsgs)) + return Collections.emptyList(); + + int totalSz = (F.isEmpty(pendingMsgs) ? 0 : pendingMsgs.size()) + + (F.isEmpty(serializablePendingMsgs) ? 0 : serializablePendingMsgs.size()); + + List res = new ArrayList<>(totalSz); + + for (int i = 0; i < totalSz; ++i) { + Message m = pendingMsgs.get(i); + + if (m == null) { + TcpDiscoveryAbstractMessage sm = serializablePendingMsgs.get(i); + assert sm != null; + + res.add(sm); + } + else { + assert serializablePendingMsgs.get(i) == null; + assert m instanceof TcpDiscoveryAbstractMessage; + + res.add((TcpDiscoveryAbstractMessage)m); + } + } + + return res; } /** + * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Sets pending messages to send to new node. * * @param msgs Pending messages to send to new node. */ - public void messages( - @Nullable Collection msgs - ) { - this.msgs = msgs; + public void messages(@Nullable List msgs) { + if (F.isEmpty(msgs)) { + serializablePendingMsgs = null; + pendingMsgs = null; + + return; + } + + int idx = 0; + + for (TcpDiscoveryAbstractMessage m : msgs) { + if (m instanceof Message) { + if (pendingMsgs == null) + pendingMsgs = U.newHashMap(msgs.size()); + + pendingMsgs.put(idx++, (Message)m); + + continue; + } + + if (serializablePendingMsgs == null) + serializablePendingMsgs = U.newHashMap(msgs.size()); + + serializablePendingMsgs.put(idx++, m); + } } /** @@ -162,13 +372,35 @@ public Collection clientTopology() { return clientTop; } + /** @return Topology history messages. */ + public @Nullable Map topologyHistoryMessages() { + return topHistMsgs; + } + + /** @param topHistMsgs Topology history messages. */ + public void topologyHistoryMessages(@Nullable Map topHistMsgs) { + this.topHistMsgs = topHistMsgs; + } + /** * Gets topology snapshots history. * * @return Map with topology snapshots history. */ - public Map> topologyHistory() { - return topHist; + public @Nullable Map> topologyHistory() { + if (topHistMsgs == null) + return null; + + Map> res = U.newHashMap(topHistMsgs.size()); + + topHistMsgs.forEach((nodeId, msgs) -> { + Collection clusterNodeImpls = msgs.clusterNodeMessages().stream().map(TcpDiscoveryNode::new) + .collect(Collectors.toList()); + + res.put(nodeId, clusterNodeImpls); + }); + + return res; } /** @@ -177,7 +409,20 @@ public Map> topologyHistory() { * @param topHist Map with topology snapshots history. */ public void topologyHistory(@Nullable Map> topHist) { - this.topHist = topHist; + if (topHist == null) { + topHistMsgs = null; + + return; + } + + topHistMsgs = U.newHashMap(topHist.size()); + + topHist.forEach((nodeId, clusterNodes) -> { + Collection clusterNodeImpls = clusterNodes.stream().map(ClusterNodeMessage::new) + .collect(Collectors.toList()); + + topHistMsgs.put(nodeId, new ClusterNodeCollectionMessage(clusterNodeImpls)); + }); } /** @@ -187,6 +432,11 @@ public DiscoveryDataPacket gridDiscoveryData() { return dataPacket; } + /** @param dataPacket Data packet data. */ + public void gridDiscoveryData(DiscoveryDataPacket dataPacket) { + this.dataPacket = dataPacket; + } + /** * Clears discovery data to minimize message size. */ @@ -210,6 +460,16 @@ public long gridStartTime() { return gridStartTime; } + /** @param gridStartTime First grid node start time. */ + public void gridStartTime(long gridStartTime) { + this.gridStartTime = gridStartTime; + } + + /** {@inheritDoc} */ + @Override public short directType() { + return 20; + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(TcpDiscoveryNodeAddedMessage.class, this, "super", super.toString()); From 1e1dd007715dc11946aa6624b98c605e1741d53c Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 01:31:49 +0300 Subject: [PATCH 02/47] fix --- .../ignite/spi/discovery/tcp/ServerImpl.java | 2 +- .../tcp/internal/TcpDiscoveryNode.java | 205 +++++++++--------- .../tcp/messages/ClusterNodeMessage.java | 7 +- .../TcpDiscoveryNodeAddedMessage.java | 56 ++--- 4 files changed, 137 insertions(+), 133 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 3b16c46392645..723ec737a7798 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -2491,7 +2491,7 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); - addFinishMsg.prepareMarshal(spi.marshaller()); + addFinishMsg.prepareMarshal(spi.marshaller());` msg = addFinishMsg; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java index 2b4ffc06b8f2b..e12b812f599ea 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java @@ -36,7 +36,6 @@ import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.IgniteNodeAttributes; import org.apache.ignite.internal.managers.discovery.IgniteClusterNode; -import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; import org.apache.ignite.internal.util.lang.GridMetadataAwareAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -47,7 +46,6 @@ import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; -import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeMessage; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_NODE_CONSISTENT_ID; @@ -64,8 +62,23 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite /** */ private static final long serialVersionUID = 0L; - /** Values holding message of {@link ClusterNode}. */ - private ClusterNodeMessage clusterNodeMsg; + /** Node ID. */ + private volatile UUID id; + + /** Consistent ID. */ + @GridToStringInclude + private Object consistentId; + + /** Node attributes. */ + @GridToStringExclude + private Map attrs; + + /** Internal discovery addresses as strings. */ + @GridToStringInclude + private Collection addrs; + + /** Internal discovery host names as strings. */ + private Collection hostNames; /** */ @GridToStringInclude @@ -75,10 +88,17 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite @GridToStringInclude private int discPort; + /** Node metrics. */ + @GridToStringExclude + private volatile ClusterMetrics metrics; + /** Node cache metrics. */ @GridToStringExclude private volatile Map cacheMetrics; + /** Node order in the topology. */ + private volatile long order; + /** Node order in the topology (internal). */ private volatile long intOrder; @@ -98,6 +118,12 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite @GridToStringExclude private boolean visible; + /** Grid local node flag (transient). */ + private boolean loc; + + /** Version. */ + private IgniteProductVersion ver; + /** Alive check time (used by clients). */ @GridToStringExclude private transient volatile long aliveCheckTimeNanos; @@ -122,12 +148,7 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite * Public default no-arg constructor for {@link Externalizable} interface. */ public TcpDiscoveryNode() { - clusterNodeMsg = new ClusterNodeMessage(); - } - - /** */ - public TcpDiscoveryNode(ClusterNodeMessage msg) { - clusterNodeMsg = msg; + // No-op. } /** @@ -141,8 +162,7 @@ public TcpDiscoveryNode(ClusterNodeMessage msg) { * @param ver Version. * @param consistentId Node consistent ID. */ - public TcpDiscoveryNode( - UUID id, + public TcpDiscoveryNode(UUID id, Collection addrs, Collection hostNames, int discPort, @@ -154,23 +174,21 @@ public TcpDiscoveryNode( assert metricsProvider != null; assert ver != null; + this.id = id; + List sortedAddrs = new ArrayList<>(addrs); - Collections.sort(sortedAddrs); - clusterNodeMsg = new ClusterNodeMessage(); - id(id); - clusterNodeMsg.consistentId(consistentId != null ? consistentId : U.consistentId(sortedAddrs, discPort)); - clusterNodeMsg.addresses(sortedAddrs); - clusterNodeMsg.hostNames(hostNames); - version(ver); + Collections.sort(sortedAddrs); - ClusterMetrics metrics = metricsProvider.metrics(); + this.addrs = sortedAddrs; + this.hostNames = hostNames; + this.discPort = discPort; + this.metricsProvider = metricsProvider; + this.ver = ver; - if (metrics != null) - setMetrics(metrics); + this.consistentId = consistentId != null ? consistentId : U.consistentId(sortedAddrs, discPort); - this.metricsProvider = metricsProvider; - this.discPort = discPort; + metrics = metricsProvider.metrics(); cacheMetrics = metricsProvider.cacheMetrics(); sockAddrs = U.toSocketAddresses(this, discPort); } @@ -190,18 +208,13 @@ public void lastSuccessfulAddress(InetSocketAddress lastSuccessfulAddr) { } /** {@inheritDoc} */ - @Override public synchronized UUID id() { - return clusterNodeMsg.id(); - } - - /** */ - private synchronized void id(UUID id) { - clusterNodeMsg.id(id); + @Override public UUID id() { + return id; } /** {@inheritDoc} */ @Override public Object consistentId() { - return clusterNodeMsg.consistentId(); + return consistentId; } /** @@ -210,13 +223,13 @@ private synchronized void id(UUID id) { * @param consistentId Consistent globally unique node ID. */ @Override public void setConsistentId(Serializable consistentId) { - clusterNodeMsg.consistentId(consistentId); + this.consistentId = consistentId; - Map map = new HashMap<>(clusterNodeMsg.attributes()); + final Map map = new HashMap<>(attrs); map.put(ATTR_NODE_CONSISTENT_ID, consistentId); - clusterNodeMsg.attributes(Collections.unmodifiableMap(map)); + attrs = Collections.unmodifiableMap(map); } /** {@inheritDoc} */ @@ -225,13 +238,13 @@ private synchronized void id(UUID id) { if (IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS.equals(name)) return null; - return (T)clusterNodeMsg.attributes().get(name); + return (T)attrs.get(name); } /** {@inheritDoc} */ @Override public Map attributes() { // Even though discovery SPI removes this attribute after authentication, keep this check for safety. - return F.view(clusterNodeMsg.attributes(), new IgnitePredicate<>() { + return F.view(attrs, new IgnitePredicate() { @Override public boolean apply(String s) { return !IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS.equals(s); } @@ -244,7 +257,7 @@ private synchronized void id(UUID id) { * @param attrs Node attributes. */ public void setAttributes(Map attrs) { - clusterNodeMsg.attributes(U.sealMap(attrs)); + this.attrs = U.sealMap(attrs); } /** @@ -253,29 +266,27 @@ public void setAttributes(Map attrs) { * @return Node attributes without filtering. */ public Map getAttributes() { - return clusterNodeMsg.attributes(); + return attrs; } /** {@inheritDoc} */ - @Override public synchronized ClusterMetrics metrics() { + @Override public ClusterMetrics metrics() { if (metricsProvider != null) { - ClusterMetrics metrics = metricsProvider.metrics(); + ClusterMetrics metrics0 = metricsProvider.metrics(); - setMetrics(metrics); + metrics = metrics0; - return metrics; + return metrics0; } - assert clusterNodeMsg.clusterMetricsMessage() != null; - - return new ClusterMetricsSnapshot(clusterNodeMsg.clusterMetricsMessage()); + return metrics; } /** {@inheritDoc} */ - @Override public synchronized void setMetrics(ClusterMetrics metrics) { + @Override public void setMetrics(ClusterMetrics metrics) { assert metrics != null; - clusterNodeMsg.clusterMetricsMessage(new NodeMetricsMessage(metrics)); + this.metrics = metrics; } /** {@inheritDoc} */ @@ -315,22 +326,22 @@ public void internalOrder(long intOrder) { /** * @return Order. */ - @Override public synchronized long order() { - return clusterNodeMsg.order(); + @Override public long order() { + return order; } /** * @param order Order of the node. */ - public synchronized void order(long order) { + public void order(long order) { assert order > 0 : "Order is invalid: " + this; - clusterNodeMsg.order(order); + this.order = order; } /** {@inheritDoc} */ @Override public IgniteProductVersion version() { - return new IgniteProductVersion(clusterNodeMsg.productVersionMessage()); + return ver; } /** @@ -339,29 +350,29 @@ public synchronized void order(long order) { public void version(IgniteProductVersion ver) { assert ver != null; - clusterNodeMsg.productVersionMessage(ver.message()); + this.ver = ver; } /** {@inheritDoc} */ @Override public Collection addresses() { - return clusterNodeMsg.addresses(); + return addrs; } /** {@inheritDoc} */ @Override public boolean isLocal() { - return clusterNodeMsg.local(); + return loc; } /** * @param loc Grid local node flag. */ public void local(boolean loc) { - clusterNodeMsg.local(loc); + this.loc = loc; } /** {@inheritDoc} */ @Override public Collection hostNames() { - return clusterNodeMsg.hostNames(); + return hostNames; } /** @@ -454,7 +465,7 @@ public void visible(boolean visible) { if (!cacheCliInit) { Boolean clientModeAttr = attribute(IgniteNodeAttributes.ATTR_CLIENT_MODE); - clusterNodeMsg.client(cacheCli = clientModeAttr != null && clientModeAttr); + cacheCli = clientModeAttr != null && clientModeAttr; cacheCliInit = true; } @@ -509,7 +520,7 @@ public void clientRouterNodeId(UUID clientRouterNodeId) { * @param newId New node ID. */ public void onClientDisconnected(UUID newId) { - id(newId); + id = newId; } /** @@ -517,10 +528,11 @@ public void onClientDisconnected(UUID newId) { * @return Copy of local node for client reconnect request. */ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { - TcpDiscoveryNode node = new TcpDiscoveryNode(id(), clusterNodeMsg.addresses(), hostNames(), discPort, - metricsProvider, version(), null); + TcpDiscoveryNode node = new TcpDiscoveryNode( + id, addrs, hostNames, discPort, metricsProvider, ver, null + ); - node.clusterNodeMsg.attributes(Collections.unmodifiableMap(new HashMap<>(nodeAttrs))); + node.attrs = Collections.unmodifiableMap(new HashMap<>(nodeAttrs)); node.clientRouterNodeId = clientRouterNodeId; return node; @@ -544,16 +556,16 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { - U.writeUuid(out, id()); - U.writeMap(out, clusterNodeMsg.attributes()); - U.writeCollection(out, clusterNodeMsg.addresses()); - U.writeCollection(out, clusterNodeMsg.hostNames()); + U.writeUuid(out, id); + U.writeMap(out, attrs); + U.writeCollection(out, addrs); + U.writeCollection(out, hostNames); out.writeInt(discPort); // Cluster metrics byte[] mtr = null; - ClusterMetrics metrics = metrics(); + ClusterMetrics metrics = this.metrics; if (metrics != null) mtr = ClusterMetricsSnapshot.serialize(metrics); @@ -563,55 +575,48 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { // Legacy: Number of cache metrics out.writeInt(0); - out.writeLong(order()); + out.writeLong(order); out.writeLong(intOrder); - out.writeObject(version()); + out.writeObject(ver); U.writeUuid(out, clientRouterNodeId); } /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - assert clusterNodeMsg != null; - - id(U.readUuid(in)); + id = U.readUuid(in); - clusterNodeMsg.attributes(U.sealMap(U.readMap(in))); - clusterNodeMsg.addresses(U.readCollection(in)); - clusterNodeMsg.hostNames(U.readCollection(in)); + attrs = U.sealMap(U.readMap(in)); + addrs = U.readCollection(in); + hostNames = U.readCollection(in); discPort = in.readInt(); - Object consistentIdAttr = clusterNodeMsg.attributes().get(ATTR_NODE_CONSISTENT_ID); + Object consistentIdAttr = attrs.get(ATTR_NODE_CONSISTENT_ID); // Cluster metrics byte[] mtr = U.readByteArray(in); if (mtr != null) - setMetrics(ClusterMetricsSnapshot.deserialize(mtr, 0)); + metrics = ClusterMetricsSnapshot.deserialize(mtr, 0); // Legacy: Cache metrics int size = in.readInt(); - for (int i = 0; i < size; i++) { - in.readInt(); - in.readObject(); - } + assert size == 0; - order(in.readLong()); + order = in.readLong(); intOrder = in.readLong(); - version((IgniteProductVersion)in.readObject()); + ver = (IgniteProductVersion)in.readObject(); clientRouterNodeId = U.readUuid(in); if (clientRouterNodeId() != null) - clusterNodeMsg.consistentId(consistentIdAttr != null ? consistentIdAttr : id()); - else { - clusterNodeMsg.consistentId(consistentIdAttr != null ? consistentIdAttr - : U.consistentId(clusterNodeMsg.addresses(), discPort)); - } + consistentId = consistentIdAttr != null ? consistentIdAttr : id; + else + consistentId = consistentIdAttr != null ? consistentIdAttr : U.consistentId(addrs, discPort); } /** {@inheritDoc} */ @Override public int hashCode() { - return id().hashCode(); + return id.hashCode(); } /** {@inheritDoc} */ @@ -630,16 +635,14 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { * @param node to copy data from */ public TcpDiscoveryNode(ClusterNode node) { - clusterNodeMsg = new ClusterNodeMessage(); - - id(node.id()); - clusterNodeMsg.consistentId(node.consistentId()); - clusterNodeMsg.addresses(node.addresses()); - clusterNodeMsg.hostNames(node.hostNames()); - order(node.order()); - version(node.version()); - clusterNodeMsg.attributes(Collections.singletonMap(ATTR_NODE_CONSISTENT_ID, clusterNodeMsg.consistentId())); - - clientRouterNodeId = node.isClient() ? node.id() : null; + this.id = node.id(); + this.consistentId = node.consistentId(); + this.addrs = node.addresses(); + this.hostNames = node.hostNames(); + this.order = node.order(); + this.ver = node.version(); + this.clientRouterNodeId = node.isClient() ? node.id() : null; + + attrs = Collections.singletonMap(ATTR_NODE_CONSISTENT_ID, consistentId); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java index 510c7ac0ff33e..ff81142bc5717 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java @@ -17,6 +17,7 @@ package org.apache.ignite.spi.discovery.tcp.messages; +import java.io.Serializable; import java.util.Collection; import java.util.Map; import java.util.UUID; @@ -77,7 +78,7 @@ public class ClusterNodeMessage implements Message { private String dataCenterId; /** Consistent ID. */ - private Object consistentId; + private Serializable consistentId; /** */ private byte[] consistentIdBytes; @@ -248,12 +249,12 @@ public void productVersionMessage(IgniteProductVersionMessage productVerMsg) { } /** @return Node consistent id. */ - public Object consistentId() { + public Serializable consistentId() { return consistentId; } /** @param consistentId Node consistent id. */ - public void consistentId(Object consistentId) { + public void consistentId(Serializable consistentId) { this.consistentId = consistentId; } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index e445617fd87e7..76738ae283a7c 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -27,12 +27,15 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.ClusterMetricsSnapshot; +import org.apache.ignite.internal.IgniteNodeAttributes; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; @@ -78,7 +81,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM /** Current topology. Initialized by coordinator. */ @GridToStringInclude - private Collection top; + private @Nullable Collection top; /** Marshalled {@link #top}. */ private byte[] topBytes; @@ -87,14 +90,11 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM @GridToStringInclude private transient Collection clientTop; - /** Marshalled {@link #clientTop}. */ - private byte[] clientTopBytes; - /** * TODO: Remove after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Java-serializable pending messages from previous node. */ - private Map serializablePendingMsgs; + private @Nullable Map serializablePendingMsgs; /** Marshalled {@link #serializablePendingMsgs}. */ private byte[] serializablePendingMsgsBytes; @@ -152,7 +152,7 @@ public void prepareMarshal(Marshaller marsh) { if (!F.isEmpty(topHistMsgs)) topHistMsgs.values().forEach(m -> m.prepareMarshal(marsh)); - if (node == null && nodeBytes == null) { + if (node != null && nodeBytes == null) { try { nodeBytes = U.marshal(marsh, node); } @@ -170,15 +170,6 @@ public void prepareMarshal(Marshaller marsh) { } } - if (clientTop != null && clientTopBytes == null) { - try { - clientTopBytes = U.marshal(marsh, clientTop); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal client topology nodes.", e); - } - } - if (serializablePendingMsgs != null && serializablePendingMsgsBytes == null) { try { serializablePendingMsgsBytes = U.marshal(marsh, serializablePendingMsgs); @@ -220,17 +211,6 @@ public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { } } - if (clientTopBytes != null && clientTop == null) { - try { - clientTop = U.unmarshal(marsh, clientTopBytes, clsLdr); - - clientTopBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal client topology nodes.", e); - } - } - if (serializablePendingMsgsBytes != null && serializablePendingMsgs == null) { try { serializablePendingMsgs = U.unmarshal(marsh, serializablePendingMsgsBytes, clsLdr); @@ -394,8 +374,28 @@ public void topologyHistoryMessages(@Nullable Map> res = U.newHashMap(topHistMsgs.size()); topHistMsgs.forEach((nodeId, msgs) -> { - Collection clusterNodeImpls = msgs.clusterNodeMessages().stream().map(TcpDiscoveryNode::new) - .collect(Collectors.toList()); + Collection clusterNodeImpls = msgs.clusterNodeMessages().stream() + .map(m -> { + TcpDiscoveryNode tcpDiscoNode = new TcpDiscoveryNode( + m.id(), + m.addresses(), + m.hostNames(), + 0, + null, + new IgniteProductVersion(m.productVersionMessage()), + m.consistentId() + ); + + tcpDiscoNode.order(m.order()); + tcpDiscoNode.local(m.local()); + tcpDiscoNode.setAttributes(m.attributes()); + tcpDiscoNode.getAttributes().put(IgniteNodeAttributes.ATTR_CLIENT_MODE, m.client()); + + if (m.clusterMetricsMessage() != null) + tcpDiscoNode.setMetrics(new ClusterMetricsSnapshot(m.clusterMetricsMessage())); + + return tcpDiscoNode; + }).collect(Collectors.toList()); res.put(nodeId, clusterNodeImpls); }); From 43f42671b1cccede80df5c2fff20293b0d92cb35 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 01:38:28 +0300 Subject: [PATCH 03/47] fix --- .../java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 723ec737a7798..3b16c46392645 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -2491,7 +2491,7 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); - addFinishMsg.prepareMarshal(spi.marshaller());` + addFinishMsg.prepareMarshal(spi.marshaller()); msg = addFinishMsg; From d68b352158b0b0a3d593a696a888ced11b3047b9 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 12:22:21 +0300 Subject: [PATCH 04/47] fix --- .../cluster/ClusterNodeMetrics.java | 5 +- .../ignite/spi/discovery/tcp/ServerImpl.java | 15 +++-- .../tcp/internal/TcpDiscoveryNode.java | 64 +++++++++++++++---- .../ClusterNodeCollectionMessage.java | 2 +- .../tcp/messages/ClusterNodeMessage.java | 8 +-- .../TcpDiscoveryNodeAddedMessage.java | 51 ++++++++++----- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java index 7bba244fc7fc6..55414ebe7f6c0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java @@ -24,6 +24,7 @@ import org.apache.ignite.cluster.ClusterMetrics; import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.processors.cache.CacheMetricsSnapshot; +import org.jetbrains.annotations.Nullable; /** * @@ -33,13 +34,13 @@ class ClusterNodeMetrics { private final ClusterMetrics nodeMetrics; /** */ - private final Map cacheMetrics; + private final @Nullable Map cacheMetrics; /** * @param nodeMetrics Node metrics. * @param cacheMetrics Cache metrics. */ - ClusterNodeMetrics(ClusterMetrics nodeMetrics, Map cacheMetrics) { + ClusterNodeMetrics(ClusterMetrics nodeMetrics, @Nullable Map cacheMetrics) { this.nodeMetrics = nodeMetrics; this.cacheMetrics = cacheMetrics; } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 3b16c46392645..cce3fb5ea6f57 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1897,6 +1897,8 @@ private void prepareNodeAddedMessage( } nodeAddedMsg.topologyHistory(hist); + + nodeAddedMsg.prepareMarshal(spi.marshaller()); } } } @@ -2646,8 +2648,6 @@ private TcpDiscoveryAbstractMessage prepare(TcpDiscoveryAbstractMessage msg, UUI msg0.topology(addedMsg.clientTopology()); - msg0.prepareMarshal(spi.marshaller()); - return msg0; } } @@ -3111,6 +3111,11 @@ protected void runTasks() { if (!locNode.id().equals(msg.senderNodeId()) && ensured) lastRingMsgTimeNanos = System.nanoTime(); + if (msg instanceof TcpDiscoveryNodeAddedMessage) { + ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(spi.marshaller(), + U.resolveClassLoader(spi.ignite().configuration())); + } + if (locNode.internalOrder() == 0) { boolean proc = false; @@ -3145,12 +3150,8 @@ else if (msg instanceof TcpDiscoveryClientReconnectMessage) { sendMessageAcrossRing(msg); } - else if (msg instanceof TcpDiscoveryNodeAddedMessage) { - ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(spi.marshaller(), - U.resolveClassLoader(spi.ignite().configuration())); - + else if (msg instanceof TcpDiscoveryNodeAddedMessage) processNodeAddedMessage((TcpDiscoveryNodeAddedMessage)msg); - } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) processNodeAddFinishedMessage((TcpDiscoveryNodeAddFinishedMessage)msg); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java index e12b812f599ea..ea9bd55c57d3e 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java @@ -94,7 +94,7 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite /** Node cache metrics. */ @GridToStringExclude - private volatile Map cacheMetrics; + private volatile @Nullable Map cacheMetrics; /** Node order in the topology. */ private volatile long order; @@ -162,35 +162,73 @@ public TcpDiscoveryNode() { * @param ver Version. * @param consistentId Node consistent ID. */ - public TcpDiscoveryNode(UUID id, + public TcpDiscoveryNode( + UUID id, Collection addrs, Collection hostNames, int discPort, DiscoveryMetricsProvider metricsProvider, IgniteProductVersion ver, - Serializable consistentId + @Nullable Serializable consistentId + ) { + this(id, consistentId, 0, false, null, addrs, hostNames, null, ver, metricsProvider.metrics()); + + this.discPort = discPort; + this.metricsProvider = metricsProvider; + cacheMetrics = metricsProvider.cacheMetrics(); + sockAddrs = U.toSocketAddresses(this, discPort); + } + + /** + * Constructor to implement {@link ClusterNode}. + * + * @param id Node id. + * @param consistentId Consistent id. + * @param order Node order. + * @param loc Local node flag. + * @param client Client node flag. + * @param addrs Node addresses. + * @param hostNames Node host names. + * @param attrs Node attributes. + * @param ver Version. + * @param metrics Node metrics. + */ + public TcpDiscoveryNode( + UUID id, + @Nullable Serializable consistentId, + long order, + boolean loc, + @Nullable Boolean client, + Collection addrs, + Collection hostNames, + @Nullable Map attrs, + IgniteProductVersion ver, + ClusterMetrics metrics ) { assert id != null; - assert metricsProvider != null; assert ver != null; + assert metrics != null; this.id = id; + this.order = order; + this.loc = loc; + this.hostNames = hostNames; + this.ver = ver; + this.metrics = metrics; List sortedAddrs = new ArrayList<>(addrs); - Collections.sort(sortedAddrs); this.addrs = sortedAddrs; - this.hostNames = hostNames; - this.discPort = discPort; - this.metricsProvider = metricsProvider; - this.ver = ver; this.consistentId = consistentId != null ? consistentId : U.consistentId(sortedAddrs, discPort); - metrics = metricsProvider.metrics(); - cacheMetrics = metricsProvider.cacheMetrics(); - sockAddrs = U.toSocketAddresses(this, discPort); + if (attrs == null) + attrs = Collections.emptyMap(); + + this.attrs = new HashMap<>(attrs); + + this.attrs.put(IgniteNodeAttributes.ATTR_CLIENT_MODE, client != null && client); } /** @@ -290,7 +328,7 @@ public Map getAttributes() { } /** {@inheritDoc} */ - @Override public Map cacheMetrics() { + @Override public @Nullable Map cacheMetrics() { if (metricsProvider != null) { Map cacheMetrics0 = metricsProvider.cacheMetrics(); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java index 35304fd68bd96..ce59d5d434301 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java @@ -72,6 +72,6 @@ public void clusterNodeMessages(Collection clusterNodeMsgs) /** {@inheritDoc} */ @Override public short directType() { - return 115; + return -110; } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java index ff81142bc5717..5fc7f344843ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java @@ -55,7 +55,7 @@ public class ClusterNodeMessage implements Message { /** */ @Order(value = 3, method = "clusterMetricsMessage") - private NodeMetricsMessage clusterMetricsMsg; + private TcpDiscoveryNodeMetricsMessage clusterMetricsMsg; /** */ @Order(value = 4) @@ -100,7 +100,7 @@ public ClusterNodeMessage(ClusterNode clusterNode) { addrs = clusterNode.addresses(); hostNames = clusterNode.hostNames(); if (clusterNode.metrics() != null) - clusterMetricsMsg = new NodeMetricsMessage(clusterNode.metrics()); + clusterMetricsMsg = new TcpDiscoveryNodeMetricsMessage(clusterNode.metrics()); order = clusterNode.order(); productVerMsg = new IgniteProductVersionMessage(clusterNode.version()); loc = clusterNode.isLocal(); @@ -111,7 +111,7 @@ public ClusterNodeMessage(ClusterNode clusterNode) { /** @param marsh Marshalled. */ public void prepareMarshal(Marshaller marsh) { - if (F.isEmpty(attrs) && attrsBytes == null) { + if (!F.isEmpty(attrs) && attrsBytes == null) { try { attrsBytes = U.marshal(marsh, attrs); } @@ -174,7 +174,7 @@ public NodeMetricsMessage clusterMetricsMessage() { } /** @param clusterMetricsMsg Node metrics message. */ - public void clusterMetricsMessage(NodeMetricsMessage clusterMetricsMsg) { + public void clusterMetricsMessage(TcpDiscoveryNodeMetricsMessage clusterMetricsMsg) { this.clusterMetricsMsg = clusterMetricsMsg; } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index 76738ae283a7c..ab81f053e7a49 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -28,7 +28,6 @@ import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.ClusterMetricsSnapshot; -import org.apache.ignite.internal.IgniteNodeAttributes; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -77,6 +76,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private TcpDiscoveryNode node; /** Marshalled {@link #node}. */ + @Order(10) private byte[] nodeBytes; /** Current topology. Initialized by coordinator. */ @@ -84,7 +84,8 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private @Nullable Collection top; /** Marshalled {@link #top}. */ - private byte[] topBytes; + @Order(value = 11, method = "topologyBytes") + private @Nullable byte[] topBytes; /** */ @GridToStringInclude @@ -135,9 +136,11 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { super(msg); node = msg.node; + nodeBytes = msg.nodeBytes; pendingMsgs = msg.pendingMsgs; serializablePendingMsgs = msg.serializablePendingMsgs; top = msg.top; + topBytes = msg.topBytes; clientTop = msg.clientTop; topHistMsgs = msg.topHistMsgs; dataPacket = msg.dataPacket; @@ -232,6 +235,16 @@ public TcpDiscoveryNode node() { return node; } + /** @return Serialized {@link #node}. */ + public byte[] nodeBytes() { + return nodeBytes; + } + + /** @param nodeBytes Serialized {@link #node}. */ + public void nodeBytes(byte[] nodeBytes) { + this.nodeBytes = nodeBytes; + } + /** * @return Pending messages. * @see #messages() @@ -334,6 +347,17 @@ public void messages(@Nullable List msgs) { */ public void topology(@Nullable Collection top) { this.top = top; + topBytes = null; + } + + /** @return Serialized {@link #top}. */ + public @Nullable byte[] topologyBytes() { + return topBytes; + } + + /** @param topBytes Serialized {@link #top}. */ + public void topologyBytes(@Nullable byte[] topBytes) { + this.topBytes = topBytes; } /** @@ -342,7 +366,7 @@ public void topology(@Nullable Collection top) { public void clientTopology(Collection top) { assert top != null && !top.isEmpty() : top; - this.clientTop = top; + clientTop = top; } /** @@ -376,24 +400,21 @@ public void topologyHistoryMessages(@Nullable Map { Collection clusterNodeImpls = msgs.clusterNodeMessages().stream() .map(m -> { + assert m.clusterMetricsMessage() != null; + TcpDiscoveryNode tcpDiscoNode = new TcpDiscoveryNode( m.id(), + m.consistentId(), + m.order(), + m.local(), + m.client(), m.addresses(), m.hostNames(), - 0, - null, + m.attributes(), new IgniteProductVersion(m.productVersionMessage()), - m.consistentId() + new ClusterMetricsSnapshot(m.clusterMetricsMessage()) ); - tcpDiscoNode.order(m.order()); - tcpDiscoNode.local(m.local()); - tcpDiscoNode.setAttributes(m.attributes()); - tcpDiscoNode.getAttributes().put(IgniteNodeAttributes.ATTR_CLIENT_MODE, m.client()); - - if (m.clusterMetricsMessage() != null) - tcpDiscoNode.setMetrics(new ClusterMetricsSnapshot(m.clusterMetricsMessage())); - return tcpDiscoNode; }).collect(Collectors.toList()); @@ -409,7 +430,7 @@ public void topologyHistoryMessages(@Nullable Map> topHist) { - if (topHist == null) { + if (F.isEmpty(topHist)) { topHistMsgs = null; return; From 1064805091d948b62070e0970d3f06e2a31a2815 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 18:31:15 +0300 Subject: [PATCH 05/47] refactoring. + dedicated if --- .../ignite/spi/discovery/tcp/ClientImpl.java | 8 +--- .../ignite/spi/discovery/tcp/ServerImpl.java | 25 +---------- .../discovery/tcp/TcpDiscoveryIoSession.java | 9 ++++ .../TcpDiscoveryMarshallableMessage.java | 41 +++++++++++++++++++ .../TcpDiscoveryNodeAddFinishedMessage.java | 7 ++-- .../TcpDiscoveryNodeAddedMessage.java | 35 +++++++++------- 6 files changed, 76 insertions(+), 49 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index fe702517dbe33..9e1714867d2d2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2160,12 +2160,8 @@ protected void processDiscoveryMessage(TcpDiscoveryAbstractMessage msg) { if (msg instanceof TraceableMessage) tracing.messages().beforeSend((TraceableMessage)msg); - if (msg instanceof TcpDiscoveryNodeAddedMessage) { - ((TcpDiscoveryNodeAddedMessage)msg) - .finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); - + if (msg instanceof TcpDiscoveryNodeAddedMessage) processNodeAddedMessage((TcpDiscoveryNodeAddedMessage)msg); - } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) processNodeAddFinishedMessage((TcpDiscoveryNodeAddFinishedMessage)msg); else if (msg instanceof TcpDiscoveryNodeLeftMessage) @@ -2311,8 +2307,6 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms delayDiscoData.clear(); } - msg.finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); - locNode.setAttributes(msg.clientNodeAttributes()); clearNodeSensitiveData(locNode); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index cce3fb5ea6f57..07fc5755eebb2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1897,8 +1897,6 @@ private void prepareNodeAddedMessage( } nodeAddedMsg.topologyHistory(hist); - - nodeAddedMsg.prepareMarshal(spi.marshaller()); } } } @@ -2484,8 +2482,6 @@ void add(TcpDiscoveryAbstractMessage msg) { // Do not need this data for client reconnect. if (addedMsg.gridDiscoveryData() != null) addedMsg.clearDiscoveryData(); - - addedMsg.prepareMarshal(spi.marshaller()); } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; @@ -2493,8 +2489,6 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); - addFinishMsg.prepareMarshal(spi.marshaller()); - msg = addFinishMsg; DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData(); @@ -3111,11 +3105,6 @@ protected void runTasks() { if (!locNode.id().equals(msg.senderNodeId()) && ensured) lastRingMsgTimeNanos = System.nanoTime(); - if (msg instanceof TcpDiscoveryNodeAddedMessage) { - ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(spi.marshaller(), - U.resolveClassLoader(spi.ignite().configuration())); - } - if (locNode.internalOrder() == 0) { boolean proc = false; @@ -3263,8 +3252,6 @@ private void sendMessageToClients(TcpDiscoveryAbstractMessage msg) { } } - ((TcpDiscoveryNodeAddedMessage)msg).prepareMarshal(spi.marshaller()); - // TODO Investigate possible optimizations: https://issues.apache.org/jira/browse/IGNITE-27722 clientMsgWorker.addMessage(msg); } @@ -4846,8 +4833,6 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { addFinishMsg.clientDiscoData(msg.gridDiscoveryData()); addFinishMsg.clientNodeAttributes(node.attributes()); - - addFinishMsg.prepareMarshal(spi.marshaller()); } addFinishMsg = tracing.messages().branch(addFinishMsg, msg); @@ -4874,11 +4859,8 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { else if (!locNodeId.equals(node.id()) && ring.node(node.id()) != null) { // Local node already has node from message in local topology. // Just pass it to coordinator via the ring. - if (sendMessageToRemotes(msg)) { - msg.prepareMarshal(spi.marshaller()); - + if (sendMessageToRemotes(msg)) sendMessageAcrossRing(msg); - } if (log.isDebugEnabled()) { log.debug("Local node already has node being added. Passing TcpDiscoveryNodeAddedMessage to " + @@ -5101,11 +5083,8 @@ else if (spiState == CONNECTING) processMessageFailedNodes(msg); } - if (sendMessageToRemotes(msg)) { - msg.prepareMarshal(spi.marshaller()); - + if (sendMessageToRemotes(msg)) sendMessageAcrossRing(msg); - } } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index fa8d71e40f171..a77b44e413d6b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -40,6 +40,7 @@ import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -140,6 +141,9 @@ void writeMessage(TcpDiscoveryAbstractMessage msg) throws IgniteCheckedException } try { + if (msg instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); + out.write(MESSAGE_SERIALIZATION); serializeMessage((Message)msg, out); @@ -212,6 +216,11 @@ T readMessage() throws IgniteCheckedException, IOException { } while (!finished); + if (msg instanceof TcpDiscoveryMarshallableMessage) { + ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), + U.resolveClassLoader(spi.ignite().configuration())); + } + return (T)msg; } catch (Exception e) { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java new file mode 100644 index 0000000000000..0cdd3621eee94 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.discovery.tcp.messages; + +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; + +/** + * Base class for TCP Discovery messages which still require external pre- and post- serialization. + *
+ * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 + */ +public interface TcpDiscoveryMarshallableMessage extends Message { + /** @param marsh Marshaller. */ + default void prepareMarshal(Marshaller marsh) { + throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); + } + + /** + * @param marsh Marshaller. + * @param clsLdr Class loader. + */ + default void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 7e75a16853d33..68afb1d4c01cb 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -27,7 +27,6 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.jetbrains.annotations.Nullable; @@ -36,7 +35,7 @@ */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { +public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { /** */ private static final long serialVersionUID = 0L; @@ -151,7 +150,7 @@ public void clientNodeAttributesBytes(@Nullable byte[] clientNodeAttrsBytes) { /** * @param marsh Marshaller. */ - public void prepareMarshal(Marshaller marsh) { + @Override public void prepareMarshal(Marshaller marsh) { if (clientNodeAttrs != null && clientNodeAttrsBytes == null) { try { clientNodeAttrsBytes = U.marshal(marsh, clientNodeAttrs); @@ -166,7 +165,7 @@ public void prepareMarshal(Marshaller marsh) { * @param marsh Marshaller. * @param clsLdr Class loader. */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (F.isEmpty(clientNodeAttrsBytes)) clientNodeAttrs = null; else { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index ab81f053e7a49..5e3e0fc990e19 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -42,6 +42,7 @@ import org.jetbrains.annotations.Nullable; /** + * TODO: Revise serialization of the {@link TcpDiscoveryNode} fields after https://issues.apache.org/jira/browse/IGNITE-27899 * Message telling nodes that new node should be added to topology. * When newly added node receives the message it connects to its next and finishes * join process. @@ -52,7 +53,7 @@ */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { +public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { /** */ private static final long serialVersionUID = 0L; @@ -92,12 +93,13 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private transient Collection clientTop; /** - * TODO: Remove after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 + * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 * Java-serializable pending messages from previous node. */ private @Nullable Map serializablePendingMsgs; /** Marshalled {@link #serializablePendingMsgs}. */ + @Order(value = 12, method = "serializablePendingMessagesBytes") private byte[] serializablePendingMsgsBytes; /** Constructor for {@link DiscoveryMessageFactory}. */ @@ -137,21 +139,16 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { node = msg.node; nodeBytes = msg.nodeBytes; - pendingMsgs = msg.pendingMsgs; - serializablePendingMsgs = msg.serializablePendingMsgs; - top = msg.top; - topBytes = msg.topBytes; + pendingMessages(msg.pendingMsgs); + topology(msg.top); clientTop = msg.clientTop; topHistMsgs = msg.topHistMsgs; dataPacket = msg.dataPacket; gridStartTime = msg.gridStartTime; } - /** - * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 - * @param marsh marshaller. - */ - public void prepareMarshal(Marshaller marsh) { + /** @param marsh marshaller. */ + @Override public void prepareMarshal(Marshaller marsh) { if (!F.isEmpty(topHistMsgs)) topHistMsgs.values().forEach(m -> m.prepareMarshal(marsh)); @@ -184,11 +181,10 @@ public void prepareMarshal(Marshaller marsh) { } /** - * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 * @param marsh Marshaller. * @param clsLdr Class loader. */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (!F.isEmpty(topHistMsgs)) topHistMsgs.values().forEach(m -> m.finishUnmarshal(marsh, clsLdr)); @@ -259,10 +255,20 @@ public Map pendingMessages() { */ public void pendingMessages(Map pendingMsgs) { this.pendingMsgs = pendingMsgs; + this.serializablePendingMsgsBytes = null; + } + + /** @return Bytes of {@link #serializablePendingMsgs}. */ + public @Nullable byte[] serializablePendingMessagesBytes() { + return serializablePendingMsgsBytes; + } + + /** @param serializablePendingMsgsBytes Bytes of {@link #serializablePendingMsgs}. */ + public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendingMsgsBytes) { + this.serializablePendingMsgsBytes = serializablePendingMsgsBytes; } /** - * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Gets pending messages sent to new node by its previous. * * @return Pending messages from previous node. @@ -299,7 +305,6 @@ public void pendingMessages(Map pendingMsgs) { } /** - * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Sets pending messages to send to new node. * * @param msgs Pending messages to send to new node. From 4adf01a488977152bbf24b6569c2bdd6e0469880 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 20:47:01 +0300 Subject: [PATCH 06/47] impl --- .../TcpDiscoveryMarshallableMessage.java | 8 +--- .../TcpDiscoveryNodeAddedMessage.java | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java index 0cdd3621eee94..de4ef13808dd4 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java @@ -27,15 +27,11 @@ */ public interface TcpDiscoveryMarshallableMessage extends Message { /** @param marsh Marshaller. */ - default void prepareMarshal(Marshaller marsh) { - throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); - } + void prepareMarshal(Marshaller marsh); /** * @param marsh Marshaller. * @param clsLdr Class loader. */ - default void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); - } + void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index 5e3e0fc990e19..d25e736bb0fa1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -178,6 +178,17 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { throw new IgniteException("Failed to marshal serializable pending messages.", e); } } + + if (F.isEmpty(pendingMsgs)) + return; + + for (Message msg : pendingMsgs.values()) { + if (msg instanceof TcpDiscoveryMarshallableMessage) { + TcpDiscoveryMarshallableMessage ms = (TcpDiscoveryMarshallableMessage)msg; + + ms.prepareMarshal(marsh); + } + } } /** @@ -220,6 +231,17 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { throw new IgniteException("Failed to unmarshal serializable pending messages.", e); } } + + if (F.isEmpty(pendingMsgs)) + return; + + for (Message msg : pendingMsgs.values()) { + if (msg instanceof TcpDiscoveryMarshallableMessage) { + TcpDiscoveryMarshallableMessage ms = (TcpDiscoveryMarshallableMessage)msg; + + ms.finishUnmarshal(marsh, clsLdr); + } + } } /** @@ -285,19 +307,22 @@ public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendin List res = new ArrayList<>(totalSz); for (int i = 0; i < totalSz; ++i) { - Message m = pendingMsgs.get(i); + Message msg = pendingMsgs == null ? null : pendingMsgs.get(i); + + if (msg == null) { + assert serializablePendingMsgs != null; - if (m == null) { TcpDiscoveryAbstractMessage sm = serializablePendingMsgs.get(i); + assert sm != null; res.add(sm); } else { - assert serializablePendingMsgs.get(i) == null; - assert m instanceof TcpDiscoveryAbstractMessage; + assert serializablePendingMsgs == null || serializablePendingMsgs.get(i) == null; + assert msg instanceof TcpDiscoveryAbstractMessage; - res.add((TcpDiscoveryAbstractMessage)m); + res.add((TcpDiscoveryAbstractMessage)msg); } } @@ -312,6 +337,7 @@ public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendin public void messages(@Nullable List msgs) { if (F.isEmpty(msgs)) { serializablePendingMsgs = null; + serializablePendingMsgsBytes = null; pendingMsgs = null; return; @@ -319,12 +345,12 @@ public void messages(@Nullable List msgs) { int idx = 0; - for (TcpDiscoveryAbstractMessage m : msgs) { - if (m instanceof Message) { + for (TcpDiscoveryAbstractMessage msg : msgs) { + if (msg instanceof Message) { if (pendingMsgs == null) pendingMsgs = U.newHashMap(msgs.size()); - pendingMsgs.put(idx++, (Message)m); + pendingMsgs.put(idx++, (Message)msg); continue; } @@ -332,7 +358,7 @@ public void messages(@Nullable List msgs) { if (serializablePendingMsgs == null) serializablePendingMsgs = U.newHashMap(msgs.size()); - serializablePendingMsgs.put(idx++, m); + serializablePendingMsgs.put(idx++, msg); } } From 330d359e5dcf684cfb966c28bb00534ac0f8293b Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 20:48:15 +0300 Subject: [PATCH 07/47] Revert "impl" This reverts commit 4adf01a488977152bbf24b6569c2bdd6e0469880. --- .../TcpDiscoveryMarshallableMessage.java | 8 +++- .../TcpDiscoveryNodeAddedMessage.java | 44 ++++--------------- 2 files changed, 15 insertions(+), 37 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java index de4ef13808dd4..0cdd3621eee94 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java @@ -27,11 +27,15 @@ */ public interface TcpDiscoveryMarshallableMessage extends Message { /** @param marsh Marshaller. */ - void prepareMarshal(Marshaller marsh); + default void prepareMarshal(Marshaller marsh) { + throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); + } /** * @param marsh Marshaller. * @param clsLdr Class loader. */ - void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr); + default void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index d25e736bb0fa1..5e3e0fc990e19 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -178,17 +178,6 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { throw new IgniteException("Failed to marshal serializable pending messages.", e); } } - - if (F.isEmpty(pendingMsgs)) - return; - - for (Message msg : pendingMsgs.values()) { - if (msg instanceof TcpDiscoveryMarshallableMessage) { - TcpDiscoveryMarshallableMessage ms = (TcpDiscoveryMarshallableMessage)msg; - - ms.prepareMarshal(marsh); - } - } } /** @@ -231,17 +220,6 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { throw new IgniteException("Failed to unmarshal serializable pending messages.", e); } } - - if (F.isEmpty(pendingMsgs)) - return; - - for (Message msg : pendingMsgs.values()) { - if (msg instanceof TcpDiscoveryMarshallableMessage) { - TcpDiscoveryMarshallableMessage ms = (TcpDiscoveryMarshallableMessage)msg; - - ms.finishUnmarshal(marsh, clsLdr); - } - } } /** @@ -307,22 +285,19 @@ public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendin List res = new ArrayList<>(totalSz); for (int i = 0; i < totalSz; ++i) { - Message msg = pendingMsgs == null ? null : pendingMsgs.get(i); - - if (msg == null) { - assert serializablePendingMsgs != null; + Message m = pendingMsgs.get(i); + if (m == null) { TcpDiscoveryAbstractMessage sm = serializablePendingMsgs.get(i); - assert sm != null; res.add(sm); } else { - assert serializablePendingMsgs == null || serializablePendingMsgs.get(i) == null; - assert msg instanceof TcpDiscoveryAbstractMessage; + assert serializablePendingMsgs.get(i) == null; + assert m instanceof TcpDiscoveryAbstractMessage; - res.add((TcpDiscoveryAbstractMessage)msg); + res.add((TcpDiscoveryAbstractMessage)m); } } @@ -337,7 +312,6 @@ public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendin public void messages(@Nullable List msgs) { if (F.isEmpty(msgs)) { serializablePendingMsgs = null; - serializablePendingMsgsBytes = null; pendingMsgs = null; return; @@ -345,12 +319,12 @@ public void messages(@Nullable List msgs) { int idx = 0; - for (TcpDiscoveryAbstractMessage msg : msgs) { - if (msg instanceof Message) { + for (TcpDiscoveryAbstractMessage m : msgs) { + if (m instanceof Message) { if (pendingMsgs == null) pendingMsgs = U.newHashMap(msgs.size()); - pendingMsgs.put(idx++, (Message)msg); + pendingMsgs.put(idx++, (Message)m); continue; } @@ -358,7 +332,7 @@ public void messages(@Nullable List msgs) { if (serializablePendingMsgs == null) serializablePendingMsgs = U.newHashMap(msgs.size()); - serializablePendingMsgs.put(idx++, msg); + serializablePendingMsgs.put(idx++, m); } } From 1baa2f222a0cd316de238c1d87eec8c8892a551e Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 20:48:23 +0300 Subject: [PATCH 08/47] Revert "refactoring. + dedicated if" This reverts commit 1064805091d948b62070e0970d3f06e2a31a2815. --- .../ignite/spi/discovery/tcp/ClientImpl.java | 8 +++- .../ignite/spi/discovery/tcp/ServerImpl.java | 25 ++++++++++- .../discovery/tcp/TcpDiscoveryIoSession.java | 9 ---- .../TcpDiscoveryMarshallableMessage.java | 41 ------------------- .../TcpDiscoveryNodeAddFinishedMessage.java | 7 ++-- .../TcpDiscoveryNodeAddedMessage.java | 35 +++++++--------- 6 files changed, 49 insertions(+), 76 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 9e1714867d2d2..fe702517dbe33 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2160,8 +2160,12 @@ protected void processDiscoveryMessage(TcpDiscoveryAbstractMessage msg) { if (msg instanceof TraceableMessage) tracing.messages().beforeSend((TraceableMessage)msg); - if (msg instanceof TcpDiscoveryNodeAddedMessage) + if (msg instanceof TcpDiscoveryNodeAddedMessage) { + ((TcpDiscoveryNodeAddedMessage)msg) + .finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); + processNodeAddedMessage((TcpDiscoveryNodeAddedMessage)msg); + } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) processNodeAddFinishedMessage((TcpDiscoveryNodeAddFinishedMessage)msg); else if (msg instanceof TcpDiscoveryNodeLeftMessage) @@ -2307,6 +2311,8 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms delayDiscoData.clear(); } + msg.finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); + locNode.setAttributes(msg.clientNodeAttributes()); clearNodeSensitiveData(locNode); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 07fc5755eebb2..cce3fb5ea6f57 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1897,6 +1897,8 @@ private void prepareNodeAddedMessage( } nodeAddedMsg.topologyHistory(hist); + + nodeAddedMsg.prepareMarshal(spi.marshaller()); } } } @@ -2482,6 +2484,8 @@ void add(TcpDiscoveryAbstractMessage msg) { // Do not need this data for client reconnect. if (addedMsg.gridDiscoveryData() != null) addedMsg.clearDiscoveryData(); + + addedMsg.prepareMarshal(spi.marshaller()); } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; @@ -2489,6 +2493,8 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); + addFinishMsg.prepareMarshal(spi.marshaller()); + msg = addFinishMsg; DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData(); @@ -3105,6 +3111,11 @@ protected void runTasks() { if (!locNode.id().equals(msg.senderNodeId()) && ensured) lastRingMsgTimeNanos = System.nanoTime(); + if (msg instanceof TcpDiscoveryNodeAddedMessage) { + ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(spi.marshaller(), + U.resolveClassLoader(spi.ignite().configuration())); + } + if (locNode.internalOrder() == 0) { boolean proc = false; @@ -3252,6 +3263,8 @@ private void sendMessageToClients(TcpDiscoveryAbstractMessage msg) { } } + ((TcpDiscoveryNodeAddedMessage)msg).prepareMarshal(spi.marshaller()); + // TODO Investigate possible optimizations: https://issues.apache.org/jira/browse/IGNITE-27722 clientMsgWorker.addMessage(msg); } @@ -4833,6 +4846,8 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { addFinishMsg.clientDiscoData(msg.gridDiscoveryData()); addFinishMsg.clientNodeAttributes(node.attributes()); + + addFinishMsg.prepareMarshal(spi.marshaller()); } addFinishMsg = tracing.messages().branch(addFinishMsg, msg); @@ -4859,8 +4874,11 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { else if (!locNodeId.equals(node.id()) && ring.node(node.id()) != null) { // Local node already has node from message in local topology. // Just pass it to coordinator via the ring. - if (sendMessageToRemotes(msg)) + if (sendMessageToRemotes(msg)) { + msg.prepareMarshal(spi.marshaller()); + sendMessageAcrossRing(msg); + } if (log.isDebugEnabled()) { log.debug("Local node already has node being added. Passing TcpDiscoveryNodeAddedMessage to " + @@ -5083,8 +5101,11 @@ else if (spiState == CONNECTING) processMessageFailedNodes(msg); } - if (sendMessageToRemotes(msg)) + if (sendMessageToRemotes(msg)) { + msg.prepareMarshal(spi.marshaller()); + sendMessageAcrossRing(msg); + } } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index a77b44e413d6b..fa8d71e40f171 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -40,7 +40,6 @@ import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -141,9 +140,6 @@ void writeMessage(TcpDiscoveryAbstractMessage msg) throws IgniteCheckedException } try { - if (msg instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); - out.write(MESSAGE_SERIALIZATION); serializeMessage((Message)msg, out); @@ -216,11 +212,6 @@ T readMessage() throws IgniteCheckedException, IOException { } while (!finished); - if (msg instanceof TcpDiscoveryMarshallableMessage) { - ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), - U.resolveClassLoader(spi.ignite().configuration())); - } - return (T)msg; } catch (Exception e) { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java deleted file mode 100644 index 0cdd3621eee94..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.spi.discovery.tcp.messages; - -import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; - -/** - * Base class for TCP Discovery messages which still require external pre- and post- serialization. - *
- * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 - */ -public interface TcpDiscoveryMarshallableMessage extends Message { - /** @param marsh Marshaller. */ - default void prepareMarshal(Marshaller marsh) { - throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); - } - - /** - * @param marsh Marshaller. - * @param clsLdr Class loader. - */ - default void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - throw new UnsupportedOperationException("Marshalling is not required for discovery message " + getClass().getSimpleName()); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 68afb1d4c01cb..7e75a16853d33 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -27,6 +27,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.jetbrains.annotations.Nullable; @@ -35,7 +36,7 @@ */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { +public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { /** */ private static final long serialVersionUID = 0L; @@ -150,7 +151,7 @@ public void clientNodeAttributesBytes(@Nullable byte[] clientNodeAttrsBytes) { /** * @param marsh Marshaller. */ - @Override public void prepareMarshal(Marshaller marsh) { + public void prepareMarshal(Marshaller marsh) { if (clientNodeAttrs != null && clientNodeAttrsBytes == null) { try { clientNodeAttrsBytes = U.marshal(marsh, clientNodeAttrs); @@ -165,7 +166,7 @@ public void clientNodeAttributesBytes(@Nullable byte[] clientNodeAttrsBytes) { * @param marsh Marshaller. * @param clsLdr Class loader. */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (F.isEmpty(clientNodeAttrsBytes)) clientNodeAttrs = null; else { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index 5e3e0fc990e19..ab81f053e7a49 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -42,7 +42,6 @@ import org.jetbrains.annotations.Nullable; /** - * TODO: Revise serialization of the {@link TcpDiscoveryNode} fields after https://issues.apache.org/jira/browse/IGNITE-27899 * Message telling nodes that new node should be added to topology. * When newly added node receives the message it connects to its next and finishes * join process. @@ -53,7 +52,7 @@ */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { +public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { /** */ private static final long serialVersionUID = 0L; @@ -93,13 +92,12 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private transient Collection clientTop; /** - * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 + * TODO: Remove after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Java-serializable pending messages from previous node. */ private @Nullable Map serializablePendingMsgs; /** Marshalled {@link #serializablePendingMsgs}. */ - @Order(value = 12, method = "serializablePendingMessagesBytes") private byte[] serializablePendingMsgsBytes; /** Constructor for {@link DiscoveryMessageFactory}. */ @@ -139,16 +137,21 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { node = msg.node; nodeBytes = msg.nodeBytes; - pendingMessages(msg.pendingMsgs); - topology(msg.top); + pendingMsgs = msg.pendingMsgs; + serializablePendingMsgs = msg.serializablePendingMsgs; + top = msg.top; + topBytes = msg.topBytes; clientTop = msg.clientTop; topHistMsgs = msg.topHistMsgs; dataPacket = msg.dataPacket; gridStartTime = msg.gridStartTime; } - /** @param marsh marshaller. */ - @Override public void prepareMarshal(Marshaller marsh) { + /** + * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 + * @param marsh marshaller. + */ + public void prepareMarshal(Marshaller marsh) { if (!F.isEmpty(topHistMsgs)) topHistMsgs.values().forEach(m -> m.prepareMarshal(marsh)); @@ -181,10 +184,11 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { } /** + * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 * @param marsh Marshaller. * @param clsLdr Class loader. */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (!F.isEmpty(topHistMsgs)) topHistMsgs.values().forEach(m -> m.finishUnmarshal(marsh, clsLdr)); @@ -255,20 +259,10 @@ public Map pendingMessages() { */ public void pendingMessages(Map pendingMsgs) { this.pendingMsgs = pendingMsgs; - this.serializablePendingMsgsBytes = null; - } - - /** @return Bytes of {@link #serializablePendingMsgs}. */ - public @Nullable byte[] serializablePendingMessagesBytes() { - return serializablePendingMsgsBytes; - } - - /** @param serializablePendingMsgsBytes Bytes of {@link #serializablePendingMsgs}. */ - public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendingMsgsBytes) { - this.serializablePendingMsgsBytes = serializablePendingMsgsBytes; } /** + * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Gets pending messages sent to new node by its previous. * * @return Pending messages from previous node. @@ -305,6 +299,7 @@ public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendin } /** + * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Sets pending messages to send to new node. * * @param msgs Pending messages to send to new node. From 9067b9b41c607655a788df6ab08af6f00eab5731 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 19 Feb 2026 21:41:20 +0300 Subject: [PATCH 09/47] fix the serialization --- .../ignite/spi/discovery/tcp/ServerImpl.java | 3 +- .../TcpDiscoveryNodeAddedMessage.java | 39 +++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index cce3fb5ea6f57..47a6f53e4d1e4 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -2485,6 +2485,7 @@ void add(TcpDiscoveryAbstractMessage msg) { if (addedMsg.gridDiscoveryData() != null) addedMsg.clearDiscoveryData(); + // Update the marshallable data. addedMsg.prepareMarshal(spi.marshaller()); } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { @@ -3263,8 +3264,6 @@ private void sendMessageToClients(TcpDiscoveryAbstractMessage msg) { } } - ((TcpDiscoveryNodeAddedMessage)msg).prepareMarshal(spi.marshaller()); - // TODO Investigate possible optimizations: https://issues.apache.org/jira/browse/IGNITE-27722 clientMsgWorker.addMessage(msg); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index ab81f053e7a49..bec486ef6d89a 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -98,6 +98,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private @Nullable Map serializablePendingMsgs; /** Marshalled {@link #serializablePendingMsgs}. */ + @Order(value = 12, method = "serializablePendingMessagesBytes") private byte[] serializablePendingMsgsBytes; /** Constructor for {@link DiscoveryMessageFactory}. */ @@ -137,10 +138,13 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { node = msg.node; nodeBytes = msg.nodeBytes; + pendingMsgs = msg.pendingMsgs; serializablePendingMsgs = msg.serializablePendingMsgs; - top = msg.top; - topBytes = msg.topBytes; + serializablePendingMsgsBytes = msg.serializablePendingMsgsBytes; + + topology(msg.topology()); + clientTop = msg.clientTop; topHistMsgs = msg.topHistMsgs; dataPacket = msg.dataPacket; @@ -181,6 +185,14 @@ public void prepareMarshal(Marshaller marsh) { throw new IgniteException("Failed to marshal serializable pending messages.", e); } } + + if (F.isEmpty(pendingMsgs)) + return; + + for (Message msg : pendingMsgs.values()) { + if (msg instanceof TcpDiscoveryNodeAddedMessage) + ((TcpDiscoveryNodeAddedMessage)msg).prepareMarshal(marsh); + } } /** @@ -224,6 +236,14 @@ public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { throw new IgniteException("Failed to unmarshal serializable pending messages.", e); } } + + if (F.isEmpty(pendingMsgs)) + return; + + for (Message msg : pendingMsgs.values()) { + if (msg instanceof TcpDiscoveryNodeAddedMessage) + ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(marsh, clsLdr); + } } /** @@ -279,7 +299,7 @@ public void pendingMessages(Map pendingMsgs) { List res = new ArrayList<>(totalSz); for (int i = 0; i < totalSz; ++i) { - Message m = pendingMsgs.get(i); + Message m = F.isEmpty(pendingMsgs) ? null : pendingMsgs.get(i); if (m == null) { TcpDiscoveryAbstractMessage sm = serializablePendingMsgs.get(i); @@ -288,7 +308,7 @@ public void pendingMessages(Map pendingMsgs) { res.add(sm); } else { - assert serializablePendingMsgs.get(i) == null; + assert serializablePendingMsgs == null || serializablePendingMsgs.get(i) == null; assert m instanceof TcpDiscoveryAbstractMessage; res.add((TcpDiscoveryAbstractMessage)m); @@ -308,6 +328,7 @@ public void messages(@Nullable List msgs) { if (F.isEmpty(msgs)) { serializablePendingMsgs = null; pendingMsgs = null; + serializablePendingMsgsBytes = null; return; } @@ -331,6 +352,16 @@ public void messages(@Nullable List msgs) { } } + /** @return Bytes of {@link #serializablePendingMsgs}. */ + public @Nullable byte[] serializablePendingMessagesBytes() { + return serializablePendingMsgsBytes; + } + + /** @param serializablePendingMsgsBytes Bytes of {@link #serializablePendingMsgs}. */ + public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendingMsgsBytes) { + this.serializablePendingMsgsBytes = serializablePendingMsgsBytes; + } + /** * Gets topology. * From d4e6b2b3899dadc2001f637ba68cd5a36d8c0894 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 20 Feb 2026 11:27:14 +0300 Subject: [PATCH 10/47] fixes --- .../apache/ignite/spi/discovery/tcp/ServerImpl.java | 6 +++++- .../tcp/messages/TcpDiscoveryNodeAddedMessage.java | 12 +++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 47a6f53e4d1e4..fb181008d9fdc 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1898,6 +1898,7 @@ private void prepareNodeAddedMessage( nodeAddedMsg.topologyHistory(hist); + // Re-marshall the changed data. nodeAddedMsg.prepareMarshal(spi.marshaller()); } } @@ -2485,7 +2486,7 @@ void add(TcpDiscoveryAbstractMessage msg) { if (addedMsg.gridDiscoveryData() != null) addedMsg.clearDiscoveryData(); - // Update the marshallable data. + // Ensure that the required data is marshalled after the message creation. addedMsg.prepareMarshal(spi.marshaller()); } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { @@ -2649,6 +2650,9 @@ private TcpDiscoveryAbstractMessage prepare(TcpDiscoveryAbstractMessage msg, UUI msg0.topology(addedMsg.clientTopology()); + // Ensure that the chnaged data is remarshalled. + msg0.prepareMarshal(spi.marshaller()); + return msg0; } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index bec486ef6d89a..64eb8337f48ef 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -185,14 +185,6 @@ public void prepareMarshal(Marshaller marsh) { throw new IgniteException("Failed to marshal serializable pending messages.", e); } } - - if (F.isEmpty(pendingMsgs)) - return; - - for (Message msg : pendingMsgs.values()) { - if (msg instanceof TcpDiscoveryNodeAddedMessage) - ((TcpDiscoveryNodeAddedMessage)msg).prepareMarshal(marsh); - } } /** @@ -325,14 +317,16 @@ public void pendingMessages(Map pendingMsgs) { * @param msgs Pending messages to send to new node. */ public void messages(@Nullable List msgs) { + serializablePendingMsgsBytes = null; + if (F.isEmpty(msgs)) { serializablePendingMsgs = null; pendingMsgs = null; - serializablePendingMsgsBytes = null; return; } + // Keeps the original message order as in a list. int idx = 0; for (TcpDiscoveryAbstractMessage m : msgs) { From fb52e0e032805a3ac9dfaecb4e2e12a6bb0363ba Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 20 Feb 2026 11:55:58 +0300 Subject: [PATCH 11/47] fixes --- .../internal/direct/DirectMessageReader.java | 29 +++++-- .../internal/direct/DirectMessageWriter.java | 24 ++++-- .../direct/stream/DirectByteBufferStream.java | 34 ++++++-- .../ignite/spi/discovery/tcp/ClientImpl.java | 11 +-- .../ignite/spi/discovery/tcp/ServerImpl.java | 38 ++------- .../discovery/tcp/TcpDiscoveryIoSession.java | 19 ++++- .../tcp/internal/TcpDiscoveryNodesRing.java | 1 + .../ClusterNodeCollectionMessage.java | 23 +----- .../tcp/messages/ClusterNodeMessage.java | 23 ++---- .../TcpDiscoveryMarshallableMessage.java | 43 ++++++++++ .../TcpDiscoveryNodeAddFinishedMessage.java | 16 ++-- .../TcpDiscoveryNodeAddedMessage.java | 78 +++++++------------ ...ByteBufferStreamImplByteOrderSelfTest.java | 2 +- 13 files changed, 179 insertions(+), 162 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java index 24d97da7b2de5..0b08ffae60146 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; import org.apache.ignite.internal.direct.state.DirectMessageState; import org.apache.ignite.internal.direct.state.DirectMessageStateItem; import org.apache.ignite.internal.direct.stream.DirectByteBufferStream; @@ -59,10 +60,23 @@ public class DirectMessageReader implements MessageReader { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public DirectMessageReader(final MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { + public DirectMessageReader(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + this(msgFactory, cacheObjProc, null); + } + + /** + * @param msgFactory Message factory. + * @param cacheObjProc Cache object processor. + * @param msgPostSerializer Optional message processor to call after the serialization. + */ + public DirectMessageReader( + final MessageFactory msgFactory, + IgniteCacheObjectProcessor cacheObjProc, + @Nullable Consumer msgPostSerializer + ) { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { @Override public StateItem apply() { - return new StateItem(msgFactory, cacheObjProc); + return new StateItem(msgFactory, cacheObjProc, msgPostSerializer); } }); } @@ -452,9 +466,14 @@ private static class StateItem implements DirectMessageStateItem { /** * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. + * @param msgPostReader Optional message post-reader. */ - public StateItem(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { - stream = new DirectByteBufferStream(msgFactory, cacheObjProc); + public StateItem( + MessageFactory msgFactory, + IgniteCacheObjectProcessor cacheObjProc, + @Nullable Consumer msgPostReader + ) { + stream = new DirectByteBufferStream(msgFactory, cacheObjProc, msgPostReader, null); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java index 1da76aa14cfe7..681e03738a221 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; import org.apache.ignite.internal.direct.state.DirectMessageState; import org.apache.ignite.internal.direct.state.DirectMessageStateItem; import org.apache.ignite.internal.direct.stream.DirectByteBufferStream; @@ -52,10 +53,18 @@ public class DirectMessageWriter implements MessageWriter { private ByteBuffer buf; /** */ - public DirectMessageWriter(final MessageFactory msgFactory) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { + public DirectMessageWriter(MessageFactory msgFactory) { + this(msgFactory, null); + } + + /** + * @param msgFactory Message factory. + * @param msgPreSerializer Optional message pre-writer. + */ + public DirectMessageWriter(MessageFactory msgFactory, @Nullable Consumer msgPreSerializer) { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { @Override public StateItem apply() { - return new StateItem(msgFactory); + return new StateItem(msgFactory, msgPreSerializer); } }); } @@ -415,9 +424,12 @@ private static class StateItem implements DirectMessageStateItem { /** */ private boolean hdrWritten; - /** */ - public StateItem(MessageFactory msgFactory) { - stream = new DirectByteBufferStream(msgFactory); + /** + * @param msgFactory Message Factory. + * @param msgPreWriter Optional message pre-writer. + */ + public StateItem(MessageFactory msgFactory, @Nullable Consumer msgPreWriter) { + stream = new DirectByteBufferStream(msgFactory, null, null, msgPreWriter); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java index 5c526bf6fd3b4..1b5d605aa0a46 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java @@ -29,6 +29,7 @@ import java.util.RandomAccess; import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; @@ -222,7 +223,13 @@ public class DirectByteBufferStream { /** Is required to instantiate {@link CacheObject} while reading messages. */ @GridToStringExclude - private final IgniteCacheObjectProcessor cacheObjProc; + @Nullable private final IgniteCacheObjectProcessor cacheObjProc; + + /** Optional message post-reader. */ + @Nullable private final Consumer msgPostReader; + + /** Optional message pre-writer. */ + @Nullable private final Consumer msgPreWriter; /** */ @GridToStringExclude @@ -345,10 +352,7 @@ public class DirectByteBufferStream { * @param msgFactory Message factory. */ public DirectByteBufferStream(MessageFactory msgFactory) { - this.msgFactory = msgFactory; - - // Is not used while writing messages. - cacheObjProc = null; + this(msgFactory, null, null, null); } /** @@ -356,10 +360,19 @@ public DirectByteBufferStream(MessageFactory msgFactory) { * * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. - */ - public DirectByteBufferStream(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + * @param msgPostReader Optional message post-reader. + * @param msgPreWriter Optional message pre-writer. + */ + public DirectByteBufferStream( + MessageFactory msgFactory, + @Nullable IgniteCacheObjectProcessor cacheObjProc, + @Nullable Consumer msgPostReader, + @Nullable Consumer msgPreWriter + ) { this.msgFactory = msgFactory; this.cacheObjProc = cacheObjProc; + this.msgPostReader = msgPostReader; + this.msgPreWriter = msgPreWriter; } /** @@ -886,6 +899,10 @@ public void writeMessage(Message msg, MessageWriter writer) { try { writer.beforeInnerMessageWrite(); + // Repeatable call. Current limitation. + if (msgPreWriter != null) + msgPreWriter.accept(msg); + lastFinished = msgFactory.serializer(msg.directType()).writeTo(msg, writer); } finally { @@ -1553,6 +1570,9 @@ public T readMessage(MessageReader reader) { msgTypeDone = false; msg = null; + if (msgPostReader != null) + msgPostReader.accept(msg0); + return (T)msg0; } else diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index fe702517dbe33..f2067dcae6fd1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2160,12 +2160,8 @@ protected void processDiscoveryMessage(TcpDiscoveryAbstractMessage msg) { if (msg instanceof TraceableMessage) tracing.messages().beforeSend((TraceableMessage)msg); - if (msg instanceof TcpDiscoveryNodeAddedMessage) { - ((TcpDiscoveryNodeAddedMessage)msg) - .finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); - + if (msg instanceof TcpDiscoveryNodeAddedMessage) processNodeAddedMessage((TcpDiscoveryNodeAddedMessage)msg); - } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) processNodeAddFinishedMessage((TcpDiscoveryNodeAddFinishedMessage)msg); else if (msg instanceof TcpDiscoveryNodeLeftMessage) @@ -2242,8 +2238,7 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { nodeAdded = true; - if (msg.topologyHistory() != null) - topHist.putAll(msg.topologyHistory()); + topHist.putAll(msg.topologyHistory()); } else { if (log.isDebugEnabled()) @@ -2311,8 +2306,6 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms delayDiscoData.clear(); } - msg.finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); - locNode.setAttributes(msg.clientNodeAttributes()); clearNodeSensitiveData(locNode); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index fb181008d9fdc..8c5ebd2933332 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -261,7 +261,7 @@ class ServerImpl extends TcpDiscoveryImpl { /** Metric for max message queue size. */ private MaxValueMetric maxMsgQueueSizeMetric; - /** Failed nodes (but still in topology). */ + /** Failed nodes (but still in topology): Node -> Id of the failure issuer node. */ private final Map failedNodes = new HashMap<>(); /** */ @@ -1897,9 +1897,6 @@ private void prepareNodeAddedMessage( } nodeAddedMsg.topologyHistory(hist); - - // Re-marshall the changed data. - nodeAddedMsg.prepareMarshal(spi.marshaller()); } } } @@ -2485,9 +2482,6 @@ void add(TcpDiscoveryAbstractMessage msg) { // Do not need this data for client reconnect. if (addedMsg.gridDiscoveryData() != null) addedMsg.clearDiscoveryData(); - - // Ensure that the required data is marshalled after the message creation. - addedMsg.prepareMarshal(spi.marshaller()); } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; @@ -2495,8 +2489,6 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); - addFinishMsg.prepareMarshal(spi.marshaller()); - msg = addFinishMsg; DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData(); @@ -2650,9 +2642,6 @@ private TcpDiscoveryAbstractMessage prepare(TcpDiscoveryAbstractMessage msg, UUI msg0.topology(addedMsg.clientTopology()); - // Ensure that the chnaged data is remarshalled. - msg0.prepareMarshal(spi.marshaller()); - return msg0; } } @@ -3116,11 +3105,6 @@ protected void runTasks() { if (!locNode.id().equals(msg.senderNodeId()) && ensured) lastRingMsgTimeNanos = System.nanoTime(); - if (msg instanceof TcpDiscoveryNodeAddedMessage) { - ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(spi.marshaller(), - U.resolveClassLoader(spi.ignite().configuration())); - } - if (locNode.internalOrder() == 0) { boolean proc = false; @@ -3819,13 +3803,11 @@ else if (!failedNextNode && sndState != null && sndState.isBackward()) { } synchronized (mux) { - for (TcpDiscoveryNode failedNode : failedNodes) { - if (!ServerImpl.this.failedNodes.containsKey(failedNode)) - ServerImpl.this.failedNodes.put(failedNode, locNodeId); - } + failedNodes.forEach(failedNode -> { + ServerImpl.this.failedNodes.putIfAbsent(failedNode, locNodeId); - for (TcpDiscoveryNode failedNode : failedNodes) failedNodesMsgSent.add(failedNode.id()); + }); } for (TcpDiscoveryNode n : failedNodes) @@ -4849,8 +4831,6 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { addFinishMsg.clientDiscoData(msg.gridDiscoveryData()); addFinishMsg.clientNodeAttributes(node.attributes()); - - addFinishMsg.prepareMarshal(spi.marshaller()); } addFinishMsg = tracing.messages().branch(addFinishMsg, msg); @@ -4877,11 +4857,8 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { else if (!locNodeId.equals(node.id()) && ring.node(node.id()) != null) { // Local node already has node from message in local topology. // Just pass it to coordinator via the ring. - if (sendMessageToRemotes(msg)) { - msg.prepareMarshal(spi.marshaller()); - + if (sendMessageToRemotes(msg)) sendMessageAcrossRing(msg); - } if (log.isDebugEnabled()) { log.debug("Local node already has node being added. Passing TcpDiscoveryNodeAddedMessage to " + @@ -5104,11 +5081,8 @@ else if (spiState == CONNECTING) processMessageFailedNodes(msg); } - if (sendMessageToRemotes(msg)) { - msg.prepareMarshal(spi.marshaller()); - + if (sendMessageToRemotes(msg)) sendMessageAcrossRing(msg); - } } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index fa8d71e40f171..0766b18660b1d 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -40,6 +40,7 @@ import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -109,8 +110,16 @@ public class TcpDiscoveryIoSession { msgBuf = ByteBuffer.allocate(MSG_BUFFER_SIZE); - msgWriter = new DirectMessageWriter(spi.messageFactory()); - msgReader = new DirectMessageReader(spi.messageFactory(), null); + msgWriter = new DirectMessageWriter(spi.messageFactory(), msg -> { + if (msg instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); + }); + msgReader = new DirectMessageReader(spi.messageFactory(), null, msg -> { + if (msg instanceof TcpDiscoveryMarshallableMessage) { + ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), + U.resolveClassLoader(spi.ignite().configuration())); + } + }); try { int sendBufSize = sock.getSendBufferSize() > 0 ? sock.getSendBufferSize() : DFLT_SOCK_BUFFER_SIZE; @@ -212,6 +221,9 @@ T readMessage() throws IgniteCheckedException, IOException { } while (!finished); + if (msg instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), clsLdr); + return (T)msg; } catch (Exception e) { @@ -270,6 +282,9 @@ public Socket socket() { * @throws IOException If serialization fails. */ private void serializeMessage(Message m, OutputStream out) throws IOException { + if (m instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)m).prepareMarshal(spi.marshaller()); + MessageSerializer msgSer = spi.messageFactory().serializer(m.directType()); msgWriter.reset(); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java index e6303ee4f0d7b..f9b54349f2cd2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java @@ -500,6 +500,7 @@ public void clear() { */ @Nullable public TcpDiscoveryNode nextNode(@Nullable Collection excluded) { assert locNode.internalOrder() > 0 : locNode; + // TODO: May fire, https://issues.apache.org/jira/browse/IGNITE-27933 assert excluded == null || excluded.isEmpty() || !excluded.contains(locNode) : excluded; rwLock.readLock().lock(); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java index ce59d5d434301..6b4a7442d5c05 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java @@ -21,17 +21,9 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; -import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.plugin.extensions.communication.Message; -/** - * Container message for a collection of {@link ClusterNodeMessage}. - *
- * Requires pre- and post- marshalling. - * - * @see #prepareMarshal(Marshaller) - * @see #prepareMarshal(Marshaller) - */ +/** A container message for a collection of {@link ClusterNodeMessage}. */ public class ClusterNodeCollectionMessage implements Message { /** The collection of wrapped {@link ClusterNodeMessage}. */ @Order(value = 0, method = "clusterNodeMessages") @@ -47,19 +39,6 @@ public ClusterNodeCollectionMessage(Collection clusterNodeMs this.clusterNodeMsgs = clusterNodeMsgs; } - /** @param marsh Marshalled. */ - public void prepareMarshal(Marshaller marsh) { - clusterNodeMsgs.forEach(msg -> msg.prepareMarshal(marsh)); - } - - /** - * @param marsh Marshalled. - * @param clsLdr Class loader. - */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - clusterNodeMsgs.forEach(msg -> msg.finishUnmarshal(marsh, clsLdr)); - } - /** @return Holder messages of {@link ClusterNode}. */ public Collection clusterNodeMessages() { return clusterNodeMsgs; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java index 5fc7f344843ee..c9ed4151fe4a1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java @@ -30,17 +30,11 @@ import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; /** - * Message for {@link ClusterNode}. Requites pre- and post- serialization with the class loader. - *
- * Requires pre- and -post marshalling. - * - * @see #prepareMarshal(Marshaller) - * @see #finishUnmarshal(Marshaller, ClassLoader) + * Message for {@link ClusterNode}. */ -public class ClusterNodeMessage implements Message { +public class ClusterNodeMessage implements TcpDiscoveryMarshallableMessage { /** Node ID. */ @Order(0) private UUID id; @@ -109,8 +103,8 @@ public ClusterNodeMessage(ClusterNode clusterNode) { attrs = clusterNode.attributes(); } - /** @param marsh Marshalled. */ - public void prepareMarshal(Marshaller marsh) { + /** {@inheritDoc} */ + @Override public void prepareMarshal(Marshaller marsh) { if (!F.isEmpty(attrs) && attrsBytes == null) { try { attrsBytes = U.marshal(marsh, attrs); @@ -130,11 +124,8 @@ public void prepareMarshal(Marshaller marsh) { } } - /** - * @param marsh Marshalled. - * @param clsLdr Class loader. - */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (attrsBytes != null && F.isEmpty(attrs)) { try { attrs = U.unmarshal(marsh, attrsBytes, clsLdr); @@ -256,6 +247,7 @@ public Serializable consistentId() { /** @param consistentId Node consistent id. */ public void consistentId(Serializable consistentId) { this.consistentId = consistentId; + consistentIdBytes = null; } /** @return Node's attributes. */ @@ -266,6 +258,7 @@ public Map attributes() { /** @param attrs Node's attributes. */ public void attributes(Map attrs) { this.attrs = attrs; + attrsBytes = null; } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java new file mode 100644 index 0000000000000..cf1854275c565 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.discovery.tcp.messages; + +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; + +/** + * Base class for TCP Discovery messages which still require external pre- and post- marshalling. + *
+ * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 + */ +public interface TcpDiscoveryMarshallableMessage extends Message { + /** + * Should be idempotent. + * + * @param marsh Marshaller. + */ + void prepareMarshal(Marshaller marsh); + + /** + * Should be idempotent. + * + * @param marsh Marshaller. + * @param clsLdr Class loader. + */ + void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr); +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 7e75a16853d33..9561fa37465c8 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -27,7 +27,6 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.jetbrains.annotations.Nullable; @@ -36,7 +35,7 @@ */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { +public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { /** */ private static final long serialVersionUID = 0L; @@ -148,10 +147,8 @@ public void clientNodeAttributesBytes(@Nullable byte[] clientNodeAttrsBytes) { this.clientNodeAttrsBytes = clientNodeAttrsBytes; } - /** - * @param marsh Marshaller. - */ - public void prepareMarshal(Marshaller marsh) { + /** {@inheritDoc} */ + @Override public void prepareMarshal(Marshaller marsh) { if (clientNodeAttrs != null && clientNodeAttrsBytes == null) { try { clientNodeAttrsBytes = U.marshal(marsh, clientNodeAttrs); @@ -162,11 +159,8 @@ public void prepareMarshal(Marshaller marsh) { } } - /** - * @param marsh Marshaller. - * @param clsLdr Class loader. - */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (F.isEmpty(clientNodeAttrsBytes)) clientNodeAttrs = null; else { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index 64eb8337f48ef..bbe960a7f9bd1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -42,17 +42,14 @@ import org.jetbrains.annotations.Nullable; /** + * TODO: Revise serialization of the {@link TcpDiscoveryNode} fields after https://issues.apache.org/jira/browse/IGNITE-27899 * Message telling nodes that new node should be added to topology. * When newly added node receives the message it connects to its next and finishes * join process. - *
- * Requires pre- and post- marshalling. - * @see #prepareMarshal(Marshaller) - * @see #finishUnmarshal(Marshaller, ClassLoader) */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { +public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { /** */ private static final long serialVersionUID = 0L; @@ -92,7 +89,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private transient Collection clientTop; /** - * TODO: Remove after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 + * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 * Java-serializable pending messages from previous node. */ private @Nullable Map serializablePendingMsgs; @@ -139,26 +136,21 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { node = msg.node; nodeBytes = msg.nodeBytes; + top = msg.top; + topBytes = msg.topBytes; + pendingMsgs = msg.pendingMsgs; serializablePendingMsgs = msg.serializablePendingMsgs; serializablePendingMsgsBytes = msg.serializablePendingMsgsBytes; - topology(msg.topology()); - clientTop = msg.clientTop; topHistMsgs = msg.topHistMsgs; dataPacket = msg.dataPacket; gridStartTime = msg.gridStartTime; } - /** - * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 - * @param marsh marshaller. - */ - public void prepareMarshal(Marshaller marsh) { - if (!F.isEmpty(topHistMsgs)) - topHistMsgs.values().forEach(m -> m.prepareMarshal(marsh)); - + /** @param marsh marshaller. */ + @Override public void prepareMarshal(Marshaller marsh) { if (node != null && nodeBytes == null) { try { nodeBytes = U.marshal(marsh, node); @@ -187,15 +179,8 @@ public void prepareMarshal(Marshaller marsh) { } } - /** - * TODO: Revise after refactoring of TcpDiscoveryNode serialization https://issues.apache.org/jira/browse/IGNITE-27899 - * @param marsh Marshaller. - * @param clsLdr Class loader. - */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - if (!F.isEmpty(topHistMsgs)) - topHistMsgs.values().forEach(m -> m.finishUnmarshal(marsh, clsLdr)); - + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (nodeBytes != null && node == null) { try { node = U.unmarshal(marsh, nodeBytes, clsLdr); @@ -228,14 +213,6 @@ public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { throw new IgniteException("Failed to unmarshal serializable pending messages.", e); } } - - if (F.isEmpty(pendingMsgs)) - return; - - for (Message msg : pendingMsgs.values()) { - if (msg instanceof TcpDiscoveryNodeAddedMessage) - ((TcpDiscoveryNodeAddedMessage)msg).finishUnmarshal(marsh, clsLdr); - } } /** @@ -258,7 +235,7 @@ public void nodeBytes(byte[] nodeBytes) { } /** - * @return Pending messages. + * @return Pending messages by their order. * @see #messages() */ public Map pendingMessages() { @@ -266,22 +243,29 @@ public Map pendingMessages() { } /** - * @param pendingMsgs Pending messages. + * @param pendingMsgs Pending messages by their order. * @see #messages(List) */ public void pendingMessages(Map pendingMsgs) { this.pendingMsgs = pendingMsgs; } + /** @return Bytes of {@link #serializablePendingMsgs}. */ + public @Nullable byte[] serializablePendingMessagesBytes() { + return serializablePendingMsgsBytes; + } + + /** @param serializablePendingMsgsBytes Bytes of {@link #serializablePendingMsgs}. */ + public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendingMsgsBytes) { + this.serializablePendingMsgsBytes = serializablePendingMsgsBytes; + } + /** - * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Gets pending messages sent to new node by its previous. * * @return Pending messages from previous node. */ @Nullable public List messages() { - assert serializablePendingMsgs == null; - if (F.isEmpty(pendingMsgs) && F.isEmpty(serializablePendingMsgs)) return Collections.emptyList(); @@ -295,6 +279,7 @@ public void pendingMessages(Map pendingMsgs) { if (m == null) { TcpDiscoveryAbstractMessage sm = serializablePendingMsgs.get(i); + assert sm != null; res.add(sm); @@ -311,7 +296,6 @@ public void pendingMessages(Map pendingMsgs) { } /** - * TODO: revise after refactoring of discovery messages serialization https://issues.apache.org/jira/browse/IGNITE-25883 * Sets pending messages to send to new node. * * @param msgs Pending messages to send to new node. @@ -346,16 +330,6 @@ public void messages(@Nullable List msgs) { } } - /** @return Bytes of {@link #serializablePendingMsgs}. */ - public @Nullable byte[] serializablePendingMessagesBytes() { - return serializablePendingMsgsBytes; - } - - /** @param serializablePendingMsgsBytes Bytes of {@link #serializablePendingMsgs}. */ - public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendingMsgsBytes) { - this.serializablePendingMsgsBytes = serializablePendingMsgsBytes; - } - /** * Gets topology. * @@ -416,9 +390,9 @@ public void topologyHistoryMessages(@Nullable Map> topologyHistory() { - if (topHistMsgs == null) - return null; + public Map> topologyHistory() { + if (F.isEmpty(topHistMsgs)) + return Collections.emptyMap(); Map> res = U.newHashMap(topHistMsgs.size()); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java index cb6c40576fe0a..44f44be77f700 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java @@ -101,7 +101,7 @@ private static DirectByteBufferStream createStream(ByteBuffer buff) { @Override public MessageSerializer serializer(short type) { return null; } - }, null); + }); stream.setBuffer(buff); From 333185b0ae7a9a8b259b2e532de495302452df44 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sat, 21 Feb 2026 17:53:02 +0300 Subject: [PATCH 12/47] fixes --- .../discovery/DiscoveryMessageFactory.java | 8 +- .../ignite/spi/discovery/tcp/ServerImpl.java | 6 +- .../TcpDiscoveryClientReconnectMessage.java | 54 +++++-- .../TcpDiscoveryNodeAddedMessage.java | 144 +++--------------- .../GridAffinityAssignmentV2Test.java | 8 +- 5 files changed, 84 insertions(+), 136 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 7a799ad101ab3..a801e15da099d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -32,6 +32,8 @@ import org.apache.ignite.internal.codegen.TcpDiscoveryClientNodesMetricsMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryClientPingRequestSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryClientPingResponseSerializer; +import org.apache.ignite.internal.codegen.TcpDiscoveryClientReconnectMessageSerializer; +import org.apache.ignite.internal.codegen.TcpDiscoveryCollectionMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryConnectionCheckMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryDiscardMessageSerializer; import org.apache.ignite.internal.codegen.TcpDiscoveryDuplicateIdMessageSerializer; @@ -66,6 +68,8 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientNodesMetricsMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingRequest; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponse; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCollectionMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryDiscardMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryDuplicateIdMessage; @@ -88,6 +92,7 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { /** {@inheritDoc} */ @Override public void registerAll(MessageFactory factory) { + factory.register((short)-111, TcpDiscoveryCollectionMessage::new, new TcpDiscoveryCollectionMessageSerializer()); factory.register((short)-110, ClusterNodeCollectionMessage::new, new ClusterNodeCollectionMessageSerializer()); factory.register((short)-109, ClusterNodeMessage::new, new ClusterNodeMessageSerializer()); factory.register((short)-108, IgniteProductVersionMessage::new, new IgniteProductVersionMessageSerializer()); @@ -121,6 +126,7 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { factory.register((short)17, TcpDiscoveryNodeFailedMessage::new, new TcpDiscoveryNodeFailedMessageSerializer()); factory.register((short)18, TcpDiscoveryStatusCheckMessage::new, new TcpDiscoveryStatusCheckMessageSerializer()); factory.register((short)19, TcpDiscoveryNodeAddFinishedMessage::new, new TcpDiscoveryNodeAddFinishedMessageSerializer()); - factory.register((short)20, TcpDiscoveryNodeAddedMessage::new, new TcpDiscoveryNodeAddedMessageSerializer()); + factory.register((short)20, TcpDiscoveryClientReconnectMessage::new, new TcpDiscoveryClientReconnectMessageSerializer()); + factory.register((short)21, TcpDiscoveryNodeAddedMessage::new, new TcpDiscoveryNodeAddedMessageSerializer()); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 8c5ebd2933332..965572a8c4450 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1888,7 +1888,7 @@ private void prepareNodeAddedMessage( } } - nodeAddedMsg.messages(msgs0); + nodeAddedMsg.pendingMessages(msgs0); Map> hist; @@ -1911,7 +1911,7 @@ private void clearNodeAddedMessage(TcpDiscoveryAbstractMessage msg) { nodeAddedMsg.topology(null); nodeAddedMsg.topologyHistory(null); - nodeAddedMsg.messages(null); + nodeAddedMsg.pendingMessages(null); nodeAddedMsg.clearUnmarshalledDiscoveryData(); } } @@ -5048,7 +5048,7 @@ else if (spiState == CONNECTING) topHist.clear(); topHist.putAll(msg.topologyHistory()); - pendingMsgs.reset(msg.messages()); + pendingMsgs.reset(msg.pendingMessages()); } else { if (log.isDebugEnabled()) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 3a826058c06b2..b0b8ca39c6d15 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -18,29 +18,40 @@ package org.apache.ignite.spi.discovery.tcp.messages; import java.util.Collection; +import java.util.Collections; import java.util.Objects; import java.util.UUID; -import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; /** * Message telling that client node is reconnecting to topology. */ @TcpDiscoveryEnsureDelivery -public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMessage { +public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMessage implements Message { /** */ private static final long serialVersionUID = 0L; /** New router nodeID. */ - private final UUID routerNodeId; + @Order(5) + private UUID routerNodeId; /** Last message ID. */ - private final IgniteUuid lastMsgId; + @Order(value = 6, method = "lastMessageId") + private IgniteUuid lastMsgId; /** Pending messages. */ - @GridToStringExclude - private Collection msgs; + @Order(value = 7, method = "pendingMessagesTransferMessage") + @Nullable private TcpDiscoveryCollectionMessage pendingMsgsMsg; + + /** Constructor for {@link DiscoveryMessageFactory}. */ + public TcpDiscoveryClientReconnectMessage() { + // No-op. + } /** * @param creatorNodeId Creator node ID. @@ -61,6 +72,11 @@ public UUID routerNodeId() { return routerNodeId; } + /** @param routerNodeId New router node ID. */ + public void routerNodeId(UUID routerNodeId) { + this.routerNodeId = routerNodeId; + } + /** * @return Last message ID. */ @@ -68,18 +84,33 @@ public IgniteUuid lastMessageId() { return lastMsgId; } + /** @param lastMsgId Last message ID. */ + public void lastMessageId(IgniteUuid lastMsgId) { + this.lastMsgId = lastMsgId; + } + /** * @param msgs Pending messages. */ - public void pendingMessages(Collection msgs) { - this.msgs = msgs; + public void pendingMessages(@Nullable Collection msgs) { + pendingMsgsMsg = msgs == null ? null : new TcpDiscoveryCollectionMessage(msgs); } /** * @return Pending messages. */ public Collection pendingMessages() { - return msgs; + return pendingMsgsMsg == null ? Collections.emptyList() : pendingMsgsMsg.messages(); + } + + /** @return Message to transfer the pending messages. */ + public @Nullable TcpDiscoveryCollectionMessage pendingMessagesTransferMessage() { + return pendingMsgsMsg; + } + + /** @param pendingMsgsMsg Message to transfer the pending messages. */ + public void pendingMessagesTransferMessage(@Nullable TcpDiscoveryCollectionMessage pendingMsgsMsg) { + this.pendingMsgsMsg = pendingMsgsMsg; } /** @@ -111,6 +142,11 @@ public boolean success() { Objects.equals(lastMsgId, other.lastMsgId); } + /** {@inheritDoc} */ + @Override public short directType() { + return 20; + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(TcpDiscoveryClientReconnectMessage.class, this, "super", super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index bbe960a7f9bd1..c2c5c4326e9db 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -17,10 +17,8 @@ package org.apache.ignite.spi.discovery.tcp.messages; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; @@ -30,13 +28,13 @@ import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; import org.jetbrains.annotations.Nullable; @@ -65,15 +63,16 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM @Order(value = 8, method = "topologyHistoryMessages") private @Nullable Map topHistMsgs; - /** {@link TcpDiscoveryAbstractMessage} pending messages from previous node which is a {@link Message}. */ - @Order(value = 9, method = "pendingMessages") - private Map pendingMsgs; + /** Message to hold collection of pending {@link TcpDiscoveryAbstractMessage}. */ + @Order(value = 9, method = "pendingMessagesTransferMessage") + private TcpDiscoveryCollectionMessage pendingMsgsMsg; /** Added node. */ private TcpDiscoveryNode node; /** Marshalled {@link #node}. */ @Order(10) + @GridToStringExclude private byte[] nodeBytes; /** Current topology. Initialized by coordinator. */ @@ -82,22 +81,13 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM /** Marshalled {@link #top}. */ @Order(value = 11, method = "topologyBytes") + @GridToStringExclude private @Nullable byte[] topBytes; /** */ @GridToStringInclude private transient Collection clientTop; - /** - * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 - * Java-serializable pending messages from previous node. - */ - private @Nullable Map serializablePendingMsgs; - - /** Marshalled {@link #serializablePendingMsgs}. */ - @Order(value = 12, method = "serializablePendingMessagesBytes") - private byte[] serializablePendingMsgsBytes; - /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryNodeAddedMessage() { // No-op. @@ -139,9 +129,7 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { top = msg.top; topBytes = msg.topBytes; - pendingMsgs = msg.pendingMsgs; - serializablePendingMsgs = msg.serializablePendingMsgs; - serializablePendingMsgsBytes = msg.serializablePendingMsgsBytes; + pendingMsgsMsg = msg.pendingMsgsMsg; clientTop = msg.clientTop; topHistMsgs = msg.topHistMsgs; @@ -168,15 +156,6 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { throw new IgniteException("Failed to marshal topology nodes.", e); } } - - if (serializablePendingMsgs != null && serializablePendingMsgsBytes == null) { - try { - serializablePendingMsgsBytes = U.marshal(marsh, serializablePendingMsgs); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal serializable pending messages.", e); - } - } } /** {@inheritDoc} */ @@ -202,17 +181,6 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { throw new IgniteException("Failed to unmarshal topology nodes.", e); } } - - if (serializablePendingMsgsBytes != null && serializablePendingMsgs == null) { - try { - serializablePendingMsgs = U.unmarshal(marsh, serializablePendingMsgsBytes, clsLdr); - - serializablePendingMsgsBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal serializable pending messages.", e); - } - } } /** @@ -234,100 +202,32 @@ public void nodeBytes(byte[] nodeBytes) { this.nodeBytes = nodeBytes; } - /** - * @return Pending messages by their order. - * @see #messages() - */ - public Map pendingMessages() { - return pendingMsgs; - } - - /** - * @param pendingMsgs Pending messages by their order. - * @see #messages(List) - */ - public void pendingMessages(Map pendingMsgs) { - this.pendingMsgs = pendingMsgs; - } - - /** @return Bytes of {@link #serializablePendingMsgs}. */ - public @Nullable byte[] serializablePendingMessagesBytes() { - return serializablePendingMsgsBytes; - } - - /** @param serializablePendingMsgsBytes Bytes of {@link #serializablePendingMsgs}. */ - public void serializablePendingMessagesBytes(@Nullable byte[] serializablePendingMsgsBytes) { - this.serializablePendingMsgsBytes = serializablePendingMsgsBytes; - } - /** * Gets pending messages sent to new node by its previous. * * @return Pending messages from previous node. */ - @Nullable public List messages() { - if (F.isEmpty(pendingMsgs) && F.isEmpty(serializablePendingMsgs)) - return Collections.emptyList(); - - int totalSz = (F.isEmpty(pendingMsgs) ? 0 : pendingMsgs.size()) - + (F.isEmpty(serializablePendingMsgs) ? 0 : serializablePendingMsgs.size()); - - List res = new ArrayList<>(totalSz); - - for (int i = 0; i < totalSz; ++i) { - Message m = F.isEmpty(pendingMsgs) ? null : pendingMsgs.get(i); - - if (m == null) { - TcpDiscoveryAbstractMessage sm = serializablePendingMsgs.get(i); - - assert sm != null; - - res.add(sm); - } - else { - assert serializablePendingMsgs == null || serializablePendingMsgs.get(i) == null; - assert m instanceof TcpDiscoveryAbstractMessage; - - res.add((TcpDiscoveryAbstractMessage)m); - } - } - - return res; + public Collection pendingMessages() { + return pendingMsgsMsg == null ? Collections.emptyList() : pendingMsgsMsg.messages(); } /** - * Sets pending messages to send to new node. + * Sets pending messages. * - * @param msgs Pending messages to send to new node. + * @param msgs Pending messages. */ - public void messages(@Nullable List msgs) { - serializablePendingMsgsBytes = null; - - if (F.isEmpty(msgs)) { - serializablePendingMsgs = null; - pendingMsgs = null; - - return; - } - - // Keeps the original message order as in a list. - int idx = 0; - - for (TcpDiscoveryAbstractMessage m : msgs) { - if (m instanceof Message) { - if (pendingMsgs == null) - pendingMsgs = U.newHashMap(msgs.size()); - - pendingMsgs.put(idx++, (Message)m); - - continue; - } + public void pendingMessages(@Nullable Collection msgs) { + pendingMsgsMsg = F.isEmpty(msgs) ? null : new TcpDiscoveryCollectionMessage(msgs); + } - if (serializablePendingMsgs == null) - serializablePendingMsgs = U.newHashMap(msgs.size()); + /** @return Message to transfer the pending messages. */ + public @Nullable TcpDiscoveryCollectionMessage pendingMessagesTransferMessage() { + return pendingMsgsMsg; + } - serializablePendingMsgs.put(idx++, m); - } + /** @param pendingMsgsMsg Message to transfer the pending messages. */ + public void pendingMessagesTransferMessage(@Nullable TcpDiscoveryCollectionMessage pendingMsgsMsg) { + this.pendingMsgsMsg = pendingMsgsMsg; } /** @@ -487,7 +387,7 @@ public void gridStartTime(long gridStartTime) { /** {@inheritDoc} */ @Override public short directType() { - return 20; + return 21; } /** {@inheritDoc} */ diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java index 5d8e966851c3c..12b076f39f947 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java @@ -29,7 +29,9 @@ import java.util.List; import java.util.Set; import java.util.UUID; +import org.apache.ignite.cluster.ClusterMetrics; import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.util.collection.BitSetIntSet; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteProductVersion; @@ -49,7 +51,11 @@ */ public class GridAffinityAssignmentV2Test { /** */ - protected DiscoveryMetricsProvider metrics = new SerializableMetricsProvider(); + protected DiscoveryMetricsProvider metrics = new SerializableMetricsProvider() { + @Override public ClusterMetrics metrics() { + return new ClusterMetricsSnapshot(); + } + }; /** */ protected IgniteProductVersion ver = new IgniteProductVersion(); From 31a3d29755dd1d179b68167963c4c7010e689c9a Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sat, 21 Feb 2026 18:29:36 +0300 Subject: [PATCH 13/47] lost serialization fix --- .../tcp/internal/TcpDiscoveryNode.java | 2 +- .../tcp/messages/ClusterNodeMessage.java | 47 +++-- .../TcpDiscoveryCollectionMessage.java | 193 ++++++++++++++++++ 3 files changed, 224 insertions(+), 18 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java index ea9bd55c57d3e..b092665310993 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java @@ -195,7 +195,7 @@ public TcpDiscoveryNode( */ public TcpDiscoveryNode( UUID id, - @Nullable Serializable consistentId, + @Nullable Object consistentId, long order, boolean loc, @Nullable Boolean client, diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java index c9ed4151fe4a1..8ce2953153e87 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java @@ -17,7 +17,6 @@ package org.apache.ignite.spi.discovery.tcp.messages; -import java.io.Serializable; import java.util.Collection; import java.util.Map; import java.util.UUID; @@ -30,6 +29,7 @@ import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.jetbrains.annotations.Nullable; /** * Message for {@link ClusterNode}. @@ -72,15 +72,17 @@ public class ClusterNodeMessage implements TcpDiscoveryMarshallableMessage { private String dataCenterId; /** Consistent ID. */ - private Serializable consistentId; + private Object consistentId; /** */ + @Order(9) private byte[] consistentIdBytes; /** Node attributes. */ private Map attrs; /** */ + @Order(value = 10, method = "attributesBytes") private byte[] attrsBytes; /** Constructor for {@link DiscoveryMessageFactory}. */ @@ -91,16 +93,19 @@ public ClusterNodeMessage() { /** @param clusterNode Cluster node. */ public ClusterNodeMessage(ClusterNode clusterNode) { id = clusterNode.id(); - addrs = clusterNode.addresses(); - hostNames = clusterNode.hostNames(); - if (clusterNode.metrics() != null) - clusterMetricsMsg = new TcpDiscoveryNodeMetricsMessage(clusterNode.metrics()); + consistentId = clusterNode.consistentId(); + dataCenterId = clusterNode.dataCenterId(); order = clusterNode.order(); - productVerMsg = new IgniteProductVersionMessage(clusterNode.version()); + addrs = clusterNode.addresses(); loc = clusterNode.isLocal(); client = clusterNode.isClient(); - dataCenterId = clusterNode.dataCenterId(); + hostNames = clusterNode.hostNames(); + productVerMsg = new IgniteProductVersionMessage(clusterNode.version()); + attrs = clusterNode.attributes(); + + if (clusterNode.metrics() != null) + clusterMetricsMsg = new TcpDiscoveryNodeMetricsMessage(clusterNode.metrics()); } /** {@inheritDoc} */ @@ -240,14 +245,18 @@ public void productVersionMessage(IgniteProductVersionMessage productVerMsg) { } /** @return Node consistent id. */ - public Serializable consistentId() { + public Object consistentId() { return consistentId; } - /** @param consistentId Node consistent id. */ - public void consistentId(Serializable consistentId) { - this.consistentId = consistentId; - consistentIdBytes = null; + /** @return Marshalled bytes of {@link #consistentId}. */ + public byte[] consistentIdBytes() { + return consistentIdBytes; + } + + /** @param consistentIdBytes Marshalled bytes of {@link #consistentId}. */ + public void consistentIdBytes(byte[] consistentIdBytes) { + this.consistentIdBytes = consistentIdBytes; } /** @return Node's attributes. */ @@ -255,10 +264,14 @@ public Map attributes() { return attrs; } - /** @param attrs Node's attributes. */ - public void attributes(Map attrs) { - this.attrs = attrs; - attrsBytes = null; + /** @return Marshalled bytes of {@link #attrs}. */ + public @Nullable byte[] attributesBytes() { + return attrsBytes; + } + + /** @param attrsBytes Marshalled bytes of {@link #attrs}. */ + public void attributesBytes(@Nullable byte[] attrsBytes) { + this.attrsBytes = attrsBytes; } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java new file mode 100644 index 0000000000000..b1956872ccd37 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.discovery.tcp.messages; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; + +/** + * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 + * Message to transfer a collection of {@link TcpDiscoveryAbstractMessage} with the original order. + * Several of them might be a {@link Message}, several may not and require the original marshalling. + */ +public class TcpDiscoveryCollectionMessage implements TcpDiscoveryMarshallableMessage { + /** {@link TcpDiscoveryAbstractMessage} pending messages which are a {@link Message}. */ + @Order(value = 0, method = "writableMessages") + @Nullable private Map writableMsgs; + + /** Marshallable or Java-serializable pending messages which are not a {@link Message}. */ + @Nullable private Map marshallableMsgs; + + /** Marshalled {@link #marshallableMsgs}. */ + @Order(value = 1, method = "marshallableMessagesBytes") + @GridToStringExclude + @Nullable private byte[] marshallableMsgsBytes; + + /** Constructor for {@link DiscoveryMessageFactory}. */ + public TcpDiscoveryCollectionMessage() { + // No-op. + } + + /** @param msgs Discovery messages to hold. */ + public TcpDiscoveryCollectionMessage(Collection msgs) { + messages(msgs); + } + + /** @param marsh marshaller. */ + @Override public void prepareMarshal(Marshaller marsh) { + if (marshallableMsgs != null && marshallableMsgsBytes == null) { + try { + marshallableMsgsBytes = U.marshal(marsh, marshallableMsgs); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal marshallable pending messages.", e); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + if (marshallableMsgsBytes != null && marshallableMsgs == null) { + try { + marshallableMsgs = U.unmarshal(marsh, marshallableMsgsBytes, clsLdr); + + marshallableMsgsBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal marshallable pending messages.", e); + } + } + } + + /** + * @return Writable messages by their order. + * @see #messages() + */ + public @Nullable Map writableMessages() { + return writableMsgs; + } + + /** @param msgs Writable messages by their order. */ + public void writableMessages(@Nullable Map msgs) { + writableMsgs = msgs; + } + + /** @return Bytes of {@link #marshallableMsgs}. */ + public @Nullable byte[] marshallableMessagesBytes() { + return marshallableMsgsBytes; + } + + /** @param marshallableMsgsBytes Bytes of {@link #marshallableMsgs}. */ + public void marshallableMessagesBytes(@Nullable byte[] marshallableMsgsBytes) { + this.marshallableMsgsBytes = marshallableMsgsBytes; + } + + /** + * Gets pending messages sent to new node by its previous. + * + * @return Pending messages from previous node. + */ + public Collection messages() { + if (F.isEmpty(writableMsgs) && F.isEmpty(marshallableMsgs)) + return Collections.emptyList(); + + int totalSz = (F.isEmpty(writableMsgs) ? 0 : writableMsgs.size()) + + (F.isEmpty(marshallableMsgs) ? 0 : marshallableMsgs.size()); + + List res = new ArrayList<>(totalSz); + + for (int i = 0; i < totalSz; ++i) { + Message m = F.isEmpty(writableMsgs) ? null : writableMsgs.get(i); + + if (m == null) { + TcpDiscoveryAbstractMessage sm = marshallableMsgs.get(i); + + assert sm != null; + + res.add(sm); + } + else { + assert marshallableMsgs == null || marshallableMsgs.get(i) == null; + assert m instanceof TcpDiscoveryAbstractMessage; + + res.add((TcpDiscoveryAbstractMessage)m); + } + } + + return res; + } + + /** + * Sets pending messages to send to new node. + * + * @param msgs Pending messages to send to new node. + */ + public void messages(@Nullable Collection msgs) { + marshallableMsgsBytes = null; + + if (F.isEmpty(msgs)) { + marshallableMsgs = null; + writableMsgs = null; + + return; + } + + // Keeps the original message order. + int idx = 0; + + for (TcpDiscoveryAbstractMessage m : msgs) { + if (m instanceof Message) { + if (writableMsgs == null) + writableMsgs = U.newHashMap(msgs.size()); + + writableMsgs.put(idx++, (Message)m); + + continue; + } + + if (marshallableMsgs == null) + marshallableMsgs = U.newHashMap(msgs.size()); + + marshallableMsgs.put(idx++, m); + } + } + + /** {@inheritDoc} */ + @Override public short directType() { + return -111; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(TcpDiscoveryCollectionMessage.class, this, "super", super.toString()); + } +} From 72721667b170bd5bb1ad073795ccae2fb648e242 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sat, 21 Feb 2026 22:20:45 +0300 Subject: [PATCH 14/47] + master --- .../discovery/DiscoveryMessageFactory.java | 43 +++++++------------ .../discovery/tcp/TcpDiscoveryIoSession.java | 1 - .../tcp/messages/ClusterNodeMessage.java | 12 +++--- .../messages/IgniteProductVersionMessage.java | 8 ++-- .../TcpDiscoveryClientReconnectMessage.java | 2 +- .../TcpDiscoveryNodeAddedMessage.java | 4 +- 6 files changed, 28 insertions(+), 42 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index a811d4b43e51d..7f46c8f9cb609 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -17,37 +17,16 @@ package org.apache.ignite.internal.managers.discovery; -import org.apache.ignite.internal.codegen.DiscoveryDataPacketSerializer; -import org.apache.ignite.internal.codegen.InetAddressMessageSerializer; -import org.apache.ignite.internal.codegen.InetSocketAddressMessageSerializer; -import org.apache.ignite.internal.codegen.NodeSpecificDataSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryAuthFailedMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryCacheMetricsMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryCheckFailedMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryClientAckResponseSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryClientMetricsUpdateMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryClientNodesMetricsMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryClientPingRequestSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryClientPingResponseSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryConnectionCheckMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryDiscardMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryDuplicateIdMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryHandshakeRequestSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryHandshakeResponseSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryLoopbackProblemMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryMetricsUpdateMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryNodeAddFinishedMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryNodeFailedMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryNodeFullMetricsMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryNodeLeftMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryNodeMetricsMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryPingRequestSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryPingResponseSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryRingLatencyCheckMessageSerializer; -import org.apache.ignite.internal.codegen.TcpDiscoveryStatusCheckMessageSerializer; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; +import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacketSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeCollectionMessage; +import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeCollectionMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeMessage; +import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; +import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.InetAddressMessage; import org.apache.ignite.spi.discovery.tcp.messages.InetAddressMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.InetSocketAddressMessage; @@ -69,6 +48,11 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingRequest; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingRequestSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponse; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponseSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCollectionMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCollectionMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryDiscardMessage; @@ -84,6 +68,9 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFullMetricsMessage; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index d275ad823205c..3b3508fdb1c96 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -40,7 +40,6 @@ import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java index 8ce2953153e87..3e4e3e08373d2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java @@ -36,7 +36,7 @@ */ public class ClusterNodeMessage implements TcpDiscoveryMarshallableMessage { /** Node ID. */ - @Order(0) + @Order(value = 0, method = "id") private UUID id; /** Internal discovery addresses as strings. */ @@ -44,7 +44,7 @@ public class ClusterNodeMessage implements TcpDiscoveryMarshallableMessage { private Collection addrs; /** Internal discovery host names as strings. */ - @Order(2) + @Order(value = 2, method = "hostNames") private Collection hostNames; /** */ @@ -52,7 +52,7 @@ public class ClusterNodeMessage implements TcpDiscoveryMarshallableMessage { private TcpDiscoveryNodeMetricsMessage clusterMetricsMsg; /** */ - @Order(value = 4) + @Order(value = 4, method = "order") private long order; /** */ @@ -64,18 +64,18 @@ public class ClusterNodeMessage implements TcpDiscoveryMarshallableMessage { private boolean loc; /** */ - @Order(7) + @Order(value = 7, method = "client") private boolean client; /** */ - @Order(8) + @Order(value = 8, method = "dataCenterId") private String dataCenterId; /** Consistent ID. */ private Object consistentId; /** */ - @Order(9) + @Order(value = 9, method = "consistentIdBytes") private byte[] consistentIdBytes; /** Node attributes. */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java index bdf1da1e1b8aa..0ef5b13290c2c 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java @@ -28,19 +28,19 @@ public class IgniteProductVersionMessage implements Message { public static final int REV_HASH_SIZE = 20; /** Major version number. */ - @Order(0) + @Order(value = 0, method = "major") private byte major; /** Minor version number. */ - @Order(1) + @Order(value = 1, method = "minor") private byte minor; /** Maintenance version number. */ - @Order(2) + @Order(value = 2, method = "maintenance") private byte maintenance; /** Stage of development. */ - @Order(3) + @Order(value = 3, method = "stage") private String stage; /** Revision timestamp. */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index b0b8ca39c6d15..77854907d7950 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -37,7 +37,7 @@ public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMess private static final long serialVersionUID = 0L; /** New router nodeID. */ - @Order(5) + @Order(value = 5, method = "routerNodeId") private UUID routerNodeId; /** Last message ID. */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index c2c5c4326e9db..6b4f94851a8b6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -56,7 +56,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private DiscoveryDataPacket dataPacket; /** Start time of the first grid node. */ - @Order(7) + @Order(value = 7, method = "gridStartTime") private long gridStartTime; /** Topology snapshots history. */ @@ -71,7 +71,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private TcpDiscoveryNode node; /** Marshalled {@link #node}. */ - @Order(10) + @Order(value = 10, method = "nodeBytes") @GridToStringExclude private byte[] nodeBytes; From 31c46d98712c2e3a035497d81353dd1a60da3298 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sat, 21 Feb 2026 22:43:38 +0300 Subject: [PATCH 15/47] minor --- .../ignite/lang/IgniteProductVersion.java | 2 +- .../TcpDiscoveryNodeAddedMessage.java | 36 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java index 3efda7095caa4..bca9354027f8b 100644 --- a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java +++ b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java @@ -50,7 +50,7 @@ public class IgniteProductVersion implements Comparable, E Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)([-.]([^0123456789][^-]+)(-SNAPSHOT)?)?(-(\\d+))?(-([\\da-f]+))?"); /** The values holding message. */ - private IgniteProductVersionMessage productVerMsg; + private final IgniteProductVersionMessage productVerMsg; /** * Empty constructor required by {@link Externalizable}. diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index 6b4f94851a8b6..d9ddc2bd8554b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -51,36 +51,28 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM /** */ private static final long serialVersionUID = 0L; - /** */ - @Order(value = 6, method = "gridDiscoveryData") - private DiscoveryDataPacket dataPacket; - - /** Start time of the first grid node. */ - @Order(value = 7, method = "gridStartTime") - private long gridStartTime; - - /** Topology snapshots history. */ - @Order(value = 8, method = "topologyHistoryMessages") - private @Nullable Map topHistMsgs; - - /** Message to hold collection of pending {@link TcpDiscoveryAbstractMessage}. */ - @Order(value = 9, method = "pendingMessagesTransferMessage") - private TcpDiscoveryCollectionMessage pendingMsgsMsg; - /** Added node. */ private TcpDiscoveryNode node; /** Marshalled {@link #node}. */ - @Order(value = 10, method = "nodeBytes") + @Order(value = 6, method = "nodeBytes") @GridToStringExclude private byte[] nodeBytes; + /** */ + @Order(value = 7, method = "gridDiscoveryData") + private DiscoveryDataPacket dataPacket; + + /** Message to hold collection of pending {@link TcpDiscoveryAbstractMessage}. */ + @Order(value = 8, method = "pendingMessagesTransferMessage") + private TcpDiscoveryCollectionMessage pendingMsgsMsg; + /** Current topology. Initialized by coordinator. */ @GridToStringInclude private @Nullable Collection top; /** Marshalled {@link #top}. */ - @Order(value = 11, method = "topologyBytes") + @Order(value = 9, method = "topologyBytes") @GridToStringExclude private @Nullable byte[] topBytes; @@ -88,6 +80,14 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM @GridToStringInclude private transient Collection clientTop; + /** Topology snapshots history. */ + @Order(value = 10, method = "topologyHistoryMessages") + private @Nullable Map topHistMsgs; + + /** Start time of the first grid node. */ + @Order(value = 11, method = "gridStartTime") + private long gridStartTime; + /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryNodeAddedMessage() { // No-op. From e3e7ae2efb904179e354c4c98240e4eb3ad51469 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sun, 22 Feb 2026 01:10:34 +0300 Subject: [PATCH 16/47] impl --- .../cluster/ClusterNodeMetrics.java | 5 ++-- .../ignite/spi/discovery/tcp/ClientImpl.java | 5 +++- .../ignite/spi/discovery/tcp/ServerImpl.java | 18 +++++++++---- .../tcp/internal/TcpDiscoveryNode.java | 27 +++++++++++-------- .../tcp/messages/ClusterNodeMessage.java | 3 ++- .../TcpDiscoveryClientReconnectMessage.java | 6 ++--- .../TcpDiscoveryCollectionMessage.java | 6 ++--- .../TcpDiscoveryNodeAddedMessage.java | 8 +++--- 8 files changed, 47 insertions(+), 31 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java index 55414ebe7f6c0..7bba244fc7fc6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterNodeMetrics.java @@ -24,7 +24,6 @@ import org.apache.ignite.cluster.ClusterMetrics; import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.processors.cache.CacheMetricsSnapshot; -import org.jetbrains.annotations.Nullable; /** * @@ -34,13 +33,13 @@ class ClusterNodeMetrics { private final ClusterMetrics nodeMetrics; /** */ - private final @Nullable Map cacheMetrics; + private final Map cacheMetrics; /** * @param nodeMetrics Node metrics. * @param cacheMetrics Cache metrics. */ - ClusterNodeMetrics(ClusterMetrics nodeMetrics, @Nullable Map cacheMetrics) { + ClusterNodeMetrics(ClusterMetrics nodeMetrics, Map cacheMetrics) { this.nodeMetrics = nodeMetrics; this.cacheMetrics = cacheMetrics; } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index f2067dcae6fd1..e64969a909dad 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2238,7 +2238,8 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { nodeAdded = true; - topHist.putAll(msg.topologyHistory()); + if (!F.isEmpty(msg.topologyHistory())) + topHist.putAll(msg.topologyHistory()); } else { if (log.isDebugEnabled()) @@ -2306,6 +2307,8 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms delayDiscoData.clear(); } + msg.finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); + locNode.setAttributes(msg.clientNodeAttributes()); clearNodeSensitiveData(locNode); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index ee497bc4df35f..42daa4304911d 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1878,7 +1878,7 @@ private void prepareNodeAddedMessage( nodeAddedMsg.topology(topToSnd); - List msgs0 = null; + Collection msgs0 = null; if (msgs != null) { msgs0 = new ArrayList<>(msgs.size()); @@ -2490,6 +2490,8 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); + addFinishMsg.prepareMarshal(spi.marshaller()); + msg = addFinishMsg; DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData(); @@ -3831,11 +3833,13 @@ else if (!failedNextNode && sndState != null && sndState.isBackward()) { } synchronized (mux) { - failedNodes.forEach(failedNode -> { - ServerImpl.this.failedNodes.putIfAbsent(failedNode, locNodeId); + for (TcpDiscoveryNode failedNode : failedNodes) { + if (!ServerImpl.this.failedNodes.containsKey(failedNode)) + ServerImpl.this.failedNodes.put(failedNode, locNodeId); + } + for (TcpDiscoveryNode failedNode : failedNodes) failedNodesMsgSent.add(failedNode.id()); - }); } for (TcpDiscoveryNode n : failedNodes) @@ -4859,6 +4863,8 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { addFinishMsg.clientDiscoData(msg.gridDiscoveryData()); addFinishMsg.clientNodeAttributes(node.attributes()); + + addFinishMsg.prepareMarshal(spi.marshaller()); } addFinishMsg = tracing.messages().branch(addFinishMsg, msg); @@ -5074,7 +5080,9 @@ else if (spiState == CONNECTING) joiningNodesDiscoDataList = new ArrayList<>(); topHist.clear(); - topHist.putAll(msg.topologyHistory()); + + if(!F.isEmpty(msg.topologyHistory())) + topHist.putAll(msg.topologyHistory()); pendingMsgs.reset(msg.pendingMessages()); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java index b092665310993..159dae9dfbdb2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java @@ -210,25 +210,27 @@ public TcpDiscoveryNode( assert metrics != null; this.id = id; - this.order = order; - this.loc = loc; - this.hostNames = hostNames; - this.ver = ver; - this.metrics = metrics; List sortedAddrs = new ArrayList<>(addrs); + Collections.sort(sortedAddrs); this.addrs = sortedAddrs; + this.hostNames = hostNames; + this.order = order; + this.loc = loc; + this.ver = ver; + this.metrics = metrics; this.consistentId = consistentId != null ? consistentId : U.consistentId(sortedAddrs, discPort); - if (attrs == null) - attrs = Collections.emptyMap(); - - this.attrs = new HashMap<>(attrs); + if (attrs != null) { + this.attrs = new HashMap<>(attrs); - this.attrs.put(IgniteNodeAttributes.ATTR_CLIENT_MODE, client != null && client); + this.attrs.put(IgniteNodeAttributes.ATTR_CLIENT_MODE, client != null && client); + } + else + this.attrs = Collections.emptyMap(); } /** @@ -639,7 +641,10 @@ public TcpDiscoveryNode clientReconnectNode(Map nodeAttrs) { // Legacy: Cache metrics int size = in.readInt(); - assert size == 0; + for (int i = 0; i < size; i++) { + in.readInt(); + in.readObject(); + } order = in.readLong(); intOrder = in.readLong(); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java index 3e4e3e08373d2..0537a1b19987f 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java @@ -18,6 +18,7 @@ package org.apache.ignite.spi.discovery.tcp.messages; import java.util.Collection; +import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.apache.ignite.IgniteCheckedException; @@ -102,7 +103,7 @@ public ClusterNodeMessage(ClusterNode clusterNode) { hostNames = clusterNode.hostNames(); productVerMsg = new IgniteProductVersionMessage(clusterNode.version()); - attrs = clusterNode.attributes(); + attrs = clusterNode.attributes() == null ? null : new HashMap<>(clusterNode.attributes()); if (clusterNode.metrics() != null) clusterMetricsMsg = new TcpDiscoveryNodeMetricsMessage(clusterNode.metrics()); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 77854907d7950..9c77a1495aad2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -38,15 +38,15 @@ public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMess /** New router nodeID. */ @Order(value = 5, method = "routerNodeId") - private UUID routerNodeId; + private volatile UUID routerNodeId; /** Last message ID. */ @Order(value = 6, method = "lastMessageId") - private IgniteUuid lastMsgId; + private volatile IgniteUuid lastMsgId; /** Pending messages. */ @Order(value = 7, method = "pendingMessagesTransferMessage") - @Nullable private TcpDiscoveryCollectionMessage pendingMsgsMsg; + @Nullable private volatile TcpDiscoveryCollectionMessage pendingMsgsMsg; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryClientReconnectMessage() { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index b1956872ccd37..313288132cabc 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.ignite.IgniteCheckedException; @@ -76,6 +75,8 @@ public TcpDiscoveryCollectionMessage(Collection msg /** {@inheritDoc} */ @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + assert marshallableMsgsBytes != null || marshallableMsgs != null || writableMsgs != null; + if (marshallableMsgsBytes != null && marshallableMsgs == null) { try { marshallableMsgs = U.unmarshal(marsh, marshallableMsgsBytes, clsLdr); @@ -117,8 +118,7 @@ public void marshallableMessagesBytes(@Nullable byte[] marshallableMsgsBytes) { * @return Pending messages from previous node. */ public Collection messages() { - if (F.isEmpty(writableMsgs) && F.isEmpty(marshallableMsgs)) - return Collections.emptyList(); + assert !F.isEmpty(writableMsgs) || !F.isEmpty(marshallableMsgs); int totalSz = (F.isEmpty(writableMsgs) ? 0 : writableMsgs.size()) + (F.isEmpty(marshallableMsgs) ? 0 : marshallableMsgs.size()); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index d9ddc2bd8554b..ff6044379b770 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -52,7 +52,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private static final long serialVersionUID = 0L; /** Added node. */ - private TcpDiscoveryNode node; + private volatile TcpDiscoveryNode node; /** Marshalled {@link #node}. */ @Order(value = 6, method = "nodeBytes") @@ -86,7 +86,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM /** Start time of the first grid node. */ @Order(value = 11, method = "gridStartTime") - private long gridStartTime; + private volatile long gridStartTime; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryNodeAddedMessage() { @@ -126,11 +126,11 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { node = msg.node; nodeBytes = msg.nodeBytes; + pendingMsgsMsg = msg.pendingMsgsMsg; + top = msg.top; topBytes = msg.topBytes; - pendingMsgsMsg = msg.pendingMsgsMsg; - clientTop = msg.clientTop; topHistMsgs = msg.topHistMsgs; dataPacket = msg.dataPacket; From 629d05164d7ff6c055fbb2f9b99026c5e6ee4ace Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sun, 22 Feb 2026 15:35:58 +0300 Subject: [PATCH 17/47] impl --- .../direct/stream/DirectByteBufferStream.java | 2 +- .../discovery/DiscoveryMessageFactory.java | 11 +- .../persistence/tree/io/BPlusMetaIO.java | 3 +- .../serializer/RecordDataV1Serializer.java | 3 +- .../ignite/lang/IgniteProductVersion.java | 121 ++++---- .../ignite/spi/discovery/tcp/ServerImpl.java | 8 +- .../tcp/internal/TcpDiscoveryNode.java | 62 +--- .../ClusterNodeCollectionMessage.java | 56 ---- .../tcp/messages/ClusterNodeMessage.java | 282 ------------------ .../messages/IgniteProductVersionMessage.java | 152 ---------- .../TcpDiscoveryClientReconnectMessage.java | 6 +- .../TcpDiscoveryCollectionMessage.java | 8 +- .../TcpDiscoveryNodeAddedMessage.java | 257 +++++++--------- .../GridAffinityAssignmentV2Test.java | 8 +- 14 files changed, 206 insertions(+), 773 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java index 1b5d605aa0a46..53f1797264003 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java @@ -359,7 +359,7 @@ public DirectByteBufferStream(MessageFactory msgFactory) { * Constructror for stream used for reading messages. * * @param msgFactory Message factory. - * @param cacheObjProc Cache object processor. + * @param cacheObjProc Optional cache object processor. * @param msgPostReader Optional message post-reader. * @param msgPreWriter Optional message pre-writer. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 7f46c8f9cb609..de6e5697e5ae2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -21,12 +21,6 @@ import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacketSerializer; -import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeCollectionMessage; -import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeCollectionMessageSerializer; -import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeMessage; -import org.apache.ignite.spi.discovery.tcp.messages.ClusterNodeMessageSerializer; -import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; -import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.InetAddressMessage; import org.apache.ignite.spi.discovery.tcp.messages.InetAddressMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.InetSocketAddressMessage; @@ -92,10 +86,7 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { /** {@inheritDoc} */ @Override public void registerAll(MessageFactory factory) { - factory.register((short)-111, TcpDiscoveryCollectionMessage::new, new TcpDiscoveryCollectionMessageSerializer()); - factory.register((short)-110, ClusterNodeCollectionMessage::new, new ClusterNodeCollectionMessageSerializer()); - factory.register((short)-109, ClusterNodeMessage::new, new ClusterNodeMessageSerializer()); - factory.register((short)-108, IgniteProductVersionMessage::new, new IgniteProductVersionMessageSerializer()); + factory.register((short)-108, TcpDiscoveryCollectionMessage::new, new TcpDiscoveryCollectionMessageSerializer()); factory.register((short)-107, NodeSpecificData::new, new NodeSpecificDataSerializer()); factory.register((short)-106, DiscoveryDataPacket::new, new DiscoveryDataPacketSerializer()); factory.register((short)-105, TcpDiscoveryNodeFullMetricsMessage::new, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java index 7ab88b3809182..edcfefc4f8890 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java @@ -23,7 +23,6 @@ import org.apache.ignite.internal.pagemem.PageUtils; import org.apache.ignite.internal.util.GridStringBuilder; import org.apache.ignite.lang.IgniteProductVersion; -import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; /** * IO routines for B+Tree meta pages. @@ -304,7 +303,7 @@ public IgniteProductVersion createdVersion(long pageAddr) { PageUtils.getByte(pageAddr, CREATED_VER_OFFSET + 1), PageUtils.getByte(pageAddr, CREATED_VER_OFFSET + 2), PageUtils.getLong(pageAddr, CREATED_VER_OFFSET + 3), - PageUtils.getBytes(pageAddr, CREATED_VER_OFFSET + 11, IgniteProductVersionMessage.REV_HASH_SIZE)); + PageUtils.getBytes(pageAddr, CREATED_VER_OFFSET + 11, IgniteProductVersion.REV_HASH_SIZE)); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java index 5fb2d97a02d13..de920fddadf31 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java @@ -120,7 +120,6 @@ import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteProductVersion; -import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; import org.apache.ignite.spi.encryption.EncryptionSpi; import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi; import org.jetbrains.annotations.Nullable; @@ -851,7 +850,7 @@ WALRecord readPlainRecord(RecordType type, ByteBufferBackedDataInput in, long flags = in.readLong(); - byte[] revHash = new byte[IgniteProductVersionMessage.REV_HASH_SIZE]; + byte[] revHash = new byte[IgniteProductVersion.REV_HASH_SIZE]; byte maj = in.readByte(); byte min = in.readByte(); byte maint = in.readByte(); diff --git a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java index bca9354027f8b..1c78694550bd5 100644 --- a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java +++ b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java @@ -27,7 +27,6 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.IgniteVersionUtils; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.spi.discovery.tcp.messages.IgniteProductVersionMessage; import org.jetbrains.annotations.NotNull; /** @@ -42,26 +41,39 @@ public class IgniteProductVersion implements Comparable, E /** */ private static final long serialVersionUID = 0L; + /** Size of the {@link #revHash }*/ + public static final int REV_HASH_SIZE = 20; + /** Size in bytes of serialized: 3 bytes (maj, min, maintenance version), 8 bytes - timestamp */ - public static final int SIZE_IN_BYTES = 3 + 8 + IgniteProductVersionMessage.REV_HASH_SIZE; + public static final int SIZE_IN_BYTES = 3 + 8 + REV_HASH_SIZE; /** Regexp parse pattern. */ private static final Pattern VER_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)([-.]([^0123456789][^-]+)(-SNAPSHOT)?)?(-(\\d+))?(-([\\da-f]+))?"); - /** The values holding message. */ - private final IgniteProductVersionMessage productVerMsg; + /** Major version number. */ + private byte major; + + /** Minor version number. */ + private byte minor; + + /** Maintenance version number. */ + private byte maintenance; + + /** Stage of development. */ + private String stage; + + /** Revision timestamp. */ + private long revTs; + + /** Revision hash. */ + private byte[] revHash; /** * Empty constructor required by {@link Externalizable}. */ public IgniteProductVersion() { - productVerMsg = new IgniteProductVersionMessage(); - } - - /** @param productVerMsg Product version message. */ - public IgniteProductVersion(IgniteProductVersionMessage productVerMsg) { - this.productVerMsg = productVerMsg; + // No-op. } /** @@ -84,17 +96,17 @@ public IgniteProductVersion(byte major, byte minor, byte maintenance, long revTs * @param revHash Revision hash. */ public IgniteProductVersion(byte major, byte minor, byte maintenance, String stage, long revTs, byte[] revHash) { - productVerMsg = new IgniteProductVersionMessage(major, minor, maintenance, stage, revTs, revHash); - - if (revHash != null && revHash.length != IgniteProductVersionMessage.REV_HASH_SIZE) { + if (revHash != null && revHash.length != REV_HASH_SIZE) { throw new IllegalArgumentException("Invalid length for SHA1 hash (must be " - + IgniteProductVersionMessage.REV_HASH_SIZE + "): " + revHash.length); + + REV_HASH_SIZE + "): " + revHash.length); } - } - /** @return {@link IgniteProductVersionMessage}. */ - public IgniteProductVersionMessage message() { - return productVerMsg; + this.major = major; + this.minor = minor; + this.maintenance = maintenance; + this.stage = stage; + this.revTs = revTs; + this.revHash = revHash != null ? revHash : new byte[REV_HASH_SIZE]; } /** @@ -103,7 +115,7 @@ public IgniteProductVersionMessage message() { * @return Major version number. */ public byte major() { - return productVerMsg.major(); + return major; } /** @@ -112,7 +124,7 @@ public byte major() { * @return Minor version number. */ public byte minor() { - return productVerMsg.minor(); + return minor; } /** @@ -121,14 +133,14 @@ public byte minor() { * @return Maintenance version number. */ public byte maintenance() { - return productVerMsg.maintenance(); + return maintenance; } /** * @return Stage of development. */ public String stage() { - return productVerMsg.stage(); + return stage; } /** @@ -137,7 +149,7 @@ public String stage() { * @return Revision timestamp. */ public long revisionTimestamp() { - return productVerMsg.revisionTimestamp(); + return revTs; } /** @@ -146,7 +158,7 @@ public long revisionTimestamp() { * @return Revision hash. */ public byte[] revisionHash() { - return productVerMsg.revisionHash(); + return revHash; } /** @@ -155,7 +167,7 @@ public byte[] revisionHash() { * @return Release date. */ public Date releaseDate() { - return new Date(revisionTimestamp() * 1000); + return new Date(revTs * 1000); } /** @@ -166,31 +178,31 @@ public Date releaseDate() { */ public boolean greaterThanEqual(int major, int minor, int maintenance) { // NOTE: Unknown version is less than any other version. - if (major == major()) - return minor == minor() ? maintenance() >= maintenance : minor() > minor; + if (major == this.major) + return minor == this.minor ? this.maintenance >= maintenance : this.minor > minor; else - return major() > major; + return this.major > major; } /** {@inheritDoc} */ @Override public int compareTo(@NotNull IgniteProductVersion o) { // NOTE: Unknown version is less than any other version. - int res = Integer.compare(major(), o.major()); + int res = Integer.compare(major, o.major); if (res != 0) return res; - res = Integer.compare(minor(), o.minor()); + res = Integer.compare(minor, o.minor); if (res != 0) return res; - res = Integer.compare(maintenance(), o.maintenance()); + res = Integer.compare(maintenance, o.maintenance); if (res != 0) return res; - return Long.compare(revisionTimestamp(), o.revisionTimestamp()); + return Long.compare(revTs, o.revTs); } /** @@ -198,17 +210,17 @@ public boolean greaterThanEqual(int major, int minor, int maintenance) { * @return Compare result. */ public int compareToIgnoreTimestamp(@NotNull IgniteProductVersion o) { - int res = Integer.compare(major(), o.major()); + int res = Integer.compare(major, o.major); if (res != 0) return res; - res = Integer.compare(minor(), o.minor()); + res = Integer.compare(minor, o.minor); if (res != 0) return res; - return Integer.compare(maintenance(), o.maintenance()); + return Integer.compare(maintenance, o.maintenance); } /** {@inheritDoc} */ @@ -221,50 +233,47 @@ public int compareToIgnoreTimestamp(@NotNull IgniteProductVersion o) { IgniteProductVersion that = (IgniteProductVersion)o; - return revisionTimestamp() == that.revisionTimestamp() && maintenance() == that.maintenance() - && minor() == that.minor() && major() == that.major(); + return revTs == that.revTs && maintenance == that.maintenance && minor == that.minor && major == that.major; } /** {@inheritDoc} */ @Override public int hashCode() { - int res = major(); + int res = major; - res = 31 * res + minor(); - res = 31 * res + maintenance(); - res = 31 * res + (int)(revisionTimestamp() ^ (revisionTimestamp() >>> 32)); + res = 31 * res + minor; + res = 31 * res + maintenance; + res = 31 * res + (int)(revTs ^ (revTs >>> 32)); return res; } /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { - out.writeByte(major()); - out.writeByte(minor()); - out.writeByte(maintenance()); - out.writeLong(revisionTimestamp()); - U.writeByteArray(out, revisionHash()); + out.writeByte(major); + out.writeByte(minor); + out.writeByte(maintenance); + out.writeLong(revTs); + U.writeByteArray(out, revHash); } /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - assert productVerMsg != null; - - productVerMsg.major(in.readByte()); - productVerMsg.minor(in.readByte()); - productVerMsg.maintenance(in.readByte()); - productVerMsg.revisionTimestamp(in.readLong()); - productVerMsg.revisionHash(U.readByteArray(in)); + major = in.readByte(); + minor = in.readByte(); + maintenance = in.readByte(); + revTs = in.readLong(); + revHash = U.readByteArray(in); } /** {@inheritDoc} */ @Override public String toString() { - String revTsStr = IgniteVersionUtils.formatBuildTimeStamp(revisionTimestamp() * 1000); + String revTsStr = IgniteVersionUtils.formatBuildTimeStamp(revTs * 1000); - String hash = U.byteArray2HexString(revisionHash()).toLowerCase(); + String hash = U.byteArray2HexString(revHash).toLowerCase(); hash = hash.length() > 8 ? hash.substring(0, 8) : hash; - return major() + "." + minor() + "." + maintenance() + "#" + revTsStr + "-sha1:" + hash; + return major + "." + minor + "." + maintenance + "#" + revTsStr + "-sha1:" + hash; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 42daa4304911d..e2f0000257d9d 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1889,7 +1889,7 @@ private void prepareNodeAddedMessage( } } - nodeAddedMsg.pendingMessages(msgs0); + nodeAddedMsg.messages(msgs0); Map> hist; @@ -1912,7 +1912,7 @@ private void clearNodeAddedMessage(TcpDiscoveryAbstractMessage msg) { nodeAddedMsg.topology(null); nodeAddedMsg.topologyHistory(null); - nodeAddedMsg.pendingMessages(null); + nodeAddedMsg.messages(null); nodeAddedMsg.clearUnmarshalledDiscoveryData(); } } @@ -5081,10 +5081,10 @@ else if (spiState == CONNECTING) topHist.clear(); - if(!F.isEmpty(msg.topologyHistory())) + if (!F.isEmpty(msg.topologyHistory())) topHist.putAll(msg.topologyHistory()); - pendingMsgs.reset(msg.pendingMessages()); + pendingMsgs.reset(msg.messages()); } else { if (log.isDebugEnabled()) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java index 159dae9dfbdb2..89f1f492e9272 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java @@ -94,7 +94,7 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite /** Node cache metrics. */ @GridToStringExclude - private volatile @Nullable Map cacheMetrics; + private volatile Map cacheMetrics; /** Node order in the topology. */ private volatile long order; @@ -162,52 +162,17 @@ public TcpDiscoveryNode() { * @param ver Version. * @param consistentId Node consistent ID. */ - public TcpDiscoveryNode( - UUID id, + public TcpDiscoveryNode(UUID id, Collection addrs, Collection hostNames, int discPort, DiscoveryMetricsProvider metricsProvider, IgniteProductVersion ver, - @Nullable Serializable consistentId - ) { - this(id, consistentId, 0, false, null, addrs, hostNames, null, ver, metricsProvider.metrics()); - - this.discPort = discPort; - this.metricsProvider = metricsProvider; - cacheMetrics = metricsProvider.cacheMetrics(); - sockAddrs = U.toSocketAddresses(this, discPort); - } - - /** - * Constructor to implement {@link ClusterNode}. - * - * @param id Node id. - * @param consistentId Consistent id. - * @param order Node order. - * @param loc Local node flag. - * @param client Client node flag. - * @param addrs Node addresses. - * @param hostNames Node host names. - * @param attrs Node attributes. - * @param ver Version. - * @param metrics Node metrics. - */ - public TcpDiscoveryNode( - UUID id, - @Nullable Object consistentId, - long order, - boolean loc, - @Nullable Boolean client, - Collection addrs, - Collection hostNames, - @Nullable Map attrs, - IgniteProductVersion ver, - ClusterMetrics metrics + Serializable consistentId ) { assert id != null; + assert metricsProvider != null; assert ver != null; - assert metrics != null; this.id = id; @@ -217,20 +182,15 @@ public TcpDiscoveryNode( this.addrs = sortedAddrs; this.hostNames = hostNames; - this.order = order; - this.loc = loc; + this.discPort = discPort; + this.metricsProvider = metricsProvider; this.ver = ver; - this.metrics = metrics; this.consistentId = consistentId != null ? consistentId : U.consistentId(sortedAddrs, discPort); - if (attrs != null) { - this.attrs = new HashMap<>(attrs); - - this.attrs.put(IgniteNodeAttributes.ATTR_CLIENT_MODE, client != null && client); - } - else - this.attrs = Collections.emptyMap(); + metrics = metricsProvider.metrics(); + cacheMetrics = metricsProvider.cacheMetrics(); + sockAddrs = U.toSocketAddresses(this, discPort); } /** @@ -330,7 +290,7 @@ public Map getAttributes() { } /** {@inheritDoc} */ - @Override public @Nullable Map cacheMetrics() { + @Override public Map cacheMetrics() { if (metricsProvider != null) { Map cacheMetrics0 = metricsProvider.cacheMetrics(); @@ -503,7 +463,7 @@ public void visible(boolean visible) { /** {@inheritDoc} */ @Override public boolean isClient() { if (!cacheCliInit) { - Boolean clientModeAttr = attribute(IgniteNodeAttributes.ATTR_CLIENT_MODE); + Boolean clientModeAttr = ((ClusterNode)this).attribute(IgniteNodeAttributes.ATTR_CLIENT_MODE); cacheCli = clientModeAttr != null && clientModeAttr; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java deleted file mode 100644 index 6b4a7442d5c05..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeCollectionMessage.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.spi.discovery.tcp.messages; - -import java.util.Collection; -import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; -import org.apache.ignite.plugin.extensions.communication.Message; - -/** A container message for a collection of {@link ClusterNodeMessage}. */ -public class ClusterNodeCollectionMessage implements Message { - /** The collection of wrapped {@link ClusterNodeMessage}. */ - @Order(value = 0, method = "clusterNodeMessages") - private Collection clusterNodeMsgs; - - /** Constructor for {@link DiscoveryMessageFactory}. */ - public ClusterNodeCollectionMessage() { - // No-op. - } - - /** @param clusterNodeMsgs Holder messages of {@link ClusterNode}. */ - public ClusterNodeCollectionMessage(Collection clusterNodeMsgs) { - this.clusterNodeMsgs = clusterNodeMsgs; - } - - /** @return Holder messages of {@link ClusterNode}. */ - public Collection clusterNodeMessages() { - return clusterNodeMsgs; - } - - /** @param clusterNodeMsgs Holder messages of {@link ClusterNode}. */ - public void clusterNodeMessages(Collection clusterNodeMsgs) { - this.clusterNodeMsgs = clusterNodeMsgs; - } - - /** {@inheritDoc} */ - @Override public short directType() { - return -110; - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java deleted file mode 100644 index 0537a1b19987f..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/ClusterNodeMessage.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.spi.discovery.tcp.messages; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteException; -import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; -import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; -import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; -import org.jetbrains.annotations.Nullable; - -/** - * Message for {@link ClusterNode}. - */ -public class ClusterNodeMessage implements TcpDiscoveryMarshallableMessage { - /** Node ID. */ - @Order(value = 0, method = "id") - private UUID id; - - /** Internal discovery addresses as strings. */ - @Order(value = 1, method = "addresses") - private Collection addrs; - - /** Internal discovery host names as strings. */ - @Order(value = 2, method = "hostNames") - private Collection hostNames; - - /** */ - @Order(value = 3, method = "clusterMetricsMessage") - private TcpDiscoveryNodeMetricsMessage clusterMetricsMsg; - - /** */ - @Order(value = 4, method = "order") - private long order; - - /** */ - @Order(value = 5, method = "productVersionMessage") - private IgniteProductVersionMessage productVerMsg; - - /** Grid local node flag (transient). */ - @Order(value = 6, method = "local") - private boolean loc; - - /** */ - @Order(value = 7, method = "client") - private boolean client; - - /** */ - @Order(value = 8, method = "dataCenterId") - private String dataCenterId; - - /** Consistent ID. */ - private Object consistentId; - - /** */ - @Order(value = 9, method = "consistentIdBytes") - private byte[] consistentIdBytes; - - /** Node attributes. */ - private Map attrs; - - /** */ - @Order(value = 10, method = "attributesBytes") - private byte[] attrsBytes; - - /** Constructor for {@link DiscoveryMessageFactory}. */ - public ClusterNodeMessage() { - // No-op. - } - - /** @param clusterNode Cluster node. */ - public ClusterNodeMessage(ClusterNode clusterNode) { - id = clusterNode.id(); - consistentId = clusterNode.consistentId(); - dataCenterId = clusterNode.dataCenterId(); - order = clusterNode.order(); - addrs = clusterNode.addresses(); - loc = clusterNode.isLocal(); - client = clusterNode.isClient(); - hostNames = clusterNode.hostNames(); - productVerMsg = new IgniteProductVersionMessage(clusterNode.version()); - - attrs = clusterNode.attributes() == null ? null : new HashMap<>(clusterNode.attributes()); - - if (clusterNode.metrics() != null) - clusterMetricsMsg = new TcpDiscoveryNodeMetricsMessage(clusterNode.metrics()); - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) { - if (!F.isEmpty(attrs) && attrsBytes == null) { - try { - attrsBytes = U.marshal(marsh, attrs); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal cluster node attributes.", e); - } - } - - if (consistentId != null && consistentIdBytes == null) { - try { - consistentIdBytes = U.marshal(marsh, consistentId); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal cluster node's consistent id.", e); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - if (attrsBytes != null && F.isEmpty(attrs)) { - try { - attrs = U.unmarshal(marsh, attrsBytes, clsLdr); - - attrsBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal cluster node attributes.", e); - } - } - - if (consistentIdBytes != null && consistentId == null) { - try { - consistentId = U.unmarshal(marsh, consistentIdBytes, clsLdr); - - consistentIdBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to cluster node's consistent id.", e); - } - } - } - - /** @return Addresses. */ - public Collection addresses() { - return addrs; - } - - /** @param addrs Addresses. */ - public void addresses(Collection addrs) { - this.addrs = addrs; - } - - /** @return Node metrics message. */ - public NodeMetricsMessage clusterMetricsMessage() { - return clusterMetricsMsg; - } - - /** @param clusterMetricsMsg Node metrics message. */ - public void clusterMetricsMessage(TcpDiscoveryNodeMetricsMessage clusterMetricsMsg) { - this.clusterMetricsMsg = clusterMetricsMsg; - } - - /** @return Client flag. */ - public boolean client() { - return client; - } - - /** @param client Client flag. */ - public void client(boolean client) { - this.client = client; - } - - /** @return Datacenter id. */ - public String dataCenterId() { - return dataCenterId; - } - - /** @param dataCenterId Datacenter id. */ - public void dataCenterId(String dataCenterId) { - this.dataCenterId = dataCenterId; - } - - /** @return Host names. */ - public Collection hostNames() { - return hostNames; - } - - /** @param hostNames Host names. */ - public void hostNames(Collection hostNames) { - this.hostNames = hostNames; - } - - /** @return Node id. */ - public UUID id() { - return id; - } - - /** @param id Node id. */ - public void id(UUID id) { - this.id = id; - } - - /** @return Node order. */ - public long order() { - return order; - } - - /** @param order Node order. */ - public void order(long order) { - this.order = order; - } - - /** @return Local node flag. */ - public boolean local() { - return loc; - } - - /** @param loc Local node flag. */ - public void local(boolean loc) { - this.loc = loc; - } - - /** @return Product version. */ - public IgniteProductVersionMessage productVersionMessage() { - return productVerMsg; - } - - /** @param productVerMsg Product version. */ - public void productVersionMessage(IgniteProductVersionMessage productVerMsg) { - this.productVerMsg = productVerMsg; - } - - /** @return Node consistent id. */ - public Object consistentId() { - return consistentId; - } - - /** @return Marshalled bytes of {@link #consistentId}. */ - public byte[] consistentIdBytes() { - return consistentIdBytes; - } - - /** @param consistentIdBytes Marshalled bytes of {@link #consistentId}. */ - public void consistentIdBytes(byte[] consistentIdBytes) { - this.consistentIdBytes = consistentIdBytes; - } - - /** @return Node's attributes. */ - public Map attributes() { - return attrs; - } - - /** @return Marshalled bytes of {@link #attrs}. */ - public @Nullable byte[] attributesBytes() { - return attrsBytes; - } - - /** @param attrsBytes Marshalled bytes of {@link #attrs}. */ - public void attributesBytes(@Nullable byte[] attrsBytes) { - this.attrsBytes = attrsBytes; - } - - /** {@inheritDoc} */ - @Override public short directType() { - return -109; - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java deleted file mode 100644 index 0ef5b13290c2c..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/IgniteProductVersionMessage.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.spi.discovery.tcp.messages; - -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; -import org.apache.ignite.lang.IgniteProductVersion; -import org.apache.ignite.plugin.extensions.communication.Message; - -/** Message for {@link IgniteProductVersion}.*/ -public class IgniteProductVersionMessage implements Message { - /** Size of the {@link #revHash }*/ - public static final int REV_HASH_SIZE = 20; - - /** Major version number. */ - @Order(value = 0, method = "major") - private byte major; - - /** Minor version number. */ - @Order(value = 1, method = "minor") - private byte minor; - - /** Maintenance version number. */ - @Order(value = 2, method = "maintenance") - private byte maintenance; - - /** Stage of development. */ - @Order(value = 3, method = "stage") - private String stage; - - /** Revision timestamp. */ - @Order(value = 4, method = "revisionTimestamp") - private long revTs; - - /** Revision hash. */ - @Order(value = 5, method = "revisionHash") - private byte[] revHash; - - /** Constructor for {@link DiscoveryMessageFactory}. */ - public IgniteProductVersionMessage() { - // No-op. - } - - /** - * @param major Major version. - * @param minor Minor version. - * @param maintenance Maintenance. - * @param stage Stage. - * @param revTs Revision timestamp. - * @param revHash Revision hash. - */ - public IgniteProductVersionMessage(byte major, byte minor, byte maintenance, String stage, long revTs, byte[] revHash) { - this.major = major; - this.minor = minor; - this.maintenance = maintenance; - this.stage = stage; - this.revTs = revTs; - this.revHash = revHash != null ? revHash : new byte[REV_HASH_SIZE]; - } - - /** @param ver Product version. */ - public IgniteProductVersionMessage(IgniteProductVersion ver) { - this( - ver.major(), - ver.minor(), - ver.maintenance(), - ver.stage(), - ver.revisionTimestamp(), - ver.revisionHash() - ); - } - - /** @return Maintenance. */ - public byte maintenance() { - return maintenance; - } - - /** @param maintenance Maintenance. */ - public void maintenance(byte maintenance) { - this.maintenance = maintenance; - } - - /** @return Major version. */ - public byte major() { - return major; - } - - /** @param major Major version. */ - public void major(byte major) { - this.major = major; - } - - /** @return Minor version. */ - public byte minor() { - return minor; - } - - /** @param minor Minor version. */ - public void minor(byte minor) { - this.minor = minor; - } - - /** @return Revision hash. */ - public byte[] revisionHash() { - return revHash; - } - - /** @param revHash Revision hash. */ - public void revisionHash(byte[] revHash) { - this.revHash = revHash; - } - - /** @return Revision timestamp. */ - public long revisionTimestamp() { - return revTs; - } - - /** @param revTs Revision timestamp. */ - public void revisionTimestamp(long revTs) { - this.revTs = revTs; - } - - /** @return Statge. */ - public String stage() { - return stage; - } - - /** @param stage Stage. */ - public void stage(String stage) { - this.stage = stage; - } - - /** {@inheritDoc} */ - @Override public short directType() { - return -108; - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 9c77a1495aad2..c801ffd5db8b6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -38,13 +38,13 @@ public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMess /** New router nodeID. */ @Order(value = 5, method = "routerNodeId") - private volatile UUID routerNodeId; + private UUID routerNodeId; /** Last message ID. */ @Order(value = 6, method = "lastMessageId") - private volatile IgniteUuid lastMsgId; + private IgniteUuid lastMsgId; - /** Pending messages. */ + /** Pending messages holder. */ @Order(value = 7, method = "pendingMessagesTransferMessage") @Nullable private volatile TcpDiscoveryCollectionMessage pendingMsgsMsg; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index 313288132cabc..a8016f8fc58d1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -129,11 +129,11 @@ public Collection messages() { Message m = F.isEmpty(writableMsgs) ? null : writableMsgs.get(i); if (m == null) { - TcpDiscoveryAbstractMessage sm = marshallableMsgs.get(i); + TcpDiscoveryAbstractMessage adm = marshallableMsgs.get(i); - assert sm != null; + assert adm != null; - res.add(sm); + res.add(adm); } else { assert marshallableMsgs == null || marshallableMsgs.get(i) == null; @@ -183,7 +183,7 @@ public void messages(@Nullable Collection msgs) { /** {@inheritDoc} */ @Override public short directType() { - return -111; + return -108; } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index ff6044379b770..133b1b76f4bb3 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -21,19 +21,15 @@ import java.util.Collections; import java.util.Map; import java.util.UUID; -import java.util.stream.Collectors; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; @@ -52,7 +48,7 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private static final long serialVersionUID = 0L; /** Added node. */ - private volatile TcpDiscoveryNode node; + private TcpDiscoveryNode node; /** Marshalled {@link #node}. */ @Order(value = 6, method = "nodeBytes") @@ -60,19 +56,18 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private byte[] nodeBytes; /** */ - @Order(value = 7, method = "gridDiscoveryData") private DiscoveryDataPacket dataPacket; - /** Message to hold collection of pending {@link TcpDiscoveryAbstractMessage}. */ - @Order(value = 8, method = "pendingMessagesTransferMessage") - private TcpDiscoveryCollectionMessage pendingMsgsMsg; + /** Pending messages containner. */ + @Order(value = 7, method = "pendingMessagesTransferMessage") + @Nullable private TcpDiscoveryCollectionMessage pendingMsgsMsg; /** Current topology. Initialized by coordinator. */ @GridToStringInclude private @Nullable Collection top; /** Marshalled {@link #top}. */ - @Order(value = 9, method = "topologyBytes") + @Order(value = 8, method = "topologyBytes") @GridToStringExclude private @Nullable byte[] topBytes; @@ -81,12 +76,16 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM private transient Collection clientTop; /** Topology snapshots history. */ - @Order(value = 10, method = "topologyHistoryMessages") - private @Nullable Map topHistMsgs; + private Map> topHist; + + /** Marshalled {@link #topHist}. */ + @Order(value = 9, method = "topologyHistoryBytes") + @GridToStringExclude + private @Nullable byte[] topHistBytes; /** Start time of the first grid node. */ - @Order(value = 11, method = "gridStartTime") - private volatile long gridStartTime; + @Order(value = 10, method = "gridStartTime") + private long gridStartTime; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryNodeAddedMessage() { @@ -101,8 +100,7 @@ public TcpDiscoveryNodeAddedMessage() { * @param dataPacket container for collecting discovery data across the cluster. * @param gridStartTime Start time of the first grid node. */ - public TcpDiscoveryNodeAddedMessage( - UUID creatorNodeId, + public TcpDiscoveryNodeAddedMessage(UUID creatorNodeId, TcpDiscoveryNode node, DiscoveryDataPacket dataPacket, long gridStartTime @@ -123,64 +121,16 @@ public TcpDiscoveryNodeAddedMessage( public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { super(msg); - node = msg.node; - nodeBytes = msg.nodeBytes; - - pendingMsgsMsg = msg.pendingMsgsMsg; - - top = msg.top; - topBytes = msg.topBytes; - - clientTop = msg.clientTop; - topHistMsgs = msg.topHistMsgs; - dataPacket = msg.dataPacket; - gridStartTime = msg.gridStartTime; - } - - /** @param marsh marshaller. */ - @Override public void prepareMarshal(Marshaller marsh) { - if (node != null && nodeBytes == null) { - try { - nodeBytes = U.marshal(marsh, node); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal cluster node.", e); - } - } - - if (top != null && topBytes == null) { - try { - topBytes = U.marshal(marsh, top); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal topology nodes.", e); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - if (nodeBytes != null && node == null) { - try { - node = U.unmarshal(marsh, nodeBytes, clsLdr); - - nodeBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal cluster node.", e); - } - } - - if (topBytes != null && top == null) { - try { - top = U.unmarshal(marsh, topBytes, clsLdr); - - topBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal topology nodes.", e); - } - } + this.node = msg.node; + this.nodeBytes = msg.nodeBytes; + this.pendingMsgsMsg = msg.pendingMsgsMsg; + this.top = msg.top; + this.topBytes = msg.topBytes; + this.clientTop = msg.clientTop; + this.topHist = msg.topHist; + this.topHistBytes = msg.topHistBytes; + this.dataPacket = msg.dataPacket; + this.gridStartTime = msg.gridStartTime; } /** @@ -192,12 +142,12 @@ public TcpDiscoveryNode node() { return node; } - /** @return Serialized {@link #node}. */ + /** @return Marshalled {@link #node}. */ public byte[] nodeBytes() { return nodeBytes; } - /** @param nodeBytes Serialized {@link #node}. */ + /** @param nodeBytes Marshalled {@link #node}. */ public void nodeBytes(byte[] nodeBytes) { this.nodeBytes = nodeBytes; } @@ -207,25 +157,25 @@ public void nodeBytes(byte[] nodeBytes) { * * @return Pending messages from previous node. */ - public Collection pendingMessages() { + @Nullable public Collection messages() { return pendingMsgsMsg == null ? Collections.emptyList() : pendingMsgsMsg.messages(); } /** - * Sets pending messages. + * Sets pending messages to send to new node. * - * @param msgs Pending messages. + * @param msgs Pending messages to send to new node. */ - public void pendingMessages(@Nullable Collection msgs) { - pendingMsgsMsg = F.isEmpty(msgs) ? null : new TcpDiscoveryCollectionMessage(msgs); + public void messages(@Nullable Collection msgs) { + pendingMsgsMsg = msgs == null ? null : new TcpDiscoveryCollectionMessage(msgs); } - /** @return Message to transfer the pending messages. */ + /** @return Pending messages containner. */ public @Nullable TcpDiscoveryCollectionMessage pendingMessagesTransferMessage() { return pendingMsgsMsg; } - /** @param pendingMsgsMsg Message to transfer the pending messages. */ + /** @param pendingMsgsMsg Pending messages containner. */ public void pendingMessagesTransferMessage(@Nullable TcpDiscoveryCollectionMessage pendingMsgsMsg) { this.pendingMsgsMsg = pendingMsgsMsg; } @@ -249,12 +199,12 @@ public void topology(@Nullable Collection top) { topBytes = null; } - /** @return Serialized {@link #top}. */ + /** @return Marshalled {@link #top}. */ public @Nullable byte[] topologyBytes() { return topBytes; } - /** @param topBytes Serialized {@link #top}. */ + /** @param topBytes Marshalled {@link #top}. */ public void topologyBytes(@Nullable byte[] topBytes) { this.topBytes = topBytes; } @@ -265,7 +215,7 @@ public void topologyBytes(@Nullable byte[] topBytes) { public void clientTopology(Collection top) { assert top != null && !top.isEmpty() : top; - clientTop = top; + this.clientTop = top; } /** @@ -275,52 +225,13 @@ public Collection clientTopology() { return clientTop; } - /** @return Topology history messages. */ - public @Nullable Map topologyHistoryMessages() { - return topHistMsgs; - } - - /** @param topHistMsgs Topology history messages. */ - public void topologyHistoryMessages(@Nullable Map topHistMsgs) { - this.topHistMsgs = topHistMsgs; - } - /** * Gets topology snapshots history. * * @return Map with topology snapshots history. */ public Map> topologyHistory() { - if (F.isEmpty(topHistMsgs)) - return Collections.emptyMap(); - - Map> res = U.newHashMap(topHistMsgs.size()); - - topHistMsgs.forEach((nodeId, msgs) -> { - Collection clusterNodeImpls = msgs.clusterNodeMessages().stream() - .map(m -> { - assert m.clusterMetricsMessage() != null; - - TcpDiscoveryNode tcpDiscoNode = new TcpDiscoveryNode( - m.id(), - m.consistentId(), - m.order(), - m.local(), - m.client(), - m.addresses(), - m.hostNames(), - m.attributes(), - new IgniteProductVersion(m.productVersionMessage()), - new ClusterMetricsSnapshot(m.clusterMetricsMessage()) - ); - - return tcpDiscoNode; - }).collect(Collectors.toList()); - - res.put(nodeId, clusterNodeImpls); - }); - - return res; + return topHist; } /** @@ -329,20 +240,18 @@ public Map> topologyHistory() { * @param topHist Map with topology snapshots history. */ public void topologyHistory(@Nullable Map> topHist) { - if (F.isEmpty(topHist)) { - topHistMsgs = null; - - return; - } - - topHistMsgs = U.newHashMap(topHist.size()); + this.topHist = topHist; + topHistBytes = null; + } - topHist.forEach((nodeId, clusterNodes) -> { - Collection clusterNodeImpls = clusterNodes.stream().map(ClusterNodeMessage::new) - .collect(Collectors.toList()); + /** @return Marshalled {@link #topHist}. */ + public @Nullable byte[] topologyHistoryBytes() { + return topHistBytes; + } - topHistMsgs.put(nodeId, new ClusterNodeCollectionMessage(clusterNodeImpls)); - }); + /** @param topHistBytes Marshalled {@link #topHist}. */ + public void topologyHistoryBytes(@Nullable byte[] topHistBytes) { + this.topHistBytes = topHistBytes; } /** @@ -352,11 +261,6 @@ public DiscoveryDataPacket gridDiscoveryData() { return dataPacket; } - /** @param dataPacket Data packet data. */ - public void gridDiscoveryData(DiscoveryDataPacket dataPacket) { - this.dataPacket = dataPacket; - } - /** * Clears discovery data to minimize message size. */ @@ -385,6 +289,73 @@ public void gridStartTime(long gridStartTime) { this.gridStartTime = gridStartTime; } + /** @param marsh marshaller. */ + @Override public void prepareMarshal(Marshaller marsh) { + if (node != null && nodeBytes == null) { + try { + nodeBytes = U.marshal(marsh, node); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal cluster node.", e); + } + } + + if (top != null && topBytes == null) { + try { + topBytes = U.marshal(marsh, top); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal topology nodes.", e); + } + } + + if (topHist != null && topHistBytes == null) { + try { + topHistBytes = U.marshal(marsh, topHist); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal topology history.", e); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + if (nodeBytes != null && node == null) { + try { + node = U.unmarshal(marsh, nodeBytes, clsLdr); + + nodeBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal cluster node.", e); + } + } + + if (topBytes != null && top == null) { + try { + top = U.unmarshal(marsh, topBytes, clsLdr); + + topBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal topology nodes.", e); + } + } + + if (topHistBytes != null && topHist == null) { + try { + topHist = U.unmarshal(marsh, topHistBytes, clsLdr); + + topHistBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal topology history.", e); + } + } + } + + /** {@inheritDoc} */ @Override public short directType() { return 21; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java index 12b076f39f947..5d8e966851c3c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentV2Test.java @@ -29,9 +29,7 @@ import java.util.List; import java.util.Set; import java.util.UUID; -import org.apache.ignite.cluster.ClusterMetrics; import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.util.collection.BitSetIntSet; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteProductVersion; @@ -51,11 +49,7 @@ */ public class GridAffinityAssignmentV2Test { /** */ - protected DiscoveryMetricsProvider metrics = new SerializableMetricsProvider() { - @Override public ClusterMetrics metrics() { - return new ClusterMetricsSnapshot(); - } - }; + protected DiscoveryMetricsProvider metrics = new SerializableMetricsProvider(); /** */ protected IgniteProductVersion ver = new IgniteProductVersion(); From 7f0cbc3d04a1362e84179affb4700453993a7cd0 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sun, 22 Feb 2026 16:16:42 +0300 Subject: [PATCH 18/47] impl --- .../discovery/DiscoveryMessageFactory.java | 3 - .../TcpDiscoveryNodeAddFinishedMessage.java | 6 +- .../TcpDiscoveryNodeAddedMessage.java | 175 ++---------------- 3 files changed, 14 insertions(+), 170 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index de6e5697e5ae2..1bff39342c9a8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -63,8 +63,6 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessageSerializer; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFullMetricsMessage; @@ -118,6 +116,5 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { factory.register((short)18, TcpDiscoveryStatusCheckMessage::new, new TcpDiscoveryStatusCheckMessageSerializer()); factory.register((short)19, TcpDiscoveryNodeAddFinishedMessage::new, new TcpDiscoveryNodeAddFinishedMessageSerializer()); factory.register((short)20, TcpDiscoveryClientReconnectMessage::new, new TcpDiscoveryClientReconnectMessageSerializer()); - factory.register((short)21, TcpDiscoveryNodeAddedMessage::new, new TcpDiscoveryNodeAddedMessageSerializer()); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index a031370211709..57d81a38662a1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -23,7 +23,6 @@ import org.apache.ignite.IgniteException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; -import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; @@ -130,6 +129,7 @@ public Map clientNodeAttributes() { */ public void clientNodeAttributes(Map clientNodeAttrs) { this.clientNodeAttrs = clientNodeAttrs; + clientNodeAttrsBytes = null; } /** @@ -160,9 +160,7 @@ public void clientNodeAttributesBytes(@Nullable byte[] clientNodeAttrsBytes) { /** {@inheritDoc} */ @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - if (F.isEmpty(clientNodeAttrsBytes)) - clientNodeAttrs = null; - else { + if (clientNodeAttrsBytes != null && clientNodeAttrs == null) { try { clientNodeAttrs = U.unmarshal(marsh, clientNodeAttrsBytes, clsLdr); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java index 133b1b76f4bb3..36540d8b7dfc1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddedMessage.java @@ -18,58 +18,38 @@ package org.apache.ignite.spi.discovery.tcp.messages; import java.util.Collection; -import java.util.Collections; import java.util.Map; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; -import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; import org.jetbrains.annotations.Nullable; /** - * TODO: Revise serialization of the {@link TcpDiscoveryNode} fields after https://issues.apache.org/jira/browse/IGNITE-27899 * Message telling nodes that new node should be added to topology. * When newly added node receives the message it connects to its next and finishes * join process. */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { +public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableMessage { /** */ private static final long serialVersionUID = 0L; /** Added node. */ - private TcpDiscoveryNode node; - - /** Marshalled {@link #node}. */ - @Order(value = 6, method = "nodeBytes") - @GridToStringExclude - private byte[] nodeBytes; + private final TcpDiscoveryNode node; /** */ private DiscoveryDataPacket dataPacket; - /** Pending messages containner. */ - @Order(value = 7, method = "pendingMessagesTransferMessage") - @Nullable private TcpDiscoveryCollectionMessage pendingMsgsMsg; + /** Pending messages from previous node. */ + private Collection msgs; /** Current topology. Initialized by coordinator. */ @GridToStringInclude - private @Nullable Collection top; - - /** Marshalled {@link #top}. */ - @Order(value = 8, method = "topologyBytes") - @GridToStringExclude - private @Nullable byte[] topBytes; + private Collection top; /** */ @GridToStringInclude @@ -78,19 +58,8 @@ public class TcpDiscoveryNodeAddedMessage extends TcpDiscoveryAbstractTraceableM /** Topology snapshots history. */ private Map> topHist; - /** Marshalled {@link #topHist}. */ - @Order(value = 9, method = "topologyHistoryBytes") - @GridToStringExclude - private @Nullable byte[] topHistBytes; - /** Start time of the first grid node. */ - @Order(value = 10, method = "gridStartTime") - private long gridStartTime; - - /** Constructor for {@link DiscoveryMessageFactory}. */ - public TcpDiscoveryNodeAddedMessage() { - // No-op. - } + private final long gridStartTime; /** * Constructor. @@ -122,13 +91,10 @@ public TcpDiscoveryNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { super(msg); this.node = msg.node; - this.nodeBytes = msg.nodeBytes; - this.pendingMsgsMsg = msg.pendingMsgsMsg; + this.msgs = msg.msgs; this.top = msg.top; - this.topBytes = msg.topBytes; this.clientTop = msg.clientTop; this.topHist = msg.topHist; - this.topHistBytes = msg.topHistBytes; this.dataPacket = msg.dataPacket; this.gridStartTime = msg.gridStartTime; } @@ -142,23 +108,13 @@ public TcpDiscoveryNode node() { return node; } - /** @return Marshalled {@link #node}. */ - public byte[] nodeBytes() { - return nodeBytes; - } - - /** @param nodeBytes Marshalled {@link #node}. */ - public void nodeBytes(byte[] nodeBytes) { - this.nodeBytes = nodeBytes; - } - /** * Gets pending messages sent to new node by its previous. * * @return Pending messages from previous node. */ @Nullable public Collection messages() { - return pendingMsgsMsg == null ? Collections.emptyList() : pendingMsgsMsg.messages(); + return msgs; } /** @@ -166,18 +122,10 @@ public void nodeBytes(byte[] nodeBytes) { * * @param msgs Pending messages to send to new node. */ - public void messages(@Nullable Collection msgs) { - pendingMsgsMsg = msgs == null ? null : new TcpDiscoveryCollectionMessage(msgs); - } - - /** @return Pending messages containner. */ - public @Nullable TcpDiscoveryCollectionMessage pendingMessagesTransferMessage() { - return pendingMsgsMsg; - } - - /** @param pendingMsgsMsg Pending messages containner. */ - public void pendingMessagesTransferMessage(@Nullable TcpDiscoveryCollectionMessage pendingMsgsMsg) { - this.pendingMsgsMsg = pendingMsgsMsg; + public void messages( + @Nullable Collection msgs + ) { + this.msgs = msgs; } /** @@ -196,17 +144,6 @@ public void pendingMessagesTransferMessage(@Nullable TcpDiscoveryCollectionMessa */ public void topology(@Nullable Collection top) { this.top = top; - topBytes = null; - } - - /** @return Marshalled {@link #top}. */ - public @Nullable byte[] topologyBytes() { - return topBytes; - } - - /** @param topBytes Marshalled {@link #top}. */ - public void topologyBytes(@Nullable byte[] topBytes) { - this.topBytes = topBytes; } /** @@ -241,17 +178,6 @@ public Map> topologyHistory() { */ public void topologyHistory(@Nullable Map> topHist) { this.topHist = topHist; - topHistBytes = null; - } - - /** @return Marshalled {@link #topHist}. */ - public @Nullable byte[] topologyHistoryBytes() { - return topHistBytes; - } - - /** @param topHistBytes Marshalled {@link #topHist}. */ - public void topologyHistoryBytes(@Nullable byte[] topHistBytes) { - this.topHistBytes = topHistBytes; } /** @@ -284,83 +210,6 @@ public long gridStartTime() { return gridStartTime; } - /** @param gridStartTime First grid node start time. */ - public void gridStartTime(long gridStartTime) { - this.gridStartTime = gridStartTime; - } - - /** @param marsh marshaller. */ - @Override public void prepareMarshal(Marshaller marsh) { - if (node != null && nodeBytes == null) { - try { - nodeBytes = U.marshal(marsh, node); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal cluster node.", e); - } - } - - if (top != null && topBytes == null) { - try { - topBytes = U.marshal(marsh, top); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal topology nodes.", e); - } - } - - if (topHist != null && topHistBytes == null) { - try { - topHistBytes = U.marshal(marsh, topHist); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal topology history.", e); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - if (nodeBytes != null && node == null) { - try { - node = U.unmarshal(marsh, nodeBytes, clsLdr); - - nodeBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal cluster node.", e); - } - } - - if (topBytes != null && top == null) { - try { - top = U.unmarshal(marsh, topBytes, clsLdr); - - topBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal topology nodes.", e); - } - } - - if (topHistBytes != null && topHist == null) { - try { - topHist = U.unmarshal(marsh, topHistBytes, clsLdr); - - topHistBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal topology history.", e); - } - } - } - - - /** {@inheritDoc} */ - @Override public short directType() { - return 21; - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(TcpDiscoveryNodeAddedMessage.class, this, "super", super.toString()); From cdedd3301ec06d82f0e3760d57178d6f087b4b50 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sun, 22 Feb 2026 17:05:46 +0300 Subject: [PATCH 19/47] fix --- .../java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java | 2 -- .../java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java | 4 ---- .../tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java | 1 - 3 files changed, 7 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index e64969a909dad..ab52e9053d66b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2307,8 +2307,6 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms delayDiscoData.clear(); } - msg.finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); - locNode.setAttributes(msg.clientNodeAttributes()); clearNodeSensitiveData(locNode); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index e2f0000257d9d..0a1e87e863e48 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -2490,8 +2490,6 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); - addFinishMsg.prepareMarshal(spi.marshaller()); - msg = addFinishMsg; DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData(); @@ -4863,8 +4861,6 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { addFinishMsg.clientDiscoData(msg.gridDiscoveryData()); addFinishMsg.clientNodeAttributes(node.attributes()); - - addFinishMsg.prepareMarshal(spi.marshaller()); } addFinishMsg = tracing.messages().branch(addFinishMsg, msg); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 57d81a38662a1..2e2be449e08a4 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -129,7 +129,6 @@ public Map clientNodeAttributes() { */ public void clientNodeAttributes(Map clientNodeAttrs) { this.clientNodeAttrs = clientNodeAttrs; - clientNodeAttrsBytes = null; } /** From 4ce70317425580f148c27aacfe22c578cbf344ae Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 23 Feb 2026 11:35:12 +0300 Subject: [PATCH 20/47] fix --- .../tcp/messages/TcpDiscoveryCollectionMessage.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index a8016f8fc58d1..8085e73e18004 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.ignite.IgniteCheckedException; @@ -75,8 +76,6 @@ public TcpDiscoveryCollectionMessage(Collection msg /** {@inheritDoc} */ @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - assert marshallableMsgsBytes != null || marshallableMsgs != null || writableMsgs != null; - if (marshallableMsgsBytes != null && marshallableMsgs == null) { try { marshallableMsgs = U.unmarshal(marsh, marshallableMsgsBytes, clsLdr); @@ -118,7 +117,8 @@ public void marshallableMessagesBytes(@Nullable byte[] marshallableMsgsBytes) { * @return Pending messages from previous node. */ public Collection messages() { - assert !F.isEmpty(writableMsgs) || !F.isEmpty(marshallableMsgs); + if (F.isEmpty(writableMsgs) && F.isEmpty(marshallableMsgs)) + return Collections.emptyList(); int totalSz = (F.isEmpty(writableMsgs) ? 0 : writableMsgs.size()) + (F.isEmpty(marshallableMsgs) ? 0 : marshallableMsgs.size()); From de7eb5e3b07e90bcb979ab2b5ec66548d1777447 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 23 Feb 2026 17:51:14 +0300 Subject: [PATCH 21/47] minority --- .../tcp/messages/TcpDiscoveryClientReconnectMessage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index c801ffd5db8b6..67856eee23d0f 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -23,6 +23,7 @@ import java.util.UUID; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.plugin.extensions.communication.Message; @@ -93,7 +94,7 @@ public void lastMessageId(IgniteUuid lastMsgId) { * @param msgs Pending messages. */ public void pendingMessages(@Nullable Collection msgs) { - pendingMsgsMsg = msgs == null ? null : new TcpDiscoveryCollectionMessage(msgs); + pendingMsgsMsg = F.isEmpty(msgs) ? null : new TcpDiscoveryCollectionMessage(msgs); } /** From 6e066b9918eb8067f90cad9024ccb6efcdc51f0f Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 24 Feb 2026 11:48:30 +0300 Subject: [PATCH 22/47] merged master --- .../ignite/spi/discovery/tcp/ClientImpl.java | 16 +++-- .../ignite/spi/discovery/tcp/ServerImpl.java | 31 ++++----- .../TcpDiscoveryClientReconnectMessage.java | 63 ++--------------- .../TcpDiscoveryCollectionMessage.java | 33 ++------- .../TcpDiscoveryNodeAddFinishedMessage.java | 67 ++----------------- ...ientSlowDiscoveryTransactionRemapTest.java | 2 +- .../TcpDiscoveryCoordinatorFailureTest.java | 2 +- .../TcpDiscoveryNodeJoinAndFailureTest.java | 2 +- .../discovery/tcp/TcpDiscoverySelfTest.java | 2 +- 9 files changed, 45 insertions(+), 173 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index ab52e9053d66b..fd1cb47d2e2ae 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2293,9 +2293,9 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms } } - if (getLocalNodeId().equals(msg.nodeId())) { + if (getLocalNodeId().equals(msg.nodeId)) { if (joining()) { - DiscoveryDataPacket dataContainer = msg.clientDiscoData(); + DiscoveryDataPacket dataContainer = msg.clientDiscoData; if (dataContainer != null) spi.onExchange(dataContainer, U.resolveClassLoader(spi.ignite().configuration())); @@ -2307,7 +2307,7 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms delayDiscoData.clear(); } - locNode.setAttributes(msg.clientNodeAttributes()); + locNode.setAttributes(msg.clientNodeAttrs); clearNodeSensitiveData(locNode); @@ -2350,7 +2350,7 @@ else if (log.isDebugEnabled()) } else { if (nodeAdded()) { - TcpDiscoveryNode node = rmtNodes.get(msg.nodeId()); + TcpDiscoveryNode node = rmtNodes.get(msg.nodeId); if (node == null) { if (log.isDebugEnabled()) @@ -2543,6 +2543,10 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms return; if (getLocalNodeId().equals(msg.creatorNodeId())) { + Collection pendingMsgs = msg.pendingMsgsMsg == null + ? Collections.emptyList() + : msg.pendingMsgsMsg.messages(); + if (reconnector != null) { assert msg.success() : msg; @@ -2553,7 +2557,7 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms reconnector = null; - for (TcpDiscoveryAbstractMessage pendingMsg : msg.pendingMessages()) { + for (TcpDiscoveryAbstractMessage pendingMsg : pendingMsgs) { if (log.isDebugEnabled()) log.debug("Process pending message on reconnect [msg=" + pendingMsg + ']'); @@ -2563,7 +2567,7 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms else { if (joinLatch.getCount() > 0) { if (msg.success()) { - for (TcpDiscoveryAbstractMessage pendingMsg : msg.pendingMessages()) { + for (TcpDiscoveryAbstractMessage pendingMsg : pendingMsgs) { if (log.isDebugEnabled()) log.debug("Process pending message on connect [msg=" + pendingMsg + ']'); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 0a1e87e863e48..51254334326a6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -137,6 +137,7 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingRequest; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponse; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessage; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCollectionMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCustomEventMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryDiscardMessage; @@ -2487,12 +2488,12 @@ void add(TcpDiscoveryAbstractMessage msg) { else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - if (addFinishMsg.clientDiscoData() != null) { + if (addFinishMsg.clientDiscoData != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); msg = addFinishMsg; - DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData(); + DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData; Set mrgdCmnData = new HashSet<>(); Set mrgdSpecData = new HashSet<>(); @@ -2503,7 +2504,7 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (msg0 instanceof TcpDiscoveryNodeAddFinishedMessage) { DiscoveryDataPacket existingDiscoData = - ((TcpDiscoveryNodeAddFinishedMessage)msg0).clientDiscoData(); + ((TcpDiscoveryNodeAddFinishedMessage)msg0).clientDiscoData; if (existingDiscoData != null) allMerged = discoData.mergeDataFrom(existingDiscoData, mrgdCmnData, mrgdSpecData); @@ -2540,9 +2541,9 @@ private void clearClientAddFinished(UUID clientId) { if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - if (addFinishMsg.clientDiscoData() != null && clientId.equals(addFinishMsg.nodeId())) { - addFinishMsg.clientDiscoData(null); - addFinishMsg.clientNodeAttributes(null); + if (addFinishMsg.clientDiscoData != null && clientId.equals(addFinishMsg.nodeId)) { + addFinishMsg.clientDiscoData = null; + addFinishMsg.clientNodeAttrs = null; break; } @@ -4136,7 +4137,7 @@ private void processJoinRequestMessage(final TcpDiscoveryJoinRequestMessage msg) Collection msgs = msgHist.messages(null, node); if (msgs != null) { - reconMsg.pendingMessages(msgs); + reconMsg.pendingMsgsMsg = new TcpDiscoveryCollectionMessage(msgs); reconMsg.success(true); } @@ -4858,9 +4859,9 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { node.id()); if (node.clientRouterNodeId() != null) { - addFinishMsg.clientDiscoData(msg.gridDiscoveryData()); + addFinishMsg.clientDiscoData = msg.gridDiscoveryData(); - addFinishMsg.clientNodeAttributes(node.attributes()); + addFinishMsg.clientNodeAttrs = node.attributes(); } addFinishMsg = tracing.messages().branch(addFinishMsg, msg); @@ -5125,7 +5126,7 @@ else if (spiState == CONNECTING) private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage msg) { assert msg != null; - UUID nodeId = msg.nodeId(); + UUID nodeId = msg.nodeId; assert nodeId != null; @@ -6985,7 +6986,7 @@ else if (msg instanceof TcpDiscoveryClientReconnectMessage) { TcpDiscoveryClientReconnectMessage msg0 = (TcpDiscoveryClientReconnectMessage)msg; // If message is received from previous node and node is connecting forward to next node. - if (!getLocalNodeId().equals(msg0.routerNodeId()) && state == CONNECTING) { + if (!getLocalNodeId().equals(msg0.routerNodeId) && state == CONNECTING) { spi.writeToSocket(msg, sock, RES_OK, sockTimeout); msgWorker.addMessage(msg); @@ -7346,25 +7347,25 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms UUID locNodeId = getLocalNodeId(); - boolean isLocNodeRouter = msg.routerNodeId().equals(locNodeId); + boolean isLocNodeRouter = msg.routerNodeId.equals(locNodeId); TcpDiscoveryNode node = ring.node(nodeId); assert node == null || node.clientRouterNodeId() != null; if (node != null) { - node.clientRouterNodeId(msg.routerNodeId()); + node.clientRouterNodeId(msg.routerNodeId); node.clientAliveTime(spi.clientFailureDetectionTimeout()); } if (!msg.verified()) { if (isLocNodeRouter || isLocalNodeCoordinator()) { if (node != null) { - Collection pending = msgHist.messages(msg.lastMessageId(), node); + Collection pending = msgHist.messages(msg.lastMsgId, node); if (pending != null) { msg.verifierNodeId(locNodeId); - msg.pendingMessages(pending); + msg.pendingMsgsMsg = new TcpDiscoveryCollectionMessage(pending); msg.success(true); if (log.isDebugEnabled()) { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 67856eee23d0f..14f1f7d20f15f 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -17,13 +17,10 @@ package org.apache.ignite.spi.discovery.tcp.messages; -import java.util.Collection; -import java.util.Collections; import java.util.Objects; import java.util.UUID; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; -import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.plugin.extensions.communication.Message; @@ -38,16 +35,16 @@ public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMess private static final long serialVersionUID = 0L; /** New router nodeID. */ - @Order(value = 5, method = "routerNodeId") - private UUID routerNodeId; + @Order(value = 5) + public UUID routerNodeId; /** Last message ID. */ - @Order(value = 6, method = "lastMessageId") - private IgniteUuid lastMsgId; + @Order(6) + public IgniteUuid lastMsgId; /** Pending messages holder. */ - @Order(value = 7, method = "pendingMessagesTransferMessage") - @Nullable private volatile TcpDiscoveryCollectionMessage pendingMsgsMsg; + @Order(7) + @Nullable public volatile TcpDiscoveryCollectionMessage pendingMsgsMsg; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryClientReconnectMessage() { @@ -66,54 +63,6 @@ public TcpDiscoveryClientReconnectMessage(UUID creatorNodeId, UUID routerNodeId, this.lastMsgId = lastMsgId; } - /** - * @return New router node ID. - */ - public UUID routerNodeId() { - return routerNodeId; - } - - /** @param routerNodeId New router node ID. */ - public void routerNodeId(UUID routerNodeId) { - this.routerNodeId = routerNodeId; - } - - /** - * @return Last message ID. - */ - public IgniteUuid lastMessageId() { - return lastMsgId; - } - - /** @param lastMsgId Last message ID. */ - public void lastMessageId(IgniteUuid lastMsgId) { - this.lastMsgId = lastMsgId; - } - - /** - * @param msgs Pending messages. - */ - public void pendingMessages(@Nullable Collection msgs) { - pendingMsgsMsg = F.isEmpty(msgs) ? null : new TcpDiscoveryCollectionMessage(msgs); - } - - /** - * @return Pending messages. - */ - public Collection pendingMessages() { - return pendingMsgsMsg == null ? Collections.emptyList() : pendingMsgsMsg.messages(); - } - - /** @return Message to transfer the pending messages. */ - public @Nullable TcpDiscoveryCollectionMessage pendingMessagesTransferMessage() { - return pendingMsgsMsg; - } - - /** @param pendingMsgsMsg Message to transfer the pending messages. */ - public void pendingMessagesTransferMessage(@Nullable TcpDiscoveryCollectionMessage pendingMsgsMsg) { - this.pendingMsgsMsg = pendingMsgsMsg; - } - /** * @param success Success flag. */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index 8085e73e18004..7b0763660177f 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -41,16 +41,16 @@ */ public class TcpDiscoveryCollectionMessage implements TcpDiscoveryMarshallableMessage { /** {@link TcpDiscoveryAbstractMessage} pending messages which are a {@link Message}. */ - @Order(value = 0, method = "writableMessages") - @Nullable private Map writableMsgs; + @Order(0) + @Nullable Map writableMsgs; /** Marshallable or Java-serializable pending messages which are not a {@link Message}. */ - @Nullable private Map marshallableMsgs; + @Nullable Map marshallableMsgs; /** Marshalled {@link #marshallableMsgs}. */ - @Order(value = 1, method = "marshallableMessagesBytes") + @Order(1) @GridToStringExclude - @Nullable private byte[] marshallableMsgsBytes; + @Nullable byte[] marshallableMsgsBytes; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryCollectionMessage() { @@ -88,29 +88,6 @@ public TcpDiscoveryCollectionMessage(Collection msg } } - /** - * @return Writable messages by their order. - * @see #messages() - */ - public @Nullable Map writableMessages() { - return writableMsgs; - } - - /** @param msgs Writable messages by their order. */ - public void writableMessages(@Nullable Map msgs) { - writableMsgs = msgs; - } - - /** @return Bytes of {@link #marshallableMsgs}. */ - public @Nullable byte[] marshallableMessagesBytes() { - return marshallableMsgsBytes; - } - - /** @param marshallableMsgsBytes Bytes of {@link #marshallableMsgs}. */ - public void marshallableMessagesBytes(@Nullable byte[] marshallableMsgsBytes) { - this.marshallableMsgsBytes = marshallableMsgsBytes; - } - /** * Gets pending messages sent to new node by its previous. * diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 2e2be449e08a4..2c811d7070575 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -40,18 +40,19 @@ public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTrac /** Added node ID. */ @Order(6) - UUID nodeId; + public UUID nodeId; /** * Client node can not get discovery data from TcpDiscoveryNodeAddedMessage, we have to pass discovery data in * TcpDiscoveryNodeAddFinishedMessage. */ @Order(7) - @GridToStringExclude DiscoveryDataPacket clientDiscoData; + @GridToStringExclude + public DiscoveryDataPacket clientDiscoData; /** */ @GridToStringExclude - private Map clientNodeAttrs; + public Map clientNodeAttrs; /** Serialized client node attributes. */ @Order(8) @@ -85,66 +86,6 @@ public TcpDiscoveryNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage msg clientNodeAttrs = msg.clientNodeAttrs; } - /** - * Gets ID of the node added. - * - * @return ID of the node added. - */ - public UUID nodeId() { - return nodeId; - } - - /** - * @param nodeId ID of the node added. - */ - public void nodeId(UUID nodeId) { - this.nodeId = nodeId; - } - - /** - * @return Discovery data for joined client. - */ - public DiscoveryDataPacket clientDiscoData() { - return clientDiscoData; - } - - /** - * @param clientDiscoData Discovery data for joined client. - */ - public void clientDiscoData(DiscoveryDataPacket clientDiscoData) { - this.clientDiscoData = clientDiscoData; - - assert clientDiscoData == null || !clientDiscoData.hasDataFromNode(nodeId); - } - - /** - * @return Client node attributes. - */ - public Map clientNodeAttributes() { - return clientNodeAttrs; - } - - /** - * @param clientNodeAttrs New client node attributes. - */ - public void clientNodeAttributes(Map clientNodeAttrs) { - this.clientNodeAttrs = clientNodeAttrs; - } - - /** - * @return Serialized client node attributes. - */ - public @Nullable byte[] clientNodeAttributesBytes() { - return clientNodeAttrsBytes; - } - - /** - * @param clientNodeAttrsBytes Serialized client node attributes. - */ - public void clientNodeAttributesBytes(@Nullable byte[] clientNodeAttrsBytes) { - this.clientNodeAttrsBytes = clientNodeAttrsBytes; - } - /** {@inheritDoc} */ @Override public void prepareMarshal(Marshaller marsh) { if (clientNodeAttrs != null && clientNodeAttrsBytes == null) { diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java index d408333bc9152..cd5450583f8ec 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java @@ -377,7 +377,7 @@ public void before() throws Exception { // Delay node join of second client. clientDiscoSpi.interceptor = msg -> { - if (msg.nodeId().toString().endsWith("2")) + if (msg.nodeId.toString().endsWith("2")) U.awaitQuiet(clientDiscoSpiBlock); }; diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java index 479cee26f6627..09870d8096882 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java @@ -341,7 +341,7 @@ private boolean isDrop(TcpDiscoveryAbstractMessage msg) { if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage finishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - if ((finishMsg.nodeId().getLeastSignificantBits() & 0xFFFF) == dropNodeIdx) { + if ((finishMsg.nodeId.getLeastSignificantBits() & 0xFFFF) == dropNodeIdx) { drop = true; dropLatch.countDown(); diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java index f449be13c8e85..1541483b16ecd 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java @@ -163,7 +163,7 @@ Test reproduces the needed behavior (two nodes in CONNECTING state) doing the fo if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage finishedMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - UUID nodeId = finishedMsg.nodeId(); + UUID nodeId = finishedMsg.nodeId; if (nodeId.equals(node2Id)) { Object workerObj = GridTestUtils.getFieldValue(impl, "msgWorker"); diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java index 999c7c747c35e..9019e69268ad7 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java @@ -2525,7 +2525,7 @@ private static class TestDiscoveryDataDuplicateSpi extends TcpDiscoverySpi { } } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { - DiscoveryDataPacket dataPacket = ((TcpDiscoveryNodeAddFinishedMessage)msg).clientDiscoData(); + DiscoveryDataPacket dataPacket = ((TcpDiscoveryNodeAddFinishedMessage)msg).clientDiscoData; if (dataPacket != null) { Map discoData = U.field(dataPacket, "nodeSpecificData"); From 6e2ec6e846f240d1fc3fdd3ddac0c610e0dad434 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 24 Feb 2026 16:41:10 +0300 Subject: [PATCH 23/47] + master --- .../ignite/spi/discovery/tcp/ClientImpl.java | 2 -- .../ignite/spi/discovery/tcp/ServerImpl.java | 5 ----- .../TcpDiscoveryClientReconnectMessage.java | 2 +- .../messages/TcpDiscoveryJoinRequestMessage.java | 16 +++++----------- 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 917ac09d82c56..fd1cb47d2e2ae 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -787,8 +787,6 @@ private static void sleepEx(long millis, Runnable before, Runnable after) throws TcpDiscoveryJoinRequestMessage joinReqMsg = new TcpDiscoveryJoinRequestMessage(node, discoveryData); - joinReqMsg.prepareMarshal(spi.marshaller()); - TcpDiscoveryNode nodef = node; joinReqMsg.spanContainer().span( diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index c18106a080fba..bca07c44b6c80 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -1124,8 +1124,6 @@ private void joinTopology() throws IgniteSpiException { TcpDiscoveryJoinRequestMessage joinReqMsg = new TcpDiscoveryJoinRequestMessage(locNode, discoveryData); - joinReqMsg.prepareMarshal(spi.marshaller()); - joinReqMsg.spanContainer().span( tracing.create(TraceableMessagesTable.traceName(joinReqMsg.getClass())) .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.ID), () -> locNode.id().toString()) @@ -3306,9 +3304,6 @@ private void sendMessageAcrossRing(TcpDiscoveryAbstractMessage msg) { if (msg instanceof TraceableMessage) tracing.messages().beforeSend((TraceableMessage)msg); - if (msg instanceof TcpDiscoveryJoinRequestMessage) - ((TcpDiscoveryJoinRequestMessage)msg).prepareMarshal(spi.marshaller()); - sendMessageToClients(msg); List failedNodes; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 14f1f7d20f15f..0344dffaecbf9 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -94,7 +94,7 @@ public boolean success() { /** {@inheritDoc} */ @Override public short directType() { - return 20; + return 21; } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java index 33b46585b432c..7c00c39c53a8f 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java @@ -23,7 +23,6 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; @@ -33,7 +32,7 @@ * Initial message sent by a node that wants to enter topology. * Sent to random node during SPI start. Then forwarded directly to coordinator. */ -public class TcpDiscoveryJoinRequestMessage extends TcpDiscoveryAbstractTraceableMessage implements Message { +public class TcpDiscoveryJoinRequestMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { /** */ private static final long serialVersionUID = 0L; @@ -95,10 +94,8 @@ public void responded(boolean responded) { setFlag(RESPONDED_FLAG_POS, responded); } - /** - * @param marsh Marshaller. - */ - public void prepareMarshal(Marshaller marsh) { + /** {@inheritDoc} */ + @Override public void prepareMarshal(Marshaller marsh) { if (node != null && nodeBytes == null) { try { nodeBytes = U.marshal(marsh, node); @@ -109,11 +106,8 @@ public void prepareMarshal(Marshaller marsh) { } } - /** - * @param marsh Marshaller. - * @param clsLdr Class loader. - */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { if (nodeBytes != null && node == null) { try { node = U.unmarshal(marsh, nodeBytes, clsLdr); From 226df11c9f61f5e8128f6045b8f0248904e645ac Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 25 Feb 2026 20:28:19 +0300 Subject: [PATCH 24/47] - Review fix --- .../ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java index f9b54349f2cd2..e6303ee4f0d7b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java @@ -500,7 +500,6 @@ public void clear() { */ @Nullable public TcpDiscoveryNode nextNode(@Nullable Collection excluded) { assert locNode.internalOrder() > 0 : locNode; - // TODO: May fire, https://issues.apache.org/jira/browse/IGNITE-27933 assert excluded == null || excluded.isEmpty() || !excluded.contains(locNode) : excluded; rwLock.readLock().lock(); From 66a1dc16e9b739cd471d2e6304b90bb55c78c555 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 25 Feb 2026 21:02:44 +0300 Subject: [PATCH 25/47] Revert refactoring --- .../internal/direct/DirectMessageReader.java | 29 +++------------ .../internal/direct/DirectMessageWriter.java | 24 ++++--------- .../direct/stream/DirectByteBufferStream.java | 36 +++++-------------- .../discovery/DiscoveryMessageFactory.java | 1 - .../discovery/tcp/TcpDiscoveryIoSession.java | 30 +++++++++++----- .../TcpDiscoveryClientReconnectMessage.java | 2 +- 6 files changed, 41 insertions(+), 81 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java index 0b08ffae60146..24d97da7b2de5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.function.Consumer; import org.apache.ignite.internal.direct.state.DirectMessageState; import org.apache.ignite.internal.direct.state.DirectMessageStateItem; import org.apache.ignite.internal.direct.stream.DirectByteBufferStream; @@ -60,23 +59,10 @@ public class DirectMessageReader implements MessageReader { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public DirectMessageReader(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { - this(msgFactory, cacheObjProc, null); - } - - /** - * @param msgFactory Message factory. - * @param cacheObjProc Cache object processor. - * @param msgPostSerializer Optional message processor to call after the serialization. - */ - public DirectMessageReader( - final MessageFactory msgFactory, - IgniteCacheObjectProcessor cacheObjProc, - @Nullable Consumer msgPostSerializer - ) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { + public DirectMessageReader(final MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { @Override public StateItem apply() { - return new StateItem(msgFactory, cacheObjProc, msgPostSerializer); + return new StateItem(msgFactory, cacheObjProc); } }); } @@ -466,14 +452,9 @@ private static class StateItem implements DirectMessageStateItem { /** * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. - * @param msgPostReader Optional message post-reader. */ - public StateItem( - MessageFactory msgFactory, - IgniteCacheObjectProcessor cacheObjProc, - @Nullable Consumer msgPostReader - ) { - stream = new DirectByteBufferStream(msgFactory, cacheObjProc, msgPostReader, null); + public StateItem(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + stream = new DirectByteBufferStream(msgFactory, cacheObjProc); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java index 681e03738a221..1da76aa14cfe7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.function.Consumer; import org.apache.ignite.internal.direct.state.DirectMessageState; import org.apache.ignite.internal.direct.state.DirectMessageStateItem; import org.apache.ignite.internal.direct.stream.DirectByteBufferStream; @@ -53,18 +52,10 @@ public class DirectMessageWriter implements MessageWriter { private ByteBuffer buf; /** */ - public DirectMessageWriter(MessageFactory msgFactory) { - this(msgFactory, null); - } - - /** - * @param msgFactory Message factory. - * @param msgPreSerializer Optional message pre-writer. - */ - public DirectMessageWriter(MessageFactory msgFactory, @Nullable Consumer msgPreSerializer) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { + public DirectMessageWriter(final MessageFactory msgFactory) { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { @Override public StateItem apply() { - return new StateItem(msgFactory, msgPreSerializer); + return new StateItem(msgFactory); } }); } @@ -424,12 +415,9 @@ private static class StateItem implements DirectMessageStateItem { /** */ private boolean hdrWritten; - /** - * @param msgFactory Message Factory. - * @param msgPreWriter Optional message pre-writer. - */ - public StateItem(MessageFactory msgFactory, @Nullable Consumer msgPreWriter) { - stream = new DirectByteBufferStream(msgFactory, null, null, msgPreWriter); + /** */ + public StateItem(MessageFactory msgFactory) { + stream = new DirectByteBufferStream(msgFactory); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java index 53f1797264003..5c526bf6fd3b4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java @@ -29,7 +29,6 @@ import java.util.RandomAccess; import java.util.Set; import java.util.UUID; -import java.util.function.Consumer; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; @@ -223,13 +222,7 @@ public class DirectByteBufferStream { /** Is required to instantiate {@link CacheObject} while reading messages. */ @GridToStringExclude - @Nullable private final IgniteCacheObjectProcessor cacheObjProc; - - /** Optional message post-reader. */ - @Nullable private final Consumer msgPostReader; - - /** Optional message pre-writer. */ - @Nullable private final Consumer msgPreWriter; + private final IgniteCacheObjectProcessor cacheObjProc; /** */ @GridToStringExclude @@ -352,27 +345,21 @@ public class DirectByteBufferStream { * @param msgFactory Message factory. */ public DirectByteBufferStream(MessageFactory msgFactory) { - this(msgFactory, null, null, null); + this.msgFactory = msgFactory; + + // Is not used while writing messages. + cacheObjProc = null; } /** * Constructror for stream used for reading messages. * * @param msgFactory Message factory. - * @param cacheObjProc Optional cache object processor. - * @param msgPostReader Optional message post-reader. - * @param msgPreWriter Optional message pre-writer. - */ - public DirectByteBufferStream( - MessageFactory msgFactory, - @Nullable IgniteCacheObjectProcessor cacheObjProc, - @Nullable Consumer msgPostReader, - @Nullable Consumer msgPreWriter - ) { + * @param cacheObjProc Cache object processor. + */ + public DirectByteBufferStream(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { this.msgFactory = msgFactory; this.cacheObjProc = cacheObjProc; - this.msgPostReader = msgPostReader; - this.msgPreWriter = msgPreWriter; } /** @@ -899,10 +886,6 @@ public void writeMessage(Message msg, MessageWriter writer) { try { writer.beforeInnerMessageWrite(); - // Repeatable call. Current limitation. - if (msgPreWriter != null) - msgPreWriter.accept(msg); - lastFinished = msgFactory.serializer(msg.directType()).writeTo(msg, writer); } finally { @@ -1570,9 +1553,6 @@ public T readMessage(MessageReader reader) { msgTypeDone = false; msg = null; - if (msgPostReader != null) - msgPostReader.accept(msg0); - return (T)msg0; } else diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 4e5d4be10e659..73f19942092ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -119,6 +119,5 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { factory.register((short)19, TcpDiscoveryNodeAddFinishedMessage::new, new TcpDiscoveryNodeAddFinishedMessageSerializer()); factory.register((short)20, TcpDiscoveryJoinRequestMessage::new, new TcpDiscoveryJoinRequestMessageSerializer()); factory.register((short)21, TcpDiscoveryClientReconnectMessage::new, new TcpDiscoveryClientReconnectMessageSerializer()); - } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index 3b3508fdb1c96..8ca92b3980d5e 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -109,16 +109,28 @@ public class TcpDiscoveryIoSession { msgBuf = ByteBuffer.allocate(MSG_BUFFER_SIZE); - msgWriter = new DirectMessageWriter(spi.messageFactory(), msg -> { - if (msg instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); - }); - msgReader = new DirectMessageReader(spi.messageFactory(), null, msg -> { - if (msg instanceof TcpDiscoveryMarshallableMessage) { - ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), - U.resolveClassLoader(spi.ignite().configuration())); + msgWriter = new DirectMessageWriter(spi.messageFactory()) { + @Override public boolean writeMessage(@Nullable Message msg) { + // Repeatable calls. Current limitation. + if (msg instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); + + return super.writeMessage(msg); + } + }; + + msgReader = new DirectMessageReader(spi.messageFactory(), null){ + @Override public @Nullable T readMessage() { + T m = super.readMessage(); + + if (isLastRead() && m instanceof TcpDiscoveryMarshallableMessage) { + ((TcpDiscoveryMarshallableMessage)m).finishUnmarshal(spi.marshaller(), + U.resolveClassLoader(spi.ignite().configuration())); + } + + return m; } - }); + }; try { int sendBufSize = sock.getSendBufferSize() > 0 ? sock.getSendBufferSize() : DFLT_SOCK_BUFFER_SIZE; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 0344dffaecbf9..45036c2283838 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -44,7 +44,7 @@ public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMess /** Pending messages holder. */ @Order(7) - @Nullable public volatile TcpDiscoveryCollectionMessage pendingMsgsMsg; + @Nullable public TcpDiscoveryCollectionMessage pendingMsgsMsg; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryClientReconnectMessage() { From 21cf4ac8c4a73c115086db9876348e4d1dfce7c1 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 25 Feb 2026 21:02:44 +0300 Subject: [PATCH 26/47] Revert refactoring --- .../internal/direct/DirectMessageReader.java | 29 +++------------ .../internal/direct/DirectMessageWriter.java | 24 ++++--------- .../direct/stream/DirectByteBufferStream.java | 36 +++++-------------- .../discovery/DiscoveryMessageFactory.java | 1 - .../discovery/tcp/TcpDiscoveryIoSession.java | 30 +++++++++++----- .../TcpDiscoveryClientReconnectMessage.java | 2 +- 6 files changed, 41 insertions(+), 81 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java index 0b08ffae60146..24d97da7b2de5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.function.Consumer; import org.apache.ignite.internal.direct.state.DirectMessageState; import org.apache.ignite.internal.direct.state.DirectMessageStateItem; import org.apache.ignite.internal.direct.stream.DirectByteBufferStream; @@ -60,23 +59,10 @@ public class DirectMessageReader implements MessageReader { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public DirectMessageReader(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { - this(msgFactory, cacheObjProc, null); - } - - /** - * @param msgFactory Message factory. - * @param cacheObjProc Cache object processor. - * @param msgPostSerializer Optional message processor to call after the serialization. - */ - public DirectMessageReader( - final MessageFactory msgFactory, - IgniteCacheObjectProcessor cacheObjProc, - @Nullable Consumer msgPostSerializer - ) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { + public DirectMessageReader(final MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { @Override public StateItem apply() { - return new StateItem(msgFactory, cacheObjProc, msgPostSerializer); + return new StateItem(msgFactory, cacheObjProc); } }); } @@ -466,14 +452,9 @@ private static class StateItem implements DirectMessageStateItem { /** * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. - * @param msgPostReader Optional message post-reader. */ - public StateItem( - MessageFactory msgFactory, - IgniteCacheObjectProcessor cacheObjProc, - @Nullable Consumer msgPostReader - ) { - stream = new DirectByteBufferStream(msgFactory, cacheObjProc, msgPostReader, null); + public StateItem(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + stream = new DirectByteBufferStream(msgFactory, cacheObjProc); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java index 681e03738a221..1da76aa14cfe7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.function.Consumer; import org.apache.ignite.internal.direct.state.DirectMessageState; import org.apache.ignite.internal.direct.state.DirectMessageStateItem; import org.apache.ignite.internal.direct.stream.DirectByteBufferStream; @@ -53,18 +52,10 @@ public class DirectMessageWriter implements MessageWriter { private ByteBuffer buf; /** */ - public DirectMessageWriter(MessageFactory msgFactory) { - this(msgFactory, null); - } - - /** - * @param msgFactory Message factory. - * @param msgPreSerializer Optional message pre-writer. - */ - public DirectMessageWriter(MessageFactory msgFactory, @Nullable Consumer msgPreSerializer) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { + public DirectMessageWriter(final MessageFactory msgFactory) { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { @Override public StateItem apply() { - return new StateItem(msgFactory, msgPreSerializer); + return new StateItem(msgFactory); } }); } @@ -424,12 +415,9 @@ private static class StateItem implements DirectMessageStateItem { /** */ private boolean hdrWritten; - /** - * @param msgFactory Message Factory. - * @param msgPreWriter Optional message pre-writer. - */ - public StateItem(MessageFactory msgFactory, @Nullable Consumer msgPreWriter) { - stream = new DirectByteBufferStream(msgFactory, null, null, msgPreWriter); + /** */ + public StateItem(MessageFactory msgFactory) { + stream = new DirectByteBufferStream(msgFactory); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java index 53f1797264003..5c526bf6fd3b4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java @@ -29,7 +29,6 @@ import java.util.RandomAccess; import java.util.Set; import java.util.UUID; -import java.util.function.Consumer; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; @@ -223,13 +222,7 @@ public class DirectByteBufferStream { /** Is required to instantiate {@link CacheObject} while reading messages. */ @GridToStringExclude - @Nullable private final IgniteCacheObjectProcessor cacheObjProc; - - /** Optional message post-reader. */ - @Nullable private final Consumer msgPostReader; - - /** Optional message pre-writer. */ - @Nullable private final Consumer msgPreWriter; + private final IgniteCacheObjectProcessor cacheObjProc; /** */ @GridToStringExclude @@ -352,27 +345,21 @@ public class DirectByteBufferStream { * @param msgFactory Message factory. */ public DirectByteBufferStream(MessageFactory msgFactory) { - this(msgFactory, null, null, null); + this.msgFactory = msgFactory; + + // Is not used while writing messages. + cacheObjProc = null; } /** * Constructror for stream used for reading messages. * * @param msgFactory Message factory. - * @param cacheObjProc Optional cache object processor. - * @param msgPostReader Optional message post-reader. - * @param msgPreWriter Optional message pre-writer. - */ - public DirectByteBufferStream( - MessageFactory msgFactory, - @Nullable IgniteCacheObjectProcessor cacheObjProc, - @Nullable Consumer msgPostReader, - @Nullable Consumer msgPreWriter - ) { + * @param cacheObjProc Cache object processor. + */ + public DirectByteBufferStream(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { this.msgFactory = msgFactory; this.cacheObjProc = cacheObjProc; - this.msgPostReader = msgPostReader; - this.msgPreWriter = msgPreWriter; } /** @@ -899,10 +886,6 @@ public void writeMessage(Message msg, MessageWriter writer) { try { writer.beforeInnerMessageWrite(); - // Repeatable call. Current limitation. - if (msgPreWriter != null) - msgPreWriter.accept(msg); - lastFinished = msgFactory.serializer(msg.directType()).writeTo(msg, writer); } finally { @@ -1570,9 +1553,6 @@ public T readMessage(MessageReader reader) { msgTypeDone = false; msg = null; - if (msgPostReader != null) - msgPostReader.accept(msg0); - return (T)msg0; } else diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 4e5d4be10e659..73f19942092ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -119,6 +119,5 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { factory.register((short)19, TcpDiscoveryNodeAddFinishedMessage::new, new TcpDiscoveryNodeAddFinishedMessageSerializer()); factory.register((short)20, TcpDiscoveryJoinRequestMessage::new, new TcpDiscoveryJoinRequestMessageSerializer()); factory.register((short)21, TcpDiscoveryClientReconnectMessage::new, new TcpDiscoveryClientReconnectMessageSerializer()); - } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index 3b3508fdb1c96..a855907658a2b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -109,16 +109,28 @@ public class TcpDiscoveryIoSession { msgBuf = ByteBuffer.allocate(MSG_BUFFER_SIZE); - msgWriter = new DirectMessageWriter(spi.messageFactory(), msg -> { - if (msg instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); - }); - msgReader = new DirectMessageReader(spi.messageFactory(), null, msg -> { - if (msg instanceof TcpDiscoveryMarshallableMessage) { - ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), - U.resolveClassLoader(spi.ignite().configuration())); + msgWriter = new DirectMessageWriter(spi.messageFactory()) { + @Override public boolean writeMessage(@Nullable Message msg) { + // Repeatable calls. Current limitation. + if (msg instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); + + return super.writeMessage(msg); + } + }; + + msgReader = new DirectMessageReader(spi.messageFactory(), null) { + @Override public @Nullable T readMessage() { + T m = super.readMessage(); + + if (isLastRead() && m instanceof TcpDiscoveryMarshallableMessage) { + ((TcpDiscoveryMarshallableMessage)m).finishUnmarshal(spi.marshaller(), + U.resolveClassLoader(spi.ignite().configuration())); + } + + return m; } - }); + }; try { int sendBufSize = sock.getSendBufferSize() > 0 ? sock.getSendBufferSize() : DFLT_SOCK_BUFFER_SIZE; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 0344dffaecbf9..45036c2283838 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -44,7 +44,7 @@ public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMess /** Pending messages holder. */ @Order(7) - @Nullable public volatile TcpDiscoveryCollectionMessage pendingMsgsMsg; + @Nullable public TcpDiscoveryCollectionMessage pendingMsgsMsg; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryClientReconnectMessage() { From 13aa4d4aa2e46640d68c3e53771d73e1d9be13fd Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 26 Feb 2026 19:10:26 +0300 Subject: [PATCH 27/47] minority --- .../ignite/spi/discovery/tcp/ClientImpl.java | 2 +- .../ignite/spi/discovery/tcp/ServerImpl.java | 4 ++-- .../TcpDiscoveryCollectionMessage.java | 8 +++----- .../TcpDiscoveryNodeAddFinishedMessage.java | 20 ++++++++++++++++++- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index d8e6e8b0f6b6d..1fe8b53eb0e40 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2308,7 +2308,7 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms delayDiscoData.clear(); } - locNode.setAttributes(msg.clientNodeAttrs); + locNode.setAttributes(msg.clientNodeAttributes()); clearNodeSensitiveData(locNode); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index b9e5367456c95..8e6fa80082c44 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -2544,7 +2544,7 @@ private void clearClientAddFinished(UUID clientId) { if (addFinishMsg.clientDiscoData != null && clientId.equals(addFinishMsg.nodeId)) { addFinishMsg.clientDiscoData = null; - addFinishMsg.clientNodeAttrs = null; + addFinishMsg.clientNodeAttributes(null); break; } @@ -4862,7 +4862,7 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { if (node.clientRouterNodeId() != null) { addFinishMsg.clientDiscoData = msg.gridDiscoveryData(); - addFinishMsg.clientNodeAttrs = node.attributes(); + addFinishMsg.clientNodeAttributes(node.attributes()); } addFinishMsg = tracing.messages().branch(addFinishMsg, msg); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index 7b0763660177f..917b3fbeba90a 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -129,14 +129,12 @@ public Collection messages() { * @param msgs Pending messages to send to new node. */ public void messages(@Nullable Collection msgs) { + writableMsgs = null; marshallableMsgsBytes = null; + marshallableMsgs = null; - if (F.isEmpty(msgs)) { - marshallableMsgs = null; - writableMsgs = null; - + if (F.isEmpty(msgs)) return; - } // Keeps the original message order. int idx = 0; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 2c811d7070575..532c44b9bdfd4 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -23,6 +23,7 @@ import org.apache.ignite.IgniteException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; @@ -52,7 +53,7 @@ public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTrac /** */ @GridToStringExclude - public Map clientNodeAttrs; + Map clientNodeAttrs; /** Serialized client node attributes. */ @Order(8) @@ -84,6 +85,23 @@ public TcpDiscoveryNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage msg nodeId = msg.nodeId; clientDiscoData = msg.clientDiscoData; clientNodeAttrs = msg.clientNodeAttrs; + clientNodeAttrsBytes = msg.clientNodeAttrsBytes; + } + + /** + * Sets new client attributes and ensures that thet will be serialized. + * + * @param attrs Client attributes. + */ + public void clientNodeAttributes(@Nullable Map attrs) { + clientNodeAttrs = F.isEmpty(attrs) ? null : attrs; + // Ensure new data will be serialized. + clientNodeAttrsBytes = null; + } + + /** @return Client attributes. */ + public @Nullable Map clientNodeAttributes() { + return clientNodeAttrs; } /** {@inheritDoc} */ From 579d25755d3534550fed45edc3a615bacd9c6610 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 26 Feb 2026 20:54:02 +0300 Subject: [PATCH 28/47] reimpl --- .../internal/direct/DirectMessageReader.java | 6 +- .../internal/direct/DirectMessageWriter.java | 2 +- .../direct/stream/DirectByteBufferStream.java | 9 +- .../discovery/tcp/TcpDiscoveryIoSession.java | 91 ++++++++++++++----- 4 files changed, 74 insertions(+), 34 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java index 24d97da7b2de5..8acb504aed6a4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java @@ -59,8 +59,8 @@ public class DirectMessageReader implements MessageReader { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public DirectMessageReader(final MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { + public DirectMessageReader(final MessageFactory msgFactory, @Nullable IgniteCacheObjectProcessor cacheObjProc) { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { @Override public StateItem apply() { return new StateItem(msgFactory, cacheObjProc); } @@ -453,7 +453,7 @@ private static class StateItem implements DirectMessageStateItem { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public StateItem(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + public StateItem(MessageFactory msgFactory, @Nullable IgniteCacheObjectProcessor cacheObjProc) { stream = new DirectByteBufferStream(msgFactory, cacheObjProc); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java index 1da76aa14cfe7..2e0ae035acd9c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java @@ -53,7 +53,7 @@ public class DirectMessageWriter implements MessageWriter { /** */ public DirectMessageWriter(final MessageFactory msgFactory) { - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { @Override public StateItem apply() { return new StateItem(msgFactory); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java index 5c526bf6fd3b4..7f3dcf8d0655c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java @@ -222,7 +222,7 @@ public class DirectByteBufferStream { /** Is required to instantiate {@link CacheObject} while reading messages. */ @GridToStringExclude - private final IgniteCacheObjectProcessor cacheObjProc; + private final @Nullable IgniteCacheObjectProcessor cacheObjProc; /** */ @GridToStringExclude @@ -345,10 +345,7 @@ public class DirectByteBufferStream { * @param msgFactory Message factory. */ public DirectByteBufferStream(MessageFactory msgFactory) { - this.msgFactory = msgFactory; - - // Is not used while writing messages. - cacheObjProc = null; + this(msgFactory, null); } /** @@ -357,7 +354,7 @@ public DirectByteBufferStream(MessageFactory msgFactory) { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public DirectByteBufferStream(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { + public DirectByteBufferStream(MessageFactory msgFactory, @Nullable IgniteCacheObjectProcessor cacheObjProc) { this.msgFactory = msgFactory; this.cacheObjProc = cacheObjProc; } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index a855907658a2b..80b8fac7c92d8 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -28,6 +28,7 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.security.cert.Certificate; +import java.util.function.Supplier; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSocket; import org.apache.ignite.IgniteCheckedException; @@ -37,7 +38,10 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.jdk.JdkMarshaller; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageFactory; +import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.jetbrains.annotations.NotNull; @@ -94,6 +98,9 @@ public class TcpDiscoveryIoSession { /** Intermediate buffer for serializing discovery messages. */ final ByteBuffer msgBuf; + /** */ + final MessageFactory msgFactory; + /** * Creates a new discovery I/O session bound to the given socket. * @@ -109,28 +116,10 @@ public class TcpDiscoveryIoSession { msgBuf = ByteBuffer.allocate(MSG_BUFFER_SIZE); - msgWriter = new DirectMessageWriter(spi.messageFactory()) { - @Override public boolean writeMessage(@Nullable Message msg) { - // Repeatable calls. Current limitation. - if (msg instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); - - return super.writeMessage(msg); - } - }; - - msgReader = new DirectMessageReader(spi.messageFactory(), null) { - @Override public @Nullable T readMessage() { - T m = super.readMessage(); - - if (isLastRead() && m instanceof TcpDiscoveryMarshallableMessage) { - ((TcpDiscoveryMarshallableMessage)m).finishUnmarshal(spi.marshaller(), - U.resolveClassLoader(spi.ignite().configuration())); - } + msgFactory = enhanceMessageFactory(spi.messageFactory()); - return m; - } - }; + msgWriter = new DirectMessageWriter(msgFactory); + msgReader = new DirectMessageReader(msgFactory, null); try { int sendBufSize = sock.getSendBufferSize() > 0 ? sock.getSendBufferSize() : DFLT_SOCK_BUFFER_SIZE; @@ -144,6 +133,60 @@ public class TcpDiscoveryIoSession { } } + /** + * @return Enhanced {@link MessageFactory} allowing to pre-marshall and post-unmarshall {@link TcpDiscoveryMarshallableMessage}. + */ + private MessageFactory enhanceMessageFactory(MessageFactory mf) { + assert clsLdr != null; + + return new MessageFactory() { + @Override public void register(short directType, Supplier supplier) throws IgniteException { + mf.register(directType, supplier); + } + + @Override public void register(short directType, Supplier supplier, + MessageSerializer serializer) throws IgniteException { + mf.register(directType, supplier, serializer); + } + + @Override public Message create(short type) { + return mf.create(type); + } + + @Override public MessageSerializer serializer(short type) { + MessageSerializer serializer = mf.serializer(type); + + return new MessageSerializer() { + private Message curMarshallableMsg; + + @Override public boolean writeTo(Message msg, MessageWriter writer) { + if (msg instanceof TcpDiscoveryMarshallableMessage && curMarshallableMsg == null) { + curMarshallableMsg = msg; + + ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); + } + + boolean res = serializer.writeTo(msg, writer); + + if (res && curMarshallableMsg != null) + curMarshallableMsg = null; + + return res; + } + + @Override public boolean readFrom(Message msg, MessageReader reader) { + boolean res = serializer.readFrom(msg, reader); + + if (res && msg instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), clsLdr); + + return res; + } + }; + } + }; + } + /** * Writes a discovery message to the underlying socket output stream. * @@ -197,12 +240,12 @@ T readMessage() throws IgniteCheckedException, IOException { throw new IOException("Received unexpected byte while reading discovery message: " + serMode); } - Message msg = spi.messageFactory().create(makeMessageType((byte)in.read(), (byte)in.read())); + Message msg = msgFactory.create(makeMessageType((byte)in.read(), (byte)in.read())); msgReader.reset(); msgReader.setBuffer(msgBuf); - MessageSerializer msgSer = spi.messageFactory().serializer(msg.directType()); + MessageSerializer msgSer = msgFactory.serializer(msg.directType()); boolean finished; @@ -277,7 +320,7 @@ void serializeMessage(Message m, OutputStream out) throws IOException { if (m instanceof TcpDiscoveryMarshallableMessage) ((TcpDiscoveryMarshallableMessage)m).prepareMarshal(spi.marshaller()); - MessageSerializer msgSer = spi.messageFactory().serializer(m.directType()); + MessageSerializer msgSer = msgFactory.serializer(m.directType()); msgWriter.reset(); msgWriter.setBuffer(msgBuf); From a186f451376f75743c52ec84a45a98ea83b3f774 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 27 Feb 2026 00:23:52 +0300 Subject: [PATCH 29/47] minority --- .../TcpDiscoveryCollectionMessage.java | 59 ++++++++----------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index 917b3fbeba90a..652204dc21ca1 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -59,7 +59,31 @@ public TcpDiscoveryCollectionMessage() { /** @param msgs Discovery messages to hold. */ public TcpDiscoveryCollectionMessage(Collection msgs) { - messages(msgs); + writableMsgs = null; + marshallableMsgsBytes = null; + marshallableMsgs = null; + + if (F.isEmpty(msgs)) + return; + + // Keeps the original message order. + int idx = 0; + + for (TcpDiscoveryAbstractMessage m : msgs) { + if (m instanceof Message) { + if (writableMsgs == null) + writableMsgs = U.newHashMap(msgs.size()); + + writableMsgs.put(idx++, (Message)m); + + continue; + } + + if (marshallableMsgs == null) + marshallableMsgs = U.newHashMap(msgs.size()); + + marshallableMsgs.put(idx++, m); + } } /** @param marsh marshaller. */ @@ -123,39 +147,6 @@ public Collection messages() { return res; } - /** - * Sets pending messages to send to new node. - * - * @param msgs Pending messages to send to new node. - */ - public void messages(@Nullable Collection msgs) { - writableMsgs = null; - marshallableMsgsBytes = null; - marshallableMsgs = null; - - if (F.isEmpty(msgs)) - return; - - // Keeps the original message order. - int idx = 0; - - for (TcpDiscoveryAbstractMessage m : msgs) { - if (m instanceof Message) { - if (writableMsgs == null) - writableMsgs = U.newHashMap(msgs.size()); - - writableMsgs.put(idx++, (Message)m); - - continue; - } - - if (marshallableMsgs == null) - marshallableMsgs = U.newHashMap(msgs.size()); - - marshallableMsgs.put(idx++, m); - } - } - /** {@inheritDoc} */ @Override public short directType() { return -108; From e31efeeedbc03ec44fea06151dc66a4c415f5944 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sat, 28 Feb 2026 14:32:46 +0300 Subject: [PATCH 30/47] refactor --- .../discovery/DiscoveryMessageFactory.java | 99 ++++++++++++++++++- .../discovery/tcp/TcpDiscoveryIoSession.java | 84 ++-------------- .../spi/discovery/tcp/TcpDiscoverySpi.java | 2 +- ...niteDiscoveryMessageSerializationTest.java | 2 +- 4 files changed, 107 insertions(+), 80 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 2e2d9148fe428..5d63ce7ade959 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -17,10 +17,17 @@ package org.apache.ignite.internal.managers.discovery; +import java.util.function.Supplier; +import org.apache.ignite.IgniteException; import org.apache.ignite.internal.processors.cache.CacheStatisticsModeChangeMessage; import org.apache.ignite.internal.processors.cache.CacheStatisticsModeChangeMessageSerializer; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacketSerializer; import org.apache.ignite.spi.discovery.tcp.messages.InetAddressMessage; @@ -65,6 +72,7 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryJoinRequestMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryLoopbackProblemMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryLoopbackProblemMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage; @@ -87,11 +95,34 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryServerOnlyCustomEventMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryStatusCheckMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryStatusCheckMessageSerializer; +import org.jetbrains.annotations.Nullable; -/** Message factory for discovery messages. */ +/** + * Message factory for discovery messages. Allows to create an enhanced {@link MessageFactory} allowing to create + * automated pre- and post- marshalling message serializer for {@link TcpDiscoveryMarshallableMessage}. + */ public class DiscoveryMessageFactory implements MessageFactoryProvider { + /** Custom data marshaller. */ + private final @Nullable Marshaller cstDataMarshall; + + /** Class loader for the custom data marshalling. */ + private final @Nullable ClassLoader cstDataMarshallClsLdr; + + /** + * @param cstDataMarshall Custom data marshaller. + * @param cstDataMarshallClsLdr Class loader for the custom data marshalling. + */ + public DiscoveryMessageFactory(@Nullable Marshaller cstDataMarshall, @Nullable ClassLoader cstDataMarshallClsLdr) { + assert cstDataMarshall == null && cstDataMarshallClsLdr == null || cstDataMarshall != null && cstDataMarshallClsLdr != null; + + this.cstDataMarshall = cstDataMarshall; + this.cstDataMarshallClsLdr = cstDataMarshallClsLdr; + } + /** {@inheritDoc} */ @Override public void registerAll(MessageFactory factory) { + factory = enhanceMessageFactory(factory); + factory.register((short)-108, TcpDiscoveryCollectionMessage::new, new TcpDiscoveryCollectionMessageSerializer()); factory.register((short)-107, NodeSpecificData::new, new NodeSpecificDataSerializer()); factory.register((short)-106, DiscoveryDataPacket::new, new DiscoveryDataPacketSerializer()); @@ -133,4 +164,70 @@ public class DiscoveryMessageFactory implements MessageFactoryProvider { // DiscoveryCustomMessage factory.register((short)500, CacheStatisticsModeChangeMessage::new, new CacheStatisticsModeChangeMessageSerializer()); } + + /** + * @return Enhanced {@link MessageFactory} allowing to create automated pre- and post- marshalling message serializer + * for {@link TcpDiscoveryMarshallableMessage}. + */ + private MessageFactory enhanceMessageFactory(MessageFactory mf) { + if (cstDataMarshall == null || cstDataMarshallClsLdr == null) + return mf; + + return new MessageFactory() { + @Override public void register( + short directType, + Supplier supplier, + MessageSerializer serializer + ) throws IgniteException { + if (supplier.get() instanceof TcpDiscoveryMarshallableMessage) { + final MessageSerializer serializer0 = serializer; + + serializer = new MessageSerializer() { + private Message curMarshallableMsg; + + @Override public boolean writeTo(Message msg, MessageWriter writer) { + if (msg instanceof TcpDiscoveryMarshallableMessage && curMarshallableMsg == null) { + curMarshallableMsg = msg; + + ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(cstDataMarshall); + } + + boolean res = serializer0.writeTo(msg, writer); + + if (res && curMarshallableMsg != null) { + assert msg instanceof TcpDiscoveryMarshallableMessage; + + curMarshallableMsg = null; + } + + return res; + } + + @Override public boolean readFrom(Message msg, MessageReader reader) { + boolean res = serializer0.readFrom(msg, reader); + + if (res && msg instanceof TcpDiscoveryMarshallableMessage) + ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(cstDataMarshall, cstDataMarshallClsLdr); + + return res; + } + }; + } + + mf.register(directType, supplier, serializer); + } + + @Override public void register(short directType, Supplier supplier) throws IgniteException { + mf.register(directType, supplier); + } + + @Override public Message create(short type) { + return mf.create(type); + } + + @Override public MessageSerializer serializer(short type) { + return mf.serializer(type); + } + }; + } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index 80b8fac7c92d8..30e9b1b73f810 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -28,7 +28,6 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.security.cert.Certificate; -import java.util.function.Supplier; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSocket; import org.apache.ignite.IgniteCheckedException; @@ -38,12 +37,8 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.jdk.JdkMarshaller; import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.plugin.extensions.communication.MessageFactory; -import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; -import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -84,7 +79,7 @@ public class TcpDiscoveryIoSession { private final Socket sock; /** */ - final DirectMessageWriter msgWriter; + private final DirectMessageWriter msgWriter; /** */ private final DirectMessageReader msgReader; @@ -96,10 +91,7 @@ public class TcpDiscoveryIoSession { private final CompositeInputStream in; /** Intermediate buffer for serializing discovery messages. */ - final ByteBuffer msgBuf; - - /** */ - final MessageFactory msgFactory; + private final ByteBuffer msgBuf; /** * Creates a new discovery I/O session bound to the given socket. @@ -116,10 +108,8 @@ public class TcpDiscoveryIoSession { msgBuf = ByteBuffer.allocate(MSG_BUFFER_SIZE); - msgFactory = enhanceMessageFactory(spi.messageFactory()); - - msgWriter = new DirectMessageWriter(msgFactory); - msgReader = new DirectMessageReader(msgFactory, null); + msgWriter = new DirectMessageWriter(spi.messageFactory()); + msgReader = new DirectMessageReader(spi.messageFactory(), null); try { int sendBufSize = sock.getSendBufferSize() > 0 ? sock.getSendBufferSize() : DFLT_SOCK_BUFFER_SIZE; @@ -133,60 +123,6 @@ public class TcpDiscoveryIoSession { } } - /** - * @return Enhanced {@link MessageFactory} allowing to pre-marshall and post-unmarshall {@link TcpDiscoveryMarshallableMessage}. - */ - private MessageFactory enhanceMessageFactory(MessageFactory mf) { - assert clsLdr != null; - - return new MessageFactory() { - @Override public void register(short directType, Supplier supplier) throws IgniteException { - mf.register(directType, supplier); - } - - @Override public void register(short directType, Supplier supplier, - MessageSerializer serializer) throws IgniteException { - mf.register(directType, supplier, serializer); - } - - @Override public Message create(short type) { - return mf.create(type); - } - - @Override public MessageSerializer serializer(short type) { - MessageSerializer serializer = mf.serializer(type); - - return new MessageSerializer() { - private Message curMarshallableMsg; - - @Override public boolean writeTo(Message msg, MessageWriter writer) { - if (msg instanceof TcpDiscoveryMarshallableMessage && curMarshallableMsg == null) { - curMarshallableMsg = msg; - - ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(spi.marshaller()); - } - - boolean res = serializer.writeTo(msg, writer); - - if (res && curMarshallableMsg != null) - curMarshallableMsg = null; - - return res; - } - - @Override public boolean readFrom(Message msg, MessageReader reader) { - boolean res = serializer.readFrom(msg, reader); - - if (res && msg instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), clsLdr); - - return res; - } - }; - } - }; - } - /** * Writes a discovery message to the underlying socket output stream. * @@ -240,12 +176,12 @@ T readMessage() throws IgniteCheckedException, IOException { throw new IOException("Received unexpected byte while reading discovery message: " + serMode); } - Message msg = msgFactory.create(makeMessageType((byte)in.read(), (byte)in.read())); + Message msg = spi.messageFactory().create(makeMessageType((byte)in.read(), (byte)in.read())); msgReader.reset(); msgReader.setBuffer(msgBuf); - MessageSerializer msgSer = msgFactory.serializer(msg.directType()); + MessageSerializer msgSer = spi.messageFactory().serializer(msg.directType()); boolean finished; @@ -275,9 +211,6 @@ T readMessage() throws IgniteCheckedException, IOException { } while (!finished); - if (msg instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(spi.marshaller(), clsLdr); - return (T)msg; } catch (Exception e) { @@ -317,10 +250,7 @@ public Socket socket() { * @throws IOException If serialization fails. */ void serializeMessage(Message m, OutputStream out) throws IOException { - if (m instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)m).prepareMarshal(spi.marshaller()); - - MessageSerializer msgSer = msgFactory.serializer(m.directType()); + MessageSerializer msgSer = spi.messageFactory().serializer(m.directType()); msgWriter.reset(); msgWriter.setBuffer(msgBuf); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java index 0d99d795a195a..c91dffcb5e7ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java @@ -2119,7 +2119,7 @@ protected void onExchange(DiscoveryDataPacket dataPacket, ClassLoader clsLdr) { registerMBean(igniteInstanceName, new TcpDiscoverySpiMBeanImpl(this), TcpDiscoverySpiMBean.class); msgFactory = new IgniteMessageFactoryImpl( - new MessageFactoryProvider[] { new DiscoveryMessageFactory() }); + new MessageFactoryProvider[] { new DiscoveryMessageFactory(marshaller(), U.resolveClassLoader(ignite().configuration())) }); impl.spiStart(igniteInstanceName); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoveryMessageSerializationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoveryMessageSerializationTest.java index 6adada121f281..f6eaab9c754ce 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoveryMessageSerializationTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoveryMessageSerializationTest.java @@ -24,6 +24,6 @@ public class IgniteDiscoveryMessageSerializationTest extends AbstractMessageSerializationTest { /** {@inheritDoc} */ @Override protected MessageFactoryProvider messageFactory() { - return new DiscoveryMessageFactory(); + return new DiscoveryMessageFactory(null, null); } } From 7ea9e341eb57df044133d9bf9627fb0bf88aa1cf Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sat, 28 Feb 2026 15:45:57 +0300 Subject: [PATCH 31/47] minor revert --- .../ignite/internal/direct/DirectMessageReader.java | 4 ++-- .../internal/direct/stream/DirectByteBufferStream.java | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java index 70bd9d22b9ee2..3217d7630a0e4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java @@ -71,7 +71,7 @@ public DirectMessageReader(final MessageFactory msgFactory, IgniteCacheObjectPro this.msgFactory = msgFactory; this.cacheObjProc = cacheObjProc; - state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure<>() { + state = new DirectMessageState<>(StateItem.class, new IgniteOutClosure() { @Override public StateItem apply() { return new StateItem(msgFactory, cacheObjProc); } @@ -521,7 +521,7 @@ private static class StateItem implements DirectMessageStateItem { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public StateItem(MessageFactory msgFactory, @Nullable IgniteCacheObjectProcessor cacheObjProc) { + public StateItem(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { stream = new DirectByteBufferStream(msgFactory, cacheObjProc); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java index 1a55c5fede245..ca3ecfc7fbc3d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java @@ -223,7 +223,7 @@ public class DirectByteBufferStream { /** Is required to instantiate {@link CacheObject} while reading messages. */ @GridToStringExclude - private final @Nullable IgniteCacheObjectProcessor cacheObjProc; + private final IgniteCacheObjectProcessor cacheObjProc; /** */ @GridToStringExclude @@ -352,7 +352,10 @@ public class DirectByteBufferStream { * @param msgFactory Message factory. */ public DirectByteBufferStream(MessageFactory msgFactory) { - this(msgFactory, null); + this.msgFactory = msgFactory; + + // Is not used while writing messages. + cacheObjProc = null; } /** @@ -361,7 +364,7 @@ public DirectByteBufferStream(MessageFactory msgFactory) { * @param msgFactory Message factory. * @param cacheObjProc Cache object processor. */ - public DirectByteBufferStream(MessageFactory msgFactory, @Nullable IgniteCacheObjectProcessor cacheObjProc) { + public DirectByteBufferStream(MessageFactory msgFactory, IgniteCacheObjectProcessor cacheObjProc) { this.msgFactory = msgFactory; this.cacheObjProc = cacheObjProc; } From cc60543e6aeaf7a7378f3acc5f325927cc16fa59 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sat, 28 Feb 2026 15:49:13 +0300 Subject: [PATCH 32/47] revert TcpDiscoveryJoinRequestMessage finishMarsh --- .../java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index e25155e6a4810..85b412d0456b9 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -6960,8 +6960,6 @@ else if (e.hasCause(ObjectStreamException.class) || else if (msg instanceof TcpDiscoveryJoinRequestMessage) { TcpDiscoveryJoinRequestMessage req = (TcpDiscoveryJoinRequestMessage)msg; - req.finishUnmarshal(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration())); - // Current node holds connection with the node that is joining the cluster. Therefore, it can // save certificates with which the connection was established to joining node attributes. if (spi.nodeAuth != null && nodeId.equals(req.node().id())) From f9f6f9256a48d06921dae11d456cd15d837acde8 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 2 Mar 2026 18:10:29 +0300 Subject: [PATCH 33/47] + master, review fixes --- .../ignite/spi/discovery/tcp/ClientImpl.java | 6 ++-- .../ignite/spi/discovery/tcp/ServerImpl.java | 24 ++++++------- .../TcpDiscoveryClientReconnectMessage.java | 14 ++++++++ .../TcpDiscoveryNodeAddFinishedMessage.java | 35 ++++++++++++++++--- ...ientSlowDiscoveryTransactionRemapTest.java | 2 +- .../TcpDiscoveryCoordinatorFailureTest.java | 2 +- .../TcpDiscoveryNodeJoinAndFailureTest.java | 2 +- .../discovery/tcp/TcpDiscoverySelfTest.java | 2 +- 8 files changed, 63 insertions(+), 24 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index ca71d5d98512c..d59b9cfe9a4dc 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2294,9 +2294,9 @@ private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage ms } } - if (getLocalNodeId().equals(msg.nodeId)) { + if (getLocalNodeId().equals(msg.nodeId())) { if (joining()) { - DiscoveryDataPacket dataContainer = msg.clientDiscoData; + DiscoveryDataPacket dataContainer = msg.clientDiscoData(); if (dataContainer != null) spi.onExchange(dataContainer, U.resolveClassLoader(spi.ignite().configuration())); @@ -2351,7 +2351,7 @@ else if (log.isDebugEnabled()) } else { if (nodeAdded()) { - TcpDiscoveryNode node = rmtNodes.get(msg.nodeId); + TcpDiscoveryNode node = rmtNodes.get(msg.nodeId()); if (node == null) { if (log.isDebugEnabled()) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 85b412d0456b9..27e21b05bedba 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -262,7 +262,7 @@ class ServerImpl extends TcpDiscoveryImpl { /** Metric for max message queue size. */ private MaxValueMetric maxMsgQueueSizeMetric; - /** Failed nodes (but still in topology): Node -> Id of the failure issuer node. */ + /** Failed nodes (but still in topology). */ private final Map failedNodes = new HashMap<>(); /** */ @@ -2489,12 +2489,12 @@ void add(TcpDiscoveryAbstractMessage msg) { else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - if (addFinishMsg.clientDiscoData != null) { + if (addFinishMsg.clientDiscoData() != null) { addFinishMsg = new TcpDiscoveryNodeAddFinishedMessage(addFinishMsg); msg = addFinishMsg; - DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData; + DiscoveryDataPacket discoData = addFinishMsg.clientDiscoData(); Set mrgdCmnData = new HashSet<>(); Set mrgdSpecData = new HashSet<>(); @@ -2505,7 +2505,7 @@ else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { if (msg0 instanceof TcpDiscoveryNodeAddFinishedMessage) { DiscoveryDataPacket existingDiscoData = - ((TcpDiscoveryNodeAddFinishedMessage)msg0).clientDiscoData; + ((TcpDiscoveryNodeAddFinishedMessage)msg0).clientDiscoData(); if (existingDiscoData != null) allMerged = discoData.mergeDataFrom(existingDiscoData, mrgdCmnData, mrgdSpecData); @@ -2542,8 +2542,8 @@ private void clearClientAddFinished(UUID clientId) { if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage addFinishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - if (addFinishMsg.clientDiscoData != null && clientId.equals(addFinishMsg.nodeId)) { - addFinishMsg.clientDiscoData = null; + if (addFinishMsg.clientDiscoData() != null && clientId.equals(addFinishMsg.nodeId())) { + addFinishMsg.clientDiscoData(null); addFinishMsg.clientNodeAttributes(null); break; @@ -4860,7 +4860,7 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { node.id()); if (node.clientRouterNodeId() != null) { - addFinishMsg.clientDiscoData = msg.gridDiscoveryData(); + addFinishMsg.clientDiscoData(msg.gridDiscoveryData()); addFinishMsg.clientNodeAttributes(node.attributes()); } @@ -5127,7 +5127,7 @@ else if (spiState == CONNECTING) private void processNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage msg) { assert msg != null; - UUID nodeId = msg.nodeId; + UUID nodeId = msg.nodeId(); assert nodeId != null; @@ -6992,7 +6992,7 @@ else if (msg instanceof TcpDiscoveryClientReconnectMessage) { TcpDiscoveryClientReconnectMessage msg0 = (TcpDiscoveryClientReconnectMessage)msg; // If message is received from previous node and node is connecting forward to next node. - if (!getLocalNodeId().equals(msg0.routerNodeId) && state == CONNECTING) { + if (!getLocalNodeId().equals(msg0.routerNodeId()) && state == CONNECTING) { spi.writeToSocket(msg, sock, RES_OK, sockTimeout); msgWorker.addMessage(msg); @@ -7353,21 +7353,21 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms UUID locNodeId = getLocalNodeId(); - boolean isLocNodeRouter = msg.routerNodeId.equals(locNodeId); + boolean isLocNodeRouter = msg.routerNodeId().equals(locNodeId); TcpDiscoveryNode node = ring.node(nodeId); assert node == null || node.clientRouterNodeId() != null; if (node != null) { - node.clientRouterNodeId(msg.routerNodeId); + node.clientRouterNodeId(msg.routerNodeId()); node.clientAliveTime(spi.clientFailureDetectionTimeout()); } if (!msg.verified()) { if (isLocNodeRouter || isLocalNodeCoordinator()) { if (node != null) { - Collection pending = msgHist.messages(msg.lastMsgId, node); + Collection pending = msgHist.messages(msg.lastMessageId(), node); if (pending != null) { msg.verifierNodeId(locNodeId); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index b771bd4a16347..04fd8a328fcb8 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -63,6 +63,20 @@ public TcpDiscoveryClientReconnectMessage(UUID creatorNodeId, UUID routerNodeId, this.lastMsgId = lastMsgId; } + /** + * @return New router node ID. + */ + public UUID routerNodeId() { + return routerNodeId; + } + + /** + * @return Last message ID. + */ + public IgniteUuid lastMessageId() { + return lastMsgId; + } + /** * @param success Success flag. */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 532c44b9bdfd4..c765ba49da2a7 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -88,6 +88,36 @@ public TcpDiscoveryNodeAddFinishedMessage(TcpDiscoveryNodeAddFinishedMessage msg clientNodeAttrsBytes = msg.clientNodeAttrsBytes; } + /** + * Gets ID of the node added. + * + * @return ID of the node added. + */ + public UUID nodeId() { + return nodeId; + } + + /** + * @return Discovery data for joined client. + */ + public DiscoveryDataPacket clientDiscoData() { + return clientDiscoData; + } + + /** + * @param clientDiscoData Discovery data for joined client. + */ + public void clientDiscoData(DiscoveryDataPacket clientDiscoData) { + this.clientDiscoData = clientDiscoData; + + assert clientDiscoData == null || !clientDiscoData.hasDataFromNode(nodeId); + } + + /** @return Client attributes. */ + public @Nullable Map clientNodeAttributes() { + return clientNodeAttrs; + } + /** * Sets new client attributes and ensures that thet will be serialized. * @@ -99,11 +129,6 @@ public void clientNodeAttributes(@Nullable Map attrs) { clientNodeAttrsBytes = null; } - /** @return Client attributes. */ - public @Nullable Map clientNodeAttributes() { - return clientNodeAttrs; - } - /** {@inheritDoc} */ @Override public void prepareMarshal(Marshaller marsh) { if (clientNodeAttrs != null && clientNodeAttrsBytes == null) { diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java index cd5450583f8ec..d408333bc9152 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryTransactionRemapTest.java @@ -377,7 +377,7 @@ public void before() throws Exception { // Delay node join of second client. clientDiscoSpi.interceptor = msg -> { - if (msg.nodeId.toString().endsWith("2")) + if (msg.nodeId().toString().endsWith("2")) U.awaitQuiet(clientDiscoSpiBlock); }; diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java index 09870d8096882..479cee26f6627 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryCoordinatorFailureTest.java @@ -341,7 +341,7 @@ private boolean isDrop(TcpDiscoveryAbstractMessage msg) { if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage finishMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - if ((finishMsg.nodeId.getLeastSignificantBits() & 0xFFFF) == dropNodeIdx) { + if ((finishMsg.nodeId().getLeastSignificantBits() & 0xFFFF) == dropNodeIdx) { drop = true; dropLatch.countDown(); diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java index 1541483b16ecd..f449be13c8e85 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryNodeJoinAndFailureTest.java @@ -163,7 +163,7 @@ Test reproduces the needed behavior (two nodes in CONNECTING state) doing the fo if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { TcpDiscoveryNodeAddFinishedMessage finishedMsg = (TcpDiscoveryNodeAddFinishedMessage)msg; - UUID nodeId = finishedMsg.nodeId; + UUID nodeId = finishedMsg.nodeId(); if (nodeId.equals(node2Id)) { Object workerObj = GridTestUtils.getFieldValue(impl, "msgWorker"); diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java index 41348231135cd..24559bdb1f6a4 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java @@ -2525,7 +2525,7 @@ private static class TestDiscoveryDataDuplicateSpi extends TcpDiscoverySpi { } } else if (msg instanceof TcpDiscoveryNodeAddFinishedMessage) { - DiscoveryDataPacket dataPacket = ((TcpDiscoveryNodeAddFinishedMessage)msg).clientDiscoData; + DiscoveryDataPacket dataPacket = ((TcpDiscoveryNodeAddFinishedMessage)msg).clientDiscoData(); if (dataPacket != null) { Map discoData = U.field(dataPacket, "nodeSpecificData"); From def2b5b99fd6edf952520361b878a7256f345385 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 2 Mar 2026 18:42:40 +0300 Subject: [PATCH 34/47] +master --- .../tcp/messages/TcpDiscoveryClientReconnectMessage.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 04fd8a328fcb8..493d8c6f4253e 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -35,15 +35,15 @@ public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMess private static final long serialVersionUID = 0L; /** New router nodeID. */ - @Order(value = 5) + @Order(0) public UUID routerNodeId; /** Last message ID. */ - @Order(6) + @Order(1) public IgniteUuid lastMsgId; /** Pending messages holder. */ - @Order(7) + @Order(2) @Nullable public TcpDiscoveryCollectionMessage pendingMsgsMsg; /** Constructor for {@link DiscoveryMessageFactory}. */ From f30b850f6329567199d5054a998f3009b9c50631 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 2 Mar 2026 18:50:02 +0300 Subject: [PATCH 35/47] minority --- .../managers/discovery/DiscoveryMessageFactory.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 53573f67cb836..868b6fe3ed642 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -190,22 +190,19 @@ private MessageFactory enhanceMessageFactory(MessageFactory mf) { final MessageSerializer serializer0 = serializer; serializer = new MessageSerializer() { - private Message curMarshallableMsg; + private boolean marshallableMsg; @Override public boolean writeTo(Message msg, MessageWriter writer) { - if (msg instanceof TcpDiscoveryMarshallableMessage && curMarshallableMsg == null) { - curMarshallableMsg = msg; + if (msg instanceof TcpDiscoveryMarshallableMessage && !marshallableMsg) { + marshallableMsg = true; ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(cstDataMarshall); } boolean res = serializer0.writeTo(msg, writer); - if (res && curMarshallableMsg != null) { - assert msg instanceof TcpDiscoveryMarshallableMessage; - - curMarshallableMsg = null; - } + if (res && marshallableMsg) + marshallableMsg = false; return res; } From 27a796e6bf2e728fea6f58d48b96706ac82f4a98 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 2 Mar 2026 19:00:16 +0300 Subject: [PATCH 36/47] javadoc --- .../tcp/messages/TcpDiscoveryCollectionMessage.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index 652204dc21ca1..ea2bc555b1e65 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -32,19 +32,22 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.jetbrains.annotations.Nullable; /** * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 - * Message to transfer a collection of {@link TcpDiscoveryAbstractMessage} with the original order. + * Message to transfer a collection of {@link TcpDiscoveryAbstractMessage}. * Several of them might be a {@link Message}, several may not and require the original marshalling. + * Allows not to keep old-style marshalling for entyre messages collection if just one of them is not a {@link Message}. + * Should be removed when all the messages implement {@link Message}. */ public class TcpDiscoveryCollectionMessage implements TcpDiscoveryMarshallableMessage { - /** {@link TcpDiscoveryAbstractMessage} pending messages which are a {@link Message}. */ + /** Pending messages which can be serialized with {@link MessageSerializer}. */ @Order(0) @Nullable Map writableMsgs; - /** Marshallable or Java-serializable pending messages which are not a {@link Message}. */ + /** Marshallable or Java-serializable pending messages which still requires old-style serialization. */ @Nullable Map marshallableMsgs; /** Marshalled {@link #marshallableMsgs}. */ From c53f798982031af8b440c6af7793d01cbe666d4c Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 2 Mar 2026 19:00:55 +0300 Subject: [PATCH 37/47] trivial --- .../discovery/tcp/messages/TcpDiscoveryCollectionMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java index ea2bc555b1e65..bdaae72d2592d 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java @@ -47,7 +47,7 @@ public class TcpDiscoveryCollectionMessage implements TcpDiscoveryMarshallableMe @Order(0) @Nullable Map writableMsgs; - /** Marshallable or Java-serializable pending messages which still requires old-style serialization. */ + /** Marshallable or Java-serializable pending messages which still require old-style serialization. */ @Nullable Map marshallableMsgs; /** Marshalled {@link #marshallableMsgs}. */ From e7b46aeac301f9409885f7799b24c370c87b42f3 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 3 Mar 2026 21:24:00 +0300 Subject: [PATCH 38/47] revert the collection message --- .../discovery/DiscoveryMessageFactory.java | 3 - .../ignite/spi/discovery/tcp/ClientImpl.java | 10 +- .../ignite/spi/discovery/tcp/ServerImpl.java | 9 +- .../TcpDiscoveryClientReconnectMessage.java | 62 ++++++- .../TcpDiscoveryCollectionMessage.java | 162 ------------------ .../TcpDiscoveryNodeAddFinishedMessage.java | 20 +-- 6 files changed, 70 insertions(+), 196 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 080bea47a2c93..83341915a5abf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -66,8 +66,6 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponseSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessageSerializer; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCollectionMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCollectionMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCustomEventMessage; @@ -135,7 +133,6 @@ public DiscoveryMessageFactory(@Nullable Marshaller cstDataMarshall, @Nullable C @Override public void registerAll(MessageFactory factory) { factory = enhanceMessageFactory(factory); - factory.register((short)-108, TcpDiscoveryCollectionMessage::new, new TcpDiscoveryCollectionMessageSerializer()); factory.register((short)-107, NodeSpecificData::new, new NodeSpecificDataSerializer()); factory.register((short)-106, DiscoveryDataPacket::new, new DiscoveryDataPacketSerializer()); factory.register((short)-105, TcpDiscoveryNodeFullMetricsMessage::new, diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index d59b9cfe9a4dc..aea469edc80e3 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -2239,7 +2239,7 @@ private void processNodeAddedMessage(TcpDiscoveryNodeAddedMessage msg) { nodeAdded = true; - if (!F.isEmpty(msg.topologyHistory())) + if (msg.topologyHistory() != null) topHist.putAll(msg.topologyHistory()); } else { @@ -2544,10 +2544,6 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms return; if (getLocalNodeId().equals(msg.creatorNodeId())) { - Collection pendingMsgs = msg.pendingMsgsMsg == null - ? Collections.emptyList() - : msg.pendingMsgsMsg.messages(); - if (reconnector != null) { assert msg.success() : msg; @@ -2558,7 +2554,7 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms reconnector = null; - for (TcpDiscoveryAbstractMessage pendingMsg : pendingMsgs) { + for (TcpDiscoveryAbstractMessage pendingMsg : msg.pendingMessages()) { if (log.isDebugEnabled()) log.debug("Process pending message on reconnect [msg=" + pendingMsg + ']'); @@ -2568,7 +2564,7 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms else { if (joinLatch.getCount() > 0) { if (msg.success()) { - for (TcpDiscoveryAbstractMessage pendingMsg : pendingMsgs) { + for (TcpDiscoveryAbstractMessage pendingMsg : msg.pendingMessages()) { if (log.isDebugEnabled()) log.debug("Process pending message on connect [msg=" + pendingMsg + ']'); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 27e21b05bedba..610526714495b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -137,7 +137,6 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingRequest; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponse; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCollectionMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCustomEventMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryDiscardMessage; @@ -4138,7 +4137,7 @@ private void processJoinRequestMessage(final TcpDiscoveryJoinRequestMessage msg) Collection msgs = msgHist.messages(null, node); if (msgs != null) { - reconMsg.pendingMsgsMsg = new TcpDiscoveryCollectionMessage(msgs); + reconMsg.pendingMessages(msgs); reconMsg.success(true); } @@ -5078,9 +5077,7 @@ else if (spiState == CONNECTING) joiningNodesDiscoDataList = new ArrayList<>(); topHist.clear(); - - if (!F.isEmpty(msg.topologyHistory())) - topHist.putAll(msg.topologyHistory()); + topHist.putAll(msg.topologyHistory()); pendingMsgs.reset(msg.messages()); } @@ -7371,7 +7368,7 @@ private void processClientReconnectMessage(TcpDiscoveryClientReconnectMessage ms if (pending != null) { msg.verifierNodeId(locNodeId); - msg.pendingMsgsMsg = new TcpDiscoveryCollectionMessage(pending); + msg.pendingMessages(pending); msg.success(true); if (log.isDebugEnabled()) { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 493d8c6f4253e..06d47e0ec8207 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -17,34 +17,42 @@ package org.apache.ignite.spi.discovery.tcp.messages; +import java.util.Collection; import java.util.Objects; import java.util.UUID; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.jetbrains.annotations.Nullable; +import org.apache.ignite.marshaller.Marshaller; /** * Message telling that client node is reconnecting to topology. */ @TcpDiscoveryEnsureDelivery -public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMessage implements Message { +public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMessage implements TcpDiscoveryMarshallableMessage { /** */ private static final long serialVersionUID = 0L; /** New router nodeID. */ @Order(0) - public UUID routerNodeId; + UUID routerNodeId; /** Last message ID. */ @Order(1) - public IgniteUuid lastMsgId; + IgniteUuid lastMsgId; - /** Pending messages holder. */ + /** Pending messages. */ + @GridToStringExclude + private Collection msgs; + + /** Srialized bytes of {@link #msgs}. */ @Order(2) - @Nullable public TcpDiscoveryCollectionMessage pendingMsgsMsg; + byte[] msgsBytes; /** Constructor for {@link DiscoveryMessageFactory}. */ public TcpDiscoveryClientReconnectMessage() { @@ -77,6 +85,20 @@ public IgniteUuid lastMessageId() { return lastMsgId; } + /** + * @param msgs Pending messages. + */ + public void pendingMessages(Collection msgs) { + this.msgs = msgs; + } + + /** + * @return Pending messages. + */ + public Collection pendingMessages() { + return msgs; + } + /** * @param success Success flag. */ @@ -106,6 +128,32 @@ public boolean success() { Objects.equals(lastMsgId, other.lastMsgId); } + /** {@inheritDoc} */ + @Override public void prepareMarshal(Marshaller marsh) { + if (msgs != null && msgsBytes == null) { + try { + msgsBytes = U.marshal(marsh, msgs); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal the pending messages.", e); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + if (msgsBytes != null && msgs == null) { + try { + msgs = U.unmarshal(marsh, msgsBytes, clsLdr); + + msgsBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal the pending messages.", e); + } + } + } + /** {@inheritDoc} */ @Override public short directType() { return 23; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java deleted file mode 100644 index bdaae72d2592d..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCollectionMessage.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.spi.discovery.tcp.messages; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteException; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.managers.discovery.DiscoveryMessageFactory; -import org.apache.ignite.internal.util.tostring.GridToStringExclude; -import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.plugin.extensions.communication.MessageSerializer; -import org.jetbrains.annotations.Nullable; - -/** - * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 - * Message to transfer a collection of {@link TcpDiscoveryAbstractMessage}. - * Several of them might be a {@link Message}, several may not and require the original marshalling. - * Allows not to keep old-style marshalling for entyre messages collection if just one of them is not a {@link Message}. - * Should be removed when all the messages implement {@link Message}. - */ -public class TcpDiscoveryCollectionMessage implements TcpDiscoveryMarshallableMessage { - /** Pending messages which can be serialized with {@link MessageSerializer}. */ - @Order(0) - @Nullable Map writableMsgs; - - /** Marshallable or Java-serializable pending messages which still require old-style serialization. */ - @Nullable Map marshallableMsgs; - - /** Marshalled {@link #marshallableMsgs}. */ - @Order(1) - @GridToStringExclude - @Nullable byte[] marshallableMsgsBytes; - - /** Constructor for {@link DiscoveryMessageFactory}. */ - public TcpDiscoveryCollectionMessage() { - // No-op. - } - - /** @param msgs Discovery messages to hold. */ - public TcpDiscoveryCollectionMessage(Collection msgs) { - writableMsgs = null; - marshallableMsgsBytes = null; - marshallableMsgs = null; - - if (F.isEmpty(msgs)) - return; - - // Keeps the original message order. - int idx = 0; - - for (TcpDiscoveryAbstractMessage m : msgs) { - if (m instanceof Message) { - if (writableMsgs == null) - writableMsgs = U.newHashMap(msgs.size()); - - writableMsgs.put(idx++, (Message)m); - - continue; - } - - if (marshallableMsgs == null) - marshallableMsgs = U.newHashMap(msgs.size()); - - marshallableMsgs.put(idx++, m); - } - } - - /** @param marsh marshaller. */ - @Override public void prepareMarshal(Marshaller marsh) { - if (marshallableMsgs != null && marshallableMsgsBytes == null) { - try { - marshallableMsgsBytes = U.marshal(marsh, marshallableMsgs); - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal marshallable pending messages.", e); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { - if (marshallableMsgsBytes != null && marshallableMsgs == null) { - try { - marshallableMsgs = U.unmarshal(marsh, marshallableMsgsBytes, clsLdr); - - marshallableMsgsBytes = null; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal marshallable pending messages.", e); - } - } - } - - /** - * Gets pending messages sent to new node by its previous. - * - * @return Pending messages from previous node. - */ - public Collection messages() { - if (F.isEmpty(writableMsgs) && F.isEmpty(marshallableMsgs)) - return Collections.emptyList(); - - int totalSz = (F.isEmpty(writableMsgs) ? 0 : writableMsgs.size()) - + (F.isEmpty(marshallableMsgs) ? 0 : marshallableMsgs.size()); - - List res = new ArrayList<>(totalSz); - - for (int i = 0; i < totalSz; ++i) { - Message m = F.isEmpty(writableMsgs) ? null : writableMsgs.get(i); - - if (m == null) { - TcpDiscoveryAbstractMessage adm = marshallableMsgs.get(i); - - assert adm != null; - - res.add(adm); - } - else { - assert marshallableMsgs == null || marshallableMsgs.get(i) == null; - assert m instanceof TcpDiscoveryAbstractMessage; - - res.add((TcpDiscoveryAbstractMessage)m); - } - } - - return res; - } - - /** {@inheritDoc} */ - @Override public short directType() { - return -108; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(TcpDiscoveryCollectionMessage.class, this, "super", super.toString()); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 544a7b3e660f5..2410876569732 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -112,20 +112,18 @@ public void clientDiscoData(DiscoveryDataPacket clientDiscoData) { assert clientDiscoData == null || !clientDiscoData.hasDataFromNode(nodeId); } - /** @return Client attributes. */ - public @Nullable Map clientNodeAttributes() { + /** + * @return Client node attributes. + */ + public Map clientNodeAttributes() { return clientNodeAttrs; } /** - * Sets new client attributes and ensures that thet will be serialized. - * - * @param attrs Client attributes. + * @param clientNodeAttrs New client node attributes. */ - public void clientNodeAttributes(@Nullable Map attrs) { - clientNodeAttrs = F.isEmpty(attrs) ? null : attrs; - // Ensure new data will be serialized. - clientNodeAttrsBytes = null; + public void clientNodeAttributes(Map clientNodeAttrs) { + this.clientNodeAttrs = clientNodeAttrs; } /** {@inheritDoc} */ @@ -135,7 +133,7 @@ public void clientNodeAttributes(@Nullable Map attrs) { clientNodeAttrsBytes = U.marshal(marsh, clientNodeAttrs); } catch (IgniteCheckedException e) { - throw new IgniteException("Failed to marshal client node attributes", e); + throw new IgniteException("Failed to marshal client node attributes.", e); } } } @@ -149,7 +147,7 @@ public void clientNodeAttributes(@Nullable Map attrs) { clientNodeAttrsBytes = null; } catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshal client node attributes", e); + throw new IgniteException("Failed to unmarshal client node attributes.", e); } } } From 3234a91e910be6c4514816f0d54d8ab4b746e34d Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 4 Mar 2026 12:58:40 +0300 Subject: [PATCH 39/47] raw --- .../calcite/message/MarshalableMessage.java | 40 ---------- .../internal/MessageSerializerGenerator.java | 20 ++++- .../discovery/DiscoveryMessageFactory.java | 77 +------------------ ...AbstractMarshallableMessageSerializer.java | 68 ++++++++++++++++ .../communication/MarshallableMessage.java} | 31 +++----- .../TcpDiscoveryClientReconnectMessage.java | 3 +- .../TcpDiscoveryJoinRequestMessage.java | 3 +- .../TcpDiscoveryNodeAddFinishedMessage.java | 3 +- .../codegen/MessageProcessorTest.java | 18 ++++- .../codegen/TestMarshallableMessage.java | 74 ++++++++++++++++++ 10 files changed, 194 insertions(+), 143 deletions(-) delete mode 100644 modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MarshalableMessage.java create mode 100644 modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java rename modules/core/src/main/java/org/apache/ignite/{spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java => plugin/extensions/communication/MarshallableMessage.java} (56%) create mode 100644 modules/core/src/test/resources/codegen/TestMarshallableMessage.java diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MarshalableMessage.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MarshalableMessage.java deleted file mode 100644 index b039c0b7512f7..0000000000000 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MarshalableMessage.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.query.calcite.message; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; - -/** - * - */ -public interface MarshalableMessage extends CalciteMessage { - /** - * Prepares the message before sending. - * - * @param ctx Cache shared context. - */ - void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; - - /** - * Prepares the message before processing. - * - * @param ctx Cache shared context. - */ - void prepareUnmarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; -} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java index 51b756c49fbf7..6ec736c99de8c 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java @@ -107,12 +107,19 @@ public class MessageSerializerGenerator { /** */ private final ProcessingEnvironment env; + /** */ + private final TypeMirror marshallableMsgType; + /** */ private int indent; /** */ MessageSerializerGenerator(ProcessingEnvironment env) { this.env = env; + + marshallableMsgType = env.getElementUtils() + .getTypeElement("org.apache.ignite.plugin.extensions.communication.MarshallableMessage") + .asType(); } /** */ @@ -153,7 +160,7 @@ void generate(TypeElement type, List fields) throws Exception { /** Generates full code for a serializer class. */ private String generateSerializerCode(TypeElement type) throws IOException { try (Writer writer = new StringWriter()) { - writeClassHeader(writer, env.getElementUtils().getPackageOf(type).toString(), type.getSimpleName() + "Serializer"); + writeClassHeader(type, writer, env.getElementUtils().getPackageOf(type).toString(), type.getSimpleName() + "Serializer"); writeClassFields(writer); @@ -891,7 +898,7 @@ private void writeClassFields(Writer writer) throws IOException { } /** Write header of serializer class: license, imports, class declaration. */ - private void writeClassHeader(Writer writer, String pkgName, String serClsName) throws IOException { + private void writeClassHeader(TypeElement type, Writer writer, String pkgName, String serClsName) throws IOException { try (InputStream in = getClass().getClassLoader().getResourceAsStream("license.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { @@ -903,10 +910,13 @@ private void writeClassHeader(Writer writer, String pkgName, String serClsName) out.println(line); } + boolean marshallableMsg = env.getTypeUtils().isAssignable(type.asType(), marshallableMsgType); + writer.write(NL); writer.write("package " + pkgName + ";" + NL + NL); - imports.add("org.apache.ignite.plugin.extensions.communication.Message"); + imports.add("org.apache.ignite.plugin.extensions.communication." + + (marshallableMsg ? "MarshallableMessage" : "Message")); imports.add("org.apache.ignite.plugin.extensions.communication.MessageSerializer"); imports.add("org.apache.ignite.plugin.extensions.communication.MessageWriter"); imports.add("org.apache.ignite.plugin.extensions.communication.MessageReader"); @@ -917,7 +927,9 @@ private void writeClassHeader(Writer writer, String pkgName, String serClsName) writer.write(NL); writer.write(CLS_JAVADOC); writer.write(NL); - writer.write("public class " + serClsName + " implements MessageSerializer {" + NL); + + writer.write("public class " + serClsName + + (marshallableMsg ? " extends AbstractMarshallableMessageSerializer {" : " implements MessageSerializer {") + NL); } /** */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index 83341915a5abf..f069e41b19f3b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -17,8 +17,6 @@ package org.apache.ignite.internal.managers.discovery; -import java.util.function.Supplier; -import org.apache.ignite.IgniteException; import org.apache.ignite.internal.processors.cache.CacheStatisticsModeChangeMessage; import org.apache.ignite.internal.processors.cache.CacheStatisticsModeChangeMessageSerializer; import org.apache.ignite.internal.processors.cache.WalStateFinishMessage; @@ -34,12 +32,8 @@ import org.apache.ignite.internal.processors.query.schema.message.SchemaProposeDiscoveryMessage; import org.apache.ignite.internal.processors.query.schema.message.SchemaProposeDiscoveryMessageSerializer; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; -import org.apache.ignite.plugin.extensions.communication.MessageReader; -import org.apache.ignite.plugin.extensions.communication.MessageSerializer; -import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacketSerializer; import org.apache.ignite.spi.discovery.tcp.messages.InetAddressMessage; @@ -82,7 +76,6 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryJoinRequestMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryLoopbackProblemMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryLoopbackProblemMessageSerializer; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMarshallableMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage; @@ -107,10 +100,7 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryStatusCheckMessageSerializer; import org.jetbrains.annotations.Nullable; -/** - * Message factory for discovery messages. Allows to create an enhanced {@link MessageFactory} allowing to create - * automated pre- and post- marshalling message serializer for {@link TcpDiscoveryMarshallableMessage}. - */ +/** Message factory for discovery messages. */ public class DiscoveryMessageFactory implements MessageFactoryProvider { /** Custom data marshaller. */ private final @Nullable Marshaller cstDataMarshall; @@ -131,8 +121,6 @@ public DiscoveryMessageFactory(@Nullable Marshaller cstDataMarshall, @Nullable C /** {@inheritDoc} */ @Override public void registerAll(MessageFactory factory) { - factory = enhanceMessageFactory(factory); - factory.register((short)-107, NodeSpecificData::new, new NodeSpecificDataSerializer()); factory.register((short)-106, DiscoveryDataPacket::new, new DiscoveryDataPacketSerializer()); factory.register((short)-105, TcpDiscoveryNodeFullMetricsMessage::new, @@ -180,67 +168,4 @@ public DiscoveryMessageFactory(@Nullable Marshaller cstDataMarshall, @Nullable C factory.register((short)506, WalStateFinishMessage::new, new WalStateFinishMessageSerializer()); factory.register((short)507, WalStateProposeMessage::new, new WalStateProposeMessageSerializer()); } - - /** - * @return Enhanced {@link MessageFactory} allowing to create automated pre- and post- marshalling message serializer - * for {@link TcpDiscoveryMarshallableMessage}. - */ - private MessageFactory enhanceMessageFactory(MessageFactory mf) { - if (cstDataMarshall == null || cstDataMarshallClsLdr == null) - return mf; - - return new MessageFactory() { - @Override public void register( - short directType, - Supplier supplier, - MessageSerializer serializer - ) throws IgniteException { - if (supplier.get() instanceof TcpDiscoveryMarshallableMessage) { - final MessageSerializer serializer0 = serializer; - - serializer = new MessageSerializer() { - private boolean marshallableMsg; - - @Override public boolean writeTo(Message msg, MessageWriter writer) { - if (msg instanceof TcpDiscoveryMarshallableMessage && !marshallableMsg) { - marshallableMsg = true; - - ((TcpDiscoveryMarshallableMessage)msg).prepareMarshal(cstDataMarshall); - } - - boolean res = serializer0.writeTo(msg, writer); - - if (res && marshallableMsg) - marshallableMsg = false; - - return res; - } - - @Override public boolean readFrom(Message msg, MessageReader reader) { - boolean res = serializer0.readFrom(msg, reader); - - if (res && msg instanceof TcpDiscoveryMarshallableMessage) - ((TcpDiscoveryMarshallableMessage)msg).finishUnmarshal(cstDataMarshall, cstDataMarshallClsLdr); - - return res; - } - }; - } - - mf.register(directType, supplier, serializer); - } - - @Override public void register(short directType, Supplier supplier) throws IgniteException { - mf.register(directType, supplier); - } - - @Override public Message create(short type) { - return mf.create(type); - } - - @Override public MessageSerializer serializer(short type) { - return mf.serializer(type); - } - }; - } } diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java new file mode 100644 index 0000000000000..1ddd6829b6994 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.plugin.extensions.communication; + +import org.apache.ignite.marshaller.Marshaller; + +/** {@link MarshallableMessage} aware message marshaller. */ +abstract class AbstractMarshallableMessageSerializer implements MessageSerializer { + /** */ + private final MessageSerializer delegate; + + /** */ + private final Marshaller marshaller; + + /** */ + private final ClassLoader clsLdr; + + /** */ + private boolean marshMsgWrite; + + /** */ + protected AbstractMarshallableMessageSerializer(MessageSerializer delegate, Marshaller marshaller, ClassLoader clsLdr) { + this.delegate = delegate; + this.marshaller = marshaller; + this.clsLdr = clsLdr; + } + + /** */ + @Override public boolean writeTo(Message msg, MessageWriter writer) { + if (msg instanceof MarshallableMessage && !marshMsgWrite) { + marshMsgWrite = true; + + ((MarshallableMessage)msg).prepareMarshal(marshaller); + } + + boolean res = delegate.writeTo(msg, writer); + + if (res && marshMsgWrite) + marshMsgWrite = false; + + return res; + } + + /** */ + @Override public boolean readFrom(Message msg, MessageReader reader) { + boolean res = delegate.readFrom(msg, reader); + + if (res && msg instanceof MarshallableMessage) + ((MarshallableMessage)msg).finishUnmarshal(marshaller, clsLdr); + + return res; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MarshallableMessage.java similarity index 56% rename from modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java rename to modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MarshallableMessage.java index cf1854275c565..f58e6cb324110 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryMarshallableMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MarshallableMessage.java @@ -15,29 +15,22 @@ * limitations under the License. */ -package org.apache.ignite.spi.discovery.tcp.messages; +package org.apache.ignite.plugin.extensions.communication; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; -/** - * Base class for TCP Discovery messages which still require external pre- and post- marshalling. - *
- * TODO: Remove/revise after https://issues.apache.org/jira/browse/IGNITE-25883 - */ -public interface TcpDiscoveryMarshallableMessage extends Message { - /** - * Should be idempotent. - * - * @param marsh Marshaller. - */ - void prepareMarshal(Marshaller marsh); +/** A {@link Message} which still requires external custom pre-marshalling and post-unmarshalling. */ +public interface MarshallableMessage extends Message { + /** @param marsh External custom marshaller. */ + public default void prepareMarshal(Marshaller marsh) { + throw new UnsupportedOperationException(); + } /** - * Should be idempotent. - * - * @param marsh Marshaller. - * @param clsLdr Class loader. + * @param marsh External custom marshaller. + * @param clsLdr External class loader to post-unmarshall. */ - void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr); + public default void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + throw new UnsupportedOperationException(); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java index 06d47e0ec8207..8ba5a8b555c21 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java @@ -29,12 +29,13 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; /** * Message telling that client node is reconnecting to topology. */ @TcpDiscoveryEnsureDelivery -public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMessage implements TcpDiscoveryMarshallableMessage { +public class TcpDiscoveryClientReconnectMessage extends TcpDiscoveryAbstractMessage implements MarshallableMessage { /** */ private static final long serialVersionUID = 0L; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java index d0c37dadb16ca..8932c3f7af901 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryJoinRequestMessage.java @@ -23,6 +23,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; @@ -32,7 +33,7 @@ * Initial message sent by a node that wants to enter topology. * Sent to random node during SPI start. Then forwarded directly to coordinator. */ -public class TcpDiscoveryJoinRequestMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { +public class TcpDiscoveryJoinRequestMessage extends TcpDiscoveryAbstractTraceableMessage implements MarshallableMessage { /** */ private static final long serialVersionUID = 0L; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index 2410876569732..bf43459b2b186 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -27,6 +27,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.jetbrains.annotations.Nullable; @@ -35,7 +36,7 @@ */ @TcpDiscoveryEnsureDelivery @TcpDiscoveryRedirectToClient -public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements TcpDiscoveryMarshallableMessage { +public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTraceableMessage implements MarshallableMessage { /** */ private static final long serialVersionUID = 0L; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java index 019364513a200..65e5abbda3203 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java @@ -219,7 +219,7 @@ public void testCustomMapperCannotBeUsedOnArrayField() { */ @Test public void testCustomMapperEnumFieldsMessage() { - Compilation compilation = compile("CustomMapperEnumFieldsMessage.java", "TransactionIsolationEnumMapper.java"); + Compilation compilation = compile("CustomMapperEnumFieldsMessage.java"); assertThat(compilation).succeeded(); @@ -228,6 +228,22 @@ public void testCustomMapperEnumFieldsMessage() { .hasSourceEquivalentTo(javaFile("CustomMapperEnumFieldsMessageSerializer.java")); } + /** + * Positive test for custom EnumMapper implementation for enum field: codegeneration tool + * generates a serializer using provided EnumMapper implementation. + * Generated serializer compiles successfully. + */ + @Test + public void testMarshallableMessage() { + Compilation compilation = compile("TestMarshallableMessage.java", "TransactionIsolationEnumMapper.java"); + + assertThat(compilation).succeeded(); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshallableMessageSerializer") + .hasSourceEquivalentTo(javaFile("TestMarshallableMessageSerializer.java")); + } + /** * Negative test for a coflict situation when two enum mappers are used for the same enum in different messages. */ diff --git a/modules/core/src/test/resources/codegen/TestMarshallableMessage.java b/modules/core/src/test/resources/codegen/TestMarshallableMessage.java new file mode 100644 index 0000000000000..58a871692d3ac --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshallableMessage.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal; + +import java.util.BitSet; +import java.util.Map; +import java.util.UUID; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; + +public class TestMarshallableMessage implements MarshallableMessage { + @Order(0) + int iv; + + @Order(1) + String sv; + + Object cstData; + + @Order(2) + byte[] cstDataBytes; + + /** {@inheritDoc} */ + @Override public void prepareMarshal(Marshaller marsh) { + if (cstData != null && cstDataBytes == null) { + try { + cstDataBytes = U.marshal(marsh, cstData); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to marshal custom data.", e); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) { + if (cstDataBytes != null && cstData == null) { + try { + cstData = U.unmarshal(marsh, cstDataBytes, clsLdr); + + cstDataBytes = null; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal custom data.", e); + } + } + } + + public short directType() { + return 0; + } +} From 48306a8db6bcf0ea62fb422984d8c651b65d536b Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 4 Mar 2026 14:48:25 +0300 Subject: [PATCH 40/47] alpha --- .../message/CalciteMarshalableMessage.java | 40 +++++++ .../calcite/message/MessageServiceImpl.java | 8 +- .../calcite/message/QueryBatchMessage.java | 2 +- .../calcite/message/QueryStartRequest.java | 2 +- .../query/calcite/message/ValueMessage.java | 2 +- .../calcite/metadata/FragmentDescription.java | 4 +- .../ignite/internal/MessageProcessor.java | 6 + .../internal/MessageSerializerGenerator.java | 109 +++++++++++++----- .../discovery/DiscoveryMessageFactory.java | 15 ++- ...AbstractMarshallableMessageSerializer.java | 26 ++--- .../communication/MessageSerializer.java | 6 +- .../codegen/MessageProcessorTest.java | 8 +- ...hallableMessageMarshallableSerializer.java | 108 +++++++++++++++++ 13 files changed, 271 insertions(+), 65 deletions(-) create mode 100644 modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMarshalableMessage.java create mode 100644 modules/core/src/test/resources/codegen/TestMarshallableMessageMarshallableSerializer.java diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMarshalableMessage.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMarshalableMessage.java new file mode 100644 index 0000000000000..b671639ebd6c4 --- /dev/null +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMarshalableMessage.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.query.calcite.message; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; + +/** + * + */ +public interface CalciteMarshalableMessage extends CalciteMessage { + /** + * Prepares the message before sending. + * + * @param ctx Cache shared context. + */ + void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; + + /** + * Prepares the message before processing. + * + * @param ctx Cache shared context. + */ + void prepareUnmarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; +} diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java index 1af28d1fe32cb..2cea51aa5cfac 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java @@ -179,8 +179,8 @@ public FailureProcessor failureProcessor() { /** */ protected void prepareMarshal(Message msg) throws IgniteCheckedException { try { - if (msg instanceof MarshalableMessage) - ((MarshalableMessage)msg).prepareMarshal(ctx); + if (msg instanceof CalciteMarshalableMessage) + ((CalciteMarshalableMessage)msg).prepareMarshal(ctx); } catch (Exception e) { failureProcessor().process(new FailureContext(FailureType.CRITICAL_ERROR, e)); @@ -192,8 +192,8 @@ protected void prepareMarshal(Message msg) throws IgniteCheckedException { /** */ protected void prepareUnmarshal(Message msg) throws IgniteCheckedException { try { - if (msg instanceof MarshalableMessage) - ((MarshalableMessage)msg).prepareUnmarshal(ctx); + if (msg instanceof CalciteMarshalableMessage) + ((CalciteMarshalableMessage)msg).prepareUnmarshal(ctx); } catch (Exception e) { failureProcessor().process(new FailureContext(FailureType.CRITICAL_ERROR, e)); diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryBatchMessage.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryBatchMessage.java index b722b6ccf3758..c21297c3a5c7d 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryBatchMessage.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryBatchMessage.java @@ -27,7 +27,7 @@ /** * */ -public class QueryBatchMessage implements MarshalableMessage, ExecutionContextAware { +public class QueryBatchMessage implements CalciteMarshalableMessage, ExecutionContextAware { /** */ @Order(0) UUID qryId; diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java index 81d843bf3eee0..fe45e12a1c8b1 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java @@ -31,7 +31,7 @@ /** * */ -public class QueryStartRequest implements MarshalableMessage, ExecutionContextAware { +public class QueryStartRequest implements CalciteMarshalableMessage, ExecutionContextAware { /** */ @Order(0) String schema; diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/ValueMessage.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/ValueMessage.java index 44c3d8d0fb549..901bcbfafa456 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/ValueMessage.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/ValueMessage.java @@ -21,7 +21,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; /** */ -public interface ValueMessage extends MarshalableMessage { +public interface ValueMessage extends CalciteMarshalableMessage { /** * @return Wrapped value. */ diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/FragmentDescription.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/FragmentDescription.java index 012591fa1e398..dce4f0f5d2f6a 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/FragmentDescription.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/FragmentDescription.java @@ -23,13 +23,13 @@ import java.util.UUID; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; -import org.apache.ignite.internal.processors.query.calcite.message.MarshalableMessage; +import org.apache.ignite.internal.processors.query.calcite.message.CalciteMarshalableMessage; import org.apache.ignite.internal.processors.query.calcite.message.MessageType; import org.apache.ignite.internal.util.UUIDCollectionMessage; import org.apache.ignite.internal.util.typedef.internal.U; /** */ -public class FragmentDescription implements MarshalableMessage { +public class FragmentDescription implements CalciteMarshalableMessage { /** */ @Order(0) long fragmentId; diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java index c4c6ab7207345..4ecb23e1c1132 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java @@ -68,6 +68,12 @@ public class MessageProcessor extends AbstractProcessor { /** Base interface that every message must implement. */ static final String MESSAGE_INTERFACE = "org.apache.ignite.plugin.extensions.communication.Message"; + /** Compressed message. */ + static final String COMPRESSED_MESSAGE_INTERFACE = "org.apache.ignite.internal.managers.communication.CompressedMessage"; + + /** Externalizable message. */ + static final String EXTERNALIZABLE_MESSAGE_INTERFACE = "org.apache.ignite.plugin.extensions.communication.MarshallableMessage"; + /** This is the only message with zero fields. A serializer must be generated due to restrictions in our communication process. */ static final String HANDSHAKE_WAIT_MESSAGE = "org.apache.ignite.spi.communication.tcp.messages.HandshakeWaitMessage"; diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java index 6ec736c99de8c..db3494cd87f25 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java @@ -56,6 +56,8 @@ import org.apache.ignite.internal.util.typedef.internal.SB; import org.jetbrains.annotations.Nullable; +import static org.apache.ignite.internal.MessageProcessor.COMPRESSED_MESSAGE_INTERFACE; +import static org.apache.ignite.internal.MessageProcessor.EXTERNALIZABLE_MESSAGE_INTERFACE; import static org.apache.ignite.internal.MessageProcessor.MESSAGE_INTERFACE; /** @@ -117,9 +119,7 @@ public class MessageSerializerGenerator { MessageSerializerGenerator(ProcessingEnvironment env) { this.env = env; - marshallableMsgType = env.getElementUtils() - .getTypeElement("org.apache.ignite.plugin.extensions.communication.MarshallableMessage") - .asType(); + marshallableMsgType = env.getElementUtils().getTypeElement(EXTERNALIZABLE_MESSAGE_INTERFACE).asType(); } /** */ @@ -128,9 +128,9 @@ void generate(TypeElement type, List fields) throws Exception { SystemViewRowAttributeWalkerProcessor.superclasses(env, type).forEach(el -> imports.add(el.toString())); - String serClsName = type.getSimpleName() + "Serializer"; + String serClsName = type.getSimpleName() + (marshallableMessage(type) ? "Marshallable" : "") + "Serializer"; String serFqnClsName = env.getElementUtils().getPackageOf(type) + "." + serClsName; - String serCode = generateSerializerCode(type); + String serCode = generateSerializerCode(type, serClsName); try { JavaFileObject file = env.getFiler().createSourceFile(serFqnClsName); @@ -158,12 +158,21 @@ void generate(TypeElement type, List fields) throws Exception { } /** Generates full code for a serializer class. */ - private String generateSerializerCode(TypeElement type) throws IOException { + private String generateSerializerCode(TypeElement type, String serClsName) throws IOException { + if (marshallableMessage(type)) { + fields.add("private final Marshaller marshaller;"); + fields.add("private final ClassLoader clsLdr;"); + } + try (Writer writer = new StringWriter()) { - writeClassHeader(type, writer, env.getElementUtils().getPackageOf(type).toString(), type.getSimpleName() + "Serializer"); + writeClassHeader(type, writer, env.getElementUtils().getPackageOf(type).toString(), serClsName); writeClassFields(writer); + ++indent; + writeConstructor(writer, type, serClsName); + --indent; + // Write #writeTo method. for (String w: write) writer.write(w + NL); @@ -184,6 +193,29 @@ private String generateSerializerCode(TypeElement type) throws IOException { } } + /** */ + private void writeConstructor(Writer writer, TypeElement type, String serClsName) throws IOException { + if (!marshallableMessage(type)) + return; + + writer.write(identedLine(METHOD_JAVADOC)); + writer.write(NL); + writer.write(identedLine("public " + serClsName + "(Marshaller marshaller, ClassLoader clsLdr) {")); + + writer.write(NL); + ++indent; + + writer.write(identedLine("this.marshaller = marshaller;")); + writer.write(NL); + writer.write(identedLine("this.clsLdr = clsLdr;")); + + --indent; + writer.write(NL); + + writer.write(identedLine("}")); + writer.write(NL); + } + /** Generates code for {@code writeTo} and {@code readFrom}. */ private void generateMethods(TypeElement type, List fields) throws Exception { start(type, write, true); @@ -198,8 +230,8 @@ private void generateMethods(TypeElement type, List fields) thr indent--; - finish(write); - finish(read); + finish(write, false, false); + finish(read, true, marshallableMessage(type)); } /** @@ -224,14 +256,15 @@ private void start(TypeElement type, Collection code, boolean write) { code.add(identedLine(METHOD_JAVADOC)); - code.add(identedLine("@Override public boolean %s(Message m, %s) {", + code.add(identedLine("@Override public boolean %s(" + type.getSimpleName() + " msg, %s) {", write ? "writeTo" : "readFrom", write ? "MessageWriter writer" : "MessageReader reader")); indent++; - code.add(identedLine("%s msg = (%s)m;", type.getSimpleName().toString(), type.getSimpleName().toString())); - code.add(EMPTY); + // TODO: revise + // code.add(identedLine("%s msg = (%s)m;", type.getSimpleName().toString(), type.getSimpleName().toString())); + //code.add(EMPTY); if (write) { code.add(identedLine("if (!writer.isHeaderWritten()) {")); @@ -240,6 +273,12 @@ private void start(TypeElement type, Collection code, boolean write) { returnFalseIfWriteFailed(code, "writer.writeHeader", "directType()"); + if (write && marshallableMessage(type)) { + code.add(EMPTY); + + code.add(identedLine("msg.prepareMarshal(marshaller);")); + } + code.add(EMPTY); code.add(identedLine("writer.onHeaderWritten();")); @@ -408,7 +447,7 @@ else if (assignableFrom(type, type("org.apache.ignite.internal.util.GridLongList returnFalseIfWriteFailed(write, field, "writer.writeGridLongList", getExpr); else if (assignableFrom(type, type(MESSAGE_INTERFACE))) { - if (sameType(type, "org.apache.ignite.internal.managers.communication.CompressedMessage")) + if (sameType(type, COMPRESSED_MESSAGE_INTERFACE)) throw new IllegalArgumentException(COMPRESSED_MSG_ERROR); if (compress) @@ -516,7 +555,7 @@ private void returnFalseIfWriteFailed(Collection code, VariableElement f String methodName = field.getAnnotation(Order.class).method(); if (Objects.equals(methodName, "")) - code.add(identedLine("if (!%s(((%s)msg).%s))", accessor, field.getEnclosingElement().getSimpleName(), argsStr)); + code.add(identedLine("if (!%s(msg.%s))", accessor, argsStr)); else code.add(identedLine("if (!%s(msg.%s))", accessor, argsStr)); @@ -539,8 +578,7 @@ private void returnFalseIfEnumWriteFailed( String methodName = field.getAnnotation(Order.class).method(); if (Objects.equals(methodName, "")) - code.add(identedLine("if (!%s(%s(((%s)msg).%s)))", - writerCall, mapperCall, field.getEnclosingElement().getSimpleName(), fieldGetterCall)); + code.add(identedLine("if (!%s(%s(msg.%s)))", writerCall, mapperCall, fieldGetterCall)); else code.add(identedLine("if (!%s(%s(msg.%s)))", writerCall, mapperCall, fieldGetterCall)); @@ -657,7 +695,7 @@ else if (assignableFrom(type, type("org.apache.ignite.internal.util.GridLongList returnFalseIfReadFailed(field, "reader.readGridLongList"); else if (assignableFrom(type, type(MESSAGE_INTERFACE))) { - if (sameType(type, "org.apache.ignite.internal.managers.communication.CompressedMessage")) + if (sameType(type, COMPRESSED_MESSAGE_INTERFACE)) throw new IllegalArgumentException(COMPRESSED_MSG_ERROR); if (compress) @@ -751,7 +789,7 @@ private String messageCollectionItemType(TypeMirror type) throws Exception { if (primitiveType != null) return primitiveType.getKind().toString(); - if (sameType(type, "org.apache.ignite.internal.managers.communication.CompressedMessage")) + if (sameType(type, COMPRESSED_MESSAGE_INTERFACE)) throw new IllegalArgumentException(COMPRESSED_MSG_ERROR); } @@ -789,8 +827,7 @@ private void returnFalseIfReadFailed(VariableElement field, String mtd, String.. String methodName = field.getAnnotation(Order.class).method(); if (Objects.equals(methodName, "")) - read.add(identedLine("((%s)msg).%s = %s(%s);", - field.getEnclosingElement().getSimpleName(), field.getSimpleName().toString(), mtd, argsStr)); + read.add(identedLine("msg.%s = %s(%s);", field.getSimpleName().toString(), mtd, argsStr)); else read.add(identedLine("msg.%s(%s(%s));", methodName, mtd, argsStr)); @@ -821,8 +858,7 @@ private void returnFalseIfEnumReadFailed(VariableElement field, String mapperDec String methodName = field.getAnnotation(Order.class).method(); if (Objects.equals(methodName, "")) - read.add(identedLine("((%s)msg).%s = %s;", - field.getEnclosingElement().getSimpleName(), field.getSimpleName().toString(), readOp)); + read.add(identedLine("msg.%s = %s;", field.getSimpleName().toString(), readOp)); else read.add(identedLine("msg.%s(%s);", methodName, readOp)); @@ -838,7 +874,7 @@ private void returnFalseIfEnumReadFailed(VariableElement field, String mapperDec } /** */ - private void finish(List code) { + private void finish(List code, boolean read, boolean marshallable) { String lastLine = code.get(code.size() - 1); if (EMPTY.equals(lastLine)) @@ -847,6 +883,12 @@ private void finish(List code) { code.add(identedLine("}")); code.add(EMPTY); + if (read && marshallable) { + code.add(identedLine("msg.finishUnmarshal(marshaller, clsLdr);")); + + code.add(EMPTY); + } + code.add(identedLine("return true;")); } @@ -910,26 +952,33 @@ private void writeClassHeader(TypeElement type, Writer writer, String pkgName, S out.println(line); } - boolean marshallableMsg = env.getTypeUtils().isAssignable(type.asType(), marshallableMsgType); - writer.write(NL); writer.write("package " + pkgName + ";" + NL + NL); - imports.add("org.apache.ignite.plugin.extensions.communication." + - (marshallableMsg ? "MarshallableMessage" : "Message")); + if (marshallableMessage(type)) + imports.add("org.apache.ignite.marshaller.Marshaller"); + imports.add("org.apache.ignite.plugin.extensions.communication.MessageSerializer"); imports.add("org.apache.ignite.plugin.extensions.communication.MessageWriter"); imports.add("org.apache.ignite.plugin.extensions.communication.MessageReader"); - for (String regularImport: imports) + for (String regularImport : imports) writer.write("import " + regularImport + ";" + NL); writer.write(NL); writer.write(CLS_JAVADOC); writer.write(NL); - writer.write("public class " + serClsName - + (marshallableMsg ? " extends AbstractMarshallableMessageSerializer {" : " implements MessageSerializer {") + NL); + // TODO: revise +// writer.write("public class " + serClsName + " implements MessageSerializer<" +// + (marshallableMsg ? "MarshallableMessage" : "Message") +// + "> {" + NL); + writer.write("public class " + serClsName + " implements MessageSerializer<"+type.getSimpleName()+"> {" + NL); + } + + /** */ + private boolean marshallableMessage(TypeElement type) { + return env.getTypeUtils().isAssignable(type.asType(), marshallableMsgType); } /** */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java index ae7afc8ae8a97..fe8e65c8244de 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoveryMessageFactory.java @@ -61,7 +61,7 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponse; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientPingResponseSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessageMarshallableSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryConnectionCheckMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCustomEventMessage; @@ -75,13 +75,13 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryHandshakeResponse; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryHandshakeResponseSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryJoinRequestMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryJoinRequestMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryJoinRequestMessageMarshallableSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryLoopbackProblemMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryLoopbackProblemMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryMetricsUpdateMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage; -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessageSerializer; +import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessageMarshallableSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFullMetricsMessage; @@ -153,12 +153,15 @@ public DiscoveryMessageFactory(@Nullable Marshaller cstDataMarshall, @Nullable C factory.register((short)16, TcpDiscoveryNodeLeftMessage::new, new TcpDiscoveryNodeLeftMessageSerializer()); factory.register((short)17, TcpDiscoveryNodeFailedMessage::new, new TcpDiscoveryNodeFailedMessageSerializer()); factory.register((short)18, TcpDiscoveryStatusCheckMessage::new, new TcpDiscoveryStatusCheckMessageSerializer()); - factory.register((short)19, TcpDiscoveryNodeAddFinishedMessage::new, new TcpDiscoveryNodeAddFinishedMessageSerializer()); - factory.register((short)20, TcpDiscoveryJoinRequestMessage::new, new TcpDiscoveryJoinRequestMessageSerializer()); + factory.register((short)19, TcpDiscoveryNodeAddFinishedMessage::new, + new TcpDiscoveryNodeAddFinishedMessageMarshallableSerializer(cstDataMarshall, cstDataMarshallClsLdr)); + factory.register((short)20, TcpDiscoveryJoinRequestMessage::new, + new TcpDiscoveryJoinRequestMessageMarshallableSerializer(cstDataMarshall, cstDataMarshallClsLdr)); factory.register((short)21, TcpDiscoveryCustomEventMessage::new, new TcpDiscoveryCustomEventMessageSerializer()); factory.register((short)22, TcpDiscoveryServerOnlyCustomEventMessage::new, new TcpDiscoveryServerOnlyCustomEventMessageSerializer()); - factory.register((short)23, TcpDiscoveryClientReconnectMessage::new, new TcpDiscoveryClientReconnectMessageSerializer()); + factory.register((short)23, TcpDiscoveryClientReconnectMessage::new, + new TcpDiscoveryClientReconnectMessageMarshallableSerializer(cstDataMarshall, cstDataMarshallClsLdr)); // DiscoveryCustomMessage factory.register((short)500, CacheStatisticsModeChangeMessage::new, new CacheStatisticsModeChangeMessageSerializer()); diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java index 1ddd6829b6994..e03fecfe94284 100644 --- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java @@ -20,9 +20,9 @@ import org.apache.ignite.marshaller.Marshaller; /** {@link MarshallableMessage} aware message marshaller. */ -abstract class AbstractMarshallableMessageSerializer implements MessageSerializer { +abstract class AbstractMarshallableMessageSerializer implements MessageSerializer { /** */ - private final MessageSerializer delegate; + private final MessageSerializer delegate; /** */ private final Marshaller marshaller; @@ -31,37 +31,37 @@ abstract class AbstractMarshallableMessageSerializer implements MessageSerialize private final ClassLoader clsLdr; /** */ - private boolean marshMsgWrite; + private boolean writeBegun; /** */ - protected AbstractMarshallableMessageSerializer(MessageSerializer delegate, Marshaller marshaller, ClassLoader clsLdr) { + protected AbstractMarshallableMessageSerializer(MessageSerializer delegate, Marshaller marshaller, ClassLoader clsLdr) { this.delegate = delegate; this.marshaller = marshaller; this.clsLdr = clsLdr; } /** */ - @Override public boolean writeTo(Message msg, MessageWriter writer) { - if (msg instanceof MarshallableMessage && !marshMsgWrite) { - marshMsgWrite = true; + @Override public boolean writeTo(AM msg, MessageWriter writer) { + if (!writeBegun) { + writeBegun = true; - ((MarshallableMessage)msg).prepareMarshal(marshaller); + msg.prepareMarshal(marshaller); } boolean res = delegate.writeTo(msg, writer); - if (res && marshMsgWrite) - marshMsgWrite = false; + if (res) + writeBegun = false; return res; } /** */ - @Override public boolean readFrom(Message msg, MessageReader reader) { + @Override public boolean readFrom(AM msg, MessageReader reader) { boolean res = delegate.readFrom(msg, reader); - if (res && msg instanceof MarshallableMessage) - ((MarshallableMessage)msg).finishUnmarshal(marshaller, clsLdr); + if (res) + msg.finishUnmarshal(marshaller, clsLdr); return res; } diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java index 706b1891572be..90df0601693c3 100644 --- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java @@ -20,7 +20,7 @@ /** * Interface for message serialization logic. */ -public interface MessageSerializer { +public interface MessageSerializer { /** * Writes this message to provided byte buffer. * @@ -28,7 +28,7 @@ public interface MessageSerializer { * @param writer Writer. * @return Whether message was fully written. */ - public boolean writeTo(Message msg, MessageWriter writer); + public boolean writeTo(M msg, MessageWriter writer); /** * Reads this message from provided byte buffer. @@ -37,5 +37,5 @@ public interface MessageSerializer { * @param reader Reader. * @return Whether message was fully read. */ - public boolean readFrom(Message msg, MessageReader reader); + public boolean readFrom(M msg, MessageReader reader); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java index 65e5abbda3203..1b09cd1820141 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java @@ -234,14 +234,14 @@ public void testCustomMapperEnumFieldsMessage() { * Generated serializer compiles successfully. */ @Test - public void testMarshallableMessage() { - Compilation compilation = compile("TestMarshallableMessage.java", "TransactionIsolationEnumMapper.java"); + public void testMarshallableMessage() throws Exception { + Compilation compilation = compile("TestMarshallableMessage.java"); assertThat(compilation).succeeded(); assertThat(compilation) - .generatedSourceFile("org.apache.ignite.internal.TestMarshallableMessageSerializer") - .hasSourceEquivalentTo(javaFile("TestMarshallableMessageSerializer.java")); + .generatedSourceFile("org.apache.ignite.internal.TestMarshallableMessageMarshallableSerializer") + .hasSourceEquivalentTo(javaFile("TestMarshallableMessageMarshallableSerializer.java")); } /** diff --git a/modules/core/src/test/resources/codegen/TestMarshallableMessageMarshallableSerializer.java b/modules/core/src/test/resources/codegen/TestMarshallableMessageMarshallableSerializer.java new file mode 100644 index 0000000000000..365ec8b80bf7e --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshallableMessageMarshallableSerializer.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal; + +import org.apache.ignite.internal.TestMarshallableMessage; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshallableMessageMarshallableSerializer implements MessageSerializer { + /** */ + private final ClassLoader clsLdr; + /** */ + private final Marshaller marshaller; + + /** */ + public TestMarshallableMessageMarshallableSerializer(Marshaller marshaller, ClassLoader clsLdr) { + this.marshaller = marshaller; + this.clsLdr = clsLdr; + } + /** */ + @Override public boolean writeTo(TestMarshallableMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + msg.prepareMarshal(marshaller); + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeInt(msg.iv)) + return false; + + writer.incrementState(); + + case 1: + if (!writer.writeString(msg.sv)) + return false; + + writer.incrementState(); + + case 2: + if (!writer.writeByteArray(msg.cstDataBytes)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** */ + @Override public boolean readFrom(TestMarshallableMessage msg, MessageReader reader) { + switch (reader.state()) { + case 0: + msg.iv = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 1: + msg.sv = reader.readString(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 2: + msg.cstDataBytes = reader.readByteArray(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + msg.finishUnmarshal(marshaller, clsLdr); + + return true; + } +} \ No newline at end of file From 0d7a4b2fd0409cedee09a8d4fba1a0c84fde17fd Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 4 Mar 2026 16:14:52 +0300 Subject: [PATCH 41/47] cleanup --- .../ignite/internal/MessageProcessor.java | 2 +- .../internal/MessageSerializerGenerator.java | 15 ++-- ...AbstractMarshallableMessageSerializer.java | 68 ------------------- .../codegen/MessageProcessorTest.java | 10 +-- 4 files changed, 9 insertions(+), 86 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java index 4ecb23e1c1132..f6cf23d4b7190 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java @@ -72,7 +72,7 @@ public class MessageProcessor extends AbstractProcessor { static final String COMPRESSED_MESSAGE_INTERFACE = "org.apache.ignite.internal.managers.communication.CompressedMessage"; /** Externalizable message. */ - static final String EXTERNALIZABLE_MESSAGE_INTERFACE = "org.apache.ignite.plugin.extensions.communication.MarshallableMessage"; + static final String MARSHALLABLE_MESSAGE_INTERFACE = "org.apache.ignite.plugin.extensions.communication.MarshallableMessage"; /** This is the only message with zero fields. A serializer must be generated due to restrictions in our communication process. */ static final String HANDSHAKE_WAIT_MESSAGE = "org.apache.ignite.spi.communication.tcp.messages.HandshakeWaitMessage"; diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java index db3494cd87f25..01584922ee16d 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java @@ -57,7 +57,7 @@ import org.jetbrains.annotations.Nullable; import static org.apache.ignite.internal.MessageProcessor.COMPRESSED_MESSAGE_INTERFACE; -import static org.apache.ignite.internal.MessageProcessor.EXTERNALIZABLE_MESSAGE_INTERFACE; +import static org.apache.ignite.internal.MessageProcessor.MARSHALLABLE_MESSAGE_INTERFACE; import static org.apache.ignite.internal.MessageProcessor.MESSAGE_INTERFACE; /** @@ -109,7 +109,7 @@ public class MessageSerializerGenerator { /** */ private final ProcessingEnvironment env; - /** */ + /** The marshallable message type. */ private final TypeMirror marshallableMsgType; /** */ @@ -119,7 +119,7 @@ public class MessageSerializerGenerator { MessageSerializerGenerator(ProcessingEnvironment env) { this.env = env; - marshallableMsgType = env.getElementUtils().getTypeElement(EXTERNALIZABLE_MESSAGE_INTERFACE).asType(); + marshallableMsgType = env.getElementUtils().getTypeElement(MARSHALLABLE_MESSAGE_INTERFACE).asType(); } /** */ @@ -262,9 +262,8 @@ private void start(TypeElement type, Collection code, boolean write) { indent++; - // TODO: revise - // code.add(identedLine("%s msg = (%s)m;", type.getSimpleName().toString(), type.getSimpleName().toString())); - //code.add(EMPTY); + code.add(identedLine("%s msg = (%s)m;", type.getSimpleName().toString(), type.getSimpleName().toString())); + code.add(EMPTY); if (write) { code.add(identedLine("if (!writer.isHeaderWritten()) {")); @@ -969,10 +968,6 @@ private void writeClassHeader(TypeElement type, Writer writer, String pkgName, S writer.write(CLS_JAVADOC); writer.write(NL); - // TODO: revise -// writer.write("public class " + serClsName + " implements MessageSerializer<" -// + (marshallableMsg ? "MarshallableMessage" : "Message") -// + "> {" + NL); writer.write("public class " + serClsName + " implements MessageSerializer<"+type.getSimpleName()+"> {" + NL); } diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java deleted file mode 100644 index e03fecfe94284..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/AbstractMarshallableMessageSerializer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.plugin.extensions.communication; - -import org.apache.ignite.marshaller.Marshaller; - -/** {@link MarshallableMessage} aware message marshaller. */ -abstract class AbstractMarshallableMessageSerializer implements MessageSerializer { - /** */ - private final MessageSerializer delegate; - - /** */ - private final Marshaller marshaller; - - /** */ - private final ClassLoader clsLdr; - - /** */ - private boolean writeBegun; - - /** */ - protected AbstractMarshallableMessageSerializer(MessageSerializer delegate, Marshaller marshaller, ClassLoader clsLdr) { - this.delegate = delegate; - this.marshaller = marshaller; - this.clsLdr = clsLdr; - } - - /** */ - @Override public boolean writeTo(AM msg, MessageWriter writer) { - if (!writeBegun) { - writeBegun = true; - - msg.prepareMarshal(marshaller); - } - - boolean res = delegate.writeTo(msg, writer); - - if (res) - writeBegun = false; - - return res; - } - - /** */ - @Override public boolean readFrom(AM msg, MessageReader reader) { - boolean res = delegate.readFrom(msg, reader); - - if (res) - msg.finishUnmarshal(marshaller, clsLdr); - - return res; - } -} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java index 1b09cd1820141..ee30d719dccc3 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java @@ -219,7 +219,7 @@ public void testCustomMapperCannotBeUsedOnArrayField() { */ @Test public void testCustomMapperEnumFieldsMessage() { - Compilation compilation = compile("CustomMapperEnumFieldsMessage.java"); + Compilation compilation = compile("CustomMapperEnumFieldsMessage.java", "TransactionIsolationEnumMapper.java"); assertThat(compilation).succeeded(); @@ -228,13 +228,9 @@ public void testCustomMapperEnumFieldsMessage() { .hasSourceEquivalentTo(javaFile("CustomMapperEnumFieldsMessageSerializer.java")); } - /** - * Positive test for custom EnumMapper implementation for enum field: codegeneration tool - * generates a serializer using provided EnumMapper implementation. - * Generated serializer compiles successfully. - */ + /** */ @Test - public void testMarshallableMessage() throws Exception { + public void testMarshallableMessage() { Compilation compilation = compile("TestMarshallableMessage.java"); assertThat(compilation).succeeded(); From 4faf553a2056b7294dd0642b1da03a842ba93110 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 4 Mar 2026 16:21:51 +0300 Subject: [PATCH 42/47] lost fix --- .../apache/ignite/internal/MessageSerializerGenerator.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java index 01584922ee16d..fa3a9301cd4e3 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java @@ -238,8 +238,6 @@ private void generateMethods(TypeElement type, List fields) thr * Generates start of write/read methods: *
      *     public boolean writeTo(Message m, MessageWriter writer) {
-     *         TestMessage msg = (TestMessage)m;
-     *
      *         if (!writer.isHeaderWritten()) {
      *             if (!writer.writeHeader(msg.directType()))
      *                 return false;
@@ -262,9 +260,6 @@ private void start(TypeElement type, Collection code, boolean write) {
 
         indent++;
 
-        code.add(identedLine("%s msg = (%s)m;", type.getSimpleName().toString(), type.getSimpleName().toString()));
-        code.add(EMPTY);
-
         if (write) {
             code.add(identedLine("if (!writer.isHeaderWritten()) {"));
 

From fb3cfbb0d151be5596f2913be5c83a8a38fe59e9 Mon Sep 17 00:00:00 2001
From: Vladimir Steshin 
Date: Wed, 4 Mar 2026 16:43:16 +0300
Subject: [PATCH 43/47] test gen messages fix

---
 .../internal/MessageSerializerGenerator.java  |   4 +-
 .../codegen/ChildMessageSerializer.java       |  20 ++--
 ...stomMapperEnumFieldsMessageSerializer.java |  15 +--
 ...aultMapperEnumFieldsMessageSerializer.java |  19 ++-
 .../TestCollectionsMessageSerializer.java     | 111 +++++++++---------
 .../codegen/TestMapMessageSerializer.java     | 107 ++++++++---------
 .../codegen/TestMessageSerializer.java        |  67 +++++------
 7 files changed, 156 insertions(+), 187 deletions(-)

diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
index fa3a9301cd4e3..3f4a59bae381f 100644
--- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
+++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
@@ -126,8 +126,6 @@ public class MessageSerializerGenerator {
     void generate(TypeElement type, List fields) throws Exception {
         generateMethods(type, fields);
 
-        SystemViewRowAttributeWalkerProcessor.superclasses(env, type).forEach(el -> imports.add(el.toString()));
-
         String serClsName = type.getSimpleName() + (marshallableMessage(type) ? "Marshallable" : "") + "Serializer";
         String serFqnClsName = env.getElementUtils().getPackageOf(type) + "." + serClsName;
         String serCode = generateSerializerCode(type, serClsName);
@@ -949,6 +947,8 @@ private void writeClassHeader(TypeElement type, Writer writer, String pkgName, S
         writer.write(NL);
         writer.write("package " + pkgName + ";" + NL + NL);
 
+        imports.add(type.toString());
+
         if (marshallableMessage(type))
             imports.add("org.apache.ignite.marshaller.Marshaller");
 
diff --git a/modules/core/src/test/resources/codegen/ChildMessageSerializer.java b/modules/core/src/test/resources/codegen/ChildMessageSerializer.java
index f7989a079c7ef..d8cd5ab58d85e 100644
--- a/modules/core/src/test/resources/codegen/ChildMessageSerializer.java
+++ b/modules/core/src/test/resources/codegen/ChildMessageSerializer.java
@@ -17,9 +17,7 @@
 
 package org.apache.ignite.internal;
 
-import org.apache.ignite.internal.AbstractMessage;
 import org.apache.ignite.internal.ChildMessage;
-import org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
 import org.apache.ignite.plugin.extensions.communication.MessageWriter;
@@ -29,11 +27,9 @@
  *
  * @see org.apache.ignite.internal.MessageProcessor
  */
-public class ChildMessageSerializer implements MessageSerializer {
+public class ChildMessageSerializer implements MessageSerializer {
     /** */
-    @Override public boolean writeTo(Message m, MessageWriter writer) {
-        ChildMessage msg = (ChildMessage)m;
-
+    @Override public boolean writeTo(ChildMessage msg, MessageWriter writer) {
         if (!writer.isHeaderWritten()) {
             if (!writer.writeHeader(msg.directType()))
                 return false;
@@ -43,13 +39,13 @@ public class ChildMessageSerializer implements MessageSerializer {
 
         switch (writer.state()) {
             case 0:
-                if (!writer.writeInt(((AbstractMessage)msg).id))
+                if (!writer.writeInt(msg.id))
                     return false;
 
                 writer.incrementState();
 
             case 1:
-                if (!writer.writeString(((ChildMessage)msg).str))
+                if (!writer.writeString(msg.str))
                     return false;
 
                 writer.incrementState();
@@ -59,12 +55,10 @@ public class ChildMessageSerializer implements MessageSerializer {
     }
 
     /** */
-    @Override public boolean readFrom(Message m, MessageReader reader) {
-        ChildMessage msg = (ChildMessage)m;
-
+    @Override public boolean readFrom(ChildMessage msg, MessageReader reader) {
         switch (reader.state()) {
             case 0:
-                ((AbstractMessage)msg).id = reader.readInt();
+                msg.id = reader.readInt();
 
                 if (!reader.isLastRead())
                     return false;
@@ -72,7 +66,7 @@ public class ChildMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 1:
-                ((ChildMessage)msg).str = reader.readString();
+                msg.str = reader.readString();
 
                 if (!reader.isLastRead())
                     return false;
diff --git a/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java b/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java
index 180f067c2f185..db939d0825792 100644
--- a/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java
+++ b/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java
@@ -19,7 +19,6 @@
 
 import org.apache.ignite.internal.CustomMapperEnumFieldsMessage;
 import org.apache.ignite.internal.TransactionIsolationEnumMapper;
-import org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
 import org.apache.ignite.plugin.extensions.communication.MessageWriter;
@@ -31,14 +30,12 @@
  *
  * @see org.apache.ignite.internal.MessageProcessor
  */
-public class CustomMapperEnumFieldsMessageSerializer implements MessageSerializer {
+public class CustomMapperEnumFieldsMessageSerializer implements MessageSerializer {
     /** */
     private final EnumMapper transactionIsolationMapper = new TransactionIsolationEnumMapper();
 
     /** */
-    @Override public boolean writeTo(Message m, MessageWriter writer) {
-        CustomMapperEnumFieldsMessage msg = (CustomMapperEnumFieldsMessage)m;
-
+    @Override public boolean writeTo(CustomMapperEnumFieldsMessage msg, MessageWriter writer) {
         if (!writer.isHeaderWritten()) {
             if (!writer.writeHeader(msg.directType()))
                 return false;
@@ -48,7 +45,7 @@ public class CustomMapperEnumFieldsMessageSerializer implements MessageSerialize
 
         switch (writer.state()) {
             case 0:
-                if (!writer.writeByte(transactionIsolationMapper.encode(((CustomMapperEnumFieldsMessage)msg).txMode)))
+                if (!writer.writeByte(transactionIsolationMapper.encode(msg.txMode)))
                     return false;
 
                 writer.incrementState();
@@ -58,12 +55,10 @@ public class CustomMapperEnumFieldsMessageSerializer implements MessageSerialize
     }
 
     /** */
-    @Override public boolean readFrom(Message m, MessageReader reader) {
-        CustomMapperEnumFieldsMessage msg = (CustomMapperEnumFieldsMessage)m;
-
+    @Override public boolean readFrom(CustomMapperEnumFieldsMessage msg, MessageReader reader) {
         switch (reader.state()) {
             case 0:
-                ((CustomMapperEnumFieldsMessage)msg).txMode = transactionIsolationMapper.decode(reader.readByte());
+                msg.txMode = transactionIsolationMapper.decode(reader.readByte());
 
                 if (!reader.isLastRead())
                     return false;
diff --git a/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java b/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java
index ce0dfcfab17ad..245f1f29ae8e5 100644
--- a/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java
+++ b/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java
@@ -19,7 +19,6 @@
 
 import org.apache.ignite.internal.DefaultMapperEnumFieldsMessage;
 import org.apache.ignite.internal.processors.cache.GridCacheOperation;
-import org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
 import org.apache.ignite.plugin.extensions.communication.MessageWriter;
@@ -31,16 +30,14 @@
  *
  * @see org.apache.ignite.internal.MessageProcessor
  */
-public class DefaultMapperEnumFieldsMessageSerializer implements MessageSerializer {
+public class DefaultMapperEnumFieldsMessageSerializer implements MessageSerializer {
     /** */
     private final GridCacheOperation[] gridCacheOperationVals = GridCacheOperation.values();
     /** */
     private final TransactionIsolation[] transactionIsolationVals = TransactionIsolation.values();
 
     /** */
-    @Override public boolean writeTo(Message m, MessageWriter writer) {
-        DefaultMapperEnumFieldsMessage msg = (DefaultMapperEnumFieldsMessage)m;
-
+    @Override public boolean writeTo(DefaultMapperEnumFieldsMessage msg, MessageWriter writer) {
         if (!writer.isHeaderWritten()) {
             if (!writer.writeHeader(msg.directType()))
                 return false;
@@ -50,13 +47,13 @@ public class DefaultMapperEnumFieldsMessageSerializer implements MessageSerializ
 
         switch (writer.state()) {
             case 0:
-                if (!writer.writeByte(DefaultEnumMapper.INSTANCE.encode(((DefaultMapperEnumFieldsMessage)msg).publicEnum)))
+                if (!writer.writeByte(DefaultEnumMapper.INSTANCE.encode(msg.publicEnum)))
                     return false;
 
                 writer.incrementState();
 
             case 1:
-                if (!writer.writeByte(DefaultEnumMapper.INSTANCE.encode(((DefaultMapperEnumFieldsMessage)msg).internalEnum)))
+                if (!writer.writeByte(DefaultEnumMapper.INSTANCE.encode(msg.internalEnum)))
                     return false;
 
                 writer.incrementState();
@@ -66,12 +63,10 @@ public class DefaultMapperEnumFieldsMessageSerializer implements MessageSerializ
     }
 
     /** */
-    @Override public boolean readFrom(Message m, MessageReader reader) {
-        DefaultMapperEnumFieldsMessage msg = (DefaultMapperEnumFieldsMessage)m;
-
+    @Override public boolean readFrom(DefaultMapperEnumFieldsMessage msg, MessageReader reader) {
         switch (reader.state()) {
             case 0:
-                ((DefaultMapperEnumFieldsMessage)msg).publicEnum = DefaultEnumMapper.INSTANCE.decode(transactionIsolationVals, reader.readByte());
+                msg.publicEnum = DefaultEnumMapper.INSTANCE.decode(transactionIsolationVals, reader.readByte());
 
                 if (!reader.isLastRead())
                     return false;
@@ -79,7 +74,7 @@ public class DefaultMapperEnumFieldsMessageSerializer implements MessageSerializ
                 reader.incrementState();
 
             case 1:
-                ((DefaultMapperEnumFieldsMessage)msg).internalEnum = DefaultEnumMapper.INSTANCE.decode(gridCacheOperationVals, reader.readByte());
+                msg.internalEnum = DefaultEnumMapper.INSTANCE.decode(gridCacheOperationVals, reader.readByte());
 
                 if (!reader.isLastRead())
                     return false;
diff --git a/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java b/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java
index 00335f38db649..2f4f365cc830a 100644
--- a/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java
+++ b/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal;
 
 import org.apache.ignite.internal.TestCollectionsMessage;
-import org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
 import org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
@@ -29,11 +28,9 @@
  *
  * @see org.apache.ignite.internal.MessageProcessor
  */
-public class TestCollectionsMessageSerializer implements MessageSerializer {
+public class TestCollectionsMessageSerializer implements MessageSerializer {
     /** */
-    @Override public boolean writeTo(Message m, MessageWriter writer) {
-        TestCollectionsMessage msg = (TestCollectionsMessage)m;
-
+    @Override public boolean writeTo(TestCollectionsMessage msg, MessageWriter writer) {
         if (!writer.isHeaderWritten()) {
             if (!writer.writeHeader(msg.directType()))
                 return false;
@@ -43,151 +40,151 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
 
         switch (writer.state()) {
             case 0:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).booleanArrayList, MessageCollectionItemType.BOOLEAN_ARR))
+                if (!writer.writeCollection(msg.booleanArrayList, MessageCollectionItemType.BOOLEAN_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 1:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).byteArrayList, MessageCollectionItemType.BYTE_ARR))
+                if (!writer.writeCollection(msg.byteArrayList, MessageCollectionItemType.BYTE_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 2:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).shortArrayList, MessageCollectionItemType.SHORT_ARR))
+                if (!writer.writeCollection(msg.shortArrayList, MessageCollectionItemType.SHORT_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 3:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).intArrayList, MessageCollectionItemType.INT_ARR))
+                if (!writer.writeCollection(msg.intArrayList, MessageCollectionItemType.INT_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 4:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).longArrayList, MessageCollectionItemType.LONG_ARR))
+                if (!writer.writeCollection(msg.longArrayList, MessageCollectionItemType.LONG_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 5:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).charArrayList, MessageCollectionItemType.CHAR_ARR))
+                if (!writer.writeCollection(msg.charArrayList, MessageCollectionItemType.CHAR_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 6:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).floatArrayList, MessageCollectionItemType.FLOAT_ARR))
+                if (!writer.writeCollection(msg.floatArrayList, MessageCollectionItemType.FLOAT_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 7:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).doubleArrayList, MessageCollectionItemType.DOUBLE_ARR))
+                if (!writer.writeCollection(msg.doubleArrayList, MessageCollectionItemType.DOUBLE_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 8:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).stringList, MessageCollectionItemType.STRING))
+                if (!writer.writeCollection(msg.stringList, MessageCollectionItemType.STRING))
                     return false;
 
                 writer.incrementState();
 
             case 9:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).uuidList, MessageCollectionItemType.UUID))
+                if (!writer.writeCollection(msg.uuidList, MessageCollectionItemType.UUID))
                     return false;
 
                 writer.incrementState();
 
             case 10:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).bitSetList, MessageCollectionItemType.BIT_SET))
+                if (!writer.writeCollection(msg.bitSetList, MessageCollectionItemType.BIT_SET))
                     return false;
 
                 writer.incrementState();
 
             case 11:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).igniteUuidList, MessageCollectionItemType.IGNITE_UUID))
+                if (!writer.writeCollection(msg.igniteUuidList, MessageCollectionItemType.IGNITE_UUID))
                     return false;
 
                 writer.incrementState();
 
             case 12:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).affTopVersionList, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION))
+                if (!writer.writeCollection(msg.affTopVersionList, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION))
                     return false;
 
                 writer.incrementState();
 
             case 13:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedBooleanList, MessageCollectionItemType.BOOLEAN))
+                if (!writer.writeCollection(msg.boxedBooleanList, MessageCollectionItemType.BOOLEAN))
                     return false;
 
                 writer.incrementState();
 
             case 14:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedByteList, MessageCollectionItemType.BYTE))
+                if (!writer.writeCollection(msg.boxedByteList, MessageCollectionItemType.BYTE))
                     return false;
 
                 writer.incrementState();
 
             case 15:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedShortList, MessageCollectionItemType.SHORT))
+                if (!writer.writeCollection(msg.boxedShortList, MessageCollectionItemType.SHORT))
                     return false;
 
                 writer.incrementState();
 
             case 16:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedIntList, MessageCollectionItemType.INT))
+                if (!writer.writeCollection(msg.boxedIntList, MessageCollectionItemType.INT))
                     return false;
 
                 writer.incrementState();
 
             case 17:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedLongList, MessageCollectionItemType.LONG))
+                if (!writer.writeCollection(msg.boxedLongList, MessageCollectionItemType.LONG))
                     return false;
 
                 writer.incrementState();
 
             case 18:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedCharList, MessageCollectionItemType.CHAR))
+                if (!writer.writeCollection(msg.boxedCharList, MessageCollectionItemType.CHAR))
                     return false;
 
                 writer.incrementState();
 
             case 19:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedFloatList, MessageCollectionItemType.FLOAT))
+                if (!writer.writeCollection(msg.boxedFloatList, MessageCollectionItemType.FLOAT))
                     return false;
 
                 writer.incrementState();
 
             case 20:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).boxedDoubleList, MessageCollectionItemType.DOUBLE))
+                if (!writer.writeCollection(msg.boxedDoubleList, MessageCollectionItemType.DOUBLE))
                     return false;
 
                 writer.incrementState();
 
             case 21:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).messageList, MessageCollectionItemType.MSG))
+                if (!writer.writeCollection(msg.messageList, MessageCollectionItemType.MSG))
                     return false;
 
                 writer.incrementState();
 
             case 22:
-                if (!writer.writeCollection(((TestCollectionsMessage)msg).gridLongListList, MessageCollectionItemType.GRID_LONG_LIST))
+                if (!writer.writeCollection(msg.gridLongListList, MessageCollectionItemType.GRID_LONG_LIST))
                     return false;
 
                 writer.incrementState();
 
             case 23:
-                if (!writer.writeSet(((TestCollectionsMessage)msg).boxedIntegerSet, MessageCollectionItemType.INT))
+                if (!writer.writeSet(msg.boxedIntegerSet, MessageCollectionItemType.INT))
                     return false;
 
                 writer.incrementState();
 
             case 24:
-                if (!writer.writeSet(((TestCollectionsMessage)msg).bitSetSet, MessageCollectionItemType.BIT_SET))
+                if (!writer.writeSet(msg.bitSetSet, MessageCollectionItemType.BIT_SET))
                     return false;
 
                 writer.incrementState();
@@ -197,12 +194,10 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
     }
 
     /** */
-    @Override public boolean readFrom(Message m, MessageReader reader) {
-        TestCollectionsMessage msg = (TestCollectionsMessage)m;
-
+    @Override public boolean readFrom(TestCollectionsMessage msg, MessageReader reader) {
         switch (reader.state()) {
             case 0:
-                ((TestCollectionsMessage)msg).booleanArrayList = reader.readCollection(MessageCollectionItemType.BOOLEAN_ARR);
+                msg.booleanArrayList = reader.readCollection(MessageCollectionItemType.BOOLEAN_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -210,7 +205,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 1:
-                ((TestCollectionsMessage)msg).byteArrayList = reader.readCollection(MessageCollectionItemType.BYTE_ARR);
+                msg.byteArrayList = reader.readCollection(MessageCollectionItemType.BYTE_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -218,7 +213,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 2:
-                ((TestCollectionsMessage)msg).shortArrayList = reader.readCollection(MessageCollectionItemType.SHORT_ARR);
+                msg.shortArrayList = reader.readCollection(MessageCollectionItemType.SHORT_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -226,7 +221,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 3:
-                ((TestCollectionsMessage)msg).intArrayList = reader.readCollection(MessageCollectionItemType.INT_ARR);
+                msg.intArrayList = reader.readCollection(MessageCollectionItemType.INT_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -234,7 +229,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 4:
-                ((TestCollectionsMessage)msg).longArrayList = reader.readCollection(MessageCollectionItemType.LONG_ARR);
+                msg.longArrayList = reader.readCollection(MessageCollectionItemType.LONG_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -242,7 +237,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 5:
-                ((TestCollectionsMessage)msg).charArrayList = reader.readCollection(MessageCollectionItemType.CHAR_ARR);
+                msg.charArrayList = reader.readCollection(MessageCollectionItemType.CHAR_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -250,7 +245,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 6:
-                ((TestCollectionsMessage)msg).floatArrayList = reader.readCollection(MessageCollectionItemType.FLOAT_ARR);
+                msg.floatArrayList = reader.readCollection(MessageCollectionItemType.FLOAT_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -258,7 +253,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 7:
-                ((TestCollectionsMessage)msg).doubleArrayList = reader.readCollection(MessageCollectionItemType.DOUBLE_ARR);
+                msg.doubleArrayList = reader.readCollection(MessageCollectionItemType.DOUBLE_ARR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -266,7 +261,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 8:
-                ((TestCollectionsMessage)msg).stringList = reader.readCollection(MessageCollectionItemType.STRING);
+                msg.stringList = reader.readCollection(MessageCollectionItemType.STRING);
 
                 if (!reader.isLastRead())
                     return false;
@@ -274,7 +269,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 9:
-                ((TestCollectionsMessage)msg).uuidList = reader.readCollection(MessageCollectionItemType.UUID);
+                msg.uuidList = reader.readCollection(MessageCollectionItemType.UUID);
 
                 if (!reader.isLastRead())
                     return false;
@@ -282,7 +277,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 10:
-                ((TestCollectionsMessage)msg).bitSetList = reader.readCollection(MessageCollectionItemType.BIT_SET);
+                msg.bitSetList = reader.readCollection(MessageCollectionItemType.BIT_SET);
 
                 if (!reader.isLastRead())
                     return false;
@@ -290,7 +285,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 11:
-                ((TestCollectionsMessage)msg).igniteUuidList = reader.readCollection(MessageCollectionItemType.IGNITE_UUID);
+                msg.igniteUuidList = reader.readCollection(MessageCollectionItemType.IGNITE_UUID);
 
                 if (!reader.isLastRead())
                     return false;
@@ -298,7 +293,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 12:
-                ((TestCollectionsMessage)msg).affTopVersionList = reader.readCollection(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION);
+                msg.affTopVersionList = reader.readCollection(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION);
 
                 if (!reader.isLastRead())
                     return false;
@@ -306,7 +301,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 13:
-                ((TestCollectionsMessage)msg).boxedBooleanList = reader.readCollection(MessageCollectionItemType.BOOLEAN);
+                msg.boxedBooleanList = reader.readCollection(MessageCollectionItemType.BOOLEAN);
 
                 if (!reader.isLastRead())
                     return false;
@@ -314,7 +309,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 14:
-                ((TestCollectionsMessage)msg).boxedByteList = reader.readCollection(MessageCollectionItemType.BYTE);
+                msg.boxedByteList = reader.readCollection(MessageCollectionItemType.BYTE);
 
                 if (!reader.isLastRead())
                     return false;
@@ -322,7 +317,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 15:
-                ((TestCollectionsMessage)msg).boxedShortList = reader.readCollection(MessageCollectionItemType.SHORT);
+                msg.boxedShortList = reader.readCollection(MessageCollectionItemType.SHORT);
 
                 if (!reader.isLastRead())
                     return false;
@@ -330,7 +325,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 16:
-                ((TestCollectionsMessage)msg).boxedIntList = reader.readCollection(MessageCollectionItemType.INT);
+                msg.boxedIntList = reader.readCollection(MessageCollectionItemType.INT);
 
                 if (!reader.isLastRead())
                     return false;
@@ -338,7 +333,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 17:
-                ((TestCollectionsMessage)msg).boxedLongList = reader.readCollection(MessageCollectionItemType.LONG);
+                msg.boxedLongList = reader.readCollection(MessageCollectionItemType.LONG);
 
                 if (!reader.isLastRead())
                     return false;
@@ -346,7 +341,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 18:
-                ((TestCollectionsMessage)msg).boxedCharList = reader.readCollection(MessageCollectionItemType.CHAR);
+                msg.boxedCharList = reader.readCollection(MessageCollectionItemType.CHAR);
 
                 if (!reader.isLastRead())
                     return false;
@@ -354,7 +349,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 19:
-                ((TestCollectionsMessage)msg).boxedFloatList = reader.readCollection(MessageCollectionItemType.FLOAT);
+                msg.boxedFloatList = reader.readCollection(MessageCollectionItemType.FLOAT);
 
                 if (!reader.isLastRead())
                     return false;
@@ -362,7 +357,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 20:
-                ((TestCollectionsMessage)msg).boxedDoubleList = reader.readCollection(MessageCollectionItemType.DOUBLE);
+                msg.boxedDoubleList = reader.readCollection(MessageCollectionItemType.DOUBLE);
 
                 if (!reader.isLastRead())
                     return false;
@@ -370,7 +365,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 21:
-                ((TestCollectionsMessage)msg).messageList = reader.readCollection(MessageCollectionItemType.MSG);
+                msg.messageList = reader.readCollection(MessageCollectionItemType.MSG);
 
                 if (!reader.isLastRead())
                     return false;
@@ -378,7 +373,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 22:
-                ((TestCollectionsMessage)msg).gridLongListList = reader.readCollection(MessageCollectionItemType.GRID_LONG_LIST);
+                msg.gridLongListList = reader.readCollection(MessageCollectionItemType.GRID_LONG_LIST);
 
                 if (!reader.isLastRead())
                     return false;
@@ -386,7 +381,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 23:
-                ((TestCollectionsMessage)msg).boxedIntegerSet = reader.readSet(MessageCollectionItemType.INT);
+                msg.boxedIntegerSet = reader.readSet(MessageCollectionItemType.INT);
 
                 if (!reader.isLastRead())
                     return false;
@@ -394,7 +389,7 @@ public class TestCollectionsMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 24:
-                ((TestCollectionsMessage)msg).bitSetSet = reader.readSet(MessageCollectionItemType.BIT_SET);
+                msg.bitSetSet = reader.readSet(MessageCollectionItemType.BIT_SET);
 
                 if (!reader.isLastRead())
                     return false;
diff --git a/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java
index 9753dd90e53e0..42d0773b7e224 100644
--- a/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java
+++ b/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal;
 
 import org.apache.ignite.internal.TestMapMessage;
-import org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
 import org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
@@ -29,11 +28,9 @@
  *
  * @see org.apache.ignite.internal.MessageProcessor
  */
-public class TestMapMessageSerializer implements MessageSerializer {
+public class TestMapMessageSerializer implements MessageSerializer {
     /** */
-    @Override public boolean writeTo(Message m, MessageWriter writer) {
-        TestMapMessage msg = (TestMapMessage)m;
-
+    @Override public boolean writeTo(TestMapMessage msg, MessageWriter writer) {
         if (!writer.isHeaderWritten()) {
             if (!writer.writeHeader(msg.directType()))
                 return false;
@@ -43,145 +40,145 @@ public class TestMapMessageSerializer implements MessageSerializer {
 
         switch (writer.state()) {
             case 0:
-                if (!writer.writeMap(((TestMapMessage)msg).booleanArrayBoxedLongMap, MessageCollectionItemType.BOOLEAN_ARR, MessageCollectionItemType.LONG))
+                if (!writer.writeMap(msg.booleanArrayBoxedLongMap, MessageCollectionItemType.BOOLEAN_ARR, MessageCollectionItemType.LONG))
                     return false;
 
                 writer.incrementState();
 
             case 1:
-                if (!writer.writeMap(((TestMapMessage)msg).byteArrayBooleanArrayMap, MessageCollectionItemType.BYTE_ARR, MessageCollectionItemType.BOOLEAN_ARR))
+                if (!writer.writeMap(msg.byteArrayBooleanArrayMap, MessageCollectionItemType.BYTE_ARR, MessageCollectionItemType.BOOLEAN_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 2:
-                if (!writer.writeMap(((TestMapMessage)msg).shortArrayByteArrayMap, MessageCollectionItemType.SHORT_ARR, MessageCollectionItemType.BYTE_ARR))
+                if (!writer.writeMap(msg.shortArrayByteArrayMap, MessageCollectionItemType.SHORT_ARR, MessageCollectionItemType.BYTE_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 3:
-                if (!writer.writeMap(((TestMapMessage)msg).intArrayShortArrayMap, MessageCollectionItemType.INT_ARR, MessageCollectionItemType.SHORT_ARR))
+                if (!writer.writeMap(msg.intArrayShortArrayMap, MessageCollectionItemType.INT_ARR, MessageCollectionItemType.SHORT_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 4:
-                if (!writer.writeMap(((TestMapMessage)msg).longArrayIntArrayMap, MessageCollectionItemType.LONG_ARR, MessageCollectionItemType.INT_ARR))
+                if (!writer.writeMap(msg.longArrayIntArrayMap, MessageCollectionItemType.LONG_ARR, MessageCollectionItemType.INT_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 5:
-                if (!writer.writeMap(((TestMapMessage)msg).charArrayLongArrayMap, MessageCollectionItemType.CHAR_ARR, MessageCollectionItemType.LONG_ARR))
+                if (!writer.writeMap(msg.charArrayLongArrayMap, MessageCollectionItemType.CHAR_ARR, MessageCollectionItemType.LONG_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 6:
-                if (!writer.writeMap(((TestMapMessage)msg).floatArrayCharArrayMap, MessageCollectionItemType.FLOAT_ARR, MessageCollectionItemType.CHAR_ARR))
+                if (!writer.writeMap(msg.floatArrayCharArrayMap, MessageCollectionItemType.FLOAT_ARR, MessageCollectionItemType.CHAR_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 7:
-                if (!writer.writeMap(((TestMapMessage)msg).doubleArrayFloatArrayMap, MessageCollectionItemType.DOUBLE_ARR, MessageCollectionItemType.FLOAT_ARR))
+                if (!writer.writeMap(msg.doubleArrayFloatArrayMap, MessageCollectionItemType.DOUBLE_ARR, MessageCollectionItemType.FLOAT_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 8:
-                if (!writer.writeMap(((TestMapMessage)msg).stringDoubleArrayMap, MessageCollectionItemType.STRING, MessageCollectionItemType.DOUBLE_ARR))
+                if (!writer.writeMap(msg.stringDoubleArrayMap, MessageCollectionItemType.STRING, MessageCollectionItemType.DOUBLE_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 9:
-                if (!writer.writeMap(((TestMapMessage)msg).uuidStringMap, MessageCollectionItemType.UUID, MessageCollectionItemType.STRING))
+                if (!writer.writeMap(msg.uuidStringMap, MessageCollectionItemType.UUID, MessageCollectionItemType.STRING))
                     return false;
 
                 writer.incrementState();
 
             case 10:
-                if (!writer.writeMap(((TestMapMessage)msg).bitSetUuidMap, MessageCollectionItemType.BIT_SET, MessageCollectionItemType.UUID))
+                if (!writer.writeMap(msg.bitSetUuidMap, MessageCollectionItemType.BIT_SET, MessageCollectionItemType.UUID))
                     return false;
 
                 writer.incrementState();
 
             case 11:
-                if (!writer.writeMap(((TestMapMessage)msg).igniteUuidBitSetMap, MessageCollectionItemType.IGNITE_UUID, MessageCollectionItemType.BIT_SET))
+                if (!writer.writeMap(msg.igniteUuidBitSetMap, MessageCollectionItemType.IGNITE_UUID, MessageCollectionItemType.BIT_SET))
                     return false;
 
                 writer.incrementState();
 
             case 12:
-                if (!writer.writeMap(((TestMapMessage)msg).affTopVersionIgniteUuidMap, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION, MessageCollectionItemType.IGNITE_UUID))
+                if (!writer.writeMap(msg.affTopVersionIgniteUuidMap, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION, MessageCollectionItemType.IGNITE_UUID))
                     return false;
 
                 writer.incrementState();
 
             case 13:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedBooleanAffTopVersionMap, MessageCollectionItemType.BOOLEAN, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION))
+                if (!writer.writeMap(msg.boxedBooleanAffTopVersionMap, MessageCollectionItemType.BOOLEAN, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION))
                     return false;
 
                 writer.incrementState();
 
             case 14:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedByteBoxedBooleanMap, MessageCollectionItemType.BYTE, MessageCollectionItemType.BOOLEAN))
+                if (!writer.writeMap(msg.boxedByteBoxedBooleanMap, MessageCollectionItemType.BYTE, MessageCollectionItemType.BOOLEAN))
                     return false;
 
                 writer.incrementState();
 
             case 15:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedShortBoxedByteMap, MessageCollectionItemType.SHORT, MessageCollectionItemType.BYTE))
+                if (!writer.writeMap(msg.boxedShortBoxedByteMap, MessageCollectionItemType.SHORT, MessageCollectionItemType.BYTE))
                     return false;
 
                 writer.incrementState();
 
             case 16:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedIntBoxedShortMap, MessageCollectionItemType.INT, MessageCollectionItemType.SHORT))
+                if (!writer.writeMap(msg.boxedIntBoxedShortMap, MessageCollectionItemType.INT, MessageCollectionItemType.SHORT))
                     return false;
 
                 writer.incrementState();
 
             case 17:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedLongBoxedIntMap, MessageCollectionItemType.LONG, MessageCollectionItemType.INT))
+                if (!writer.writeMap(msg.boxedLongBoxedIntMap, MessageCollectionItemType.LONG, MessageCollectionItemType.INT))
                     return false;
 
                 writer.incrementState();
 
             case 18:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedCharBoxedLongMap, MessageCollectionItemType.CHAR, MessageCollectionItemType.LONG))
+                if (!writer.writeMap(msg.boxedCharBoxedLongMap, MessageCollectionItemType.CHAR, MessageCollectionItemType.LONG))
                     return false;
 
                 writer.incrementState();
 
             case 19:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedFloatBoxedCharMap, MessageCollectionItemType.FLOAT, MessageCollectionItemType.CHAR))
+                if (!writer.writeMap(msg.boxedFloatBoxedCharMap, MessageCollectionItemType.FLOAT, MessageCollectionItemType.CHAR))
                     return false;
 
                 writer.incrementState();
 
             case 20:
-                if (!writer.writeMap(((TestMapMessage)msg).boxedDoubleBoxedFloatMap, MessageCollectionItemType.DOUBLE, MessageCollectionItemType.FLOAT))
+                if (!writer.writeMap(msg.boxedDoubleBoxedFloatMap, MessageCollectionItemType.DOUBLE, MessageCollectionItemType.FLOAT))
                     return false;
 
                 writer.incrementState();
 
             case 21:
-                if (!writer.writeMap(((TestMapMessage)msg).messageBoxedDoubleMap, MessageCollectionItemType.MSG, MessageCollectionItemType.DOUBLE))
+                if (!writer.writeMap(msg.messageBoxedDoubleMap, MessageCollectionItemType.MSG, MessageCollectionItemType.DOUBLE))
                     return false;
 
                 writer.incrementState();
 
             case 22:
-                if (!writer.writeMap(((TestMapMessage)msg).integerGridLongListMap, MessageCollectionItemType.INT, MessageCollectionItemType.GRID_LONG_LIST))
+                if (!writer.writeMap(msg.integerGridLongListMap, MessageCollectionItemType.INT, MessageCollectionItemType.GRID_LONG_LIST))
                     return false;
 
                 writer.incrementState();
 
             case 23:
-                if (!writer.writeMap(((TestMapMessage)msg).gridLongListIntegerMap, MessageCollectionItemType.GRID_LONG_LIST, MessageCollectionItemType.INT))
+                if (!writer.writeMap(msg.gridLongListIntegerMap, MessageCollectionItemType.GRID_LONG_LIST, MessageCollectionItemType.INT))
                     return false;
 
                 writer.incrementState();
@@ -191,12 +188,10 @@ public class TestMapMessageSerializer implements MessageSerializer {
     }
 
     /** */
-    @Override public boolean readFrom(Message m, MessageReader reader) {
-        TestMapMessage msg = (TestMapMessage)m;
-
+    @Override public boolean readFrom(TestMapMessage msg, MessageReader reader) {
         switch (reader.state()) {
             case 0:
-                ((TestMapMessage)msg).booleanArrayBoxedLongMap = reader.readMap(MessageCollectionItemType.BOOLEAN_ARR, MessageCollectionItemType.LONG, false);
+                msg.booleanArrayBoxedLongMap = reader.readMap(MessageCollectionItemType.BOOLEAN_ARR, MessageCollectionItemType.LONG, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -204,7 +199,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 1:
-                ((TestMapMessage)msg).byteArrayBooleanArrayMap = reader.readMap(MessageCollectionItemType.BYTE_ARR, MessageCollectionItemType.BOOLEAN_ARR, false);
+                msg.byteArrayBooleanArrayMap = reader.readMap(MessageCollectionItemType.BYTE_ARR, MessageCollectionItemType.BOOLEAN_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -212,7 +207,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 2:
-                ((TestMapMessage)msg).shortArrayByteArrayMap = reader.readMap(MessageCollectionItemType.SHORT_ARR, MessageCollectionItemType.BYTE_ARR, false);
+                msg.shortArrayByteArrayMap = reader.readMap(MessageCollectionItemType.SHORT_ARR, MessageCollectionItemType.BYTE_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -220,7 +215,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 3:
-                ((TestMapMessage)msg).intArrayShortArrayMap = reader.readMap(MessageCollectionItemType.INT_ARR, MessageCollectionItemType.SHORT_ARR, false);
+                msg.intArrayShortArrayMap = reader.readMap(MessageCollectionItemType.INT_ARR, MessageCollectionItemType.SHORT_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -228,7 +223,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 4:
-                ((TestMapMessage)msg).longArrayIntArrayMap = reader.readMap(MessageCollectionItemType.LONG_ARR, MessageCollectionItemType.INT_ARR, false);
+                msg.longArrayIntArrayMap = reader.readMap(MessageCollectionItemType.LONG_ARR, MessageCollectionItemType.INT_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -236,7 +231,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 5:
-                ((TestMapMessage)msg).charArrayLongArrayMap = reader.readMap(MessageCollectionItemType.CHAR_ARR, MessageCollectionItemType.LONG_ARR, false);
+                msg.charArrayLongArrayMap = reader.readMap(MessageCollectionItemType.CHAR_ARR, MessageCollectionItemType.LONG_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -244,7 +239,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 6:
-                ((TestMapMessage)msg).floatArrayCharArrayMap = reader.readMap(MessageCollectionItemType.FLOAT_ARR, MessageCollectionItemType.CHAR_ARR, false);
+                msg.floatArrayCharArrayMap = reader.readMap(MessageCollectionItemType.FLOAT_ARR, MessageCollectionItemType.CHAR_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -252,7 +247,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 7:
-                ((TestMapMessage)msg).doubleArrayFloatArrayMap = reader.readMap(MessageCollectionItemType.DOUBLE_ARR, MessageCollectionItemType.FLOAT_ARR, false);
+                msg.doubleArrayFloatArrayMap = reader.readMap(MessageCollectionItemType.DOUBLE_ARR, MessageCollectionItemType.FLOAT_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -260,7 +255,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 8:
-                ((TestMapMessage)msg).stringDoubleArrayMap = reader.readMap(MessageCollectionItemType.STRING, MessageCollectionItemType.DOUBLE_ARR, false);
+                msg.stringDoubleArrayMap = reader.readMap(MessageCollectionItemType.STRING, MessageCollectionItemType.DOUBLE_ARR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -268,7 +263,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 9:
-                ((TestMapMessage)msg).uuidStringMap = reader.readMap(MessageCollectionItemType.UUID, MessageCollectionItemType.STRING, false);
+                msg.uuidStringMap = reader.readMap(MessageCollectionItemType.UUID, MessageCollectionItemType.STRING, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -276,7 +271,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 10:
-                ((TestMapMessage)msg).bitSetUuidMap = reader.readMap(MessageCollectionItemType.BIT_SET, MessageCollectionItemType.UUID, false);
+                msg.bitSetUuidMap = reader.readMap(MessageCollectionItemType.BIT_SET, MessageCollectionItemType.UUID, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -284,7 +279,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 11:
-                ((TestMapMessage)msg).igniteUuidBitSetMap = reader.readMap(MessageCollectionItemType.IGNITE_UUID, MessageCollectionItemType.BIT_SET, false);
+                msg.igniteUuidBitSetMap = reader.readMap(MessageCollectionItemType.IGNITE_UUID, MessageCollectionItemType.BIT_SET, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -292,7 +287,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 12:
-                ((TestMapMessage)msg).affTopVersionIgniteUuidMap = reader.readMap(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION, MessageCollectionItemType.IGNITE_UUID, false);
+                msg.affTopVersionIgniteUuidMap = reader.readMap(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION, MessageCollectionItemType.IGNITE_UUID, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -300,7 +295,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 13:
-                ((TestMapMessage)msg).boxedBooleanAffTopVersionMap = reader.readMap(MessageCollectionItemType.BOOLEAN, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION, false);
+                msg.boxedBooleanAffTopVersionMap = reader.readMap(MessageCollectionItemType.BOOLEAN, MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -308,7 +303,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 14:
-                ((TestMapMessage)msg).boxedByteBoxedBooleanMap = reader.readMap(MessageCollectionItemType.BYTE, MessageCollectionItemType.BOOLEAN, false);
+                msg.boxedByteBoxedBooleanMap = reader.readMap(MessageCollectionItemType.BYTE, MessageCollectionItemType.BOOLEAN, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -316,7 +311,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 15:
-                ((TestMapMessage)msg).boxedShortBoxedByteMap = reader.readMap(MessageCollectionItemType.SHORT, MessageCollectionItemType.BYTE, false);
+                msg.boxedShortBoxedByteMap = reader.readMap(MessageCollectionItemType.SHORT, MessageCollectionItemType.BYTE, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -324,7 +319,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 16:
-                ((TestMapMessage)msg).boxedIntBoxedShortMap = reader.readMap(MessageCollectionItemType.INT, MessageCollectionItemType.SHORT, false);
+                msg.boxedIntBoxedShortMap = reader.readMap(MessageCollectionItemType.INT, MessageCollectionItemType.SHORT, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -332,7 +327,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 17:
-                ((TestMapMessage)msg).boxedLongBoxedIntMap = reader.readMap(MessageCollectionItemType.LONG, MessageCollectionItemType.INT, false);
+                msg.boxedLongBoxedIntMap = reader.readMap(MessageCollectionItemType.LONG, MessageCollectionItemType.INT, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -340,7 +335,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 18:
-                ((TestMapMessage)msg).boxedCharBoxedLongMap = reader.readMap(MessageCollectionItemType.CHAR, MessageCollectionItemType.LONG, false);
+                msg.boxedCharBoxedLongMap = reader.readMap(MessageCollectionItemType.CHAR, MessageCollectionItemType.LONG, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -348,7 +343,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 19:
-                ((TestMapMessage)msg).boxedFloatBoxedCharMap = reader.readMap(MessageCollectionItemType.FLOAT, MessageCollectionItemType.CHAR, false);
+                msg.boxedFloatBoxedCharMap = reader.readMap(MessageCollectionItemType.FLOAT, MessageCollectionItemType.CHAR, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -356,7 +351,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 20:
-                ((TestMapMessage)msg).boxedDoubleBoxedFloatMap = reader.readMap(MessageCollectionItemType.DOUBLE, MessageCollectionItemType.FLOAT, false);
+                msg.boxedDoubleBoxedFloatMap = reader.readMap(MessageCollectionItemType.DOUBLE, MessageCollectionItemType.FLOAT, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -364,7 +359,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 21:
-                ((TestMapMessage)msg).messageBoxedDoubleMap = reader.readMap(MessageCollectionItemType.MSG, MessageCollectionItemType.DOUBLE, false);
+                msg.messageBoxedDoubleMap = reader.readMap(MessageCollectionItemType.MSG, MessageCollectionItemType.DOUBLE, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -372,7 +367,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 22:
-                ((TestMapMessage)msg).integerGridLongListMap = reader.readMap(MessageCollectionItemType.INT, MessageCollectionItemType.GRID_LONG_LIST, false);
+                msg.integerGridLongListMap = reader.readMap(MessageCollectionItemType.INT, MessageCollectionItemType.GRID_LONG_LIST, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -380,7 +375,7 @@ public class TestMapMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 23:
-                ((TestMapMessage)msg).gridLongListIntegerMap = reader.readMap(MessageCollectionItemType.GRID_LONG_LIST, MessageCollectionItemType.INT, false);
+                msg.gridLongListIntegerMap = reader.readMap(MessageCollectionItemType.GRID_LONG_LIST, MessageCollectionItemType.INT, false);
 
                 if (!reader.isLastRead())
                     return false;
diff --git a/modules/core/src/test/resources/codegen/TestMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMessageSerializer.java
index 10a7eb4a8a884..f14de0fc03b25 100644
--- a/modules/core/src/test/resources/codegen/TestMessageSerializer.java
+++ b/modules/core/src/test/resources/codegen/TestMessageSerializer.java
@@ -19,7 +19,6 @@
 
 import org.apache.ignite.internal.TestMessage;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
-import org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
 import org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
@@ -30,11 +29,9 @@
  *
  * @see org.apache.ignite.internal.MessageProcessor
  */
-public class TestMessageSerializer implements MessageSerializer {
+public class TestMessageSerializer implements MessageSerializer {
     /** */
-    @Override public boolean writeTo(Message m, MessageWriter writer) {
-        TestMessage msg = (TestMessage)m;
-
+    @Override public boolean writeTo(TestMessage msg, MessageWriter writer) {
         if (!writer.isHeaderWritten()) {
             if (!writer.writeHeader(msg.directType()))
                 return false;
@@ -44,67 +41,67 @@ public class TestMessageSerializer implements MessageSerializer {
 
         switch (writer.state()) {
             case 0:
-                if (!writer.writeInt(((TestMessage)msg).id))
+                if (!writer.writeInt(msg.id))
                     return false;
 
                 writer.incrementState();
 
             case 1:
-                if (!writer.writeByteArray(((TestMessage)msg).byteArr))
+                if (!writer.writeByteArray(msg.byteArr))
                     return false;
 
                 writer.incrementState();
 
             case 2:
-                if (!writer.writeString(((TestMessage)msg).str))
+                if (!writer.writeString(msg.str))
                     return false;
 
                 writer.incrementState();
 
             case 3:
-                if (!writer.writeObjectArray(((TestMessage)msg).strArr, MessageCollectionItemType.STRING))
+                if (!writer.writeObjectArray(msg.strArr, MessageCollectionItemType.STRING))
                     return false;
 
                 writer.incrementState();
 
             case 4:
-                if (!writer.writeObjectArray(((TestMessage)msg).intMatrix, MessageCollectionItemType.INT_ARR))
+                if (!writer.writeObjectArray(msg.intMatrix, MessageCollectionItemType.INT_ARR))
                     return false;
 
                 writer.incrementState();
 
             case 5:
-                if (!writer.writeMessage(((TestMessage)msg).ver))
+                if (!writer.writeMessage(msg.ver))
                     return false;
 
                 writer.incrementState();
 
             case 6:
-                if (!writer.writeObjectArray(((TestMessage)msg).verArr, MessageCollectionItemType.MSG))
+                if (!writer.writeObjectArray(msg.verArr, MessageCollectionItemType.MSG))
                     return false;
 
                 writer.incrementState();
 
             case 7:
-                if (!writer.writeUuid(((TestMessage)msg).uuid))
+                if (!writer.writeUuid(msg.uuid))
                     return false;
 
                 writer.incrementState();
 
             case 8:
-                if (!writer.writeIgniteUuid(((TestMessage)msg).ignUuid))
+                if (!writer.writeIgniteUuid(msg.ignUuid))
                     return false;
 
                 writer.incrementState();
 
             case 9:
-                if (!writer.writeAffinityTopologyVersion(((TestMessage)msg).topVer))
+                if (!writer.writeAffinityTopologyVersion(msg.topVer))
                     return false;
 
                 writer.incrementState();
 
             case 10:
-                if (!writer.writeBitSet(((TestMessage)msg).bitSet))
+                if (!writer.writeBitSet(msg.bitSet))
                     return false;
 
                 writer.incrementState();
@@ -116,19 +113,19 @@ public class TestMessageSerializer implements MessageSerializer {
                 writer.incrementState();
 
             case 12:
-                if (!writer.writeKeyCacheObject(((TestMessage)msg).keyCacheObject))
+                if (!writer.writeKeyCacheObject(msg.keyCacheObject))
                     return false;
 
                 writer.incrementState();
 
             case 13:
-                if (!writer.writeCacheObject(((TestMessage)msg).cacheObject))
+                if (!writer.writeCacheObject(msg.cacheObject))
                     return false;
 
                 writer.incrementState();
 
             case 14:
-                if (!writer.writeGridLongList(((TestMessage)msg).gridLongList))
+                if (!writer.writeGridLongList(msg.gridLongList))
                     return false;
 
                 writer.incrementState();
@@ -138,12 +135,10 @@ public class TestMessageSerializer implements MessageSerializer {
     }
 
     /** */
-    @Override public boolean readFrom(Message m, MessageReader reader) {
-        TestMessage msg = (TestMessage)m;
-
+    @Override public boolean readFrom(TestMessage msg, MessageReader reader) {
         switch (reader.state()) {
             case 0:
-                ((TestMessage)msg).id = reader.readInt();
+                msg.id = reader.readInt();
 
                 if (!reader.isLastRead())
                     return false;
@@ -151,7 +146,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 1:
-                ((TestMessage)msg).byteArr = reader.readByteArray();
+                msg.byteArr = reader.readByteArray();
 
                 if (!reader.isLastRead())
                     return false;
@@ -159,7 +154,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 2:
-                ((TestMessage)msg).str = reader.readString();
+                msg.str = reader.readString();
 
                 if (!reader.isLastRead())
                     return false;
@@ -167,7 +162,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 3:
-                ((TestMessage)msg).strArr = reader.readObjectArray(MessageCollectionItemType.STRING, String.class);
+                msg.strArr = reader.readObjectArray(MessageCollectionItemType.STRING, String.class);
 
                 if (!reader.isLastRead())
                     return false;
@@ -175,7 +170,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 4:
-                ((TestMessage)msg).intMatrix = reader.readObjectArray(MessageCollectionItemType.INT, int[].class);
+                msg.intMatrix = reader.readObjectArray(MessageCollectionItemType.INT, int[].class);
 
                 if (!reader.isLastRead())
                     return false;
@@ -183,7 +178,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 5:
-                ((TestMessage)msg).ver = reader.readMessage();
+                msg.ver = reader.readMessage();
 
                 if (!reader.isLastRead())
                     return false;
@@ -191,7 +186,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 6:
-                ((TestMessage)msg).verArr = reader.readObjectArray(MessageCollectionItemType.MSG, GridCacheVersion.class);
+                msg.verArr = reader.readObjectArray(MessageCollectionItemType.MSG, GridCacheVersion.class);
 
                 if (!reader.isLastRead())
                     return false;
@@ -199,7 +194,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 7:
-                ((TestMessage)msg).uuid = reader.readUuid();
+                msg.uuid = reader.readUuid();
 
                 if (!reader.isLastRead())
                     return false;
@@ -207,7 +202,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 8:
-                ((TestMessage)msg).ignUuid = reader.readIgniteUuid();
+                msg.ignUuid = reader.readIgniteUuid();
 
                 if (!reader.isLastRead())
                     return false;
@@ -215,7 +210,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 9:
-                ((TestMessage)msg).topVer = reader.readAffinityTopologyVersion();
+                msg.topVer = reader.readAffinityTopologyVersion();
 
                 if (!reader.isLastRead())
                     return false;
@@ -223,7 +218,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 10:
-                ((TestMessage)msg).bitSet = reader.readBitSet();
+                msg.bitSet = reader.readBitSet();
 
                 if (!reader.isLastRead())
                     return false;
@@ -239,7 +234,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 12:
-                ((TestMessage)msg).keyCacheObject = reader.readKeyCacheObject();
+                msg.keyCacheObject = reader.readKeyCacheObject();
 
                 if (!reader.isLastRead())
                     return false;
@@ -247,7 +242,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 13:
-                ((TestMessage)msg).cacheObject = reader.readCacheObject();
+                msg.cacheObject = reader.readCacheObject();
 
                 if (!reader.isLastRead())
                     return false;
@@ -255,7 +250,7 @@ public class TestMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 14:
-                ((TestMessage)msg).gridLongList = reader.readGridLongList();
+                msg.gridLongList = reader.readGridLongList();
 
                 if (!reader.isLastRead())
                     return false;

From 0bed1f413c2b01bfc8e1ea3f4d81e4d1056e193d Mon Sep 17 00:00:00 2001
From: Vladimir Steshin 
Date: Wed, 4 Mar 2026 20:34:59 +0300
Subject: [PATCH 44/47] checkstyle

---
 .../org/apache/ignite/internal/MessageSerializerGenerator.java | 3 +--
 .../tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java       | 1 -
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
index 3f4a59bae381f..d8092aba619e7 100644
--- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
+++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
@@ -51,7 +51,6 @@
 import javax.tools.FileObject;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
-import org.apache.ignite.internal.systemview.SystemViewRowAttributeWalkerProcessor;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.jetbrains.annotations.Nullable;
@@ -963,7 +962,7 @@ private void writeClassHeader(TypeElement type, Writer writer, String pkgName, S
         writer.write(CLS_JAVADOC);
         writer.write(NL);
 
-        writer.write("public class " + serClsName + " implements MessageSerializer<"+type.getSimpleName()+"> {" + NL);
+        writer.write("public class " + serClsName + " implements MessageSerializer<" + type.getSimpleName() + "> {" + NL);
     }
 
     /** */
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java
index bf43459b2b186..820c42156b53e 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java
@@ -23,7 +23,6 @@
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.Order;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
-import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.Marshaller;

From c189dc2cbf33c148277e0a60681a02eacf1bca2d Mon Sep 17 00:00:00 2001
From: Vladimir Steshin 
Date: Fri, 6 Mar 2026 12:51:14 +0300
Subject: [PATCH 45/47] + master

---
 .../tcp/messages/TcpDiscoveryClientReconnectMessage.java        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java
index 8ba5a8b555c21..83ac6fbd2c154 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryClientReconnectMessage.java
@@ -157,7 +157,7 @@ public boolean success() {
 
     /** {@inheritDoc} */
     @Override public short directType() {
-        return 23;
+        return 24;
     }
 
     /** {@inheritDoc} */

From f49fabb097480e5ce5c4d19a148c860d99acbc21 Mon Sep 17 00:00:00 2001
From: Vladimir Steshin 
Date: Fri, 6 Mar 2026 12:55:24 +0300
Subject: [PATCH 46/47] major codegen fixes

---
 .../internal/MessageSerializerGenerator.java  | 89 +++++++++++++------
 .../resources/codegen/AbstractMessage.java    |  3 +
 .../test/resources/codegen/ChildMessage.java  |  3 +
 .../codegen/ChildMessageSerializer.java       | 33 ++++++-
 4 files changed, 100 insertions(+), 28 deletions(-)

diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
index d8092aba619e7..da844353a1024 100644
--- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
+++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java
@@ -51,6 +51,7 @@
 import javax.tools.FileObject;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
+import org.apache.ignite.internal.systemview.SystemViewRowAttributeWalkerProcessor;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.jetbrains.annotations.Nullable;
@@ -108,6 +109,9 @@ public class MessageSerializerGenerator {
     /** */
     private final ProcessingEnvironment env;
 
+    /** Stored type of the message being processed. */
+    private TypeElement type;
+
     /** The marshallable message type. */
     private final TypeMirror marshallableMsgType;
 
@@ -123,11 +127,17 @@ public class MessageSerializerGenerator {
 
     /** */
     void generate(TypeElement type, List fields) throws Exception {
-        generateMethods(type, fields);
+        assert this.type == null : "Message serializer generator isn't stateless and is supposed to be single-use.";
+
+        this.type = type;
+
+        generateMethods(fields);
+
+        SystemViewRowAttributeWalkerProcessor.superclasses(env, type).forEach(el -> imports.add(el.toString()));
 
-        String serClsName = type.getSimpleName() + (marshallableMessage(type) ? "Marshallable" : "") + "Serializer";
+        String serClsName = type.getSimpleName() + (marshallableMessage() ? "Marshallable" : "") + "Serializer";
         String serFqnClsName = env.getElementUtils().getPackageOf(type) + "." + serClsName;
-        String serCode = generateSerializerCode(type, serClsName);
+        String serCode = generateSerializerCode(serClsName);
 
         try {
             JavaFileObject file = env.getFiler().createSourceFile(serFqnClsName);
@@ -155,19 +165,19 @@ void generate(TypeElement type, List fields) throws Exception {
     }
 
     /** Generates full code for a serializer class. */
-    private String generateSerializerCode(TypeElement type, String serClsName) throws IOException {
-        if (marshallableMessage(type)) {
+    private String generateSerializerCode(String serClsName) throws IOException {
+        if (marshallableMessage()) {
             fields.add("private final Marshaller marshaller;");
             fields.add("private final ClassLoader clsLdr;");
         }
 
         try (Writer writer = new StringWriter()) {
-            writeClassHeader(type, writer, env.getElementUtils().getPackageOf(type).toString(), serClsName);
+            writeClassHeader(writer, env.getElementUtils().getPackageOf(type).toString(), serClsName);
 
             writeClassFields(writer);
 
             ++indent;
-            writeConstructor(writer, type, serClsName);
+            writeConstructor(writer, serClsName);
             --indent;
 
             // Write #writeTo method.
@@ -191,8 +201,8 @@ private String generateSerializerCode(TypeElement type, String serClsName) throw
     }
 
     /** */
-    private void writeConstructor(Writer writer, TypeElement type, String serClsName) throws IOException {
-        if (!marshallableMessage(type))
+    private void writeConstructor(Writer writer, String serClsName) throws IOException {
+        if (!marshallableMessage())
             return;
 
         writer.write(identedLine(METHOD_JAVADOC));
@@ -214,9 +224,9 @@ private void writeConstructor(Writer writer, TypeElement type, String serClsName
     }
 
     /** Generates code for {@code writeTo} and {@code readFrom}. */
-    private void generateMethods(TypeElement type, List fields) throws Exception {
-        start(type, write, true);
-        start(type, read, false);
+    private void generateMethods(List fields) throws Exception {
+        start(write, true);
+        start(read, false);
 
         indent++;
 
@@ -228,7 +238,7 @@ private void generateMethods(TypeElement type, List fields) thr
         indent--;
 
         finish(write, false, false);
-        finish(read, true, marshallableMessage(type));
+        finish(read, true, marshallableMessage());
     }
 
     /**
@@ -246,7 +256,7 @@ private void generateMethods(TypeElement type, List fields) thr
      * @param code Code lines.
      * @param write Whether write code is generated.
      */
-    private void start(TypeElement type, Collection code, boolean write) {
+    private void start(Collection code, boolean write) {
         indent = 1;
 
         code.add(identedLine(METHOD_JAVADOC));
@@ -264,7 +274,7 @@ private void start(TypeElement type, Collection code, boolean write) {
 
             returnFalseIfWriteFailed(code, "writer.writeHeader", "directType()");
 
-            if (write && marshallableMessage(type)) {
+            if (write && marshallableMessage()) {
                 code.add(EMPTY);
 
                 code.add(identedLine("msg.prepareMarshal(marshaller);"));
@@ -545,8 +555,14 @@ private void returnFalseIfWriteFailed(Collection code, VariableElement f
 
         String methodName = field.getAnnotation(Order.class).method();
 
-        if (Objects.equals(methodName, ""))
-            code.add(identedLine("if (!%s(msg.%s))", accessor, argsStr));
+        if (Objects.equals(methodName, "")) {
+            if (type.equals(field.getEnclosingElement()))
+                code.add(identedLine("if (!%s(msg.%s))", accessor, argsStr));
+            else {
+                // Field has to be requested from a super class object.
+                code.add(identedLine("if (!%s(((%s)msg).%s))", accessor, field.getEnclosingElement().getSimpleName(), argsStr));
+            }
+        }
         else
             code.add(identedLine("if (!%s(msg.%s))", accessor, argsStr));
 
@@ -568,8 +584,15 @@ private void returnFalseIfEnumWriteFailed(
         String fieldGetterCall) {
         String methodName = field.getAnnotation(Order.class).method();
 
-        if (Objects.equals(methodName, ""))
-            code.add(identedLine("if (!%s(%s(msg.%s)))", writerCall, mapperCall, fieldGetterCall));
+        if (Objects.equals(methodName, "")) {
+            if (type.equals(field.getEnclosingElement()))
+                code.add(identedLine("if (!%s(%s(msg.%s)))", writerCall, mapperCall, fieldGetterCall));
+            else {
+                // Field has to be requested from a super class object.
+                code.add(identedLine("if (!%s(%s(((%s)msg).%s)))",
+                    writerCall, mapperCall, field.getEnclosingElement().getSimpleName(), fieldGetterCall));
+            }
+        }
         else
             code.add(identedLine("if (!%s(%s(msg.%s)))", writerCall, mapperCall, fieldGetterCall));
 
@@ -817,8 +840,15 @@ private void returnFalseIfReadFailed(VariableElement field, String mtd, String..
 
         String methodName = field.getAnnotation(Order.class).method();
 
-        if (Objects.equals(methodName, ""))
-            read.add(identedLine("msg.%s = %s(%s);", field.getSimpleName().toString(), mtd, argsStr));
+        if (Objects.equals(methodName, "")) {
+            if (type.equals(field.getEnclosingElement()))
+                read.add(identedLine("msg.%s = %s(%s);", field.getSimpleName().toString(), mtd, argsStr));
+            else {
+                // Field has to be requested from a super class object.
+                read.add(identedLine("((%s)msg).%s = %s(%s);",
+                    field.getEnclosingElement().getSimpleName(), field.getSimpleName().toString(), mtd, argsStr));
+            }
+        }
         else
             read.add(identedLine("msg.%s(%s(%s));", methodName, mtd, argsStr));
 
@@ -848,8 +878,15 @@ private void returnFalseIfEnumReadFailed(VariableElement field, String mapperDec
 
         String methodName = field.getAnnotation(Order.class).method();
 
-        if (Objects.equals(methodName, ""))
-            read.add(identedLine("msg.%s = %s;", field.getSimpleName().toString(), readOp));
+        if (Objects.equals(methodName, "")) {
+            if (type.equals(field.getEnclosingElement()))
+                read.add(identedLine("msg.%s = %s;", field.getSimpleName().toString(), readOp));
+            else {
+                // Field has to be requested from a super class object.
+                read.add(identedLine("((%s)msg).%s = %s;",
+                    field.getEnclosingElement().getSimpleName(), field.getSimpleName().toString(), readOp));
+            }
+        }
         else
             read.add(identedLine("msg.%s(%s);", methodName, readOp));
 
@@ -931,7 +968,7 @@ private void writeClassFields(Writer writer) throws IOException {
     }
 
     /** Write header of serializer class: license, imports, class declaration. */
-    private void writeClassHeader(TypeElement type, Writer writer, String pkgName, String serClsName) throws IOException {
+    private void writeClassHeader(Writer writer, String pkgName, String serClsName) throws IOException {
         try (InputStream in = getClass().getClassLoader().getResourceAsStream("license.txt");
              BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
 
@@ -948,7 +985,7 @@ private void writeClassHeader(TypeElement type, Writer writer, String pkgName, S
 
         imports.add(type.toString());
 
-        if (marshallableMessage(type))
+        if (marshallableMessage())
             imports.add("org.apache.ignite.marshaller.Marshaller");
 
         imports.add("org.apache.ignite.plugin.extensions.communication.MessageSerializer");
@@ -966,7 +1003,7 @@ private void writeClassHeader(TypeElement type, Writer writer, String pkgName, S
     }
 
     /** */
-    private boolean marshallableMessage(TypeElement type) {
+    private boolean marshallableMessage() {
         return env.getTypeUtils().isAssignable(type.asType(), marshallableMsgType);
     }
 
diff --git a/modules/core/src/test/resources/codegen/AbstractMessage.java b/modules/core/src/test/resources/codegen/AbstractMessage.java
index a309841ba5c4a..d63c3cc5f2ffb 100644
--- a/modules/core/src/test/resources/codegen/AbstractMessage.java
+++ b/modules/core/src/test/resources/codegen/AbstractMessage.java
@@ -26,6 +26,9 @@ public abstract class AbstractMessage implements Message {
     @Order(0)
     int id;
 
+    @Order(1)
+    byte flags;
+
     public short directType() {
         return 0;
     }
diff --git a/modules/core/src/test/resources/codegen/ChildMessage.java b/modules/core/src/test/resources/codegen/ChildMessage.java
index fa97a6cbc4441..b89460948a889 100644
--- a/modules/core/src/test/resources/codegen/ChildMessage.java
+++ b/modules/core/src/test/resources/codegen/ChildMessage.java
@@ -23,4 +23,7 @@
 public class ChildMessage extends AbstractMessage {
     @Order(0)
     String str;
+
+    @Order(1)
+    byte flags;
 }
diff --git a/modules/core/src/test/resources/codegen/ChildMessageSerializer.java b/modules/core/src/test/resources/codegen/ChildMessageSerializer.java
index d8cd5ab58d85e..9ca035db40488 100644
--- a/modules/core/src/test/resources/codegen/ChildMessageSerializer.java
+++ b/modules/core/src/test/resources/codegen/ChildMessageSerializer.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal;
 
+import org.apache.ignite.internal.AbstractMessage;
 import org.apache.ignite.internal.ChildMessage;
 import org.apache.ignite.plugin.extensions.communication.MessageReader;
 import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
@@ -39,16 +40,28 @@ public class ChildMessageSerializer implements MessageSerializer {
 
         switch (writer.state()) {
             case 0:
-                if (!writer.writeInt(msg.id))
+                if (!writer.writeInt(((AbstractMessage)msg).id))
                     return false;
 
                 writer.incrementState();
 
             case 1:
+                if (!writer.writeByte(((AbstractMessage)msg).flags))
+                    return false;
+
+                writer.incrementState();
+
+            case 2:
                 if (!writer.writeString(msg.str))
                     return false;
 
                 writer.incrementState();
+
+            case 3:
+                if (!writer.writeByte(msg.flags))
+                    return false;
+
+                writer.incrementState();
         }
 
         return true;
@@ -58,7 +71,7 @@ public class ChildMessageSerializer implements MessageSerializer {
     @Override public boolean readFrom(ChildMessage msg, MessageReader reader) {
         switch (reader.state()) {
             case 0:
-                msg.id = reader.readInt();
+                ((AbstractMessage)msg).id = reader.readInt();
 
                 if (!reader.isLastRead())
                     return false;
@@ -66,8 +79,24 @@ public class ChildMessageSerializer implements MessageSerializer {
                 reader.incrementState();
 
             case 1:
+                ((AbstractMessage)msg).flags = reader.readByte();
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 2:
                 msg.str = reader.readString();
 
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 3:
+                msg.flags = reader.readByte();
+
                 if (!reader.isLastRead())
                     return false;
 

From a37044b22faa94fe7f8f1e43098b05c8ad40266f Mon Sep 17 00:00:00 2001
From: Vladimir Steshin 
Date: Sat, 7 Mar 2026 11:37:56 +0300
Subject: [PATCH 47/47] test fix

---
 .../communication/AbstractMessageSerializationTest.java        | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/AbstractMessageSerializationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/AbstractMessageSerializationTest.java
index 317ff20a961ec..2f28cfc4146b0 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/AbstractMessageSerializationTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/AbstractMessageSerializationTest.java
@@ -435,7 +435,8 @@ private void readField(Class type) {
         @Override public byte[] readByteArray() {
             readField(byte[].class);
 
-            return new byte[0];
+            // Messages may try to post-marshall non-null byte data.
+            return null;
         }
 
         /** {@inheritDoc} */