This is an automated email from the ASF dual-hosted git repository.

ptupitsyn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 8cc19b1  IGNITE-14293 .NET: Fix AffinityKey metadata in 
QueryEntity.KeyType
8cc19b1 is described below

commit 8cc19b1041b64d7dd3bb368ce4b9cadee07a3718
Author: Pavel Tupitsyn <ptupit...@apache.org>
AuthorDate: Wed Mar 10 18:43:44 2021 +0300

    IGNITE-14293 .NET: Fix AffinityKey metadata in QueryEntity.KeyType
    
    `AffinityKey` system type, when used as a `QueryEntiry` key, got 
overwritten by `UnmanagedCallbacks.BinaryTypeGet` call, which broke the mapping 
to a corresponding Java type.
    
    * Add missing check for existing registered type (actual fix in 
Marshaller.cs)
    * Add check for system type overwrite
    * Add test for `AffinityKey` + `QueryEntity`
    * Improve examples tests - SQL and LINQ examples were affected by this bug
    * Change cache names in examples so different examples do not interfere
    
    Co-authored-by: Igor Sapego <isap...@apache.org>
---
 .../Cache/Affinity/AffinityTest.cs                 | 40 +++++++++++++
 .../Apache.Ignite.Core.Tests/Examples/Example.cs   | 12 ++++
 .../Examples/ExamplesTestBase.cs                   | 69 ++++++++++++++++++++--
 .../Examples/ExpectedOutput/AtomicReference.txt    |  2 +-
 .../Examples/ExpectedOutput/ClientReconnect.txt    |  3 +-
 .../Examples/ExpectedOutput/DataStreamer.txt       |  2 +-
 .../Examples/ExpectedOutput/Lifecycle.txt          |  2 +-
 .../Examples/ExpectedOutput/Linq.txt               |  8 +--
 .../Examples/ExpectedOutput/LinqThin.txt           |  8 +--
 .../Examples/ExpectedOutput/Messaging.txt          | 40 ++++++-------
 .../ExpectedOutput/OptimisticTransaction.txt       |  2 +-
 .../ExpectedOutput/OptimisticTransactionThin.txt   |  2 +-
 .../ExpectedOutput/PeerAssemblyLoading.txt         |  2 +-
 .../Examples/ExpectedOutput/PutGet.txt             |  6 +-
 .../Examples/ExpectedOutput/PutGetThin.txt         |  6 +-
 .../Examples/ExpectedOutput/SqlThin.txt            |  2 -
 .../TransactionDeadlockDetection.txt               | 10 ++--
 .../Apache.Ignite.Core/Impl/Binary/Marshaller.cs   | 21 +++++++
 .../examples/Thick/Cache/QueryFullText/Program.cs  |  2 +-
 .../examples/Thick/Cache/QueryScan/Program.cs      |  2 +-
 .../dotnet/examples/Thick/Cache/Store/Program.cs   |  2 +-
 .../examples/Thick/Cache/Transaction/Program.cs    |  4 +-
 .../dotnet/examples/Thick/Sql/Linq/Program.cs      |  6 +-
 .../examples/Thin/Cache/QueryScanThin/Program.cs   |  2 +-
 .../examples/Thin/Cache/TransactionThin/Program.cs |  4 +-
 .../dotnet/examples/Thin/Sql/LinqThin/Program.cs   |  6 +-
 26 files changed, 198 insertions(+), 67 deletions(-)

diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs
index 37bc53b..cd7a327 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs
@@ -122,6 +122,46 @@ namespace Apache.Ignite.Core.Tests.Cache.Affinity
         }
 
         /// <summary>
+        /// Tests that <see cref="AffinityKey"/> works when used as <see 
cref="QueryEntity.KeyType"/>.
+        /// </summary>
+        [Test]
+        public void TestAffinityKeyWithQueryEntity()
+        {
+            var cacheCfg = new CacheConfiguration(TestUtils.TestName)
+            {
+                QueryEntities = new List<QueryEntity>
+                {
+                    new QueryEntity(typeof(AffinityKey), 
typeof(QueryEntityValue))
+                }
+            };
+
+            var ignite = Ignition.GetIgnite("grid-0");
+            var cache = ignite.GetOrCreateCache<AffinityKey, 
QueryEntityValue>(cacheCfg);
+            var aff = ignite.GetAffinity(cache.Name);
+
+            var ignite2 = Ignition.GetIgnite("grid-1");
+            var cache2 = ignite2.GetOrCreateCache<AffinityKey, 
QueryEntityValue>(cacheCfg);
+            var aff2 = ignite2.GetAffinity(cache2.Name);
+
+            // Check mapping.
+            for (var i = 0; i < 100; i++)
+            {
+                Assert.AreEqual(aff.GetPartition(i), aff.GetPartition(new 
AffinityKey("foo" + i, i)));
+                Assert.AreEqual(aff2.GetPartition(i), aff2.GetPartition(new 
AffinityKey("bar" + i, i)));
+                Assert.AreEqual(aff.GetPartition(i), aff2.GetPartition(i));
+            }
+
+            // Check put/get.
+            var key = new AffinityKey("x", 123);
+            var expected = new QueryEntityValue {Name = "y", AffKey = 321};
+            cache[key] = expected;
+
+            var val = cache2[key];
+            Assert.AreEqual(expected.Name, val.Name);
+            Assert.AreEqual(expected.AffKey, val.AffKey);
+        }
+
+        /// <summary>
         /// Tests that <see cref="AffinityKeyMappedAttribute"/> works when 
used on a property of a type that is
         /// specified as <see cref="QueryEntity.KeyType"/> or <see 
cref="QueryEntity.ValueType"/>.
         /// </summary>
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
index c35f64e..b7b671d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
@@ -29,6 +29,13 @@ namespace Apache.Ignite.Core.Tests.Examples
     /// </summary>
     public class Example
     {
+        /** Examples with undefined output order. */
+        private static readonly IReadOnlyCollection<string> 
UnorderedOutputExamples = new HashSet<string>
+        {
+            "Dml", "Ddl", "EntryProcessor", "Func", "Messaging", 
"QueryContinuous", "Task", "Sql", "Linq", "AtomicLong",
+            "ClientReconnect"
+        };
+
         /** All projects. */
         public static readonly Example[] AllProjects = GetExamples()
             .OrderBy(x => x.Name)
@@ -64,6 +71,9 @@ namespace Apache.Ignite.Core.Tests.Examples
         /** Whether this example disallows external nodes. */
         public bool DisallowsExternalNode { get; }
 
+        /** Whether the output of this example can be unordered (e.g. compute 
task execution order is not guaranteed. */
+        public bool UndefinedOutputOrder { get; }
+
         /// <summary>
         /// Initializes a new instance of <see cref="Example"/> class.
         /// </summary>
@@ -76,6 +86,8 @@ namespace Apache.Ignite.Core.Tests.Examples
             RequiresExternalNode = sourceCode.Contains("ServerNode project");
             DisallowsExternalNode = sourceCode.Contains("without external 
node");
             IsClient = sourceCode.Contains("GetClientNodeConfiguration") && 
!DisallowsExternalNode;
+            UndefinedOutputOrder = UnorderedOutputExamples.Contains(name) ||
+                                   
UnorderedOutputExamples.Contains(name.Replace("Thin", ""));
         }
 
         /// <summary>
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs
index 16b402b..053072a 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs
@@ -19,6 +19,7 @@ namespace Apache.Ignite.Core.Tests.Examples
 {
     using System;
     using System.IO;
+    using System.Linq;
     using System.Text;
     using System.Text.RegularExpressions;
     using NUnit.Framework;
@@ -82,7 +83,7 @@ namespace Apache.Ignite.Core.Tests.Examples
                 StringAssert.Contains(line, output);
             }
 
-            var expectedOutputFile = 
Path.Combine(ExamplePaths.ExpectedOutputDir, example.Name)+ ".txt";
+            var expectedOutputFile = 
Path.Combine(ExamplePaths.ExpectedOutputDir, example.Name) + ".txt";
 
             Assert.IsTrue(File.Exists(expectedOutputFile), 
$"File.Exists({expectedOutputFile})");
 
@@ -94,13 +95,37 @@ namespace Apache.Ignite.Core.Tests.Examples
                 expectedOutputFile = expectedOutputFile2;
             }
 
-            var expectedLines = File.ReadAllLines(expectedOutputFile);
+            var expectedLines = File.ReadAllLines(expectedOutputFile)
+                .Where(l => !string.IsNullOrWhiteSpace(l))
+                .ToList();
 
-            foreach (var line in expectedLines)
+            if (example.UndefinedOutputOrder)
             {
-                if (!string.IsNullOrWhiteSpace(line))
+                var expLines = expectedLines.GroupBy(l => l)
+                    .Select(g => new {g.Key, Count = g.Count()})
+                    .ToList();
+
+                foreach (var line in expLines)
+                {
+                    var count = GetSubstringCount(output, 
GetExpectedLine(line.Key));
+
+                    Assert.AreEqual(line.Count, count, "Unexpected line 
occurence count: " + line.Key);
+                }
+            }
+            else
+            {
+                var lastIdx = 0;
+
+                foreach (var line in expectedLines)
                 {
-                    StringAssert.Contains(line, output);
+                    var idx = output.IndexOf(GetExpectedLine(line), lastIdx, 
StringComparison.Ordinal);
+
+                    if (idx < 0)
+                    {
+                        Assert.Fail("Expected line not found after index {0}: 
{1}", lastIdx, line);
+                    }
+
+                    lastIdx = idx;
                 }
             }
         }
@@ -109,5 +134,39 @@ namespace Apache.Ignite.Core.Tests.Examples
         /// Gets the example output.
         /// </summary>
         private string GetOutput() => Regex.Replace(_outSb.ToString(), 
@"idHash=(\d+)", "idHash=_");
+
+        /// <summary>
+        /// Gets substring count.
+        /// </summary>
+        private static int GetSubstringCount(string str, string substr)
+        {
+            int startIdx = 0;
+            int count = 0;
+
+            while (true)
+            {
+                var idx = str.IndexOf(substr, startIdx, 
StringComparison.Ordinal);
+
+                if (idx < startIdx)
+                {
+                    break;
+                }
+
+                startIdx = idx + substr.Length;
+                count++;
+            }
+
+            return count;
+        }
+
+        /// <summary>
+        /// Gets the expected line.
+        /// </summary>
+        private static string GetExpectedLine(string line)
+        {
+            return line.EndsWith("*")
+                ? line.Substring(0, line.Length - 1)
+                : line + "\n";
+        }
     }
 }
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/AtomicReference.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/AtomicReference.txt
index 044feb3..dbd222c 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/AtomicReference.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/AtomicReference.txt
@@ -1 +1 @@
->>> Current atomic reference value:
+>>> Current atomic reference value:*
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/ClientReconnect.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/ClientReconnect.txt
index bfe8e77..f710a91 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/ClientReconnect.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/ClientReconnect.txt
@@ -5,7 +5,7 @@
 >>> Put value with key: 1
 >>> Put value with key: 2
 >>> Put value with key: 3
-Ignite node stopped OK [name=serverNode, uptime=
+Ignite node stopped OK [name=serverNode, uptime=*
 >>> Server node stopped.
 >>> Put value with key: 4
 >>> Client disconnected from the cluster. Failed to put value with key: 4
@@ -16,3 +16,4 @@ Ignite node stopped OK [name=serverNode, uptime=
 >>> Put value with key: 7
 >>> Put value with key: 8
 >>> Put value with key: 9
+Ignite node stopped OK [name=serverNode, uptime=*
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/DataStreamer.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/DataStreamer.txt
index 435a20d..59c6029 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/DataStreamer.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/DataStreamer.txt
@@ -48,4 +48,4 @@ Loaded 460000 accounts.
 Loaded 470000 accounts.
 Loaded 480000 accounts.
 Loaded 490000 accounts.
->>> Loaded 500000 accounts in
+>>> Loaded 500000 accounts in *
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Lifecycle.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Lifecycle.txt
index a02929a..03ea472 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Lifecycle.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Lifecycle.txt
@@ -10,7 +10,7 @@
 
 >>> Ignite lifecycle event occurred: AfterNodeStop
 >>> Ignite name: lifecycle-example
-Ignite node stopped OK [name=lifecycle-example, uptime=
+Ignite node stopped OK [name=lifecycle-example, uptime=*
 
 >>> Started (should be false): False
 
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Linq.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Linq.txt
index 4f6ba3c..7319965 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Linq.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Linq.txt
@@ -3,7 +3,7 @@
 >>> Employees with zipcode 94109:
 >>>    Employee [name=James Wilson, salary=12500, address=Address [street=1096 
 >>> Eddy Street, San Francisco, CA, zip=94109], departments=[Human Resources, 
 >>> Customer Service]]
 >>>    Employee [name=Allison Mathis, salary=25300, address=Address 
 >>> [street=2702 Freedom Lane, San Francisco, CA, zip=94109], 
 >>> departments=[Development]]
->>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_cache_query_employee".EMPLOYEE as _T0 where (_T0.ZIP IS NOT DISTINCT 
FROM ?)
+>>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_linq_employee".EMPLOYEE as _T0 where (_T0.ZIP IS NOT DISTINCT FROM ?)
 
 >>> Employees with zipcode 94109 using compiled query:
 >>>    Employee [name=James Wilson, salary=12500, address=Address [street=1096 
 >>> Eddy Street, San Francisco, CA, zip=94109], departments=[Human Resources, 
 >>> Customer Service]]
@@ -13,13 +13,13 @@
 >>>     Employee [name=James Wilson, salary=12500, address=Address 
 >>> [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
 >>> departments=[Human Resources, Customer Service]]
 >>>     Employee [name=Daniel Adams, salary=11000, address=Address [street=184 
 >>> Fidler Drive, San Antonio, TX, zip=78130], departments=[Development, QA]]
 >>>     Employee [name=Cristian Moss, salary=12500, address=Address 
 >>> [street=667 Jerry Dove Drive, Florence, SC, zip=29501], 
 >>> departments=[Logistics]]
->>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_cache_query_employee_colocated".EMPLOYEE as _T0 , 
"dotnet_cache_query_organization".ORGANIZATION as _T1 where 
((_T0.ORGANIZATIONID IS NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT 
DISTINCT FROM ?))
+>>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_linq_employee_colocated".EMPLOYEE as _T0 , 
"dotnet_linq_organization".ORGANIZATION as _T1 where ((_T0.ORGANIZATIONID IS 
NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT DISTINCT FROM ?))
 
 >>> Employees working for Apache using distributed joins:
 >>>     Employee [name=James Wilson, salary=12500, address=Address 
 >>> [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
 >>> departments=[Human Resources, Customer Service]]
 >>>     Employee [name=Daniel Adams, salary=11000, address=Address [street=184 
 >>> Fidler Drive, San Antonio, TX, zip=78130], departments=[Development, QA]]
 >>>     Employee [name=Cristian Moss, salary=12500, address=Address 
 >>> [street=667 Jerry Dove Drive, Florence, SC, zip=29501], 
 >>> departments=[Logistics]]
->>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_cache_query_employee".EMPLOYEE as _T0 , 
"dotnet_cache_query_organization".ORGANIZATION as _T1 where 
((_T0.ORGANIZATIONID IS NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT 
DISTINCT FROM ?))
+>>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_linq_employee".EMPLOYEE as _T0 , 
"dotnet_linq_organization".ORGANIZATION as _T1 where ((_T0.ORGANIZATIONID IS 
NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT DISTINCT FROM ?))
 
 >>> Employee names and their salaries:
 >>>     [Name=James Wilson, salary=12500]
@@ -29,4 +29,4 @@
 >>>     [Name=Breana Robbin, salary=6500]
 >>>     [Name=Philip Horsley, salary=19800]
 >>>     [Name=Brian Peters, salary=10600]
->>> Generated SQL: select _T0.NAME, _T0.SALARY from 
"dotnet_cache_query_employee".EMPLOYEE as _T0
+>>> Generated SQL: select _T0.NAME, _T0.SALARY from 
"dotnet_linq_employee".EMPLOYEE as _T0
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/LinqThin.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/LinqThin.txt
index a4dc80d..b671263 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/LinqThin.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/LinqThin.txt
@@ -3,7 +3,7 @@
 >>> Employees with zipcode 94109:
 >>>    Employee [name=James Wilson, salary=12500, address=Address [street=1096 
 >>> Eddy Street, San Francisco, CA, zip=94109], departments=[Human Resources, 
 >>> Customer Service]]
 >>>    Employee [name=Allison Mathis, salary=25300, address=Address 
 >>> [street=2702 Freedom Lane, San Francisco, CA, zip=94109], 
 >>> departments=[Development]]
->>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_cache_query_employee".EMPLOYEE as _T0 where (_T0.ZIP IS NOT DISTINCT 
FROM ?)
+>>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_linq_employee".EMPLOYEE as _T0 where (_T0.ZIP IS NOT DISTINCT FROM ?)
 
 >>> Employees with zipcode 94109 using compiled query:
 >>>    Employee [name=James Wilson, salary=12500, address=Address [street=1096 
 >>> Eddy Street, San Francisco, CA, zip=94109], departments=[Human Resources, 
 >>> Customer Service]]
@@ -13,13 +13,13 @@
 >>>     Employee [name=Daniel Adams, salary=11000, address=Address [street=184 
 >>> Fidler Drive, San Antonio, TX, zip=78130], departments=[Development, QA]]
 >>>     Employee [name=James Wilson, salary=12500, address=Address 
 >>> [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
 >>> departments=[Human Resources, Customer Service]]
 >>>     Employee [name=Cristian Moss, salary=12500, address=Address 
 >>> [street=667 Jerry Dove Drive, Florence, SC, zip=29501], 
 >>> departments=[Logistics]]
->>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_cache_query_employee_colocated".EMPLOYEE as _T0 , 
"dotnet_cache_query_organization".ORGANIZATION as _T1 where 
((_T0.ORGANIZATIONID IS NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT 
DISTINCT FROM ?))
+>>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_linq_employee_colocated".EMPLOYEE as _T0 , 
"dotnet_linq_organization".ORGANIZATION as _T1 where ((_T0.ORGANIZATIONID IS 
NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT DISTINCT FROM ?))
 
 >>> Employees working for Apache using distributed joins:
 >>>     Employee [name=James Wilson, salary=12500, address=Address 
 >>> [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
 >>> departments=[Human Resources, Customer Service]]
 >>>     Employee [name=Daniel Adams, salary=11000, address=Address [street=184 
 >>> Fidler Drive, San Antonio, TX, zip=78130], departments=[Development, QA]]
 >>>     Employee [name=Cristian Moss, salary=12500, address=Address 
 >>> [street=667 Jerry Dove Drive, Florence, SC, zip=29501], 
 >>> departments=[Logistics]]
->>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_cache_query_employee".EMPLOYEE as _T0 , 
"dotnet_cache_query_organization".ORGANIZATION as _T1 where 
((_T0.ORGANIZATIONID IS NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT 
DISTINCT FROM ?))
+>>> Generated SQL: select _T0._KEY, _T0._VAL from 
"dotnet_linq_employee".EMPLOYEE as _T0 , 
"dotnet_linq_organization".ORGANIZATION as _T1 where ((_T0.ORGANIZATIONID IS 
NOT DISTINCT FROM _T1._KEY) and (_T1.NAME IS NOT DISTINCT FROM ?))
 
 >>> Employee names and their salaries:
 >>>     [Name=James Wilson, salary=12500]
@@ -29,4 +29,4 @@
 >>>     [Name=Breana Robbin, salary=6500]
 >>>     [Name=Philip Horsley, salary=19800]
 >>>     [Name=Brian Peters, salary=10600]
->>> Generated SQL: select _T0.NAME, _T0.SALARY from 
"dotnet_cache_query_employee".EMPLOYEE as _T0
+>>> Generated SQL: select _T0.NAME, _T0.SALARY from 
"dotnet_linq_employee".EMPLOYEE as _T0
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Messaging.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Messaging.txt
index 61efbaf..b8c2da5 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Messaging.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/Messaging.txt
@@ -6,23 +6,23 @@
 >>> Finished sending ordered messages.
 >>> Check output on all nodes for message printouts.
 >>> Waiting for messages acknowledgements from all remote nodes...
-Received unordered message [msg=6, fromNodeId=
-Received unordered message [msg=0, fromNodeId=
-Received unordered message [msg=5, fromNodeId=
-Received unordered message [msg=4, fromNodeId=
-Received unordered message [msg=7, fromNodeId=
-Received unordered message [msg=3, fromNodeId=
-Received unordered message [msg=2, fromNodeId=
-Received unordered message [msg=1, fromNodeId=
-Received unordered message [msg=9, fromNodeId=
-Received unordered message [msg=8, fromNodeId=
-Received ordered message [msg=0, fromNodeId=
-Received ordered message [msg=1, fromNodeId=
-Received ordered message [msg=2, fromNodeId=
-Received ordered message [msg=3, fromNodeId=
-Received ordered message [msg=4, fromNodeId=
-Received ordered message [msg=5, fromNodeId=
-Received ordered message [msg=6, fromNodeId=
-Received ordered message [msg=7, fromNodeId=
-Received ordered message [msg=8, fromNodeId=
-Received ordered message [msg=9, fromNodeId=
+Received unordered message [msg=6, fromNodeId=*
+Received unordered message [msg=0, fromNodeId=*
+Received unordered message [msg=5, fromNodeId=*
+Received unordered message [msg=4, fromNodeId=*
+Received unordered message [msg=7, fromNodeId=*
+Received unordered message [msg=3, fromNodeId=*
+Received unordered message [msg=2, fromNodeId=*
+Received unordered message [msg=1, fromNodeId=*
+Received unordered message [msg=9, fromNodeId=*
+Received unordered message [msg=8, fromNodeId=*
+Received ordered message [msg=0, fromNodeId=*
+Received ordered message [msg=1, fromNodeId=*
+Received ordered message [msg=2, fromNodeId=*
+Received ordered message [msg=3, fromNodeId=*
+Received ordered message [msg=4, fromNodeId=*
+Received ordered message [msg=5, fromNodeId=*
+Received ordered message [msg=6, fromNodeId=*
+Received ordered message [msg=7, fromNodeId=*
+Received ordered message [msg=8, fromNodeId=*
+Received ordered message [msg=9, fromNodeId=*
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransaction.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransaction.txt
index 07b70de..626bcbf 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransaction.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransaction.txt
@@ -2,6 +2,6 @@
 
 successfully incremented cached value.
 
-failed to increment cached value. Caught an expected optimistic exception: 
Failed to prepare transaction
+failed to increment cached value. Caught an expected optimistic exception: 
Failed to prepare transaction*
 
 >>> Resulting value in cache: 1
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransactionThin.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransactionThin.txt
index 07b70de..626bcbf 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransactionThin.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/OptimisticTransactionThin.txt
@@ -2,6 +2,6 @@
 
 successfully incremented cached value.
 
-failed to increment cached value. Caught an expected optimistic exception: 
Failed to prepare transaction
+failed to increment cached value. Caught an expected optimistic exception: 
Failed to prepare transaction*
 
 >>> Resulting value in cache: 1
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PeerAssemblyLoading.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PeerAssemblyLoading.txt
index b7fbacd..31d8216 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PeerAssemblyLoading.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PeerAssemblyLoading.txt
@@ -1,4 +1,4 @@
 >>> Peer loading example started.
 >>> Executing an action on all remote nodes...
-Hello from automatically deployed assembly! Version is 1.0.
+Hello from automatically deployed assembly! Version is 1.0.*
 >>> Action executed, check output on remote nodes.
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGet.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGet.txt
index 352fdf9..da5d9cd 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGet.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGet.txt
@@ -1,12 +1,12 @@
 >>> Cache put-get example started.
 
->>> Retrieved organization instance from cache: Organization [name=Microsoft, 
address=Address [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
type=Private, lastUpdated=
+>>> Retrieved organization instance from cache: Organization [name=Microsoft, 
address=Address [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
type=Private, lastUpdated=*
 
 >>> Retrieved organization name from binary object: Microsoft
 
 >>> Retrieved organization instances from cache:
->>>     Organization [name=Microsoft, address=Address [street=1096 Eddy 
Street, San Francisco, CA, zip=94109], type=Private, lastUpdated=
->>>     Organization [name=Red Cross, address=Address [street=184 Fidler 
Drive, San Antonio, TX, zip=78205], type=NonProfit, lastUpdated=
+>>>     Organization [name=Microsoft, address=Address [street=1096 Eddy 
Street, San Francisco, CA, zip=94109], type=Private, lastUpdated=*
+>>>     Organization [name=Red Cross, address=Address [street=184 Fidler 
Drive, San Antonio, TX, zip=78205], type=NonProfit, lastUpdated=*
 
 >>> Retrieved organization names from binary objects:
 >>>     Microsoft
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGetThin.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGetThin.txt
index 352fdf9..da5d9cd 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGetThin.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/PutGetThin.txt
@@ -1,12 +1,12 @@
 >>> Cache put-get example started.
 
->>> Retrieved organization instance from cache: Organization [name=Microsoft, 
address=Address [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
type=Private, lastUpdated=
+>>> Retrieved organization instance from cache: Organization [name=Microsoft, 
address=Address [street=1096 Eddy Street, San Francisco, CA, zip=94109], 
type=Private, lastUpdated=*
 
 >>> Retrieved organization name from binary object: Microsoft
 
 >>> Retrieved organization instances from cache:
->>>     Organization [name=Microsoft, address=Address [street=1096 Eddy 
Street, San Francisco, CA, zip=94109], type=Private, lastUpdated=
->>>     Organization [name=Red Cross, address=Address [street=184 Fidler 
Drive, San Antonio, TX, zip=78205], type=NonProfit, lastUpdated=
+>>>     Organization [name=Microsoft, address=Address [street=1096 Eddy 
Street, San Francisco, CA, zip=94109], type=Private, lastUpdated=*
+>>>     Organization [name=Red Cross, address=Address [street=184 Fidler 
Drive, San Antonio, TX, zip=78205], type=NonProfit, lastUpdated=*
 
 >>> Retrieved organization names from binary objects:
 >>>     Microsoft
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/SqlThin.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/SqlThin.txt
index 4d5656d..0edc941 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/SqlThin.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/SqlThin.txt
@@ -2,7 +2,6 @@
 
 >>> Employees with zipcode 94109 (SQL):
 >>>     [Name=James Wilson, salary=12500]
->>>     [Name=James Wilson, salary=12500]
 >>>     [Name=Allison Mathis, salary=25300]
 
 >>> Employees working for Apache:
@@ -12,6 +11,5 @@
 
 >>> Employees working for Apache (distributed joins enabled):
 >>>     James Wilson
->>>     James Wilson
 >>>     Daniel Adams
 >>>     Cristian Moss
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/TransactionDeadlockDetection.txt
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/TransactionDeadlockDetection.txt
index a69b756..beb2ad5 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/TransactionDeadlockDetection.txt
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExpectedOutput/TransactionDeadlockDetection.txt
@@ -1,6 +1,6 @@
 >>> Transaction deadlock detection example started.
 
->>> Transaction deadlock in thread
+>>> Transaction deadlock in thread *
 Deadlock detected:
 
 K1: TX1 holds lock, TX2 waits lock.
@@ -8,10 +8,10 @@ K2: TX2 holds lock, TX1 waits lock.
 
 Transactions:
 
-TX1 [txId=GridCacheVersion [topVer=
-TX2 [txId=GridCacheVersion [topVer=
+TX1 [txId=GridCacheVersion [topVer=*
+TX2 [txId=GridCacheVersion [topVer=*
 
 Keys:
 
-K1 [key=
-K2 [key=
+K1 [key=*
+K2 [key=*
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
index f6346a5..a7c5411 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.Impl.Binary
     using System;
     using System.Collections.Generic;
     using System.Diagnostics;
+    using System.Diagnostics.CodeAnalysis;
     using System.Linq;
     using System.Runtime.Serialization;
     using System.Threading;
@@ -565,6 +566,11 @@ namespace Apache.Ignite.Core.Impl.Binary
 
                 if (type != null)
                 {
+                    if (_typeToDesc.TryGetValue(type, out desc))
+                    {
+                        return desc;
+                    }
+
                     return AddUserType(type, typeId, GetTypeName(type), true, 
desc);
                 }
             }
@@ -665,12 +671,26 @@ namespace Apache.Ignite.Core.Impl.Binary
                 ThrowConflictingTypeError(type, desc0.Type, typeId);
             }
 
+            ValidateRegistration(type);
             _typeToDesc.Set(type, desc);
 
             return desc;
         }
 
         /// <summary>
+        /// Validates type registration.
+        /// </summary>
+        [ExcludeFromCodeCoverage]
+        private void ValidateRegistration(Type type)
+        {
+            BinaryFullTypeDescriptor desc;
+            if (_typeToDesc.TryGetValue(type, out desc) && !desc.UserType)
+            {
+                throw new BinaryObjectException("Invalid attempt to overwrite 
system type registration: " + type);
+            }
+        }
+
+        /// <summary>
         /// Throws the conflicting type error.
         /// </summary>
         private static void ThrowConflictingTypeError(object type1, object 
type2, int typeId)
@@ -805,6 +825,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             if (type != null)
             {
+                ValidateRegistration(type);
                 _typeToDesc.Set(type, descriptor);
             }
 
diff --git 
a/modules/platforms/dotnet/examples/Thick/Cache/QueryFullText/Program.cs 
b/modules/platforms/dotnet/examples/Thick/Cache/QueryFullText/Program.cs
index f18f47e..c721233 100644
--- a/modules/platforms/dotnet/examples/Thick/Cache/QueryFullText/Program.cs
+++ b/modules/platforms/dotnet/examples/Thick/Cache/QueryFullText/Program.cs
@@ -29,7 +29,7 @@ namespace Apache.Ignite.Examples.Thick.Cache.QueryFullText
     /// </summary>
     public static class Program
     {
-        private const string EmployeeCacheName = "dotnet_cache_query_employee";
+        private const string EmployeeCacheName = 
"dotnet_cache_query_full_text_employee";
 
         public static void Main()
         {
diff --git a/modules/platforms/dotnet/examples/Thick/Cache/QueryScan/Program.cs 
b/modules/platforms/dotnet/examples/Thick/Cache/QueryScan/Program.cs
index 357c02f..21d036d 100644
--- a/modules/platforms/dotnet/examples/Thick/Cache/QueryScan/Program.cs
+++ b/modules/platforms/dotnet/examples/Thick/Cache/QueryScan/Program.cs
@@ -30,7 +30,7 @@ namespace Apache.Ignite.Examples.Thick.Cache.QueryScan
     /// </summary>
     public static class Program
     {
-        private const string EmployeeCacheName = "dotnet_cache_query_employee";
+        private const string EmployeeCacheName = 
"dotnet_cache_query_scan_employee";
 
         public static void Main()
         {
diff --git a/modules/platforms/dotnet/examples/Thick/Cache/Store/Program.cs 
b/modules/platforms/dotnet/examples/Thick/Cache/Store/Program.cs
index e59ee35..5a69b74 100644
--- a/modules/platforms/dotnet/examples/Thick/Cache/Store/Program.cs
+++ b/modules/platforms/dotnet/examples/Thick/Cache/Store/Program.cs
@@ -78,7 +78,7 @@ namespace Apache.Ignite.Examples.Thick.Cache.Store
                     ));
 
                 Console.WriteLine();
-                Console.WriteLine(">>> Put entry to cache. ");
+                Console.WriteLine(">>> Put entry to cache.");
                 Console.WriteLine(">>> Current cache size: " + 
cache.GetSize());
 
                 // Clear values again.
diff --git 
a/modules/platforms/dotnet/examples/Thick/Cache/Transaction/Program.cs 
b/modules/platforms/dotnet/examples/Thick/Cache/Transaction/Program.cs
index 1bad509..8de3ac5 100644
--- a/modules/platforms/dotnet/examples/Thick/Cache/Transaction/Program.cs
+++ b/modules/platforms/dotnet/examples/Thick/Cache/Transaction/Program.cs
@@ -103,7 +103,7 @@ namespace Apache.Ignite.Examples.Thick.Cache.Transaction
             Console.WriteLine(">>> Transfer finished.");
 
             Console.WriteLine();
-            Console.WriteLine(">>> Accounts after transfer: ");
+            Console.WriteLine(">>> Accounts after transfer:");
             Console.WriteLine(">>>     " + cache.Get(1));
             Console.WriteLine(">>>     " + cache.Get(2));
             Console.WriteLine();
@@ -122,7 +122,7 @@ namespace Apache.Ignite.Examples.Thick.Cache.Transaction
             cache.Put(2, new Account(2, 200));
 
             Console.WriteLine();
-            Console.WriteLine(">>> Accounts before transfer: ");
+            Console.WriteLine(">>> Accounts before transfer:");
             Console.WriteLine(">>>     " + cache.Get(1));
             Console.WriteLine(">>>     " + cache.Get(2));
             Console.WriteLine();
diff --git a/modules/platforms/dotnet/examples/Thick/Sql/Linq/Program.cs 
b/modules/platforms/dotnet/examples/Thick/Sql/Linq/Program.cs
index b97cb65..4afc010 100644
--- a/modules/platforms/dotnet/examples/Thick/Sql/Linq/Program.cs
+++ b/modules/platforms/dotnet/examples/Thick/Sql/Linq/Program.cs
@@ -33,11 +33,11 @@ namespace Apache.Ignite.Examples.Thick.Sql.Linq
     /// </summary>
     public static class Program
     {
-        private const string OrganizationCacheName = 
"dotnet_cache_query_organization";
+        private const string OrganizationCacheName = 
"dotnet_linq_organization";
 
-        private const string EmployeeCacheName = "dotnet_cache_query_employee";
+        private const string EmployeeCacheName = "dotnet_linq_employee";
 
-        private const string EmployeeCacheNameColocated = 
"dotnet_cache_query_employee_colocated";
+        private const string EmployeeCacheNameColocated = 
"dotnet_linq_employee_colocated";
 
         public static void Main()
         {
diff --git 
a/modules/platforms/dotnet/examples/Thin/Cache/QueryScanThin/Program.cs 
b/modules/platforms/dotnet/examples/Thin/Cache/QueryScanThin/Program.cs
index e7087d7..4670516 100644
--- a/modules/platforms/dotnet/examples/Thin/Cache/QueryScanThin/Program.cs
+++ b/modules/platforms/dotnet/examples/Thin/Cache/QueryScanThin/Program.cs
@@ -36,7 +36,7 @@ namespace Apache.Ignite.Examples.Thin.Cache.QueryScanThin
     /// </summary>
     public static class Program
     {
-        private const string EmployeeCacheName = "dotnet_cache_query_employee";
+        private const string EmployeeCacheName = 
"dotnet_cache_query_scan_employee";
 
         public static void Main()
         {
diff --git 
a/modules/platforms/dotnet/examples/Thin/Cache/TransactionThin/Program.cs 
b/modules/platforms/dotnet/examples/Thin/Cache/TransactionThin/Program.cs
index 073e0e4..681fb03 100644
--- a/modules/platforms/dotnet/examples/Thin/Cache/TransactionThin/Program.cs
+++ b/modules/platforms/dotnet/examples/Thin/Cache/TransactionThin/Program.cs
@@ -109,7 +109,7 @@ namespace Apache.Ignite.Examples.Thin.Cache.TransactionThin
             Console.WriteLine(">>> Transfer finished.");
 
             Console.WriteLine();
-            Console.WriteLine(">>> Accounts after transfer: ");
+            Console.WriteLine(">>> Accounts after transfer:");
             Console.WriteLine(">>>     " + cache.Get(1));
             Console.WriteLine(">>>     " + cache.Get(2));
             Console.WriteLine();
@@ -128,7 +128,7 @@ namespace Apache.Ignite.Examples.Thin.Cache.TransactionThin
             cache.Put(2, new Account(2, 200));
 
             Console.WriteLine();
-            Console.WriteLine(">>> Accounts before transfer: ");
+            Console.WriteLine(">>> Accounts before transfer:");
             Console.WriteLine(">>>     " + cache.Get(1));
             Console.WriteLine(">>>     " + cache.Get(2));
             Console.WriteLine();
diff --git a/modules/platforms/dotnet/examples/Thin/Sql/LinqThin/Program.cs 
b/modules/platforms/dotnet/examples/Thin/Sql/LinqThin/Program.cs
index db2e270..119b809 100644
--- a/modules/platforms/dotnet/examples/Thin/Sql/LinqThin/Program.cs
+++ b/modules/platforms/dotnet/examples/Thin/Sql/LinqThin/Program.cs
@@ -39,11 +39,11 @@ namespace Apache.Ignite.Examples.Thin.Sql.LinqThin
     /// </summary>
     public static class Program
     {
-        private const string OrganizationCacheName = 
"dotnet_cache_query_organization";
+        private const string OrganizationCacheName = 
"dotnet_linq_organization";
 
-        private const string EmployeeCacheName = "dotnet_cache_query_employee";
+        private const string EmployeeCacheName = "dotnet_linq_employee";
 
-        private const string EmployeeCacheNameColocated = 
"dotnet_cache_query_employee_colocated";
+        private const string EmployeeCacheNameColocated = 
"dotnet_linq_employee_colocated";
 
         public static void Main()
         {

Reply via email to