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 d88d46e5d1a IGNITE-28889 Refactored Ignite Feature Set related classes 
serialization (#13367)
d88d46e5d1a is described below

commit d88d46e5d1a89597f2bb24e3e73b6630e807bd28
Author: Mikhail Petrov <[email protected]>
AuthorDate: Wed Jul 15 11:43:06 2026 +0300

    IGNITE-28889 Refactored Ignite Feature Set related classes serialization 
(#13367)
---
 .../ignite/internal/CoreMessagesProvider.java      |  6 +-
 .../rollingupgrade/RollingUpgradeClusterData.java  |  5 +-
 .../rollingupgrade/RollingUpgradeProcessor.java    | 18 ++----
 .../feature/IgniteComponentFeatureSet.java         | 45 ++++++--------
 .../feature/IgniteCoreFeatureSet.java              | 56 +++++++++++++++++
 .../feature/IgniteFeatureManager.java              | 21 +++----
 .../rollingupgrade/feature/IgniteFeatureSet.java   | 17 +++++-
 .../feature/IgniteNodeFeatureSet.java              |  9 ++-
 .../feature/IgnitePluginFeatureSet.java            | 71 ++++++++++++++++++++++
 .../rollingupgrade/AbstractRollingUpgradeTest.java |  9 ++-
 10 files changed, 190 insertions(+), 67 deletions(-)

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 10ceff0dfbc..f7330c5a47f 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
@@ -237,8 +237,9 @@ import 
org.apache.ignite.internal.processors.query.stat.messages.StatisticsRespo
 import 
org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultRequest;
 import 
org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultResponse;
 import 
org.apache.ignite.internal.processors.rollingupgrade.RollingUpgradeClusterData;
-import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
+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.IgnitePluginFeatureSet;
 import org.apache.ignite.internal.processors.security.SecurityContextWrapper;
 import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest;
 import 
org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult;
@@ -696,7 +697,8 @@ public class CoreMessagesProvider extends 
AbstractMarshallableMessageFactoryProv
         // [13600 - 13700]: Rolling Upgrade messages.
         msgIdx = 13600;
         withNoSchema(IgniteFeatureSet.class);
-        withNoSchema(IgniteComponentFeatureSet.class);
+        withNoSchema(IgniteCoreFeatureSet.class);
+        withNoSchema(IgnitePluginFeatureSet.class);
         withNoSchema(RollingUpgradeClusterData.class);
 
         assert msgIdx <= MAX_MESSAGE_ID;
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 f28dc98558a..f9a7b491d12 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
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.processors.rollingupgrade;
 
-import java.util.Collection;
 import java.util.UUID;
 import org.apache.ignite.internal.Order;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
@@ -35,7 +34,7 @@ public class RollingUpgradeClusterData implements Message {
 
     /** */
     @Order(2)
-    Collection<IgniteComponentFeatureSet> activeFeatures;
+    IgniteComponentFeatureSet[] activeFeatures;
 
     /** */
     public RollingUpgradeClusterData() {
@@ -46,7 +45,7 @@ public class RollingUpgradeClusterData implements Message {
     public RollingUpgradeClusterData(
         boolean isVersionUpgradeEnabled,
         UUID curFinalizeProcId,
-        Collection<IgniteComponentFeatureSet> activeFeatures
+        IgniteComponentFeatureSet[] activeFeatures
     ) {
         this.isVersionUpgradeEnabled = isVersionUpgradeEnabled;
         this.curFinalizeProcId = curFinalizeProcId;
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 ab2f9cda1d9..d334167d2c8 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
@@ -20,7 +20,6 @@ package org.apache.ignite.internal.processors.rollingupgrade;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -34,16 +33,13 @@ 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.IgniteVersionUtils;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import 
org.apache.ignite.internal.processors.nodevalidation.DiscoveryNodeValidationProcessor;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
-import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteCoreFeature;
+import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteCoreFeatureSet;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeature;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeatureManager;
-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.SupportedFeatureRegistry;
 import org.apache.ignite.internal.util.distributed.DistributedProcess;
 import org.apache.ignite.internal.util.distributed.InitMessage;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
@@ -99,15 +95,11 @@ public class RollingUpgradeProcessor extends 
GridProcessorAdapter implements Dis
 
     /** */
     public RollingUpgradeProcessor(GridKernalContext ctx) {
-        this(ctx, new IgniteComponentFeatureSet(
-            IgniteCoreFeature.COMPONENT_NAME,
-            IgniteVersionUtils.VER,
-            IgniteFeatureSet.buildFrom(SupportedFeatureRegistry.class))
-        );
+        this(ctx, IgniteCoreFeatureSet.local());
     }
 
     /** */
-    protected RollingUpgradeProcessor(GridKernalContext ctx, 
IgniteComponentFeatureSet coreFeatures) {
+    protected RollingUpgradeProcessor(GridKernalContext ctx, 
IgniteCoreFeatureSet coreFeatures) {
         super(ctx);
 
         enableProc = new ClusterVersionUpgradeEnableProcess();
@@ -192,7 +184,7 @@ public class RollingUpgradeProcessor extends 
GridProcessorAdapter implements Dis
             ATTR_IGNITE_FEATURES,
             U.marshal(
                 ctx.marshallerContext().jdkMarshaller(),
-                featureMgr.localVersionFeatures().values().toArray(new 
IgniteComponentFeatureSet[0]))
+                featureMgr.localVersionFeatures().values())
         );
 
         ctx.event().addLocalEventListener(
@@ -417,7 +409,7 @@ public class RollingUpgradeProcessor extends 
GridProcessorAdapter implements Dis
             attrVal,
             U.resolveClassLoader(ctx.config()));
 
-        return new IgniteNodeFeatureSet(List.of(nodeFeatures));
+        return new IgniteNodeFeatureSet(nodeFeatures);
     }
 
     /** */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteComponentFeatureSet.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteComponentFeatureSet.java
index a689f0f52b9..d76a5b6e8fa 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteComponentFeatureSet.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteComponentFeatureSet.java
@@ -28,20 +28,16 @@ import org.apache.ignite.lang.IgniteProductVersion;
 import org.apache.ignite.plugin.extensions.communication.Message;
 
 /** Represents a set of {@link IgniteFeature}s available for the specific 
Ignite component version. */
-public class IgniteComponentFeatureSet implements Message, Externalizable {
+public abstract class IgniteComponentFeatureSet implements Message, 
Externalizable {
     /** */
     private static final long serialVersionUID = 0L;
 
     /** */
     @Order(0)
-    String compName;
+    IgniteProductVersion ver;
 
     /** */
     @Order(1)
-    IgniteProductVersion compVer;
-
-    /** */
-    @Order(2)
     IgniteFeatureSet features;
 
     /** */
@@ -50,24 +46,20 @@ public class IgniteComponentFeatureSet implements Message, 
Externalizable {
     }
 
     /** */
-    public IgniteComponentFeatureSet(String compName, IgniteProductVersion 
compVer, IgniteFeatureSet features) {
-        A.notNull(compName, "component name");
-        A.notNull(compVer, "component version");
+    protected IgniteComponentFeatureSet(IgniteProductVersion ver, 
IgniteFeatureSet features) {
+        A.notNull(ver, "component version");
         A.notNull(features, "component features");
 
-        this.compName = compName;
-        this.compVer = compVer;
+        this.ver = ver;
         this.features = features;
     }
 
     /** */
-    public String componentName() {
-        return compName;
-    }
+    public abstract String componentName();
 
     /** */
     public IgniteProductVersion version() {
-        return compVer;
+        return ver;
     }
 
     /** */
@@ -77,21 +69,22 @@ public class IgniteComponentFeatureSet implements Message, 
Externalizable {
 
     /** */
     public boolean isUpgradableTo(IgniteComponentFeatureSet target) {
-        return Objects.equals(compName, target.compName) && 
features.isUpgradableTo(target.features);
+        return Objects.equals(componentName(), target.componentName()) && 
features.isUpgradableTo(target.features);
     }
 
     /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeUTF(compName);
-        out.writeObject(compVer);
-        out.writeObject(features);
+        ver.writeExternal(out);
+        features.writeExternal(out);
     }
 
     /** {@inheritDoc} */
     @Override public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException {
-        compName = in.readUTF();
-        compVer = (IgniteProductVersion)in.readObject();
-        features = (IgniteFeatureSet)in.readObject();
+        ver = new IgniteProductVersion();
+        ver.readExternal(in);
+
+        features = new IgniteFeatureSet();
+        features.readExternal(in);
     }
 
     /** {@inheritDoc} */
@@ -101,18 +94,18 @@ public class IgniteComponentFeatureSet implements Message, 
Externalizable {
 
         IgniteComponentFeatureSet other = (IgniteComponentFeatureSet)o;
 
-        return Objects.equals(compName, other.compName)
+        return Objects.equals(componentName(), other.componentName())
             && Objects.equals(features, other.features)
-            && Objects.equals(compVer, other.compVer);
+            && Objects.equals(ver, other.ver);
     }
 
     /** {@inheritDoc} */
     @Override public String toString() {
-        return "IgniteComponent [name=" + compName + ", ver=" + compVer + ']';
+        return "IgniteComponent [name=" + componentName() + ", ver=" + ver + 
']';
     }
 
     /** {@inheritDoc} */
     @Override public int hashCode() {
-        return Objects.hash(compName, features, compVer);
+        return Objects.hash(componentName(), features, ver);
     }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteCoreFeatureSet.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteCoreFeatureSet.java
new file mode 100644
index 00000000000..8c495d80825
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteCoreFeatureSet.java
@@ -0,0 +1,56 @@
+/*
+ * 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.rollingupgrade.feature;
+
+import org.apache.ignite.internal.IgniteVersionUtils;
+import org.apache.ignite.lang.IgniteProductVersion;
+
+/**
+ * Represents the set of {@link IgniteFeature}s associated with Ignite core 
functionality.
+ * Its name is always {@link IgniteCoreFeature#COMPONENT_NAME}.
+ */
+public class IgniteCoreFeatureSet extends IgniteComponentFeatureSet {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private static final IgniteCoreFeatureSet INSTANCE = new 
IgniteCoreFeatureSet(
+        IgniteVersionUtils.VER,
+        IgniteFeatureSet.buildFrom(SupportedFeatureRegistry.class)
+    );
+
+    /** */
+    public IgniteCoreFeatureSet() {
+        // No-op.
+    }
+
+    /** */
+    public IgniteCoreFeatureSet(IgniteProductVersion compVer, IgniteFeatureSet 
features) {
+        super(compVer, features);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String componentName() {
+        return IgniteCoreFeature.COMPONENT_NAME;
+    }
+
+    /** */
+    public static IgniteCoreFeatureSet local() {
+        return INSTANCE;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureManager.java
index f9a229dc839..4ee85b0c50e 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureManager.java
@@ -17,9 +17,8 @@
 
 package org.apache.ignite.internal.processors.rollingupgrade.feature;
 
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -43,9 +42,9 @@ public class IgniteFeatureManager {
     private volatile IgniteNodeFeatureSet activeFeatures;
 
     /** */
-    public IgniteFeatureManager(GridKernalContext ctx, 
IgniteComponentFeatureSet locCoreFeatures) {
+    public IgniteFeatureManager(GridKernalContext ctx, IgniteCoreFeatureSet 
coreFeatures) {
         this.ctx = ctx;
-        this.locVerFeatures = collectLocalVersionFeatures(ctx, 
locCoreFeatures);
+        this.locVerFeatures = collectLocalVersionFeatures(ctx, coreFeatures);
         locVerFeaturesActivationFut = new GridFutureAdapter<>();
     }
 
@@ -124,23 +123,23 @@ public class IgniteFeatureManager {
     }
 
     /** */
-    private IgniteNodeFeatureSet collectLocalVersionFeatures(GridKernalContext 
ctx, IgniteComponentFeatureSet locCoreFeatures) {
-        Set<IgniteComponentFeatureSet> features = new HashSet<>();
+    private IgniteNodeFeatureSet collectLocalVersionFeatures(GridKernalContext 
ctx, IgniteCoreFeatureSet coreFeatures) {
+        Collection<IgniteComponentFeatureSet> features = new ArrayList<>();
 
-        features.add(locCoreFeatures);
+        features.add(coreFeatures);
 
         IgniteComponentFeatureSetProvider[] components = 
ctx.plugins().extensions(IgniteComponentFeatureSetProvider.class);
 
         if (!F.isEmpty(components)) {
             for (IgniteComponentFeatureSetProvider component : components)
-                features.add(buildComponentFeatures(component));
+                features.add(buildPluginFeatureSet(component));
         }
 
-        return new IgniteNodeFeatureSet(features);
+        return new 
IgniteNodeFeatureSet(features.toArray(IgniteComponentFeatureSet[]::new));
     }
 
     /** */
-    private IgniteComponentFeatureSet 
buildComponentFeatures(IgniteComponentFeatureSetProvider cmpFeaturesProvider) {
+    private IgniteComponentFeatureSet 
buildPluginFeatureSet(IgniteComponentFeatureSetProvider cmpFeaturesProvider) {
         Collection<IgniteFeature> cmpFeatures = cmpFeaturesProvider.features();
 
         A.notEmpty(cmpFeatures, "component features");
@@ -154,7 +153,7 @@ public class IgniteFeatureManager {
                 " [componentName=" + cmpFeaturesProvider.componentName() + 
']');
         }
 
-        return new IgniteComponentFeatureSet(
+        return new IgnitePluginFeatureSet(
             cmpFeaturesProvider.componentName(),
             cmpFeaturesProvider.componentVersion(),
             IgniteFeatureSet.buildFrom(cmpFeatures)
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureSet.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureSet.java
index aa994965bc2..ad0c1177944 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureSet.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgniteFeatureSet.java
@@ -206,14 +206,27 @@ public class IgniteFeatureSet implements 
Iterable<Integer>, Message, Externaliza
     @Override public void writeExternal(ObjectOutput out) throws IOException {
         out.writeInt(rangeStartInclusive);
         out.writeInt(rangeEndInclusive);
-        out.writeObject(sparseSuffix);
+
+        boolean hasSparseSuffix = sparseSuffix != null;
+
+        out.writeBoolean(hasSparseSuffix);
+
+        if (hasSparseSuffix)
+            sparseSuffix.writeExternal(out);
     }
 
     /** {@inheritDoc} */
     @Override public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException {
         rangeStartInclusive = in.readInt();
         rangeEndInclusive = in.readInt();
-        sparseSuffix = (GridIntList)in.readObject();
+
+        boolean hasSparseSuffix = in.readBoolean();
+
+        if (hasSparseSuffix) {
+            sparseSuffix = new GridIntList();
+
+            sparseSuffix.readExternal(in);
+        }
     }
 
     /** {@inheritDoc} */
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 6bf5661c5bb..ef06cb57fbf 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,7 +17,6 @@
 
 package org.apache.ignite.internal.processors.rollingupgrade.feature;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -38,7 +37,7 @@ public class IgniteNodeFeatureSet {
     private final Map<String, IgniteComponentFeatureSet> features;
 
     /** */
-    public IgniteNodeFeatureSet(Collection<IgniteComponentFeatureSet> 
features) {
+    public IgniteNodeFeatureSet(IgniteComponentFeatureSet... features) {
         this.features = indexByComponentName(features);
     }
 
@@ -48,8 +47,8 @@ public class IgniteNodeFeatureSet {
     }
 
     /** */
-    public Collection<IgniteComponentFeatureSet> values() {
-        return Collections.unmodifiableCollection(features.values());
+    public IgniteComponentFeatureSet[] values() {
+        return features.values().toArray(IgniteComponentFeatureSet[]::new);
     }
 
     /** */
@@ -98,7 +97,7 @@ public class IgniteNodeFeatureSet {
     }
 
     /** */
-    private static Map<String, IgniteComponentFeatureSet> 
indexByComponentName(Collection<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/internal/processors/rollingupgrade/feature/IgnitePluginFeatureSet.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgnitePluginFeatureSet.java
new file mode 100644
index 00000000000..7c444c9d4fe
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/feature/IgnitePluginFeatureSet.java
@@ -0,0 +1,71 @@
+/*
+ * 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.rollingupgrade.feature;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.internal.Order;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.lang.IgniteProductVersion;
+
+/**
+ * Represents the set of {@link IgniteFeature}s associated with a user plugin.
+ * Explicitly stores the name of the plugin to which the feature set belongs.
+ */
+public class IgnitePluginFeatureSet extends IgniteComponentFeatureSet {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    @Order(0)
+    String compName;
+
+    /** */
+    public IgnitePluginFeatureSet() {
+        // No-op.
+    }
+
+    /** */
+    public IgnitePluginFeatureSet(String compName, IgniteProductVersion 
compVer, IgniteFeatureSet features) {
+        super(compVer, features);
+
+        A.notNull(compName, "component name");
+
+        this.compName = compName;
+    }
+
+    /** */
+    public String componentName() {
+        return compName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeUTF(compName);
+
+        super.writeExternal(out);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException {
+        compName = in.readUTF();
+
+        super.readExternal(in);
+    }
+}
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/rollingupgrade/AbstractRollingUpgradeTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/rollingupgrade/AbstractRollingUpgradeTest.java
index 98718dfb635..8eef1221032 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/rollingupgrade/AbstractRollingUpgradeTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/rollingupgrade/AbstractRollingUpgradeTest.java
@@ -47,6 +47,7 @@ import 
org.apache.ignite.internal.processors.nodevalidation.DiscoveryNodeValidat
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSet;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteComponentFeatureSetProvider;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteCoreFeature;
+import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteCoreFeatureSet;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeature;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeatureSet;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.TestIgniteReleaseFeatures_2_18_0;
@@ -72,7 +73,6 @@ import org.jspecify.annotations.Nullable;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static org.apache.ignite.events.EventType.EVT_NODE_VALIDATION_FAILED;
 import static org.apache.ignite.internal.IgniteVersionUtils.semanticVersion;
-import static 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteCoreFeature.COMPONENT_NAME;
 
 /**
  * Provides the ability to override a node's version and supported {@link 
IgniteFeature}s in order to
@@ -179,8 +179,7 @@ public abstract class AbstractRollingUpgradeTest extends 
GridCommonAbstractTest
 
         TestVersions testVersions = TestVersions.parse(ver);
 
-        IgniteComponentFeatureSet testCoreFeatures = new 
IgniteComponentFeatureSet(
-            COMPONENT_NAME,
+        IgniteCoreFeatureSet testCoreFeatures = new IgniteCoreFeatureSet(
             IgniteProductVersion.fromString(testVersions.coreVersion()),
             
IgniteFeatureSet.buildFrom(readDeclaredCoreFeatures(testVersions.coreVersion()))
         );
@@ -492,7 +491,7 @@ public abstract class AbstractRollingUpgradeTest extends 
GridCommonAbstractTest
 
     /** */
     String resolveNodeCompoundVersion(int nodeIdx) {
-        return ru(nodeIdx).features().localVersionFeatures().values().stream()
+        return 
Arrays.stream(ru(nodeIdx).features().localVersionFeatures().values())
             
.sorted(Comparator.comparing(IgniteComponentFeatureSet::componentName))
             .map(f -> semanticVersion(f.version()))
             .collect(Collectors.joining("|"));
@@ -603,7 +602,7 @@ public abstract class AbstractRollingUpgradeTest extends 
GridCommonAbstractTest
         public static CountDownLatch nodeJoinValidationCompletedLatch;
 
         /** */
-        public TestRollingUpgradeProcessor(GridKernalContext ctx, 
IgniteComponentFeatureSet testCoreFeatures) {
+        public TestRollingUpgradeProcessor(GridKernalContext ctx, 
IgniteCoreFeatureSet testCoreFeatures) {
             super(ctx, testCoreFeatures);
 
             ctx.event().addLocalEventListener(new 
TestNodeValidationFailedEventListener(), EVT_NODE_VALIDATION_FAILED);

Reply via email to