IGNITE-1964 .NET: Enum type ID is written if it is registered as portable type.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/19d2dd05 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/19d2dd05 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/19d2dd05 Branch: refs/heads/ignite-1270 Commit: 19d2dd0571ba1e92593da50b8b35b35e2fb7b6e7 Parents: 171bbee Author: Pavel Tupitsyn <[email protected]> Authored: Mon Nov 23 12:08:26 2015 +0300 Committer: vozerov-gridgain <[email protected]> Committed: Mon Nov 23 12:08:26 2015 +0300 ---------------------------------------------------------------------- .../platform/PlatformComputeEchoTask.java | 18 +++++++ .../Binary/BinarySelfTest.cs | 35 ++++++++++++++ .../Compute/ComputeApiTest.cs | 51 +++++++++++++++----- .../Impl/Binary/BinarySystemHandlers.cs | 2 +- .../Impl/Binary/BinaryUtils.cs | 36 ++++++++++---- .../Impl/Binary/BinaryWriter.cs | 32 +++++++----- 6 files changed, 140 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/19d2dd05/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java index fe4e01c..c464945 100644 --- a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java +++ b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java @@ -17,13 +17,17 @@ package org.apache.ignite.platform; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteException; +import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.compute.ComputeJob; import org.apache.ignite.compute.ComputeJobAdapter; import org.apache.ignite.compute.ComputeJobResult; import org.apache.ignite.compute.ComputeTaskAdapter; import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.resources.IgniteInstanceResource; import org.jetbrains.annotations.Nullable; import java.util.Collections; @@ -88,6 +92,9 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object> /** Type: enum array. */ private static final int TYPE_ENUM_ARRAY = 17; + /** Type: enum array. */ + private static final int TYPE_ENUM_FIELD = 18; + /** {@inheritDoc} */ @Nullable @Override public Map<? extends ComputeJob, ClusterNode> map(List<ClusterNode> subgrid, @Nullable Integer arg) { @@ -106,6 +113,10 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object> /** Type. */ private Integer type; + /** Ignite. */ + @IgniteInstanceResource + private Ignite ignite; + /** * Constructor. * @@ -180,6 +191,13 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object> PlatformComputeEnum.FOO }; + case TYPE_ENUM_FIELD: + IgniteCache<Integer, BinaryObject> cache = ignite.cache(null).withKeepBinary(); + BinaryObject obj = cache.get(TYPE_ENUM_FIELD); + PlatformComputeEnum val = obj.field("interopEnum"); + + return val; + default: throw new IgniteException("Unknown type: " + type); } http://git-wip-us.apache.org/repos/asf/ignite/blob/19d2dd05/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs index 102afd1..f7455be 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs @@ -486,6 +486,23 @@ namespace Apache.Ignite.Core.Tests.Binary Assert.AreEqual(_marsh.Unmarshal<TestEnum>(_marsh.Marshal(val)), val); } + /// <summary> + /// Tests the write of registered enum. + /// </summary> + [Test] + public void TestWriteEnumRegistered() + { + var marsh = + new Marshaller(new BinaryConfiguration + { + TypeConfigurations = new[] { new BinaryTypeConfiguration(typeof(TestEnum)) } + }); + + TestEnum val = TestEnum.Val1; + + Assert.AreEqual(marsh.Unmarshal<TestEnum>(marsh.Marshal(val)), val); + } + /** * <summary>Check write of enum.</summary> */ @@ -497,6 +514,24 @@ namespace Apache.Ignite.Core.Tests.Binary Assert.AreEqual(vals, newVals); } + + /// <summary> + /// Tests the write of registered enum array. + /// </summary> + [Test] + public void TestWriteEnumArrayRegistered() + { + var marsh = + new Marshaller(new BinaryConfiguration + { + TypeConfigurations = new[] { new BinaryTypeConfiguration(typeof(TestEnum)) } + }); + + TestEnum[] vals = { TestEnum.Val2, TestEnum.Val3 }; + TestEnum[] newVals = marsh.Unmarshal<TestEnum[]>(marsh.Marshal(vals)); + + Assert.AreEqual(vals, newVals); + } /// <summary> /// Test object with dates. http://git-wip-us.apache.org/repos/asf/ignite/blob/19d2dd05/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs index 68616ab..1e999e3 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs @@ -105,6 +105,9 @@ namespace Apache.Ignite.Core.Tests.Compute /** Type: enum array. */ private const int EchoTypeEnumArray = 17; + /** Type: enum field. */ + private const int EchoTypeEnumField = 18; + /** First node. */ private IIgnite _grid1; @@ -861,9 +864,9 @@ namespace Apache.Ignite.Core.Tests.Compute [Test] public void TestEchoTaskEnum() { - var res = _grid1.GetCompute().ExecuteJavaTask<InteropComputeEnum>(EchoTask, EchoTypeEnum); + var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnum); - Assert.AreEqual(InteropComputeEnum.Bar, res); + Assert.AreEqual(PlatformComputeEnum.Bar, res); } /// <summary> @@ -872,17 +875,34 @@ namespace Apache.Ignite.Core.Tests.Compute [Test] public void TestEchoTaskEnumArray() { - var res = _grid1.GetCompute().ExecuteJavaTask<InteropComputeEnum[]>(EchoTask, EchoTypeEnumArray); + var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum[]>(EchoTask, EchoTypeEnumArray); Assert.AreEqual(new[] { - InteropComputeEnum.Bar, - InteropComputeEnum.Baz, - InteropComputeEnum.Foo + PlatformComputeEnum.Bar, + PlatformComputeEnum.Baz, + PlatformComputeEnum.Foo }, res); } /// <summary> + /// Tests the echo task reading enum from a binary object field. + /// Ensures that Java can understand enums written by .NET. + /// </summary> + [Test] + public void TestEchoTaskEnumField() + { + var enumVal = PlatformComputeEnum.Baz; + + _grid1.GetCache<int, InteropComputeEnumFieldTest>(null) + .Put(EchoTypeEnumField, new InteropComputeEnumFieldTest {InteropEnum = enumVal}); + + var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnumField); + + Assert.AreEqual(enumVal, res); + } + + /// <summary> /// Test for binary argument in Java. /// </summary> [Test] @@ -1107,11 +1127,15 @@ namespace Apache.Ignite.Core.Tests.Compute BinaryConfiguration portCfg = new BinaryConfiguration(); - ICollection<BinaryTypeConfiguration> portTypeCfgs = new List<BinaryTypeConfiguration>(); + var portTypeCfgs = new List<BinaryTypeConfiguration> + { + new BinaryTypeConfiguration(typeof (PlatformComputeBinarizable)), + new BinaryTypeConfiguration(typeof (PlatformComputeNetBinarizable)), + new BinaryTypeConfiguration(JavaBinaryCls), + new BinaryTypeConfiguration(typeof(PlatformComputeEnum)), + new BinaryTypeConfiguration(typeof(InteropComputeEnumFieldTest)) + }; - portTypeCfgs.Add(new BinaryTypeConfiguration(typeof(PlatformComputeBinarizable))); - portTypeCfgs.Add(new BinaryTypeConfiguration(typeof(PlatformComputeNetBinarizable))); - portTypeCfgs.Add(new BinaryTypeConfiguration(JavaBinaryCls)); portCfg.TypeConfigurations = portTypeCfgs; @@ -1294,10 +1318,15 @@ namespace Apache.Ignite.Core.Tests.Compute } } - public enum InteropComputeEnum + public enum PlatformComputeEnum { Foo, Bar, Baz } + + public class InteropComputeEnumFieldTest + { + public PlatformComputeEnum InteropEnum { get; set; } + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/19d2dd05/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs index 2c10d6a..b49c29d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs @@ -631,7 +631,7 @@ namespace Apache.Ignite.Core.Impl.Binary { ctx.Stream.WriteByte(BinaryUtils.TypeEnum); - BinaryUtils.WriteEnum(ctx.Stream, (Enum)obj); + BinaryUtils.WriteEnum(ctx, obj); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/19d2dd05/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs index a387066..1aed03f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs @@ -1001,11 +1001,14 @@ namespace Apache.Ignite.Core.Impl.Binary /// </summary> /// <param name="val">Array.</param> /// <param name="ctx">Write context.</param> - public static void WriteArray(Array val, BinaryWriter ctx) + /// <param name="elementType">Type of the array element.</param> + public static void WriteArray(Array val, BinaryWriter ctx, int elementType = ObjTypeId) { + Debug.Assert(val != null && ctx != null); + IBinaryStream stream = ctx.Stream; - stream.WriteInt(ObjTypeId); + stream.WriteInt(elementType); stream.WriteInt(val.Length); @@ -1291,18 +1294,31 @@ namespace Apache.Ignite.Core.Impl.Binary /// <summary> /// Write enum. /// </summary> - /// <param name="stream">Stream.</param> + /// <param name="writer">Writer.</param> /// <param name="val">Value.</param> - public static void WriteEnum(IBinaryStream stream, Enum val) + public static void WriteEnum<T>(BinaryWriter writer, T val) + { + writer.WriteInt(GetEnumTypeId(val.GetType(), writer.Marshaller)); + writer.WriteInt(TypeCaster<int>.Cast(val)); + } + + /// <summary> + /// Gets the enum type identifier. + /// </summary> + /// <param name="enumType">The enum type.</param> + /// <param name="marshaller">The marshaller.</param> + /// <returns>Enum type id.</returns> + public static int GetEnumTypeId(Type enumType, Marshaller marshaller) { - if (Enum.GetUnderlyingType(val.GetType()) == TypInt) + if (Enum.GetUnderlyingType(enumType) == TypInt) { - stream.WriteInt(ObjTypeId); - stream.WriteInt((int) (object) val); + var desc = marshaller.GetDescriptor(enumType); + + return desc == null ? ObjTypeId : desc.TypeId; } - else - throw new BinaryObjectException("Only Int32 underlying type is supported for enums: " + - val.GetType().Name); + + throw new BinaryObjectException("Only Int32 underlying type is supported for enums: " + + enumType.Name); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/19d2dd05/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs index e09a7f4..c00dad6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs @@ -25,6 +25,7 @@ namespace Apache.Ignite.Core.Impl.Binary using Apache.Ignite.Core.Impl.Binary.IO; using Apache.Ignite.Core.Impl.Binary.Metadata; using Apache.Ignite.Core.Impl.Binary.Structure; + using Apache.Ignite.Core.Impl.Common; /// <summary> /// Binary writer implementation. @@ -792,8 +793,7 @@ namespace Apache.Ignite.Core.Impl.Binary { WriteFieldId(fieldName, BinaryUtils.TypeEnum); - _stream.WriteByte(BinaryUtils.TypeEnum); - BinaryUtils.WriteEnum(_stream, (Enum)(object)val); + WriteEnum(val); } /// <summary> @@ -804,7 +804,7 @@ namespace Apache.Ignite.Core.Impl.Binary public void WriteEnum<T>(T val) { _stream.WriteByte(BinaryUtils.TypeEnum); - BinaryUtils.WriteEnum(_stream, (Enum)(object)val); + BinaryUtils.WriteEnum(this, val); } /// <summary> @@ -820,10 +820,7 @@ namespace Apache.Ignite.Core.Impl.Binary if (val == null) WriteNullField(); else - { - _stream.WriteByte(BinaryUtils.TypeArrayEnum); - BinaryUtils.WriteArray(val, this); - } + WriteEnumArray0(val); } /// <summary> @@ -836,10 +833,21 @@ namespace Apache.Ignite.Core.Impl.Binary if (val == null) WriteNullRawField(); else - { - _stream.WriteByte(BinaryUtils.TypeArrayEnum); - BinaryUtils.WriteArray(val, this); - } + WriteEnumArray0(val); + } + + /// <summary> + /// Writes the enum array. + /// </summary> + /// <param name="val">The value.</param> + private void WriteEnumArray0<T>(T[] val) + { + _stream.WriteByte(BinaryUtils.TypeArrayEnum); + + // typeof(T) can yield wrong results (string[] is object[], for example) + var elementType = val.GetType().GetElementType(); + + BinaryUtils.WriteArray(val, this, BinaryUtils.GetEnumTypeId(elementType, Marshaller)); } /// <summary> @@ -1048,7 +1056,7 @@ namespace Apache.Ignite.Core.Impl.Binary return; // Suppose that we faced normal object and perform descriptor lookup. - IBinaryTypeDescriptor desc = _marsh.GetDescriptor(type); + IBinaryTypeDescriptor desc = type.IsEnum ? null : _marsh.GetDescriptor(type); if (desc != null) {
