You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/08/28 14:48:06 UTC

[5/8] ignite git commit: ignite-6180: restoring marshaller mappings on node start is implemented

ignite-6180: restoring marshaller mappings on node start is implemented

Signed-off-by: Andrey Gura <ag...@apache.org>


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

Branch: refs/heads/ignite-6149
Commit: 418c43889aac293cef8bcd6c5e4b90f85fc30e7c
Parents: 02801f8
Author: Ilya Lantukh <il...@gridgain.com>
Authored: Fri Aug 25 13:12:32 2017 +0300
Committer: Andrey Gura <ag...@apache.org>
Committed: Fri Aug 25 16:32:49 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/418c4388/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 bb93354..d133676 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
@@ -517,6 +517,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/418c4388/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/418c4388/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/418c4388/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;
     }