Repository: ignite Updated Branches: refs/heads/ignite-6181-1 [created] 2468e0090
ignite-6180: restoring marshaller mappings on node start is implemented Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9399610d Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9399610d Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9399610d Branch: refs/heads/ignite-6181-1 Commit: 9399610d2dd4b67b1da6475ce2141787fb8dbb0e Parents: b2b596b Author: Ilya Lantukh <ilant...@gridgain.com> Authored: Fri Aug 25 13:12:32 2017 +0300 Committer: Ilya Lantukh <ilant...@gridgain.com> Committed: Fri Aug 25 13:12:32 2017 +0300 ---------------------------------------------------------------------- .../ignite/internal/MarshallerContextImpl.java | 3 + .../internal/MarshallerMappingFileStore.java | 76 +++++++++++- ...MarshallerMappingRestoreOnNodeStartTest.java | 116 +++++++++++++++++++ .../IgnitePdsWithIndexingCoreTestSuite.java | 2 + 4 files changed, 196 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/9399610d/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java index 6f15507..33b6ff8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java @@ -519,6 +519,9 @@ public class MarshallerContextImpl implements MarshallerContext { this.transport = transport; closProc = ctx.closure(); clientNode = ctx.clientNode(); + + if (ctx.config().isPersistentStoreEnabled()) + fileStore.restoreMappings(this); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/9399610d/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java index 03f79c9..e4a844e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java @@ -34,6 +34,7 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.util.GridStripedLock; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.MarshallerContext; /** * File-based persistence provider for {@link MarshallerContextImpl}. @@ -53,6 +54,9 @@ final class MarshallerMappingFileStore { /** */ private final File workDir; + /** */ + private final String FILE_EXTENSION = ".classname"; + /** * @param log Logger. */ @@ -137,11 +141,81 @@ final class MarshallerMappingFileStore { } /** + * Restores all mappings available in file system to marshaller context. + * This method should be used only on node startup. + * + * @param marshCtx Marshaller context to register mappings. + */ + void restoreMappings(MarshallerContext marshCtx) throws IgniteCheckedException { + for (File file : workDir.listFiles()) { + String name = file.getName(); + + byte platformId = getPlatformId(name); + + int typeId = getTypeId(name); + + try (FileInputStream in = new FileInputStream(file)) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + String className = reader.readLine(); + + marshCtx.registerClassNameLocally(platformId, typeId, className); + } + } + catch (IOException e) { + throw new IgniteCheckedException("Reading marshaller mapping from file " + + name + + " failed." + , e); + } + } + } + + /** + * @param fileName Name of file with marshaller mapping information. + * @throws IgniteCheckedException If file name format is broken. + */ + private byte getPlatformId(String fileName) throws IgniteCheckedException { + String lastSymbol = fileName.substring(fileName.length() - 1); + + byte platformId; + + try { + platformId = Byte.parseByte(lastSymbol); + } + catch (NumberFormatException e) { + throw new IgniteCheckedException("Reading marshaller mapping from file " + + fileName + + " failed; last symbol of file name is expected to be numeric.", e); + } + + return platformId; + } + + /** + * @param fileName Name of file with marshaller mapping information. + * @throws IgniteCheckedException If file name format is broken. + */ + private int getTypeId(String fileName) throws IgniteCheckedException { + int typeId; + + try { + typeId = Integer.parseInt(fileName.substring(0, fileName.indexOf(FILE_EXTENSION))); + } + catch (NumberFormatException e) { + throw new IgniteCheckedException("Reading marshaller mapping from file " + + fileName + + " failed; type ID is expected to be numeric.", e); + } + + return typeId; + } + + /** * @param platformId Platform id. * @param typeId Type id. */ private String getFileName(byte platformId, int typeId) { - return typeId + ".classname" + platformId; + return typeId + FILE_EXTENSION + platformId; } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/9399610d/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsMarshallerMappingRestoreOnNodeStartTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsMarshallerMappingRestoreOnNodeStartTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsMarshallerMappingRestoreOnNodeStartTest.java new file mode 100644 index 0000000..517b9ea --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsMarshallerMappingRestoreOnNodeStartTest.java @@ -0,0 +1,116 @@ +/* + * 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.cache.persistence; + +import java.nio.file.Paths; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.cache.affinity.AffinityKeyMapped; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.PersistentStoreConfiguration; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * + */ +public class IgnitePdsMarshallerMappingRestoreOnNodeStartTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + int gridIndex = getTestIgniteInstanceIndex(gridName); + + IgniteConfiguration cfg = super.getConfiguration(gridName); + + String tmpDir = System.getProperty("java.io.tmpdir"); + + cfg.setWorkDirectory(Paths.get(tmpDir, "srv" + gridIndex).toString()); + + cfg.setPersistentStoreConfiguration( + new PersistentStoreConfiguration() + ); + + cfg.setCacheConfiguration(new CacheConfiguration() + .setName(DEFAULT_CACHE_NAME) + .setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC) + .setCacheMode(CacheMode.REPLICATED)); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + + String tmpDir = System.getProperty("java.io.tmpdir"); + + deleteRecursively(Paths.get(tmpDir, "srv0").toFile()); + deleteRecursively(Paths.get(tmpDir, "srv1").toFile()); + } + + /** + * Test verifies that binary metadata from regular java classes is saved and restored correctly + * on cluster restart. + */ + public void testStaticMetadataIsRestoredOnRestart() throws Exception { + startGrids(1); + + Ignite ignite0 = grid(0); + + ignite0.active(true); + + IgniteCache<Object, Object> cache0 = ignite0.cache(DEFAULT_CACHE_NAME); + + cache0.put(0, new TestValue1(0)); + + stopAllGrids(); + + startGrids(1); + + ignite0 = grid(0); + + ignite0.active(true); + + Ignite ignite1 = startGrid(1); + + awaitPartitionMapExchange(); + + ignite1.cache(DEFAULT_CACHE_NAME).get(0); + } + + /** + * + */ + private static class TestValue1 { + /** */ + @AffinityKeyMapped + private final int val; + + /** + * @param val Value. + */ + TestValue1(int val) { + this.val = val; + } + + /** */ + int getValue() { + return val; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/9399610d/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java index bb9c9d1..ae8ea18 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java @@ -19,6 +19,7 @@ package org.apache.ignite.testsuites; import junit.framework.TestSuite; import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsAtomicCacheRebalancingTest; import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsBinaryMetadataOnClusterRestartTest; +import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsMarshallerMappingRestoreOnNodeStartTest; import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsTxCacheRebalancingTest; import org.apache.ignite.internal.processors.cache.persistence.IgnitePersistentStoreCacheGroupsTest; import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsMultiNodePutGetRestartTest; @@ -51,6 +52,7 @@ public class IgnitePdsWithIndexingCoreTestSuite extends TestSuite { suite.addTestSuite(IgnitePdsTxCacheRebalancingTest.class); suite.addTestSuite(IgnitePdsBinaryMetadataOnClusterRestartTest.class); + suite.addTestSuite(IgnitePdsMarshallerMappingRestoreOnNodeStartTest.class); return suite; }