Repository: ignite
Updated Branches:
  refs/heads/master 14055683a -> a38cbb2d6


IGNITE-7506 Fixed resetting of GridClusterStateProcessor#compatibilityMode flag


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a38cbb2d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a38cbb2d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a38cbb2d

Branch: refs/heads/master
Commit: a38cbb2d6aa324a400f09ddbaa75c1c8ee5462ce
Parents: 1405568
Author: Sergey Chugunov <[email protected]>
Authored: Wed Jan 24 18:22:11 2018 +0300
Committer: Alexey Goncharuk <[email protected]>
Committed: Wed Jan 24 18:22:11 2018 +0300

----------------------------------------------------------------------
 .../internal/cluster/IgniteClusterImpl.java     | 37 +++++++++++++++++--
 .../internal/managers/discovery/DiscoCache.java | 19 ++++++++--
 .../discovery/GridDiscoveryManager.java         | 15 ++++++--
 .../cluster/GridClusterStateProcessor.java      | 38 +++++++++++++++++++-
 4 files changed, 99 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a38cbb2d/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
index 8cdb550..b69923b 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
@@ -47,6 +47,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteComponentType;
 import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.processors.cluster.BaselineTopology;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
@@ -59,10 +60,12 @@ import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.lang.IgniteProductVersion;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IPS;
@@ -87,6 +90,9 @@ public class IgniteClusterImpl extends ClusterGroupAdapter 
implements IgniteClus
     /** Client reconnect future. */
     private IgniteFuture<?> reconnecFut;
 
+    /** Minimal IgniteProductVersion supporting BaselineTopology */
+    private static final IgniteProductVersion MIN_BLT_SUPPORTING_VER = 
IgniteProductVersion.fromString("2.4.0");
+
     /**
      * Required by {@link Externalizable}.
      */
@@ -365,9 +371,37 @@ public class IgniteClusterImpl extends ClusterGroupAdapter 
implements IgniteClus
     }
 
     /**
+     * Verifies all nodes in current cluster topology support BaselineTopology 
feature
+     * so compatibilityMode flag is enabled to reset.
+     *
+     * @param discoCache
+     */
+    private void verifyBaselineTopologySupport(DiscoCache discoCache) {
+        if 
(discoCache.minimumServerNodeVersion().compareTo(MIN_BLT_SUPPORTING_VER) < 0) {
+            SB sb = new SB("Cluster contains nodes that don't support 
BaselineTopology: [");
+
+            for (ClusterNode cn : discoCache.serverNodes()) {
+                if (cn.version().compareTo(MIN_BLT_SUPPORTING_VER) < 0)
+                    sb
+                        .a("[")
+                        .a(cn.consistentId())
+                        .a(":")
+                        .a(cn.version())
+                        .a("], ");
+            }
+
+            sb.d(sb.length() - 2, sb.length());
+
+            throw new IgniteException(sb.a("]").toString());
+        }
+    }
+
+    /**
      * Executes validation checks of cluster state and BaselineTopology before 
changing BaselineTopology to new one.
      */
     private void validateBeforeBaselineChange(Collection<? extends 
BaselineNode> baselineTop) {
+        verifyBaselineTopologySupport(ctx.discovery().discoCache());
+
         if (!ctx.state().clusterState().active())
             throw new IgniteException("Changing BaselineTopology on inactive 
cluster is not allowed.");
 
@@ -381,9 +415,6 @@ public class IgniteClusterImpl extends ClusterGroupAdapter 
implements IgniteClus
                 if (!onlineNodes.isEmpty())
                     throw new IgniteException("Removing online nodes from 
BaselineTopology is not supported: " + onlineNodes);
             }
-            else
-                //should never happen, actually: if cluster was activated, we 
expect it to have a BaselineTopology.
-                throw new IgniteException("Previous BaselineTopology was not 
found.");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/a38cbb2d/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
index 7bc0344..c21698f 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
@@ -87,9 +87,12 @@ public class DiscoCache {
     /** Alive nodes. */
     final Set<UUID> alives = new GridConcurrentHashSet<>();
 
-    /** */
+    /** Minimum {@link IgniteProductVersion} across all nodes including client 
nodes. */
     private final IgniteProductVersion minNodeVer;
 
+    /** Minimum {@link IgniteProductVersion} across alive server nodes. */
+    private final IgniteProductVersion minSrvNodeVer;
+
     /** */
     private final AffinityTopologyVersion topVer;
 
@@ -139,7 +142,8 @@ public class DiscoCache {
         Set<UUID> alives0,
         @Nullable Map<UUID, Short> nodeIdToConsIdx,
         @Nullable  Map<Short, UUID> consIdxToNodeId,
-        IgniteProductVersion minNodeVer
+        IgniteProductVersion minNodeVer,
+        IgniteProductVersion minSrvNodeVer
     ) {
         this.topVer = topVer;
         this.state = state;
@@ -155,6 +159,7 @@ public class DiscoCache {
         this.nodeMap = nodeMap;
         alives.addAll(alives0);
         this.minNodeVer = minNodeVer;
+        this.minSrvNodeVer = minSrvNodeVer;
         this.nodeIdToConsIdx = nodeIdToConsIdx;
         this.consIdxToNodeId = consIdxToNodeId;
 
@@ -188,6 +193,13 @@ public class DiscoCache {
     }
 
     /**
+     * @return Minimum server node version.
+     */
+    public IgniteProductVersion minimumServerNodeVersion() {
+        return minSrvNodeVer;
+    }
+
+    /**
      * @return Current cluster state.
      */
     public DiscoveryDataClusterState state() {
@@ -425,7 +437,8 @@ public class DiscoCache {
             alives,
             nodeIdToConsIdx,
             consIdxToNodeId,
-            minNodeVer);
+            minNodeVer,
+            minSrvNodeVer);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/a38cbb2d/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
----------------------------------------------------------------------
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 65cc666..82d0f66 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
@@ -2249,6 +2249,7 @@ public class GridDiscoveryManager extends 
GridManagerAdapter<DiscoverySpi> {
         List<? extends BaselineNode> baselineNodes;
 
         IgniteProductVersion minVer = null;
+        IgniteProductVersion minSrvVer = null;
 
         for (ClusterNode node : topSnapshot) {
             if (alive(node))
@@ -2262,8 +2263,14 @@ public class GridDiscoveryManager extends 
GridManagerAdapter<DiscoverySpi> {
                 if (!node.isLocal())
                     rmtNodes.add(node);
 
-                if (!CU.clientNode(node))
+                if (!CU.clientNode(node)) {
                     srvNodes.add(node);
+
+                    if (minSrvVer == null)
+                        minSrvVer = node.version();
+                    else if (node.version().compareTo(minSrvVer) < 0)
+                        minSrvVer = node.version();
+                }
             }
 
             nodeMap.put(node.id(), node);
@@ -2341,7 +2348,8 @@ public class GridDiscoveryManager extends 
GridManagerAdapter<DiscoverySpi> {
             alives,
             nodeIdToConsIdx == null ? null : 
Collections.unmodifiableMap(nodeIdToConsIdx),
             consIdxToNodeId == null ? null : 
Collections.unmodifiableMap(consIdxToNodeId),
-            minVer);
+            minVer,
+            minSrvVer);
     }
 
     /**
@@ -3174,6 +3182,7 @@ public class GridDiscoveryManager extends 
GridManagerAdapter<DiscoverySpi> {
             discoCache.alives,
             discoCache.nodeIdToConsIdx,
             discoCache.consIdxToNodeId,
-            discoCache.minimumNodeVersion());
+            discoCache.minimumNodeVersion(),
+            discoCache.minimumServerNodeVersion());
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/a38cbb2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
index 73c9d7f..f28df8a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
@@ -65,10 +65,12 @@ import org.apache.ignite.internal.util.typedef.CI2;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.lang.IgniteProductVersion;
 import org.apache.ignite.lang.IgniteRunnable;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
@@ -128,6 +130,9 @@ public class GridClusterStateProcessor extends 
GridProcessorAdapter implements I
     /** */
     private final JdkMarshaller marsh = new JdkMarshaller();
 
+    /** Minimal IgniteProductVersion supporting BaselineTopology */
+    private static final IgniteProductVersion MIN_BLT_SUPPORTING_VER = 
IgniteProductVersion.fromString("2.4.0");
+
     /** Listener. */
     private final GridLocalEventListener lsr = new GridLocalEventListener() {
         @Override public void onEvent(Event evt) {
@@ -417,6 +422,9 @@ public class GridClusterStateProcessor extends 
GridProcessorAdapter implements I
                 (msg.baselineTopology() == null ? ": null"
                     : "[id=" + msg.baselineTopology().id() + "]"));
 
+        if (msg.baselineTopology() != null)
+            compatibilityMode = false;
+
         if (state.transition()) {
             if (isApplicable(msg, state)) {
                 GridChangeGlobalStateFuture fut = changeStateFuture(msg);
@@ -713,7 +721,7 @@ public class GridClusterStateProcessor extends 
GridProcessorAdapter implements I
         if (inMemoryMode)
             return changeGlobalState0(activate, null, false);
 
-        BaselineTopology newBlt = compatibilityMode ? null :
+        BaselineTopology newBlt = (compatibilityMode && 
!forceChangeBaselineTopology) ? null :
             calculateNewBaselineTopology(activate, baselineNodes, 
forceChangeBaselineTopology);
 
         return changeGlobalState0(activate, newBlt, 
forceChangeBaselineTopology);
@@ -783,12 +791,40 @@ public class GridClusterStateProcessor extends 
GridProcessorAdapter implements I
         return bltNodes;
     }
 
+    /**
+     * Verifies all nodes in current cluster topology support BaselineTopology 
feature
+     * so compatibilityMode flag is enabled to reset.
+     *
+     * @param discoCache
+     */
+    private void verifyBaselineTopologySupport(DiscoCache discoCache) {
+        if 
(discoCache.minimumServerNodeVersion().compareTo(MIN_BLT_SUPPORTING_VER) < 0) {
+            SB sb = new SB("Cluster contains nodes that don't support 
BaselineTopology: [");
+
+            for (ClusterNode cn : discoCache.serverNodes()) {
+                if (cn.version().compareTo(MIN_BLT_SUPPORTING_VER) < 0)
+                    sb
+                        .a("[")
+                        .a(cn.consistentId())
+                        .a(":")
+                        .a(cn.version())
+                        .a("], ");
+            }
+
+            sb.d(sb.length() - 2, sb.length());
+
+            throw new IgniteException(sb.a("]").toString());
+        }
+    }
+
     /** */
     private IgniteInternalFuture<?> changeGlobalState0(final boolean activate,
         BaselineTopology blt, boolean forceChangeBaselineTopology) {
         if (ctx.isDaemon() || ctx.clientNode()) {
             GridFutureAdapter<Void> fut = new GridFutureAdapter<>();
 
+            verifyBaselineTopologySupport(ctx.discovery().discoCache());
+
             sendComputeChangeGlobalState(activate, blt, 
forceChangeBaselineTopology, fut);
 
             return fut;

Reply via email to