You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dg...@apache.org on 2019/04/18 15:56:41 UTC

[ignite] branch master updated: IGNITE-11678 Forbidding joining persistence node to in-memory cluster

This is an automated email from the ASF dual-hosted git repository.

dgovorukhin 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 772c5cc  IGNITE-11678 Forbidding joining persistence node to in-memory cluster
772c5cc is described below

commit 772c5cc0cea4391e1e50cec6b1dde86eed24b6e1
Author: Anton Kalashnikov <ka...@yandex.ru>
AuthorDate: Thu Apr 18 18:56:09 2019 +0300

    IGNITE-11678 Forbidding joining persistence node to in-memory cluster
    
    Signed-off-by: Dmitriy Govorukhin <dm...@gmail.com>
---
 .../cluster/GridClusterStateProcessor.java         |  46 ++++++++
 .../ignite/spi/IgniteNodeValidationResult.java     |   8 ++
 .../processors/cluster/BaselineAutoAdjustTest.java | 127 +++++++++++++++++++++
 3 files changed, 181 insertions(+)

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 83c36fb..18ac29a 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
@@ -37,12 +37,14 @@ import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cluster.BaselineNode;
 import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.Event;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteFeatures;
 import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.IgniteNodeAttributes;
 import org.apache.ignite.internal.cluster.ClusterGroupAdapter;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.cluster.DistributedBaselineConfiguration;
@@ -187,6 +189,50 @@ public class GridClusterStateProcessor extends GridProcessorAdapter implements I
         );
     }
 
+    /** {@inheritDoc} */
+    @Override public @Nullable IgniteNodeValidationResult validateNode(ClusterNode node) {
+        if (!isBaselineAutoAdjustEnabled() || baselineAutoAdjustTimeout() != 0)
+            return null;
+
+        Collection<ClusterNode> nodes = ctx.discovery().aliveServerNodes();
+
+        //Any node allowed to join if cluster has at least one persist node.
+        if (nodes.stream().anyMatch(serNode -> CU.isPersistenceEnabled(extractDataStorage(serNode))))
+            return null;
+
+        DataStorageConfiguration crdDsCfg = extractDataStorage(node);
+
+        if (!CU.isPersistenceEnabled(crdDsCfg))
+            return null;
+
+        return new IgniteNodeValidationResult(
+            node.id(),
+            "Joining persistence node to in-memory cluster couldn't be allowed " +
+            "due to baseline auto-adjust is enabled and timeout equal to 0"
+        );
+    }
+
+    /**
+     * Extract and unmarshal data storage configuration from given node.
+     *
+     * @param node Source of data storage configuration.
+     * @return Data storage configuration for given node.
+     */
+    private DataStorageConfiguration extractDataStorage(ClusterNode node) {
+        Object dsCfgBytes = node.attribute(IgniteNodeAttributes.ATTR_DATA_STORAGE_CONFIG);
+
+        if (dsCfgBytes instanceof byte[]) {
+            try {
+                return new JdkMarshaller().unmarshal((byte[])dsCfgBytes, U.resolveClassLoader(ctx.config()));
+            }
+            catch (IgniteCheckedException e) {
+                U.error(log, "Failed to unmarshal remote data storage configuration [remoteNode=" + node + "]", e);
+            }
+        }
+
+        return null;
+    }
+
     /**
      * @return {@code True} if {@link IGridClusterStateProcessor} has detected that cluster is working
      * in compatibility mode (nodes of different versions are joined to the cluster).
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteNodeValidationResult.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteNodeValidationResult.java
index 3dd4caf..0ad0263 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteNodeValidationResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteNodeValidationResult.java
@@ -35,6 +35,14 @@ public class IgniteNodeValidationResult {
 
     /**
      * @param nodeId Offending node ID.
+     * @param msg Message logged locally and sending to joining node.
+     */
+    public IgniteNodeValidationResult(UUID nodeId, String msg) {
+        this(nodeId, msg, msg);
+    }
+
+    /**
+     * @param nodeId Offending node ID.
      * @param msg Message logged locally.
      * @param sndMsg Message sent to joining node.
      */
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustTest.java
index e0fb95d..04fa266 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/BaselineAutoAdjustTest.java
@@ -23,12 +23,16 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.PartitionLossPolicy;
 import org.apache.ignite.cluster.BaselineNode;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.spi.IgniteSpiException;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.common.GridCommonTest;
 import org.junit.After;
@@ -409,4 +413,127 @@ public class BaselineAutoAdjustTest extends GridCommonAbstractTest {
             5_000
         ));
     }
+
+    /**
+     * @throws Exception if failed.
+     */
+    @Test
+    public void shouldNodeWithPersistenceSuccessfullyJoinedToClusterWhenAutoAdjustDisabled() throws Exception {
+        IgniteEx ignite0 = startGrid(inMemoryConfiguration(0));
+
+        ignite0.cluster().active(true);
+
+        ignite0.cluster().baselineAutoAdjustEnabled(false);
+
+        startGrid(persistentRegionConfiguration(1));
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    @Test
+    public void shouldNodeWithPersistenceSuccessfullyJoinedToClusterWhenTimeoutGreaterThanZero() throws Exception {
+        IgniteEx ignite0 = startGrid(inMemoryConfiguration(0));
+
+        ignite0.cluster().active(true);
+
+        ignite0.cluster().baselineAutoAdjustTimeout(1);
+
+        startGrid(persistentRegionConfiguration(1));
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    @Test
+    public void shouldJoinSuccessBecauseCoordinatorIsPersistent() throws Exception {
+        IgniteEx ignite0 = startGrid(persistentRegionConfiguration(0));
+
+        ignite0.cluster().active(true);
+
+        startGrid(inMemoryConfiguration(1));
+
+        startGrid(persistentRegionConfiguration(2));
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    @Test
+    public void shouldJoinSuccessBecauseClusterHasPersistentNode() throws Exception {
+        IgniteEx ignite0 = startGrid(inMemoryConfiguration(0));
+
+        ignite0.cluster().active(true);
+
+        ignite0.cluster().baselineAutoAdjustEnabled(false);
+
+        startGrid(persistentRegionConfiguration(1));
+
+        ignite0.cluster().baselineAutoAdjustEnabled(true);
+
+        startGrid(persistentRegionConfiguration(2));
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    @Test
+    public void shouldJoinFailedBecauseCoordinatorIsInMemoryNodeAndEnabledAutoAdjust() throws Exception {
+        IgniteEx ignite0 = startGrid(inMemoryConfiguration(0));
+        startGrid(inMemoryConfiguration(1));
+
+        ignite0.cluster().active(true);
+
+        try {
+            startGrid(persistentRegionConfiguration(2));
+        }
+        catch (IgniteCheckedException ex) {
+            if (!X.hasCause(ex, "Joining persistence node to in-memory cluster couldn't be allowed", IgniteSpiException.class))
+                fail("Join should be fail due to cluster has in-memory node and enabled auto-adjust.");
+        }
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    private IgniteConfiguration inMemoryConfiguration(int id) throws Exception {
+        IgniteConfiguration conf = getConfiguration(getTestIgniteInstanceName(id));
+
+        DataStorageConfiguration storageCfg = new DataStorageConfiguration();
+
+        storageCfg.getDefaultDataRegionConfiguration()
+            .setPersistenceEnabled(false)
+            .setMaxSize(500L * 1024 * 1024);
+
+        storageCfg.setDataRegionConfigurations(new DataRegionConfiguration()
+            .setName("InMemoryRegion")
+            .setPersistenceEnabled(false)
+            .setMaxSize(500L * 1024 * 1024));
+
+        conf.setDataStorageConfiguration(storageCfg);
+
+        return conf;
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    private IgniteConfiguration persistentRegionConfiguration(int id) throws Exception {
+        IgniteConfiguration conf = getConfiguration(getTestIgniteInstanceName(id));
+
+        DataStorageConfiguration storageCfg = new DataStorageConfiguration();
+
+        storageCfg.getDefaultDataRegionConfiguration()
+            .setPersistenceEnabled(false)
+            .setMaxSize(500L * 1024 * 1024);
+
+        storageCfg.setDataRegionConfigurations(new DataRegionConfiguration()
+            .setName("PersistentRegion")
+            .setPersistenceEnabled(true)
+            .setMaxSize(500L * 1024 * 1024));
+
+        conf.setDataStorageConfiguration(storageCfg);
+
+        return conf;
+    }
 }