This is an automated email from the ASF dual-hosted git repository.
petrov-mg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 86943b54d24 IGNITE-28990 Extended IgniteClusterNode API with Ignite
Features getter (#13488)
86943b54d24 is described below
commit 86943b54d2436a41d38d8361f6446c59936d43d8
Author: Mikhail Petrov <[email protected]>
AuthorDate: Mon Aug 17 20:56:00 2026 +0300
IGNITE-28990 Extended IgniteClusterNode API with Ignite Features getter
(#13488)
---
.../jol/GridAffinityAssignmentJolBenchmark.java | 5 +-
.../ignite/internal/CoreMessagesProvider.java | 2 +
.../managers/discovery/IgniteClusterNode.java | 8 ++
.../wal/reader/StandaloneGridKernalContext.java | 8 +-
.../rollingupgrade/RollingUpgradeClusterData.java | 13 ++-
.../rollingupgrade/RollingUpgradeProcessor.java | 101 ++++++---------------
.../feature/IgniteNodeFeatureSet.java | 87 ++++++++++++++----
.../discovery/isolated/IsolatedDiscoverySpi.java | 8 +-
.../spi/discovery/isolated/IsolatedNode.java | 13 ++-
.../ignite/spi/discovery/tcp/ClientImpl.java | 2 +-
.../ignite/spi/discovery/tcp/ServerImpl.java | 6 +-
.../ignite/spi/discovery/tcp/TcpDiscoverySpi.java | 17 +---
.../discovery/tcp/internal/TcpDiscoveryNode.java | 26 +++++-
.../tcp/messages/TcpDiscoveryHandshakeRequest.java | 7 +-
.../messages/TcpDiscoveryHandshakeResponse.java | 7 +-
.../affinity/GridAffinityAssignmentV2Test.java | 4 +-
.../spi/discovery/zk/ZookeeperDiscoverySpi.java | 13 ++-
.../zk/internal/ZookeeperClusterNode.java | 17 ++++
.../zk/internal/ZookeeperDiscoverySpiTestBase.java | 14 +--
19 files changed, 218 insertions(+), 140 deletions(-)
diff --git
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jol/GridAffinityAssignmentJolBenchmark.java
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jol/GridAffinityAssignmentJolBenchmark.java
index df474379073..1477f3357ed 100644
---
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jol/GridAffinityAssignmentJolBenchmark.java
+++
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jol/GridAffinityAssignmentJolBenchmark.java
@@ -42,6 +42,8 @@ import
org.apache.ignite.spi.discovery.DiscoveryMetricsProvider;
import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
import org.openjdk.jol.info.GraphLayout;
+import static
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet.LOCAL_CORE_FEATURES;
+
/**
*
*/
@@ -333,7 +335,8 @@ public class GridAffinityAssignmentJolBenchmark {
0,
metrics,
ver,
- "Node_" + idx
+ "Node_" + idx,
+ LOCAL_CORE_FEATURES
);
node.setAttributes(Collections.emptyMap());
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
index ef05f8b47fd..f7537f0b20f 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
@@ -264,6 +264,7 @@ import
org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultRe
import
org.apache.ignite.internal.processors.rollingupgrade.RollingUpgradeClusterData;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteCoreFeatureSet;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeatureSet;
+import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgnitePluginFeatureSet;
import org.apache.ignite.internal.processors.security.SecurityContextWrapper;
import
org.apache.ignite.internal.processors.service.LazyServiceConfigurationMessage;
@@ -756,6 +757,7 @@ public class CoreMessagesProvider extends
AbstractMessageFactoryProvider {
register(IgniteCoreFeatureSet.class);
register(IgnitePluginFeatureSet.class);
register(RollingUpgradeClusterData.class);
+ register(IgniteNodeFeatureSet.class);
assert msgIdx <= MAX_MESSAGE_ID;
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteClusterNode.java
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteClusterNode.java
index 34ba45683ec..78abd199589 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteClusterNode.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteClusterNode.java
@@ -22,11 +22,19 @@ import java.util.Map;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cluster.ClusterMetrics;
import org.apache.ignite.cluster.ClusterNode;
+import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
/**
*
*/
public interface IgniteClusterNode extends ClusterNode {
+ /**
+ * Gets the set of Ignite features supported by this node.
+ *
+ * @return Ignite Node Feature set.
+ */
+ public IgniteNodeFeatureSet features();
+
/**
* Sets consistent globally unique node ID which survives node restarts.
*
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
index 44a5bdabcf5..835cfb15d14 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
@@ -91,7 +91,6 @@ import
org.apache.ignite.internal.processors.query.GridQueryProcessor;
import org.apache.ignite.internal.processors.resource.GridResourceProcessor;
import org.apache.ignite.internal.processors.rest.IgniteRestProcessor;
import
org.apache.ignite.internal.processors.rollingupgrade.RollingUpgradeProcessor;
-import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteCoreFeatureSet;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import
org.apache.ignite.internal.processors.schedule.IgniteScheduleProcessorAdapter;
import org.apache.ignite.internal.processors.security.IgniteSecurity;
@@ -116,6 +115,8 @@ import
org.apache.ignite.spi.metric.noop.NoopMetricExporterSpi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import static
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet.LOCAL_CORE_FEATURES;
+
/**
* Dummy context for offline utilities. All grid components registered in the
standalone context
* must be properly stopped since the lifecycle of them are controlled by
kernal.
@@ -179,9 +180,6 @@ public class StandaloneGridKernalContext implements
GridKernalContext {
/** Operation context dispacther. */
private final OperationContextDispatcher opCtxDispatcher = new
OperationContextDispatcher();
- /** */
- private final IgniteNodeFeatureSet locNodeFeatures = new
IgniteNodeFeatureSet(IgniteCoreFeatureSet.local());
-
/**
* @param log Logger.
* @param ft Node file tree.
@@ -324,7 +322,7 @@ public class StandaloneGridKernalContext implements
GridKernalContext {
/** {@inheritDoc} */
@Override public IgniteNodeFeatureSet localNodeFeatures() {
- return locNodeFeatures;
+ return LOCAL_CORE_FEATURES;
}
/** {@inheritDoc} */
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeClusterData.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeClusterData.java
index 1c86dbda18f..e842017f355 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeClusterData.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeClusterData.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.processors.rollingupgrade;
import java.util.UUID;
import org.apache.ignite.internal.Order;
-import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.jetbrains.annotations.Nullable;
@@ -36,11 +35,11 @@ public class RollingUpgradeClusterData implements Message {
/** */
@Order(2)
- IgniteComponentFeatureSet[] activeFeatures;
+ IgniteNodeFeatureSet activeFeatures;
/** */
@Order(3)
- @Nullable IgniteComponentFeatureSet[] prevActiveFeatures;
+ @Nullable IgniteNodeFeatureSet prevActiveFeatures;
/** */
public RollingUpgradeClusterData() {
@@ -56,17 +55,17 @@ public class RollingUpgradeClusterData implements Message {
) {
this.isVersionUpgradeEnabled = isVersionUpgradeEnabled;
this.curFinalizeProcId = curFinalizeProcId;
- this.activeFeatures = activeFeatures.values();
- this.prevActiveFeatures = prevActiveFeatures == null ? null :
prevActiveFeatures.values();
+ this.activeFeatures = activeFeatures;
+ this.prevActiveFeatures = prevActiveFeatures;
}
/** */
public IgniteNodeFeatureSet activeFeatures() {
- return new IgniteNodeFeatureSet(activeFeatures);
+ return activeFeatures;
}
/** */
@Nullable public IgniteNodeFeatureSet previousActiveFeatures() {
- return prevActiveFeatures == null ? null : new
IgniteNodeFeatureSet(prevActiveFeatures);
+ return prevActiveFeatures;
}
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
index 76318e8a3dd..690b1f29521 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
@@ -17,8 +17,8 @@
package org.apache.ignite.internal.processors.rollingupgrade;
+import java.util.Collection;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
@@ -33,6 +33,7 @@ import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.events.DiscoveryEvent;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.managers.discovery.IgniteClusterNode;
import org.apache.ignite.internal.processors.GridProcessorAdapter;
import
org.apache.ignite.internal.processors.nodevalidation.DiscoveryNodeValidationProcessor;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
@@ -57,7 +58,6 @@ import static
org.apache.ignite.events.EventType.EVT_NODE_JOINED;
import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
import static org.apache.ignite.events.EventType.EVT_NODE_VALIDATION_FAILED;
import static
org.apache.ignite.internal.GridComponent.DiscoveryDataExchangeType.ROLLING_UPGRADE_PROC;
-import static
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IGNITE_FEATURES;
import static
org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.RU_ABORT_VERSION_FINALIZATION;
import static
org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.RU_COMPLETE_VERSION_FINALIZATION;
import static
org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.RU_ENABLE;
@@ -174,19 +174,12 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
/** */
IgniteComponentUpgradeState state(String cmpName) {
synchronized (topGuard) {
- return detectComponentUpgradeState(clusterFeatures(), cmpName);
+ return detectComponentUpgradeState(clusterNodes(), cmpName);
}
}
/** {@inheritDoc} */
@Override public void start() throws IgniteCheckedException {
- ctx.addNodeAttribute(
- ATTR_IGNITE_FEATURES,
- U.marshal(
- ctx.marshallerContext().jdkMarshaller(),
- featureMgr.localVersionFeatures().values())
- );
-
ctx.event().addLocalEventListener(
evt -> {
synchronized (topGuard) {
@@ -236,16 +229,7 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
" cluster version finalization process is complete
[joiningNode=" + joiningNode + ']');
}
- IgniteNodeFeatureSet joiningNodeFeatures;
-
- try {
- joiningNodeFeatures = extractNodeFeatures(joiningNode);
- }
- catch (IgniteCheckedException e) {
- return new IgniteNodeValidationResult(
- joiningNode.id(),
- "Failed to resolve joining node features [joiningNode=" +
joiningNode + ", errMsg=" + e.getMessage() + ']');
- }
+ IgniteNodeFeatureSet joiningNodeFeatures =
extractNodeFeatures(joiningNode);
if (isVerUpgradeEnabled) {
if (!joiningNode.isClient() &&
!joiningNodeFeatures.components().containsAll(featureMgr.activeFeatures().components()))
{
@@ -258,10 +242,10 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
);
}
- Map<ClusterNode, IgniteNodeFeatureSet> clusterFeatures =
clusterFeatures();
+ Set<ClusterNode> clusterNodes = clusterNodes();
for (IgniteComponentFeatureSet rmtCmpFeatures :
joiningNodeFeatures.values()) {
- IgniteComponentUpgradeState state =
detectComponentUpgradeState(clusterFeatures, rmtCmpFeatures.componentName());
+ IgniteComponentUpgradeState state =
detectComponentUpgradeState(clusterNodes, rmtCmpFeatures.componentName());
if (!state.isCompatible(rmtCmpFeatures.version())) {
return new IgniteNodeValidationResult(
@@ -316,11 +300,8 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
}
/** */
- private IgniteComponentUpgradeState detectComponentUpgradeState(
- Map<ClusterNode, IgniteNodeFeatureSet> clusterFeatures,
- String cmpName
- ) {
- SortedSet<IgniteProductVersion> clusterCmpVersions =
distinctClusterComponentVersions(clusterFeatures, cmpName);
+ private IgniteComponentUpgradeState
detectComponentUpgradeState(Collection<ClusterNode> clusterNodes, String
cmpName) {
+ SortedSet<IgniteProductVersion> clusterCmpVersions =
distinctClusterComponentVersions(clusterNodes, cmpName);
assert !clusterCmpVersions.isEmpty() && clusterCmpVersions.size() <= 2
: "Cluster nodes must run no more than" +
" two versions of the component [cmpName=" + cmpName + ",
clusterCmpVersions=" + clusterCmpVersions.size() + "]";
@@ -342,20 +323,17 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
}
/** */
- private SortedSet<IgniteProductVersion> distinctClusterComponentVersions(
- Map<ClusterNode, IgniteNodeFeatureSet> clusterFeatures,
- String cmpName
- ) {
+ private SortedSet<IgniteProductVersion>
distinctClusterComponentVersions(Collection<ClusterNode> clusterNodes, String
cmpName) {
SortedSet<IgniteProductVersion> distinctCmpVersions = new
TreeSet<>(Comparator.nullsFirst(Comparator.naturalOrder()));
- clusterFeatures.forEach((node, nodeFeatures) -> {
- IgniteComponentFeatureSet cmpFeatures =
nodeFeatures.componentFeatures(cmpName);
+ for (ClusterNode node : clusterNodes) {
+ IgniteComponentFeatureSet cmpFeatures =
extractNodeFeatures(node).componentFeatures(cmpName);
if (node.isClient() && cmpFeatures == null)
- return; // Components are optional on client nodes, even when
they are configured on servers.
+ continue; // Components are optional on client nodes, even
when they are configured on servers.
distinctCmpVersions.add(cmpFeatures == null ? null :
cmpFeatures.version());
- });
+ }
return distinctCmpVersions;
}
@@ -371,17 +349,17 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
/** */
private boolean isReadyForVersionFinalization() {
- Map<ClusterNode, IgniteNodeFeatureSet> clusterFeatures =
clusterFeatures();
+ Collection<ClusterNode> clusterNodes = clusterNodes();
Set<IgniteNodeFeatureSet> distinctServerNodeFeatureSets = new
HashSet<>();
Set<IgniteNodeFeatureSet> distinctClientNodeFeatureSets = new
HashSet<>();
- clusterFeatures.forEach((node, features) -> {
+ for (ClusterNode node : clusterNodes) {
if (!node.isClient())
- distinctServerNodeFeatureSets.add(features);
+ distinctServerNodeFeatureSets.add(extractNodeFeatures(node));
else
- distinctClientNodeFeatureSets.add(features);
- });
+ distinctClientNodeFeatureSets.add(extractNodeFeatures(node));
+ }
if (distinctServerNodeFeatureSets.size() != 1)
return false;
@@ -402,15 +380,10 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
}
/** */
- private IgniteNodeFeatureSet extractNodeFeatures(ClusterNode node) throws
IgniteCheckedException {
- byte[] attrVal = node.attribute(ATTR_IGNITE_FEATURES);
+ private static IgniteNodeFeatureSet extractNodeFeatures(ClusterNode node) {
+ assert node instanceof IgniteClusterNode : node;
- IgniteComponentFeatureSet[] nodeFeatures = U.unmarshal(
- ctx.marshallerContext().jdkMarshaller(),
- attrVal,
- U.resolveClassLoader(ctx.config()));
-
- return new IgniteNodeFeatureSet(nodeFeatures);
+ return ((IgniteClusterNode)node).features();
}
/** */
@@ -418,25 +391,6 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
return F.isEmpty(errors) ? null : F.firstValue(errors);
}
- /** */
- private Map<ClusterNode, IgniteNodeFeatureSet> clusterFeatures() {
- assert Thread.holdsLock(topGuard);
-
- try {
- Map<ClusterNode, IgniteNodeFeatureSet> res = new HashMap<>();
-
- for (ClusterNode node : clusterNodes())
- res.put(node, extractNodeFeatures(node));
-
- return res;
- }
- catch (IgniteCheckedException e) {
- U.error(log, "Failed to resolve cluster features", e);
-
- throw new IgniteException("Failed to resolve cluster features", e);
- }
- }
-
/** */
private Set<ClusterNode> clusterNodes() {
assert Thread.holdsLock(topGuard);
@@ -560,13 +514,14 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
curFinalizeProcId = reqId;
- if (!isReadyForVersionFinalization())
+ if (!isReadyForVersionFinalization()) {
return new GridFinishedFuture<>(new IgniteException(
- "Cluster version finalization failed. The cluster contains
nodes running" +
- " different versions of one or more components. Retry
the operation after upgrading" +
- " all cluster node components to the same version" +
- " [clusterFeatures=" +
clusterFeatures().entrySet().stream().collect(
- Collectors.toMap(e -> e.getKey().id(),
Map.Entry::getValue)) + ']'));
+ "Cluster version finalization failed. The cluster
contains nodes running" +
+ " different versions of one or more components.
Retry the operation after upgrading" +
+ " all cluster node components to the same version"
+
+ " [clusterFeatures=" +
clusterNodes().stream().collect(Collectors.toMap(
+ ClusterNode::id,
RollingUpgradeProcessor::extractNodeFeatures)) + ']'));
+ }
return new GridFinishedFuture<>();
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteNodeFeatureSet.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteNodeFeatureSet.java
index ef06cb57fbf..d00439e4156 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteNodeFeatureSet.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteNodeFeatureSet.java
@@ -17,6 +17,11 @@
package org.apache.ignite.internal.processors.rollingupgrade.feature;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -24,36 +29,56 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.ignite.IgniteException;
-import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.Order;
+import org.apache.ignite.plugin.extensions.communication.Message;
import org.jetbrains.annotations.Nullable;
/**
* Represents a set of {@link IgniteFeature}s supported by an Ignite node.
Ignite is divided into independent components.
* Each component is associated with its version and a set of {@link
IgniteFeature}s.
*/
-public class IgniteNodeFeatureSet {
+public class IgniteNodeFeatureSet implements Message, Externalizable {
/** */
- @GridToStringExclude
- private final Map<String, IgniteComponentFeatureSet> features;
+ private static final long serialVersionUID = 0L;
/** */
- public IgniteNodeFeatureSet(IgniteComponentFeatureSet... features) {
- this.features = indexByComponentName(features);
+ public static final IgniteNodeFeatureSet LOCAL_CORE_FEATURES = new
IgniteNodeFeatureSet(new IgniteComponentFeatureSet[] {
+ IgniteCoreFeatureSet.local()
+ });
+
+ /** */
+ @Order(0)
+ IgniteComponentFeatureSet[] features;
+
+ /** */
+ @Nullable private volatile Map<String, IgniteComponentFeatureSet>
featuresByComponent;
+
+ /** */
+ public IgniteNodeFeatureSet() {
+ // No-op.
+ }
+
+ /** */
+ public IgniteNodeFeatureSet(IgniteComponentFeatureSet[] features) {
+ assert features != null;
+
+ this.features = features;
+ this.featuresByComponent = indexByComponentName(features);
}
/** */
public Set<String> components() {
- return Collections.unmodifiableSet(features.keySet());
+ return Collections.unmodifiableSet(featuresByComponent().keySet());
}
/** */
public IgniteComponentFeatureSet[] values() {
- return features.values().toArray(IgniteComponentFeatureSet[]::new);
+ return features;
}
/** */
@Nullable public IgniteComponentFeatureSet componentFeatures(String
cmpName) {
- return features.get(cmpName);
+ return featuresByComponent().get(cmpName);
}
/** */
@@ -61,8 +86,8 @@ public class IgniteNodeFeatureSet {
if (!components().containsAll(other.components()))
return false;
- for (IgniteComponentFeatureSet otherCmpFeatures :
other.features.values()) {
- if
(!otherCmpFeatures.equals(features.get(otherCmpFeatures.componentName())))
+ for (IgniteComponentFeatureSet otherCmpFeatures : other.features) {
+ if
(!otherCmpFeatures.equals(featuresByComponent().get(otherCmpFeatures.componentName())))
return false;
}
@@ -71,11 +96,41 @@ public class IgniteNodeFeatureSet {
/** */
public boolean contains(IgniteFeature feature) {
- IgniteComponentFeatureSet cmpFeatures =
features.get(feature.componentName());
+ IgniteComponentFeatureSet cmpFeatures =
featuresByComponent().get(feature.componentName());
return cmpFeatures != null && cmpFeatures.contains(feature.id());
}
+ /** */
+ private Map<String, IgniteComponentFeatureSet> featuresByComponent() {
+ Map<String, IgniteComponentFeatureSet> featuresByComponent =
this.featuresByComponent;
+
+ if (featuresByComponent != null)
+ return featuresByComponent;
+
+ featuresByComponent = indexByComponentName(features);
+
+ this.featuresByComponent = featuresByComponent;
+
+ return featuresByComponent;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeInt(features.length);
+
+ for (IgniteComponentFeatureSet feature : features)
+ out.writeObject(feature);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
+ features = new IgniteComponentFeatureSet[in.readInt()];
+
+ for (int i = 0; i < features.length; i++)
+ features[i] = (IgniteComponentFeatureSet)in.readObject();
+ }
+
/** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (o == null || getClass() != o.getClass())
@@ -83,21 +138,21 @@ public class IgniteNodeFeatureSet {
IgniteNodeFeatureSet other = (IgniteNodeFeatureSet)o;
- return Objects.equals(features, other.features);
+ return Objects.equals(featuresByComponent(),
other.featuresByComponent());
}
/** {@inheritDoc} */
@Override public int hashCode() {
- return Objects.hashCode(features);
+ return Objects.hashCode(featuresByComponent());
}
/** {@inheritDoc} */
@Override public String toString() {
- return
features.values().stream().map(IgniteComponentFeatureSet::toString).collect(Collectors.joining(",
", "[", "]"));
+ return
Arrays.stream(features).map(IgniteComponentFeatureSet::toString).collect(Collectors.joining(",
", "[", "]"));
}
/** */
- private static Map<String, IgniteComponentFeatureSet>
indexByComponentName(IgniteComponentFeatureSet... features) {
+ private static Map<String, IgniteComponentFeatureSet>
indexByComponentName(IgniteComponentFeatureSet[] features) {
Map<String, IgniteComponentFeatureSet> res = new HashMap<>();
for (IgniteComponentFeatureSet compFeatures : features) {
diff --git
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedDiscoverySpi.java
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedDiscoverySpi.java
index 7a46fa1e0c0..d5556f56816 100644
---
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedDiscoverySpi.java
+++
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedDiscoverySpi.java
@@ -54,6 +54,7 @@ import static java.util.Collections.singleton;
import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;
import static
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS;
import static
org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT;
+import static
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet.LOCAL_CORE_FEATURES;
import static
org.apache.ignite.internal.processors.security.SecurityUtils.authenticateLocalNode;
import static
org.apache.ignite.internal.processors.security.SecurityUtils.withSecurityContext;
@@ -125,7 +126,12 @@ public class IsolatedDiscoverySpi extends IgniteSpiAdapter
implements IgniteDisc
/** {@inheritDoc} */
@Override public void setNodeAttributes(Map<String, Object> attrs,
IgniteProductVersion ver) {
- locNode = new IsolatedNode(ignite.configuration().getNodeId(), attrs,
ver);
+ locNode = new IsolatedNode(
+ ignite.configuration().getNodeId(),
+ attrs,
+ ver,
+ ignite instanceof IgniteKernal ?
ignite.context().localNodeFeatures() : LOCAL_CORE_FEATURES
+ );
}
/** {@inheritDoc} */
diff --git
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedNode.java
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedNode.java
index 2489d95900b..3e18ddea775 100644
---
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedNode.java
+++
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/isolated/IsolatedNode.java
@@ -27,6 +27,7 @@ import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cluster.ClusterMetrics;
import org.apache.ignite.internal.ClusterMetricsSnapshot;
import org.apache.ignite.internal.managers.discovery.IgniteClusterNode;
+import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteProductVersion;
@@ -48,6 +49,9 @@ public class IsolatedNode implements IgniteClusterNode {
/** Node attributes. */
private Map<String, Object> attrs;
+ /** Node features. */
+ private final IgniteNodeFeatureSet features;
+
/** */
private volatile ClusterMetrics metrics = new ClusterMetricsSnapshot();
@@ -58,11 +62,13 @@ public class IsolatedNode implements IgniteClusterNode {
* @param id Node ID.
* @param attrs Node attributes.
* @param ver Node version.
+ * @param features Node features.
*/
- public IsolatedNode(UUID id, Map<String, Object> attrs,
IgniteProductVersion ver) {
+ public IsolatedNode(UUID id, Map<String, Object> attrs,
IgniteProductVersion ver, IgniteNodeFeatureSet features) {
this.id = id;
this.attrs = U.sealMap(attrs);
this.ver = ver;
+ this.features = features;
}
/** {@inheritDoc} */
@@ -75,6 +81,11 @@ public class IsolatedNode implements IgniteClusterNode {
return consistentId;
}
+ /** {@inheritDoc} */
+ @Override public IgniteNodeFeatureSet features() {
+ return features;
+ }
+
/** {@inheritDoc} */
@Override public <T> T attribute(String name) {
return (T)attrs.get(name);
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 e6d27b3bb48..53b1dbfc935 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
@@ -709,7 +709,7 @@ class ClientImpl extends TcpDiscoveryImpl {
TcpDiscoveryIoSession ses = createSession(sock);
- TcpDiscoveryHandshakeRequest req = new
TcpDiscoveryHandshakeRequest(locNodeId, spi.localNodeFeatures());
+ TcpDiscoveryHandshakeRequest req = new
TcpDiscoveryHandshakeRequest(locNodeId, locNode.features());
req.client(true);
req.dcId(locNode.dataCenterId());
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 d326fd8769a..c97661427c1 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
@@ -1507,7 +1507,7 @@ class ServerImpl extends TcpDiscoveryImpl {
openSock = true;
- TcpDiscoveryHandshakeRequest req = new
TcpDiscoveryHandshakeRequest(locNodeId, spi.localNodeFeatures());
+ TcpDiscoveryHandshakeRequest req = new
TcpDiscoveryHandshakeRequest(locNodeId, locNode.features());
// Handshake.
spi.writeMessage(ses, req,
timeoutHelper.nextTimeoutChunk(spi.getSocketTimeout()));
@@ -3419,7 +3419,7 @@ class ServerImpl extends TcpDiscoveryImpl {
openSock = true;
// Handshake.
- TcpDiscoveryHandshakeRequest hndMsg = new
TcpDiscoveryHandshakeRequest(locNodeId, spi.localNodeFeatures());
+ TcpDiscoveryHandshakeRequest hndMsg = new
TcpDiscoveryHandshakeRequest(locNodeId, locNode.features());
if (sndState != null) {
// If want a forced connection, we set the
change-topology node flag to current node id.
@@ -6602,7 +6602,7 @@ class ServerImpl extends TcpDiscoveryImpl {
TcpDiscoveryHandshakeResponse res = new
TcpDiscoveryHandshakeResponse(
locNodeId,
locNode.internalOrder(),
- spi.localNodeFeatures()
+ locNode.features()
);
if (req.client()) {
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 b92ca657ad7..84da71e3cec 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
@@ -472,9 +472,6 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter
implements IgniteDiscovery
/** For test purposes. */
private boolean skipAddrsRandomization = false;
- /** */
- private IgniteNodeFeatureSet locNodeFeatures;
-
/**
* Gets current SPI state.
*
@@ -1196,8 +1193,6 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter
implements IgniteDiscovery
// Init local node.
initAddresses();
- locNodeFeatures = ((IgniteEx)ignite).context().localNodeFeatures();
-
locNode = new TcpDiscoveryNode(
ignite.configuration().getNodeId(),
addrs.get1(),
@@ -1205,7 +1200,8 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter
implements IgniteDiscovery
srvPort,
metricsProvider,
locNodeVer,
- consistentId());
+ consistentId(),
+ ignite.context().localNodeFeatures());
if (addExtAddrAttr) {
Collection<InetSocketAddress> extAddrs = addrRslvr == null ? null :
@@ -1695,11 +1691,6 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter
implements IgniteDiscovery
}
}
- /** */
- IgniteNodeFeatureSet localNodeFeatures() {
- return locNodeFeatures;
- }
-
/** */
void validateRemoteFeatures(IgniteNodeFeatureSet rmtFeatures) throws
IgniteCheckedException {
if (rmtFeatures == null) {
@@ -1709,7 +1700,7 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter
implements IgniteDiscovery
}
for (IgniteComponentFeatureSet rmtCmpFeatures : rmtFeatures.values()) {
- IgniteComponentFeatureSet locCmpFeatures =
locNodeFeatures.componentFeatures(rmtCmpFeatures.componentName());
+ IgniteComponentFeatureSet locCmpFeatures =
locNode.features().componentFeatures(rmtCmpFeatures.componentName());
if (locCmpFeatures == null)
continue;
@@ -1724,7 +1715,7 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter
implements IgniteDiscovery
if (!src.isUpgradableTo(target)) {
throw new UnsupportedNodeVersionException("Remote node
component versions are not supported" +
- " [locComponents=" + locNodeFeatures +
+ " [locComponents=" + locNode.features() +
", rmtComponents=" + rmtFeatures + ']');
}
}
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 8f1bee5ceb2..f31b3366c30 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
@@ -38,6 +38,7 @@ import org.apache.ignite.internal.IgniteNodeAttributes;
import org.apache.ignite.internal.Marshalled;
import org.apache.ignite.internal.Order;
import org.apache.ignite.internal.managers.discovery.IgniteClusterNode;
+import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import org.apache.ignite.internal.util.lang.GridMetadataAwareAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -154,6 +155,11 @@ public class TcpDiscoveryNode extends
GridMetadataAwareAdapter implements Ignite
@Order(10)
UUID clientRouterNodeId;
+ /** Node features. */
+ @GridToStringExclude
+ @Order(11)
+ IgniteNodeFeatureSet features;
+
/** */
@GridToStringExclude
private transient volatile InetSocketAddress lastSuccessfulAddr;
@@ -183,6 +189,7 @@ public class TcpDiscoveryNode extends
GridMetadataAwareAdapter implements Ignite
* @param metricsProvider Metrics provider.
* @param ver Version.
* @param consistentId Node consistent ID.
+ * @param features Node features.
*/
public TcpDiscoveryNode(UUID id,
Collection<String> addrs,
@@ -190,11 +197,13 @@ public class TcpDiscoveryNode extends
GridMetadataAwareAdapter implements Ignite
int discPort,
DiscoveryMetricsProvider metricsProvider,
IgniteProductVersion ver,
- Serializable consistentId
+ Serializable consistentId,
+ IgniteNodeFeatureSet features
) {
assert id != null;
assert metricsProvider != null;
assert ver != null;
+ assert features != null;
this.id = id;
@@ -207,6 +216,7 @@ public class TcpDiscoveryNode extends
GridMetadataAwareAdapter implements Ignite
this.discPort = discPort;
this.metricsProvider = metricsProvider;
this.ver = ver;
+ this.features = features;
this.consistentId = consistentId != null ? consistentId :
U.consistentId(sortedAddrs, discPort);
@@ -359,6 +369,11 @@ public class TcpDiscoveryNode extends
GridMetadataAwareAdapter implements Ignite
return ver;
}
+ /** {@inheritDoc} */
+ @Override public IgniteNodeFeatureSet features() {
+ return features;
+ }
+
/**
* @param ver Version.
*/
@@ -544,7 +559,14 @@ public class TcpDiscoveryNode extends
GridMetadataAwareAdapter implements Ignite
*/
public TcpDiscoveryNode clientReconnectNode(Map<String, Object> nodeAttrs)
{
TcpDiscoveryNode node = new TcpDiscoveryNode(
- id, addrs, hostNames, discPort, metricsProvider, ver, null
+ id,
+ addrs,
+ hostNames,
+ discPort,
+ metricsProvider,
+ ver,
+ null,
+ features
);
node.attrs = Collections.unmodifiableMap(new HashMap<>(nodeAttrs));
diff --git
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeRequest.java
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeRequest.java
index d2a33c6d059..560be2a9c16 100644
---
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeRequest.java
+++
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeRequest.java
@@ -19,7 +19,6 @@ package org.apache.ignite.spi.discovery.tcp.messages;
import java.util.UUID;
import org.apache.ignite.internal.Order;
-import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
@@ -39,7 +38,7 @@ public class TcpDiscoveryHandshakeRequest extends
TcpDiscoveryAbstractMessage {
/** */
@Order(2)
- IgniteComponentFeatureSet[] nodeFeatures;
+ IgniteNodeFeatureSet nodeFeatures;
/**
* Default constructor for {@link MessageFactory}.
@@ -57,7 +56,7 @@ public class TcpDiscoveryHandshakeRequest extends
TcpDiscoveryAbstractMessage {
public TcpDiscoveryHandshakeRequest(UUID creatorNodeId,
IgniteNodeFeatureSet locNodeFeatures) {
super(creatorNodeId);
- this.nodeFeatures = locNodeFeatures.values();
+ this.nodeFeatures = locNodeFeatures;
}
/**
@@ -90,7 +89,7 @@ public class TcpDiscoveryHandshakeRequest extends
TcpDiscoveryAbstractMessage {
/** @return Features supported by the sender node. */
public IgniteNodeFeatureSet nodeFeatures() {
- return nodeFeatures == null ? null : new
IgniteNodeFeatureSet(nodeFeatures);
+ return nodeFeatures;
}
/** {@inheritDoc} */
diff --git
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeResponse.java
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeResponse.java
index d11e0814ef8..0c936624017 100644
---
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeResponse.java
+++
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryHandshakeResponse.java
@@ -21,7 +21,6 @@ import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.UUID;
import org.apache.ignite.internal.Order;
-import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -46,7 +45,7 @@ public class TcpDiscoveryHandshakeResponse extends
TcpDiscoveryAbstractMessage {
/** */
@Order(3)
- IgniteComponentFeatureSet[] nodeFeatures;
+ IgniteNodeFeatureSet nodeFeatures;
/**
* Default constructor for {@link MessageFactory}.
@@ -67,7 +66,7 @@ public class TcpDiscoveryHandshakeResponse extends
TcpDiscoveryAbstractMessage {
order = locNodeOrder;
- this.nodeFeatures = locNodeFeatures.values();
+ this.nodeFeatures = locNodeFeatures;
}
/**
@@ -115,7 +114,7 @@ public class TcpDiscoveryHandshakeResponse extends
TcpDiscoveryAbstractMessage {
/** @return Features supported by the sender node. */
public IgniteNodeFeatureSet nodeFeatures() {
- return nodeFeatures == null ? null : new
IgniteNodeFeatureSet(nodeFeatures);
+ return nodeFeatures;
}
/** {@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 f994cee551f..c1c81095fba 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
@@ -40,6 +40,7 @@ import
org.apache.ignite.spi.discovery.DiscoveryMetricsProvider;
import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
import org.junit.Test;
+import static
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet.LOCAL_CORE_FEATURES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
@@ -249,7 +250,8 @@ public class GridAffinityAssignmentV2Test {
0,
metrics,
v,
- consistentId
+ consistentId,
+ LOCAL_CORE_FEATURES
);
node.setAttributes(Collections.emptyMap());
diff --git
a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
index 8f9b3008583..37b96375777 100644
---
a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
+++
b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
@@ -23,9 +23,11 @@ import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.IgniteConfiguration;
@@ -39,6 +41,7 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteProductVersion;
+import org.apache.ignite.marshaller.Marshallers;
import
org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider;
import org.apache.ignite.resources.LoggerResource;
import org.apache.ignite.spi.IgniteSpiAdapter;
@@ -66,6 +69,7 @@ import org.jetbrains.annotations.Nullable;
import static
org.apache.ignite.IgniteSystemProperties.IGNITE_CONSISTENT_ID_BY_HOST_WITHOUT_PORT;
import static org.apache.ignite.IgniteSystemProperties.getBoolean;
+import static
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IGNITE_FEATURES;
import static
org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.DISCO_METRICS;
/**
@@ -364,8 +368,15 @@ public class ZookeeperDiscoverySpi extends
IgniteSpiAdapter implements IgniteDis
log.debug("Node version to set: " + ver);
}
- locNodeAttrs = attrs;
locNodeVer = ver;
+ locNodeAttrs = new HashMap<>(attrs);
+
+ try {
+ locNodeAttrs.put(ATTR_IGNITE_FEATURES,
Marshallers.jdk().marshal(ignite.context().localNodeFeatures()));
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteSpiException("Failed to initialize Ignite Node
Features attribute", e);
+ }
}
/** {@inheritDoc} */
diff --git
a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClusterNode.java
b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClusterNode.java
index bd657912425..198f9b275d0 100644
---
a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClusterNode.java
+++
b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClusterNode.java
@@ -27,19 +27,24 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cluster.ClusterMetrics;
import org.apache.ignite.internal.ClusterMetricsSnapshot;
import org.apache.ignite.internal.IgniteNodeAttributes;
import org.apache.ignite.internal.SecurityCredentialsAttrFilterPredicate;
import org.apache.ignite.internal.managers.discovery.IgniteClusterNode;
+import
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteNodeFeatureSet;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteProductVersion;
+import org.apache.ignite.marshaller.Marshallers;
+import org.apache.ignite.spi.IgniteSpiException;
import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider;
import org.jetbrains.annotations.Nullable;
+import static
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IGNITE_FEATURES;
import static
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_NODE_CONSISTENT_ID;
import static org.apache.ignite.internal.util.lang.ClusterNodeFunc.eqNodes;
@@ -144,6 +149,18 @@ public class ZookeeperClusterNode implements
IgniteClusterNode, Externalizable,
return id;
}
+ /** {@inheritDoc} */
+ @Override public IgniteNodeFeatureSet features() {
+ byte[] nodeFeaturesAttr = attribute(ATTR_IGNITE_FEATURES);
+
+ try {
+ return Marshallers.jdk().unmarshal(nodeFeaturesAttr,
U.gridClassLoader());
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteSpiException("Failed to resolve Ignite Node
Features", e);
+ }
+ }
+
/** {@inheritDoc} */
@Override public Object consistentId() {
return consistentId;
diff --git
a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiTestBase.java
b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiTestBase.java
index 929908e2ac8..79661366303 100644
---
a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiTestBase.java
+++
b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiTestBase.java
@@ -67,11 +67,11 @@ import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.lang.IgniteInClosure;
import org.apache.ignite.lang.IgniteOutClosure;
import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.security.SecurityCredentials;
import org.apache.ignite.plugin.segmentation.SegmentationPolicy;
import org.apache.ignite.resources.IgniteInstanceResource;
-import org.apache.ignite.spi.IgniteSpiException;
import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
import org.apache.ignite.spi.communication.tcp.internal.GridNioServerWrapper;
import org.apache.ignite.spi.discovery.DiscoverySpiNodeAuthenticator;
@@ -934,13 +934,13 @@ class ZookeeperDiscoverySpiTestBase extends
GridCommonAbstractTest {
/** */
private static class TestAuthZookeeperDiscoverySpi extends
TestZookeeperDiscoverySpi {
- /** */
- @Override public void spiStart(@Nullable String igniteInstanceName)
throws IgniteSpiException {
- ((IgniteEx)ignite).context().addNodeAttribute(
- ATTR_SECURITY_CREDENTIALS,
- new SecurityCredentials(null, null, igniteInstanceName));
+ /** {@inheritDoc} */
+ @Override public void setNodeAttributes(Map<String, Object> attrs,
IgniteProductVersion ver) {
+ Map<String, Object> attrsWithCreds = new HashMap<>(attrs);
+
+ attrsWithCreds.put(ATTR_SECURITY_CREDENTIALS, new
SecurityCredentials(null, null, igniteInstanceName));
- super.spiStart(igniteInstanceName);
+ super.setNodeAttributes(attrsWithCreds, ver);
}
}
}