Skip to content

Commit

Permalink
IGNITE-6536 Node fails when detects mapping storage corruption
Browse files Browse the repository at this point in the history
Signed-off-by: Andrey Gura <agura@apache.org>
  • Loading branch information
sergey-chugunov-1985 authored and agura committed Oct 11, 2017
1 parent b0158fb commit 5490c7d
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 9 deletions.
Expand Up @@ -167,16 +167,19 @@ void restoreMappings(MarshallerContext marshCtx) throws IgniteCheckedException {

try (FileInputStream in = new FileInputStream(file)) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
String className = reader.readLine();
String clsName = reader.readLine();

marshCtx.registerClassNameLocally(platformId, typeId, className);
if (clsName == null) {
throw new IgniteCheckedException("Class name is null for [platformId=" + platformId +
", typeId=" + typeId + "], marshaller mappings storage is broken. " +
"Clean up marshaller directory (<work_dir>/marshaller) and restart the node.");
}

marshCtx.registerClassNameLocally(platformId, typeId, clsName);
}
}
catch (IOException e) {
throw new IgniteCheckedException("Reading marshaller mapping from file "
+ name
+ " failed."
, e);
throw new IgniteCheckedException("Reading marshaller mapping from file " + name + " failed.", e);
}
}
}
Expand Down
Expand Up @@ -23,13 +23,16 @@
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.PersistentStoreConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
import org.apache.ignite.internal.processors.marshaller.MappingProposedMessage;
Expand All @@ -47,6 +50,9 @@ public class IgniteMarshallerCacheFSRestoreTest extends GridCommonAbstractTest {
/** */
private volatile boolean isDuplicateObserved = true;

/** */
private boolean isPersistenceEnabled;

/**
*
*/
Expand All @@ -67,6 +73,7 @@ private static class SimpleValue {
}
}

/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);

Expand All @@ -75,13 +82,17 @@ private static class SimpleValue {

cfg.setDiscoverySpi(discoSpi);

CacheConfiguration singleCacheConfig = new CacheConfiguration()
CacheConfiguration singleCacheCfg = new CacheConfiguration()
.setName(DEFAULT_CACHE_NAME)
.setCacheMode(CacheMode.PARTITIONED)
.setBackups(1)
.setAtomicityMode(CacheAtomicityMode.ATOMIC);

cfg.setCacheConfiguration(singleCacheConfig);
cfg.setCacheConfiguration(singleCacheCfg);

//persistence must be enabled to verify restoring mappings from FS case
if (isPersistenceEnabled)
cfg.setPersistentStoreConfiguration(new PersistentStoreConfiguration());

return cfg;
}
Expand Down Expand Up @@ -110,11 +121,14 @@ private void cleanUpWorkDir() throws Exception {
* In that case the request must not be marked as duplicate and must be processed in a regular way.
* No hangs must take place.
*
* @see <a href="https://issues.apache.org/jira/browse/IGNITE-5401">IGNITE-5401</a> Take a look at JIRA ticket for more information about context of this test.
* @see <a href="https://issues.apache.org/jira/browse/IGNITE-5401">IGNITE-5401</a> JIRA ticket
* provides more information about context of this test.
*
* This test must never hang on proposing of MarshallerMapping.
*/
public void testFileMappingReadAndPropose() throws Exception {
isPersistenceEnabled = false;

prepareMarshallerFileStore();

IgniteEx ignite0 = startGrid(0);
Expand Down Expand Up @@ -162,6 +176,57 @@ private void prepareMarshallerFileStore() throws Exception {
}
}

/**
* Verifies scenario that node with corrupted marshaller mapping store must fail on startup
* with appropriate error message.
*
* @see <a href="https://issues.apache.org/jira/browse/IGNITE-6536">IGNITE-6536</a> JIRA provides more information
* about this case.
*/
public void testNodeStartFailsOnCorruptedStorage() throws Exception {
isPersistenceEnabled = true;

Ignite ig = startGrids(3);

ig.active(true);

ig.cache(DEFAULT_CACHE_NAME).put(0, new SimpleValue(0, "value0"));

stopAllGrids();

corruptMarshallerStorage();

try {
startGrid(0);
}
catch (IgniteCheckedException e) {
verifyException((IgniteCheckedException) e.getCause());
}
}

/**
* Class name for CustomClass class mapping file gets cleaned up from file system.
*/
private void corruptMarshallerStorage() throws Exception {
String marshallerDir = U.defaultWorkDirectory() + File.separator + "marshaller";

File[] storedMappingsFiles = new File(marshallerDir).listFiles();

assert storedMappingsFiles.length == 1;

try (FileOutputStream out = new FileOutputStream(storedMappingsFiles[0])) {
out.getChannel().truncate(0);
}
}

/** */
private void verifyException(IgniteCheckedException e) throws Exception {
String msg = e.getMessage();

if (msg == null || !msg.contains("Class name is null"))
throw new Exception("Exception with unexpected message was thrown: " + msg, e);
}

/** */
private class TestTcpDiscoverySpi extends TcpDiscoverySpi {

Expand Down

0 comments on commit 5490c7d

Please sign in to comment.