diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 489973f..4fa3564 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -71,6 +71,7 @@ import org.apache.ignite.lang.*; import org.apache.ignite.lifecycle.*; import org.apache.ignite.marshaller.*; import org.apache.ignite.marshaller.optimized.*; +import org.apache.ignite.marshaller.portable.*; import org.apache.ignite.mxbean.*; import org.apache.ignite.plugin.*; import org.apache.ignite.spi.*; @@ -1170,6 +1171,9 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { add(ATTR_MARSHALLER, cfg.getMarshaller().getClass().getName()); add(ATTR_USER_NAME, System.getProperty("user.name")); add(ATTR_GRID_NAME, gridName); + add(ATTR_PORTABLE_PROTO_VER, cfg.getMarshaller() instanceof PortableMarshaller ? + ((PortableMarshaller)cfg.getMarshaller()).getProtocolVersion().toString() : + PortableMarshaller.DFLT_PORTABLE_PROTO_VER.toString()); add(ATTR_PEER_CLASSLOADING, cfg.isPeerClassLoadingEnabled()); add(ATTR_DEPLOYMENT_MODE, cfg.getDeploymentMode()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java index 10b8df0..ea3eafd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java @@ -135,6 +135,9 @@ public final class IgniteNodeAttributes { /** Node consistent id. */ public static final String ATTR_NODE_CONSISTENT_ID = ATTR_PREFIX + ".consistent.id"; + /** Portable protocol version. */ + public static final String ATTR_PORTABLE_PROTO_VER = ATTR_PREFIX + ".portable.proto.ver"; + /** * Enforces singleton. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java index a7363af..8437468 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java @@ -906,6 +906,8 @@ public class GridDiscoveryManager extends GridManagerAdapter { // Fetch local node attributes once. String locPreferIpV4 = locNode.attribute("java.net.preferIPv4Stack"); + String locPortableProtoVer = locNode.attribute(ATTR_PORTABLE_PROTO_VER); + Object locMode = locNode.attribute(ATTR_DEPLOYMENT_MODE); int locJvmMajVer = nodeJavaMajorVersion(locNode); @@ -950,11 +952,18 @@ public class GridDiscoveryManager extends GridManagerAdapter { boolean rmtP2pEnabled = n.attribute(ATTR_PEER_CLASSLOADING); if (locP2pEnabled != rmtP2pEnabled) - throw new IgniteCheckedException("Remote node has peer class loading enabled flag different from local " + - "[locId8=" + U.id8(locNode.id()) + ", locPeerClassLoading=" + locP2pEnabled + + throw new IgniteCheckedException("Remote node has peer class loading enabled flag different from" + + " local [locId8=" + U.id8(locNode.id()) + ", locPeerClassLoading=" + locP2pEnabled + ", rmtId8=" + U.id8(n.id()) + ", rmtPeerClassLoading=" + rmtP2pEnabled + ", rmtAddrs=" + U.addressesAsString(n) + ']'); } + + String rmtPortableProtoVer = n.attribute(ATTR_PORTABLE_PROTO_VER); + + // In order to support backward compatibility skip the check for nodes that don't have this attribute. + if (rmtPortableProtoVer != null && !F.eq(locPortableProtoVer, rmtPortableProtoVer)) + throw new IgniteCheckedException("Remote node has portable protocol version different from local " + + "[locVersion=" + locPortableProtoVer + ", rmtVersion=" + rmtPortableProtoVer + ']'); } if (log.isDebugEnabled()) diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java index 2cac90e..32f8b29 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/portable/PortableMarshaller.java @@ -277,6 +277,9 @@ public class PortableMarshaller extends AbstractMarshaller { * @param protoVer Portable protocol version. */ public void setProtocolVersion(PortableProtocolVersion protoVer) { + if (protoVer == null) + throw new IllegalArgumentException("Wrong portable protocol version: " + protoVer); + this.protoVer = protoVer; } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java index e76c615..7e11592 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java @@ -18,12 +18,17 @@ package org.apache.ignite.internal.managers.discovery; import org.apache.ignite.*; +import org.apache.ignite.cluster.*; import org.apache.ignite.configuration.*; +import org.apache.ignite.internal.*; import org.apache.ignite.spi.discovery.tcp.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; import org.apache.ignite.testframework.junits.common.*; +import java.lang.reflect.*; +import java.util.*; + import static org.apache.ignite.configuration.DeploymentMode.*; /** @@ -151,6 +156,51 @@ public abstract class GridDiscoveryManagerAttributesSelfTest extends GridCommonA } /** + * @throws Exception If failed. + */ + public void testDifferentPortableProtocolVersions() throws Exception { + startGridWithPortableProtocolVer("VER_99_99_99"); + + try { + startGrid(1); + + fail(); + } + catch (IgniteCheckedException e) { + if (!e.getCause().getMessage().startsWith("Remote node has portable protocol version different from local")) + throw e; + } + } + + /** + * @throws Exception If failed. + */ + public void testNullPortableProtocolVersion() throws Exception { + startGridWithPortableProtocolVer(null); + + // Must not fail in order to preserve backward compatibility with the nodes that don't have this property yet. + startGrid(1); + } + + /** + * @throws Exception If failed. + */ + private void startGridWithPortableProtocolVer(String ver) throws Exception { + Ignite ignite = startGrid(0); + + ClusterNode clusterNode = ignite.cluster().localNode(); + + Field f = clusterNode.getClass().getDeclaredField("attrs"); + f.setAccessible(true); + + Map attrs = new HashMap<>((Map)f.get(clusterNode)); + + attrs.put(IgniteNodeAttributes.ATTR_PORTABLE_PROTO_VER, ver); + + f.set(clusterNode, attrs); + } + + /** * @param preferIpV4 {@code java.net.preferIPv4Stack} system property value. * @throws Exception If failed. */