IGNITE-4914 Distributing marshaller mappings for multiple platforms fixed This closes #1741
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/037bca6f Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/037bca6f Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/037bca6f Branch: refs/heads/ignite-1192 Commit: 037bca6f92c6041f75e9db83cd6befd635321177 Parents: 7c80c47 Author: Sergey Chugunov <sergey.chugu...@gmail.com> Authored: Thu Apr 6 11:25:57 2017 +0300 Committer: Pavel Tupitsyn <ptupit...@apache.org> Committed: Thu Apr 6 11:25:57 2017 +0300 ---------------------------------------------------------------------- .../ignite/internal/MarshallerContextImpl.java | 20 +++-- .../marshaller/MarshallerContextSelfTest.java | 80 ++++++++++++++++++-- 2 files changed, 88 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/037bca6f/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 ce79b4f..effd481 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 @@ -25,6 +25,7 @@ import java.net.URL; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; @@ -145,9 +146,11 @@ public class MarshallerContextImpl implements MarshallerContext { /** */ public ArrayList<Map<Integer, MappedName>> getCachedMappings() { - ArrayList<Map<Integer, MappedName>> result = new ArrayList<>(allCaches.size()); + int size = allCaches.size(); + + ArrayList<Map<Integer, MappedName>> result = new ArrayList<>(size); - for (int i = 0; i < allCaches.size(); i++) { + for (int i = 0; i < size; i++) { Map res; if (i == JAVA_ID) @@ -155,8 +158,10 @@ public class MarshallerContextImpl implements MarshallerContext { else res = allCaches.get(i); - if (!res.isEmpty()) + if (res != null && !res.isEmpty()) result.add(res); + else + result.add(Collections.<Integer, MappedName>emptyMap()); } return result; @@ -164,12 +169,12 @@ public class MarshallerContextImpl implements MarshallerContext { /** * @param platformId Platform id. - * @param marshallerMapping Marshaller mapping. + * @param marshallerMappings All marshaller mappings for given platformId. */ - public void onMappingDataReceived(byte platformId, Map<Integer, MappedName> marshallerMapping) { + public void onMappingDataReceived(byte platformId, Map<Integer, MappedName> marshallerMappings) { ConcurrentMap<Integer, MappedName> platformCache = getCacheFor(platformId); - for (Map.Entry<Integer, MappedName> e : marshallerMapping.entrySet()) + for (Map.Entry<Integer, MappedName> e : marshallerMappings.entrySet()) platformCache.put(e.getKey(), new MappedName(e.getValue().className(), true)); } @@ -299,7 +304,8 @@ public class MarshallerContextImpl implements MarshallerContext { /** * * @param item type mapping to propose - * @return false if there is a conflict with another mapping in local cache, true otherwise. + * @return null if cache doesn't contain any mappings for given (platformId, typeId) pair, + * previous class name otherwise. */ public String onMappingProposed(MarshallerMappingItem item) { ConcurrentMap<Integer, MappedName> cache = getCacheFor(item.platformId()); http://git-wip-us.apache.org/repos/asf/ignite/blob/037bca6f/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java index 5883898..db3738d 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java @@ -21,7 +21,9 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -29,6 +31,7 @@ import org.apache.ignite.Ignite; import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.MarshallerContextImpl; import org.apache.ignite.internal.processors.closure.GridClosureProcessor; +import org.apache.ignite.internal.processors.marshaller.MappedName; import org.apache.ignite.internal.processors.marshaller.MarshallerMappingItem; import org.apache.ignite.internal.processors.pool.PoolProcessor; import org.apache.ignite.internal.util.typedef.internal.U; @@ -60,22 +63,27 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest { ctx.add(new GridClosureProcessor(ctx)); } + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + } + /** * @throws Exception If failed. */ public void testClassName() throws Exception { - MarshallerContextImpl ctx = new MarshallerContextImpl(null); + MarshallerContextImpl marshCtx = new MarshallerContextImpl(null); - ctx.onMarshallerProcessorStarted(this.ctx, null); + marshCtx.onMarshallerProcessorStarted(ctx, null); MarshallerMappingItem item = new MarshallerMappingItem(JAVA_ID, 1, String.class.getName()); - ctx.onMappingProposed(item); + marshCtx.onMappingProposed(item); - ctx.onMappingAccepted(item); + marshCtx.onMappingAccepted(item); try (Ignite g1 = startGrid(1)) { - MarshallerContextImpl marshCtx = ((IgniteKernal)g1).context().marshallerContext(); + marshCtx = ((IgniteKernal)g1).context().marshallerContext(); String clsName = marshCtx.getClassName(JAVA_ID, 1); assertEquals("java.lang.String", clsName); @@ -83,6 +91,68 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest { } /** + * Test for adding non-java mappings (with platformId > 0) to MarshallerContext and collecting them + * for discovery. + * + * @throws Exception If failed. + */ + public void testMultiplatformMappingsCollecting() throws Exception { + String nonJavaClassName = "random.platform.Mapping"; + + MarshallerContextImpl marshCtx = new MarshallerContextImpl(null); + + marshCtx.onMarshallerProcessorStarted(ctx, null); + + MarshallerMappingItem item = new MarshallerMappingItem((byte) 2, 101, nonJavaClassName); + + marshCtx.onMappingProposed(item); + + marshCtx.onMappingAccepted(item); + + ArrayList<Map<Integer, MappedName>> allMappings = marshCtx.getCachedMappings(); + + assertEquals(allMappings.size(), 3); + + assertTrue(allMappings.get(0).isEmpty()); + + assertTrue(allMappings.get(1).isEmpty()); + + Map<Integer, MappedName> nonJavaMappings = allMappings.get(2); + + assertNotNull(nonJavaMappings); + + assertNotNull(nonJavaMappings.get(101)); + + assertEquals(nonJavaClassName, nonJavaMappings.get(101).className()); + } + + /** + * Test for adding non-java mappings (with platformId > 0) to MarshallerContext and distributing them + * to newly joining nodes. + * + * @throws Exception If failed. + */ + public void testMultiplatformMappingsDistributing() throws Exception { + String nonJavaClassName = "random.platform.Mapping"; + + Ignite grid0 = startGrid(0); + + MarshallerContextImpl marshCtx0 = ((IgniteKernal)grid0).context().marshallerContext(); + + MarshallerMappingItem item = new MarshallerMappingItem((byte) 2, 101, nonJavaClassName); + + marshCtx0.onMappingProposed(item); + + marshCtx0.onMappingAccepted(item); + + Ignite grid1 = startGrid(1); + + MarshallerContextImpl marshCtx1 = ((IgniteKernal)grid1).context().marshallerContext(); + + assertEquals(nonJavaClassName, marshCtx1.getClassName((byte) 2, 101)); + } + + /** * @throws Exception If failed. */ public void testOnUpdated() throws Exception {