You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sk...@apache.org on 2020/04/08 17:10:41 UTC
[ignite] branch master updated: IGNITE-12805 Fixed
NullPointerException when memory restore is in progress. Fixes #7562
This is an automated email from the ASF dual-hosted git repository.
sk0x50 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 b816729 IGNITE-12805 Fixed NullPointerException when memory restore is in progress. Fixes #7562
b816729 is described below
commit b8167296b13c8ecb0b035f5495d65039a3a86105
Author: Slava Koptilin <sl...@gmail.com>
AuthorDate: Wed Apr 8 20:10:13 2020 +0300
IGNITE-12805 Fixed NullPointerException when memory restore is in progress. Fixes #7562
---
.../cache/ValidationOnNodeJoinUtils.java | 14 +++--
.../db/IgniteCacheGroupsWithRestartsTest.java | 66 ++++++++++++++++++++++
2 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ValidationOnNodeJoinUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ValidationOnNodeJoinUtils.java
index 78e8b3f..ed3ea76 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ValidationOnNodeJoinUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ValidationOnNodeJoinUtils.java
@@ -50,6 +50,7 @@ import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteFeatures;
import org.apache.ignite.internal.IgniteNodeAttributes;
import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.cluster.DetachedClusterNode;
import org.apache.ignite.internal.processors.affinity.LocalAffinityFunction;
import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor;
@@ -328,7 +329,12 @@ public class ValidationOnNodeJoinUtils {
"Custom IndexingSpi cannot be used with TRANSACTIONAL_SNAPSHOT atomicity mode");
}
- if (cc.isWriteBehindEnabled() && ctx.discovery().cacheAffinityNode(ctx.discovery().localNode(), cc.getName())) {
+ // This method can be called when memory recovery is in progress,
+ // which means that the GridDiscovery manager is not started, and therefore localNode is also not initialized.
+ ClusterNode locNode = ctx.discovery().localNode() != null ? ctx.discovery().localNode():
+ new DetachedClusterNode(ctx.pdsFolderResolver().resolveFolders().consistentId(), ctx.nodeAttributes());
+
+ if (cc.isWriteBehindEnabled() && ctx.discovery().cacheAffinityNode(locNode, cc.getName())) {
if (cfgStore == null)
throw new IgniteCheckedException("Cannot enable write-behind (writer or store is not provided) " +
"for cache: " + U.maskName(cc.getName()));
@@ -343,13 +349,11 @@ public class ValidationOnNodeJoinUtils {
"'writeBehindFlushSize' parameters to 0 for cache: " + U.maskName(cc.getName()));
}
- if (cc.isReadThrough() && cfgStore == null
- && ctx.discovery().cacheAffinityNode(ctx.discovery().localNode(), cc.getName()))
+ if (cc.isReadThrough() && cfgStore == null && ctx.discovery().cacheAffinityNode(locNode, cc.getName()))
throw new IgniteCheckedException("Cannot enable read-through (loader or store is not provided) " +
"for cache: " + U.maskName(cc.getName()));
- if (cc.isWriteThrough() && cfgStore == null
- && ctx.discovery().cacheAffinityNode(ctx.discovery().localNode(), cc.getName()))
+ if (cc.isWriteThrough() && cfgStore == null && ctx.discovery().cacheAffinityNode(locNode, cc.getName()))
throw new IgniteCheckedException("Cannot enable write-through (writer or store is not provided) " +
"for cache: " + U.maskName(cc.getName()));
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteCacheGroupsWithRestartsTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteCacheGroupsWithRestartsTest.java
index c6851c6..0520153 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteCacheGroupsWithRestartsTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteCacheGroupsWithRestartsTest.java
@@ -26,12 +26,18 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.BiFunction;
+import javax.cache.Cache;
+import javax.cache.configuration.Factory;
+import javax.cache.integration.CacheLoaderException;
+import javax.cache.integration.CacheWriterException;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.cache.QueryIndex;
import org.apache.ignite.cache.QueryIndexType;
import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cache.store.CacheStore;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ConnectorConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
@@ -55,6 +61,7 @@ import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
+import static org.apache.ignite.cluster.ClusterState.ACTIVE;
import static org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.IGNITE_PDS_SKIP_CHECKPOINT_ON_NODE_STOP;
import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.DFLT_STORE_DIR;
@@ -266,6 +273,37 @@ public class IgniteCacheGroupsWithRestartsTest extends GridCommonAbstractTest {
}
/**
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testNodeRestartWith3rdPartyCacheStoreAndPersistenceEnabled() throws Exception {
+ IgniteEx crd = startGrid(0);
+
+ crd.cluster().state(ACTIVE);
+
+ String cacheName = "test-cache-3rd-party-write-behind-and-ignite-persistence";
+ CacheConfiguration ccfg = new CacheConfiguration(cacheName)
+ .setWriteBehindEnabled(true)
+ .setWriteThrough(true)
+ .setReadThrough(true)
+ .setCacheStoreFactory(new StoreFactory());
+
+ IgniteCache cache = crd.getOrCreateCache(ccfg);
+
+ cache.put(12, 42);
+
+ stopGrid(0);
+
+ crd = startGrid(0);
+
+ crd.cluster().state(ACTIVE);
+
+ cache = crd.cache(cacheName);
+
+ assertEquals("Cache was not properly restored or required key is lost.", 42, cache.get(12));
+ }
+
+ /**
* @param doFindAndRemove Do find and remove.
*/
private void testFindAndDeleteGarbage(
@@ -400,4 +438,32 @@ public class IgniteCacheGroupsWithRestartsTest extends GridCommonAbstractTest {
return S.toString(Account.class, this);
}
}
+
+ /**
+ * Test store factory.
+ */
+ private static class StoreFactory implements Factory<CacheStore> {
+ /** {@inheritDoc} */
+ @Override public CacheStore create() {
+ return new TestStore();
+ }
+ }
+
+ /**
+ * Test store.
+ */
+ private static class TestStore extends CacheStoreAdapter {
+ /** {@inheritDoc} */
+ @Override public Object load(Object key) throws CacheLoaderException {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void write(Cache.Entry entry) throws CacheWriterException {
+ }
+
+ /** {@inheritDoc} */
+ @Override public void delete(Object key) throws CacheWriterException {
+ }
+ }
}