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/12/19 11:34:34 UTC

[1/7] ignite git commit: GridNioServer: ses can be null on close if async connect failed

Repository: ignite
Updated Branches:
  refs/heads/ignite-zk-ce 9e4f2c20c -> 4525b9218


GridNioServer: ses can be null on close if async connect failed


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

Branch: refs/heads/ignite-zk-ce
Commit: edc66af8221508e8d892bd9bd1e550ada9ac4a47
Parents: 91be7af
Author: sboikov <sb...@gridgain.com>
Authored: Mon Dec 18 14:41:46 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Mon Dec 18 14:41:46 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/util/nio/GridNioServer.java | 59 +++++++++++---------
 1 file changed, 34 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/edc66af8/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
index 1d595d2..97f6020 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
@@ -2293,7 +2293,11 @@ public class GridNioServer<T> {
                     else if (log.isDebugEnabled())
                         log.debug("Failed to process selector key [ses=" + ses + ", err=" + e + ']');
 
-                    close(ses, new GridNioException(e));
+                    // Can be null if async connect failed.
+                    if (ses != null)
+                        close(ses, new GridNioException(e));
+                    else
+                        closeKey(key);
                 }
             }
         }
@@ -2517,6 +2521,34 @@ public class GridNioServer<T> {
         }
 
         /**
+         * @param key Key.
+         */
+        private void closeKey(SelectionKey key) {
+            // Shutdown input and output so that remote client will see correct socket close.
+            Socket sock = ((SocketChannel)key.channel()).socket();
+
+            try {
+                try {
+                    sock.shutdownInput();
+                }
+                catch (IOException ignored) {
+                    // No-op.
+                }
+
+                try {
+                    sock.shutdownOutput();
+                }
+                catch (IOException ignored) {
+                    // No-op.
+                }
+            }
+            finally {
+                U.close(key, log);
+                U.close(sock, log);
+            }
+        }
+
+        /**
          * Closes the session and all associated resources, then notifies the listener.
          *
          * @param ses Session to be closed.
@@ -2536,8 +2568,6 @@ public class GridNioServer<T> {
             sessions.remove(ses);
             workerSessions.remove(ses);
 
-            SelectionKey key = ses.key();
-
             if (ses.setClosed()) {
                 ses.onClosed();
 
@@ -2549,28 +2579,7 @@ public class GridNioServer<T> {
                         ((DirectBuffer)ses.readBuffer()).cleaner().clean();
                 }
 
-                // Shutdown input and output so that remote client will see correct socket close.
-                Socket sock = ((SocketChannel)key.channel()).socket();
-
-                try {
-                    try {
-                        sock.shutdownInput();
-                    }
-                    catch (IOException ignored) {
-                        // No-op.
-                    }
-
-                    try {
-                        sock.shutdownOutput();
-                    }
-                    catch (IOException ignored) {
-                        // No-op.
-                    }
-                }
-                finally {
-                    U.close(key, log);
-                    U.close(sock, log);
-                }
+                closeKey(ses.key());
 
                 if (e != null)
                     filterChain.onExceptionCaught(ses, e);


[3/7] ignite git commit: zk

Posted by sb...@apache.org.
zk


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

Branch: refs/heads/ignite-zk-ce
Commit: 1fb53f38d4ca5fbd42f9e036be2ddeecc4b38db6
Parents: 9e4f2c20c
Author: sboikov <sb...@gridgain.com>
Authored: Mon Dec 18 18:15:12 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Mon Dec 18 18:15:12 2017 +0300

----------------------------------------------------------------------
 .../ZookeeperDiscoverySpiBasicTest.java         | 58 ++++++++++----------
 1 file changed, 30 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1fb53f38/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
index a29f478..58098b9 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
@@ -1924,14 +1924,14 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     public void testCommunicationErrorResolve_KillNode_1() throws Exception {
-        communicationErrorResolve_KillNodes(2, Collections.singletonList(2L));
+        communicationErrorResolve_KillNodes(2, Collections.singleton(2L));
     }
 
     /**
      * @throws Exception If failed.
      */
     public void testCommunicationErrorResolve_KillNode_2() throws Exception {
-        communicationErrorResolve_KillNodes(3, Collections.singletonList(2L));
+        communicationErrorResolve_KillNodes(3, Collections.singleton(2L));
     }
 
     /**
@@ -1942,6 +1942,34 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testCommunicationErrorResolve_KillCoordinator_1() throws Exception {
+        communicationErrorResolve_KillNodes(2, Collections.singleton(1L));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCommunicationErrorResolve_KillCoordinator_2() throws Exception {
+        communicationErrorResolve_KillNodes(3, Collections.singleton(1L));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCommunicationErrorResolve_KillCoordinator_3() throws Exception {
+        communicationErrorResolve_KillNodes(10, Arrays.asList(1L, 4L, 6L));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCommunicationErrorResolve_KillCoordinator_4() throws Exception {
+        communicationErrorResolve_KillNodes(10, Arrays.asList(1L, 2L, 3L));
+    }
+
+    /**
      * @param startNodes Number of nodes to start.
      * @param killNodes Nodes to kill by resolve process.
      * @throws Exception If failed.
@@ -1988,32 +2016,6 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
-    public void testCommunicationErrorResolve_KillCoordinator() throws Exception {
-        // Kill coordinator.
-        testCommSpi = true;
-
-        commProblemRslvr = new TestNodeKillCommunicationProblemResolver(Collections.singleton(1L));
-
-        startGrids(3);
-
-        ZkTestCommunicationSpi commSpi = ZkTestCommunicationSpi.forNode(ignite(2));
-
-        commSpi.checkRes = new BitSet(3);
-
-        ZookeeperDiscoverySpi spi = spi(ignite(1));
-
-        spi.onCommunicationConnectionError(ignite(0).cluster().localNode(), new Exception("test"));
-
-        waitForTopology(2);
-
-        startGrid(10);
-
-        waitForTopology(3);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
     public void testConnectionCheck() throws Exception {
        final int NODES = 5;
 


[5/7] ignite git commit: IGNITE-7229 .NET: Rename ICache.QueryFields to Query, add FieldNames

Posted by sb...@apache.org.
IGNITE-7229 .NET: Rename ICache.QueryFields to Query, add FieldNames

This closes #3247


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

Branch: refs/heads/ignite-zk-ce
Commit: 8f327a18bea8cd4efda0d9ffea1acf7a11d56f90
Parents: a2b195c
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Tue Dec 19 10:20:08 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Tue Dec 19 10:20:08 2017 +0300

----------------------------------------------------------------------
 .../query/PlatformAbstractQueryCursor.java      |  9 +++
 .../cache/query/PlatformFieldsQueryCursor.java  | 24 ++++++-
 .../ExpiryCacheHolderTest.cs                    |  5 ++
 .../Binary/BinaryFooterTest.cs                  |  2 +-
 .../Binary/Serializable/SqlDmlTest.cs           |  6 +-
 .../Cache/CacheTestAsyncWrapper.cs              |  7 ++
 .../Cache/Query/CacheDmlQueriesTest.cs          | 18 ++---
 .../Query/CacheQueriesCodeConfigurationTest.cs  |  2 +-
 .../Cache/Query/CacheQueriesTest.cs             | 69 +++++++++++++++-----
 .../Query/Linq/CacheLinqTest.Introspection.cs   |  2 +-
 .../Client/Cache/SqlQueryTest.cs                |  4 +-
 .../dotnet/Apache.Ignite.Core/Cache/ICache.cs   |  8 +++
 .../Impl/Binary/BinaryReaderExtensions.cs       |  2 +-
 .../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs  | 29 +++++---
 .../Impl/Cache/ICacheInternal.cs                |  2 +-
 .../Impl/Cache/Query/FieldsQueryCursor.cs       | 39 +++++++++++
 .../Impl/Cache/Query/PlatformQueryQursorBase.cs |  8 +++
 .../Impl/Client/Cache/CacheClient.cs            |  2 +-
 .../Cache/Query/ClientFieldsQueryCursor.cs      | 12 +---
 .../NuGet/LINQPad/BinaryModeExample.linq        |  2 +-
 .../NuGet/LINQPad/QueryExample.linq             |  2 +-
 .../Apache.Ignite.Linq/CacheLinqExtensions.cs   | 10 +--
 .../Impl/CacheFieldsQueryExecutor.cs            | 10 +--
 modules/platforms/dotnet/Apache.Ignite.ndproj   |  2 +-
 .../Datagrid/BinaryModeExample.cs               |  5 +-
 .../Datagrid/QueryDmlExample.cs                 | 18 ++---
 .../Datagrid/QueryExample.cs                    |  5 +-
 .../dotnet/examples/dotnetcore/SqlExample.cs    |  2 +-
 28 files changed, 224 insertions(+), 82 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
index 20e98fc..aef8e59 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
@@ -176,6 +176,15 @@ public abstract class PlatformAbstractQueryCursor<T> extends PlatformAbstractTar
     protected abstract void write(BinaryRawWriterEx writer, T val);
 
     /**
+     * Gets the cursor.
+     *
+     * @return Cursor.
+     */
+    public QueryCursorEx<T> cursor() {
+        return cursor;
+    }
+
+    /**
      * Query cursor consumer.
      */
     private static class Consumer<T> implements QueryCursorEx.Consumer<T> {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
index 25f86f2..15561b0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
@@ -17,15 +17,21 @@
 
 package org.apache.ignite.internal.processors.platform.cache.query;
 
-import java.util.List;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
 import org.apache.ignite.internal.binary.BinaryRawWriterEx;
 import org.apache.ignite.internal.processors.cache.query.QueryCursorEx;
 import org.apache.ignite.internal.processors.platform.PlatformContext;
 
+import java.util.List;
+
 /**
  * Interop cursor for fields query.
  */
 public class PlatformFieldsQueryCursor extends PlatformAbstractQueryCursor<List<?>> {
+    /** Gets field names. */
+    private static final int OP_GET_FIELD_NAMES = 7;
+
     /**
      * Constructor.
      *
@@ -52,4 +58,20 @@ public class PlatformFieldsQueryCursor extends PlatformAbstractQueryCursor<List<
         
         writer.writeInt(rowSizePos, rowEndPos - rowSizePos);
     }
+
+    /** {@inheritDoc} */
+    @Override public void processOutStream(int type, final BinaryRawWriterEx writer) throws IgniteCheckedException {
+        if (type == OP_GET_FIELD_NAMES) {
+            FieldsQueryCursor fq = (FieldsQueryCursor) cursor();
+
+            int cnt = fq.getColumnsCount();
+            writer.writeInt(cnt);
+
+            for (int i = 0; i < cnt; i++) {
+                writer.writeString(fq.getFieldName(i));
+            }
+        } else {
+            super.processOutStream(type, writer);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs
index 2fe3309..93e3a53 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs
@@ -419,6 +419,11 @@ namespace Apache.Ignite.AspNet.Tests
                 throw new NotImplementedException();
             }
 
+            public IFieldsQueryCursor Query(SqlFieldsQuery qry)
+            {
+                throw new NotImplementedException();
+            }
+
             public IQueryCursor<IList> QueryFields(SqlFieldsQuery qry)
             {
                 throw new NotImplementedException();

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryFooterTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryFooterTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryFooterTest.cs
index 9fa4538..34df6d7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryFooterTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryFooterTest.cs
@@ -146,7 +146,7 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(dt.Arr, cache[1].Arr);
 
             // SQL: read field on Java side to ensure correct offset handling.
-            var res = cache.QueryFields(new SqlFieldsQuery("select int from OffsetTest")).GetAll()[0][0];
+            var res = cache.Query(new SqlFieldsQuery("select int from OffsetTest")).GetAll()[0][0];
             Assert.AreEqual(dt.Int, (int) res);
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
index 4b77dbe..0ffd068 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
@@ -107,7 +107,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
 
             // Test DML.
             var guid = Guid.NewGuid();
-            var insertRes = cache.QueryFields(new SqlFieldsQuery(
+            var insertRes = cache.Query(new SqlFieldsQuery(
                 "insert into SimpleSerializable(_key, Byte, Bool, Short, Int, Long, Float, Double, " +
                 "Decimal, Guid, String) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", 
                 3, 45, true, 43, 33, 99, 4.5f, 6.7, 9.04m, guid, "bar33")).GetAll();
@@ -141,7 +141,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
             Assert.AreEqual(uint.MaxValue, cache[1].Uint);
 
             // Test SQL.
-            var sqlRes = cache.QueryFields(new SqlFieldsQuery(
+            var sqlRes = cache.Query(new SqlFieldsQuery(
                 "select uint from DotNetSpecificSerializable where uint <> 0")).GetAll();
 
             Assert.AreEqual(1, sqlRes.Count);
@@ -152,7 +152,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
             Assert.AreEqual(uint.MaxValue, linqRes);
 
             // Test DML.
-            var dmlRes = cache.QueryFields(new SqlFieldsQuery(
+            var dmlRes = cache.Query(new SqlFieldsQuery(
                 "insert into DotNetSpecificSerializable(_key, uint) values (?, ?), (?, ?)",
                 2, uint.MaxValue, 3, 88)).GetAll();
             Assert.AreEqual(1, dmlRes.Count);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs
index 5ba2fc9..0b1af41 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs
@@ -445,6 +445,13 @@ namespace Apache.Ignite.Core.Tests.Cache
         }
 
         /** <inheritDoc /> */
+        public IFieldsQueryCursor Query(SqlFieldsQuery qry)
+        {
+            return _cache.Query(qry);
+        }
+
+        /** <inheritDoc /> */
+        [Obsolete]
         public IQueryCursor<IList> QueryFields(SqlFieldsQuery qry)
         {
             return _cache.QueryFields(qry);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
index 741dff0..f289e56 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
@@ -76,7 +76,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);
 
             // Test insert.
-            var res = cache.QueryFields(new SqlFieldsQuery("insert into foo(_key, id, name) " +
+            var res = cache.Query(new SqlFieldsQuery("insert into foo(_key, id, name) " +
                                                            "values (?, ?, ?), (?, ?, ?)",
                 1, 2, "John", 3, 4, "Mary")).GetAll();
 
@@ -118,7 +118,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
 
             var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);
 
-            var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery(
+            var ex = Assert.Throws<IgniteException>(() => cache.Query(new SqlFieldsQuery(
                 "insert into foo(_key, name) values (?, ?)", 1, "bar")).GetAll());
 
             Assert.AreEqual("Null value is not allowed for column 'ID'", ex.Message);
@@ -133,7 +133,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var cfg = new CacheConfiguration("not_null_attr", new QueryEntity(typeof(int), typeof(Foo)));
             var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);
 
-            var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery(
+            var ex = Assert.Throws<IgniteException>(() => cache.Query(new SqlFieldsQuery(
                 "insert into foo(_key, id) values (?, ?)", 1, 2)).GetAll());
 
             Assert.AreEqual("Null value is not allowed for column 'NAME'", ex.Message);
@@ -169,7 +169,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
 
             foreach (var val in vals)
             {
-                var res = cache.QueryFields(new SqlFieldsQuery(
+                var res = cache.Query(new SqlFieldsQuery(
                     "insert into string(_key, _val) values (?, ?)", val, val.ToString())).GetAll();
 
                 Assert.AreEqual(1, res.Count);
@@ -190,7 +190,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var cache = Ignition.GetIgnite().CreateCache<Key, Foo>(cfg);
 
             // Test insert.
-            var res = cache.QueryFields(new SqlFieldsQuery("insert into foo(hi, lo, id, name) " +
+            var res = cache.Query(new SqlFieldsQuery("insert into foo(hi, lo, id, name) " +
                                                "values (-1, 65500, 3, 'John'), (255, 128, 6, 'Mary')")).GetAll();
 
             Assert.AreEqual(1, res.Count);
@@ -240,7 +240,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var cache = Ignition.GetIgnite().CreateCache<Key2, Foo>(cfg);
 
             // Test insert.
-            var res = cache.QueryFields(new SqlFieldsQuery("insert into foo(hi, lo, str, id, name) " +
+            var res = cache.Query(new SqlFieldsQuery("insert into foo(hi, lo, str, id, name) " +
                                                "values (1, 2, 'Фу', 3, 'John'), (4, 5, 'Бар', 6, 'Mary')")).GetAll();
 
             Assert.AreEqual(1, res.Count);
@@ -293,7 +293,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var cache = Ignition.GetIgnite().CreateCache<Key, Foo>(cfg);
 
             var ex = Assert.Throws<IgniteException>(
-                () => cache.QueryFields(new SqlFieldsQuery("insert into foo(lo, hi, id, name) " +
+                () => cache.Query(new SqlFieldsQuery("insert into foo(lo, hi, id, name) " +
                                                            "values (1, 2, 3, 'John'), (4, 5, 6, 'Mary')")));
 
             Assert.AreEqual("Ownership flag not set for binary property. Have you set 'keyFields' " +
@@ -322,7 +322,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var cache = Ignition.GetIgnite().CreateCache<object, object>(cfg)
                 .WithKeepBinary<IBinaryObject, IBinaryObject>();
 
-            var res = cache.QueryFields(new SqlFieldsQuery("insert into car(VIN, Id, Make, Year) " +
+            var res = cache.Query(new SqlFieldsQuery("insert into car(VIN, Id, Make, Year) " +
                                                            "values ('DLRDMC', 88, 'DeLorean', 1982)")).GetAll();
 
             Assert.AreEqual(1, res.Count);
@@ -362,7 +362,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             };
 
             // Test insert.
-            var res = cache.QueryFields(new SqlFieldsQuery(
+            var res = cache.Query(new SqlFieldsQuery(
                     "insert into string(byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal, " +
                     "guid, string, key, _val) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
                     key.Byte, key.SByte, key.Short, key.UShort, key.Int, key.UInt, key.Long, key.ULong, key.Float,

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs
index 2e24ff6..9768fca 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs
@@ -91,7 +91,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
                     Assert.AreEqual(2, cursor.GetAll().Single().Key);
                 }
 
-                using (var cursor = cache.QueryFields(new SqlFieldsQuery(
+                using (var cursor = cache.Query(new SqlFieldsQuery(
                     "select _key from CustomTableName where age > ? and birthday < ?", 10, DateTime.UtcNow)))
                 {
                     Assert.AreEqual(2, cursor.GetAll().Single()[0]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
index 8134b3d..278d1fd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
@@ -20,7 +20,6 @@
 namespace Apache.Ignite.Core.Tests.Cache.Query
 {
     using System;
-    using System.Collections;
     using System.Collections.Generic;
     using System.Diagnostics.CodeAnalysis;
     using System.Linq;
@@ -156,7 +155,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         public void TestValidationSqlFields()
         {
             // 1. No sql.
-            Assert.Throws<ArgumentException>(() => { Cache().QueryFields(new SqlFieldsQuery(null)); });
+            Assert.Throws<ArgumentException>(() => { Cache().Query(new SqlFieldsQuery(null)); });
         }
 
         /// <summary>
@@ -285,11 +284,9 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             Cache().Put(3, new QueryPerson("Sidorov", 50));
 
             // 1. Empty result set.
-            using (
-                IQueryCursor<IList> cursor = Cache().QueryFields(
-                    new SqlFieldsQuery("SELECT age FROM QueryPerson WHERE age < ?", 50)))
+            using (var cursor = Cache().Query(new SqlFieldsQuery("SELECT age FROM QueryPerson WHERE age < ?", 50)))
             {
-                foreach (IList entry in cursor.GetAll())
+                foreach (var entry in cursor.GetAll())
                     Assert.IsTrue((int) entry[0] < 50);
             }
         }
@@ -390,7 +387,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
                 Lazy = lazy
             };
 
-            using (IQueryCursor<IList> cursor = cache.QueryFields(qry))
+            using (var cursor = cache.Query(qry))
             {
                 HashSet<int> exp0 = new HashSet<int>(exp);
 
@@ -403,9 +400,12 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
                 }
 
                 Assert.AreEqual(0, exp0.Count);
+                Assert.AreEqual(new[] {"NAME", "AGE"}, cursor.FieldNames);
             }
 
-            using (IQueryCursor<IList> cursor = cache.QueryFields(qry))
+            // Test old API as well.
+#pragma warning disable 618
+            using (var cursor = cache.QueryFields(qry))
             {
                 HashSet<int> exp0 = new HashSet<int>(exp);
 
@@ -418,6 +418,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
 
                 Assert.AreEqual(0, exp0.Count);
             }
+#pragma warning restore 618
         }
 
         /// <summary>
@@ -622,7 +623,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             strings[1] = "foo";
 
             // Default schema.
-            var res = doubles.QueryFields(new SqlFieldsQuery(
+            var res = doubles.Query(new SqlFieldsQuery(
                     "select S._val from double as D join \"strings\".string as S on S._key = D._key"))
                 .Select(x => (string) x[0])
                 .Single();
@@ -630,7 +631,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             Assert.AreEqual("foo", res);
 
             // Custom schema.
-            res = doubles.QueryFields(new SqlFieldsQuery(
+            res = doubles.Query(new SqlFieldsQuery(
                     "select S._val from \"doubles\".double as D join string as S on S._key = D._key")
                 {
                     Schema = strings.Name
@@ -667,13 +668,13 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var sql = "select T0.Age from QueryPerson as T0 " +
                       "inner join QueryPerson as T1 on ((? - T1.Age - 1) = T0._key)";
 
-            var res = cache.QueryFields(new SqlFieldsQuery(sql, count)).GetAll().Distinct().Count();
+            var res = cache.Query(new SqlFieldsQuery(sql, count)).GetAll().Distinct().Count();
 
             Assert.Greater(res, 0);
             Assert.Less(res, count);
 
             // Test distributed join: returns complete results
-            res = cache.QueryFields(new SqlFieldsQuery(sql, count) {EnableDistributedJoins = true})
+            res = cache.Query(new SqlFieldsQuery(sql, count) {EnableDistributedJoins = true})
                 .GetAll().Distinct().Count();
 
             Assert.AreEqual(count, res);
@@ -709,7 +710,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
 
             cache[1] = new QueryPerson("Joe", 48);
 
-            var row = cache.QueryFields(new SqlFieldsQuery("select * from QueryPerson")).GetAll()[0];
+            var row = cache.Query(new SqlFieldsQuery("select * from QueryPerson")).GetAll()[0];
             Assert.AreEqual(2, row.Count);
             Assert.AreEqual(48, row[0]);
             Assert.AreEqual("Joe", row[1]);
@@ -736,7 +737,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
 
             cache[1] = new QueryPerson("John", 33);
 
-            row = cache.QueryFields(new SqlFieldsQuery("select * from QueryPerson")).GetAll()[0];
+            row = cache.Query(new SqlFieldsQuery("select * from QueryPerson")).GetAll()[0];
             
             Assert.AreEqual(3, row.Count);
             Assert.AreEqual(33, row[0]);
@@ -746,7 +747,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             Assert.AreEqual("John", person.Name);
 
             // Check explicit select.
-            row = cache.QueryFields(new SqlFieldsQuery("select FullKey from QueryPerson")).GetAll()[0];
+            row = cache.Query(new SqlFieldsQuery("select FullKey from QueryPerson")).GetAll()[0];
             Assert.AreEqual(1, row[0]);
         }
 
@@ -786,11 +787,47 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             };
 
             // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
-            var ex = Assert.Throws<CacheException>(() => cache.QueryFields(fieldsQry).ToArray());
+            var ex = Assert.Throws<CacheException>(() => cache.Query(fieldsQry).ToArray());
             Assert.IsTrue(ex.ToString().Contains("QueryCancelledException: The query was cancelled while executing."));
         }
 
         /// <summary>
+        /// Tests the FieldNames property.
+        /// </summary>
+        [Test]
+        public void TestFieldNames()
+        {
+            var cache = Cache();
+            PopulateCache(cache, false, 5, x => true);
+
+            // Get before iteration.
+            var qry = new SqlFieldsQuery("SELECT * FROM QueryPerson");
+            var cur = cache.Query(qry);
+            var names = cur.FieldNames;
+
+            Assert.AreEqual(new[] {"AGE", "NAME" }, names);
+            
+            cur.Dispose();
+            Assert.AreSame(names, cur.FieldNames);
+
+            Assert.Throws<NotSupportedException>(() => cur.FieldNames.Add("x"));
+
+            // Custom order, key-val, get after iteration.
+            qry.Sql = "SELECT NAME, _key, AGE, _val FROM QueryPerson";
+            cur = cache.Query(qry);
+            cur.GetAll();
+
+            Assert.AreEqual(new[] { "NAME", "_KEY", "AGE", "_VAL" }, cur.FieldNames);
+
+            // Get after disposal.
+            qry.Sql = "SELECT 1, AGE FROM QueryPerson";
+            cur = cache.Query(qry);
+            cur.Dispose();
+            
+            Assert.AreEqual(new[] { "1", "AGE" }, cur.FieldNames);
+        }
+
+        /// <summary>
         /// Validates the query results.
         /// </summary>
         /// <param name="cache">Cache.</param>

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Introspection.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Introspection.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Introspection.cs
index 6e7483e..aa26548 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Introspection.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Introspection.cs
@@ -72,7 +72,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
 
             Assert.AreEqual(new[] { 10 }, fq.Arguments);
             Assert.IsTrue(fq.Local);
-            Assert.AreEqual(PersonCount - 11, cache.QueryFields(fq).GetAll().Count);
+            Assert.AreEqual(PersonCount - 11, cache.Query(fq).GetAll().Count);
             Assert.AreEqual(999, fq.PageSize);
             Assert.IsFalse(fq.EnableDistributedJoins);
             Assert.IsTrue(fq.EnforceJoinOrder);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs
index 6f6df11..b9de090 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs
@@ -114,7 +114,9 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
 
             // DateTime.
             qry = new SqlFieldsQuery("select Id, DateTime from Person where DateTime > ?", DateTime.UtcNow.AddDays(9));
-            Assert.AreEqual(cache[Count].DateTime, cache.Query(qry).Single().Last());
+            cursor = cache.Query(qry);
+            Assert.AreEqual(new[] {"ID", "DATETIME" }, cursor.FieldNames);
+            Assert.AreEqual(cache[Count].DateTime, cursor.Single().Last());
 
             // Invalid args.
             qry.Sql = null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs
index f83f279..8a9fe59 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs
@@ -705,6 +705,14 @@ namespace Apache.Ignite.Core.Cache
         /// </summary>
         /// <param name="qry">SQL fields query.</param>
         /// <returns>Cursor.</returns>
+        IFieldsQueryCursor Query(SqlFieldsQuery qry);
+
+        /// <summary>
+        /// Queries separate entry fields.
+        /// </summary>
+        /// <param name="qry">SQL fields query.</param>
+        /// <returns>Cursor.</returns>
+        [Obsolete("Use Query(SqlFieldsQuery qry) instead.")]
         IQueryCursor<IList> QueryFields(SqlFieldsQuery qry);
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
index db2f84f..b13318c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
@@ -130,7 +130,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Reads the string collection.
         /// </summary>
-        public static ICollection<string> ReadStringCollection(this IBinaryRawReader reader)
+        public static List<string> ReadStringCollection(this IBinaryRawReader reader)
         {
             Debug.Assert(reader != null);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
index ca9fb63..6661161 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
@@ -1054,17 +1054,26 @@ namespace Apache.Ignite.Core.Impl.Cache
         #region Queries
 
         /** <inheritDoc /> */
+        public IFieldsQueryCursor Query(SqlFieldsQuery qry)
+        {
+            var cursor = QueryFieldsInternal(qry);
+
+            return new FieldsQueryCursor(cursor, _flagKeepBinary, 
+                (reader, count) => ReadFieldsArrayList(reader, count));
+        }
+
+        /** <inheritDoc /> */
         public IQueryCursor<IList> QueryFields(SqlFieldsQuery qry)
         {
-            return QueryFields(qry, ReadFieldsArrayList);
+            return Query(qry, (reader, count) => (IList) ReadFieldsArrayList(reader, count));
         }
 
         /// <summary>
         /// Reads the fields array list.
         /// </summary>
-        private static IList ReadFieldsArrayList(IBinaryRawReader reader, int count)
+        private static List<object> ReadFieldsArrayList(IBinaryRawReader reader, int count)
         {
-            IList res = new ArrayList(count);
+            var res = new List<object>(count);
 
             for (var i = 0; i < count; i++)
                 res.Add(reader.ReadObject<object>());
@@ -1073,15 +1082,21 @@ namespace Apache.Ignite.Core.Impl.Cache
         }
 
         /** <inheritDoc /> */
-        public IQueryCursor<T> QueryFields<T>(SqlFieldsQuery qry, Func<IBinaryRawReader, int, T> readerFunc)
+        public IQueryCursor<T> Query<T>(SqlFieldsQuery qry, Func<IBinaryRawReader, int, T> readerFunc)
+        {
+            var cursor = QueryFieldsInternal(qry);
+
+            return new FieldsQueryCursor<T>(cursor, _flagKeepBinary, readerFunc);
+        }
+
+        private IPlatformTargetInternal QueryFieldsInternal(SqlFieldsQuery qry)
         {
             IgniteArgumentCheck.NotNull(qry, "qry");
-            IgniteArgumentCheck.NotNull(readerFunc, "readerFunc");
 
             if (string.IsNullOrEmpty(qry.Sql))
                 throw new ArgumentException("Sql cannot be null or empty");
 
-            var cursor = DoOutOpObject((int) CacheOp.QrySqlFields, writer =>
+            return DoOutOpObject((int) CacheOp.QrySqlFields, writer =>
             {
                 writer.WriteBoolean(qry.Local);
                 writer.WriteString(qry.Sql);
@@ -1097,8 +1112,6 @@ namespace Apache.Ignite.Core.Impl.Cache
                 writer.WriteBoolean(qry.Colocated);
                 writer.WriteString(qry.Schema); // Schema
             });
-        
-            return new FieldsQueryCursor<T>(cursor, _flagKeepBinary, readerFunc);
         }
 
         /** <inheritDoc /> */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
index 1ec5341..fb968cf 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
@@ -36,7 +36,7 @@ namespace Apache.Ignite.Core.Impl.Cache
         /// <returns>
         /// Cursor.
         /// </returns>
-        IQueryCursor<T> QueryFields<T>(SqlFieldsQuery qry, Func<IBinaryRawReader, int, T> readerFunc);
+        IQueryCursor<T> Query<T>(SqlFieldsQuery qry, Func<IBinaryRawReader, int, T> readerFunc);
 
         /// <summary>
         /// Invokes a cache extension.

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
index c60e010..c9e64a8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
@@ -18,7 +18,11 @@
 namespace Apache.Ignite.Core.Impl.Cache.Query
 {
     using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
     using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Impl.Binary;
 
     /// <summary>
     /// Cursor for entry-based queries.
@@ -47,4 +51,39 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
             // No-op.
         }
     }
+
+    /// <summary>
+    /// Cursor for entry-based queries.
+    /// </summary>
+    internal class FieldsQueryCursor : FieldsQueryCursor<IList<object>>, IFieldsQueryCursor
+    {
+        /** */
+        private const int OpGetFieldNames = 7;
+
+        /** */
+        private IList<string> _fieldNames;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="target">Target.</param>
+        /// <param name="keepBinary">Keep poratble flag.</param>
+        /// <param name="readerFunc">The reader function.</param>
+        public FieldsQueryCursor(IPlatformTargetInternal target, bool keepBinary, 
+            Func<IBinaryRawReader, int, IList<object>> readerFunc) : base(target, keepBinary, readerFunc)
+        {
+            // No-op.
+        }
+
+        /** <inheritdoc /> */
+        public IList<string> FieldNames
+        {
+            get
+            {
+                return _fieldNames ??
+                       (_fieldNames = new ReadOnlyCollection<string>(
+                           Target.OutStream(OpGetFieldNames, reader => reader.ReadStringCollection())));
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs
index fc78392..3f1e4fc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs
@@ -54,6 +54,14 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
             _target = target;
         }
 
+        /// <summary>
+        /// Gets the target.
+        /// </summary>
+        public IPlatformTargetInternal Target
+        {
+            get { return _target; }
+        }
+
         /** <inheritdoc /> */
         protected override IList<T> GetAllInternal()
         {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
index 93829c2..2344417 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
@@ -196,7 +196,7 @@ namespace Apache.Ignite.Core.Impl.Client.Cache
         }
 
         /** <inheritDoc /> */
-        public IQueryCursor<T> QueryFields<T>(SqlFieldsQuery sqlFieldsQuery, Func<IBinaryRawReader, int, T> readerFunc)
+        public IQueryCursor<T> Query<T>(SqlFieldsQuery sqlFieldsQuery, Func<IBinaryRawReader, int, T> readerFunc)
         {
             return DoOutInOp(ClientOp.QuerySqlFields, 
                 w => WriteSqlFieldsQuery(w, sqlFieldsQuery, false),

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientFieldsQueryCursor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientFieldsQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientFieldsQueryCursor.cs
index 2e57863..c8f7e1f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientFieldsQueryCursor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientFieldsQueryCursor.cs
@@ -22,6 +22,7 @@ namespace Apache.Ignite.Core.Impl.Client.Cache.Query
     using System.Diagnostics;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
 
     /// <summary>
@@ -64,16 +65,9 @@ namespace Apache.Ignite.Core.Impl.Client.Cache.Query
         /// <summary>
         /// Reads the columns.
         /// </summary>
-        internal static string[] ReadColumns(IBinaryRawReader reader)
+        internal static List<string> ReadColumns(IBinaryRawReader reader)
         {
-            var res = new string[reader.ReadInt()];
-
-            for (var i = 0; i < res.Length; i++)
-            {
-                res[i] = reader.ReadString();
-            }
-
-            return res;
+            return reader.ReadStringCollection();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/BinaryModeExample.linq
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/BinaryModeExample.linq b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/BinaryModeExample.linq
index 2220650..4b2291e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/BinaryModeExample.linq
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/BinaryModeExample.linq
@@ -90,6 +90,6 @@ using (var ignite = Ignition.Start())
 		.Dump("Persons with age less than 40:");
 		
 	// Run SQL fields query.
-	cache.QueryFields(new SqlFieldsQuery("select name from Person order by name"))
+	cache.Query(new SqlFieldsQuery("select name from Person order by name"))
 		.Dump("All person names:");
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq
index 19d55a3..b3d63ba 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/NuGet/LINQPad/QueryExample.linq
@@ -66,7 +66,7 @@ void Main()
 			.Dump("Persons working for " + orgName);
 
 		// Fields query
-		orgs.QueryFields(new SqlFieldsQuery("select name, size from Organization")).Dump("Fields query");
+		orgs.Query(new SqlFieldsQuery("select name, size from Organization")).Dump("Fields query");
 
 		// Full text query
 		persons.Query(new TextQuery(typeof(Person), "Chris*")).Dump("Persons starting with 'Chris'");

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Linq/CacheLinqExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/CacheLinqExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/CacheLinqExtensions.cs
index 940b23b..935666f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/CacheLinqExtensions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/CacheLinqExtensions.cs
@@ -23,6 +23,7 @@ namespace Apache.Ignite.Linq
     using System.Linq.Expressions;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Cache.Query;
     using Apache.Ignite.Core.Impl.Cache;
     using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Linq.Impl;
@@ -37,8 +38,7 @@ namespace Apache.Ignite.Linq
         /// Gets an <see cref="IQueryable{T}"/> instance over this cache.
         /// <para />
         /// Resulting query will be translated to cache SQL query and executed over the cache instance 
-        /// via either <see cref="ICache{TK,TV}.Query"/> or <see cref="ICache{TK,TV}.QueryFields"/>,
-        /// depending on requested result. 
+        /// via <see cref="ICache{TK,TV}.Query(SqlFieldsQuery)"/>. 
         /// <para />
         /// Result of this method (and subsequent query) can be cast to <see cref="ICacheQueryable"/>
         /// for introspection, or converted with <see cref="ToCacheQueryable{T}"/> extension method.
@@ -59,7 +59,7 @@ namespace Apache.Ignite.Linq
         /// Gets an <see cref="IQueryable{T}"/> instance over this cache.
         /// <para />
         /// Resulting query will be translated to cache SQL query and executed over the cache instance 
-        /// via either <see cref="ICache{TK,TV}.Query"/> or <see cref="ICache{TK,TV}.QueryFields"/>,
+        /// via <see cref="ICache{TK,TV}.Query(SqlFieldsQuery)"/>. 
         /// depending on requested result. 
         /// <para />
         /// Result of this method (and subsequent query) can be cast to <see cref="ICacheQueryable"/> for introspection.
@@ -82,7 +82,7 @@ namespace Apache.Ignite.Linq
         /// Gets an <see cref="IQueryable{T}" /> instance over this cache.
         /// <para />
         /// Resulting query will be translated to cache SQL query and executed over the cache instance
-        /// via either <see cref="ICache{TK,TV}.Query" /> or <see cref="ICache{TK,TV}.QueryFields" />,
+        /// via <see cref="ICache{TK,TV}.Query(SqlFieldsQuery)"/>. 
         /// depending on requested result.
         /// <para />
         /// Result of this method (and subsequent query) can be cast to <see cref="ICacheQueryable" /> for introspection.
@@ -112,7 +112,7 @@ namespace Apache.Ignite.Linq
         /// Gets an <see cref="IQueryable{T}" /> instance over this cache.
         /// <para />
         /// Resulting query will be translated to cache SQL query and executed over the cache instance
-        /// via either <see cref="ICache{TK,TV}.Query" /> or <see cref="ICache{TK,TV}.QueryFields" />,
+        /// via <see cref="ICache{TK,TV}.Query(SqlFieldsQuery)"/>. 
         /// depending on requested result.
         /// <para />
         /// Result of this method (and subsequent query) can be cast to <see cref="ICacheQueryable" /> for introspection.

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryExecutor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryExecutor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryExecutor.cs
index fb34270..9d0edd7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryExecutor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryExecutor.cs
@@ -89,7 +89,7 @@ namespace Apache.Ignite.Linq.Impl
 
             var selector = GetResultSelector<T>(queryModel.SelectClause.Selector);
 
-            return _cache.QueryFields(qry, selector);
+            return _cache.Query(qry, selector);
         }
 
         /// <summary>
@@ -102,7 +102,7 @@ namespace Apache.Ignite.Linq.Impl
             var qryText = GetQueryData(queryModel).QueryText;
             var selector = GetResultSelector<T>(queryModel.SelectClause.Selector);
 
-            return args => _cache.QueryFields(GetFieldsQuery(qryText, args), selector);
+            return args => _cache.Query(GetFieldsQuery(qryText, args), selector);
         }
 
         /// <summary>
@@ -144,7 +144,7 @@ namespace Apache.Ignite.Linq.Impl
             // Simple case: lambda with no parameters. Only embedded parameters are used.
             if (!queryLambda.Parameters.Any())
             {
-                return argsUnused => _cache.QueryFields(GetFieldsQuery(qryText, qryParams), selector);
+                return argsUnused => _cache.Query(GetFieldsQuery(qryText, qryParams), selector);
             }
 
             // These are in order of usage in query
@@ -157,7 +157,7 @@ namespace Apache.Ignite.Linq.Impl
             if (qryOrderArgs.Length == qryParams.Length
                 && qryOrderArgs.SequenceEqual(userOrderArgs))
             {
-                return args => _cache.QueryFields(GetFieldsQuery(qryText, args), selector);
+                return args => _cache.Query(GetFieldsQuery(qryText, args), selector);
             }
 
             // General case: embedded args and lambda args are mixed; same args can be used multiple times.
@@ -172,7 +172,7 @@ namespace Apache.Ignite.Linq.Impl
                 return -1;
             }).ToArray();
 
-            return args => _cache.QueryFields(
+            return args => _cache.Query(
                 GetFieldsQuery(qryText, MapQueryArgs(args, qryParams, mapping)), selector);
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/Apache.Ignite.ndproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.ndproj b/modules/platforms/dotnet/Apache.Ignite.ndproj
index 5ed9e3c..ae99617 100644
--- a/modules/platforms/dotnet/Apache.Ignite.ndproj
+++ b/modules/platforms/dotnet/Apache.Ignite.ndproj
@@ -2029,7 +2029,7 @@ select new {
 // is equal to 3 minutes per derived class used by the base class +
 // 3 minutes per member of a derived class used by the base class.
 //</HowToFix>]]></Query>
-      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Class shouldn't be too deep in inheritance tree</Name>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Class shouldn't be too deep in inheritance tree</Name>
         
 warnif count > 0 from t in JustMyCode.Types 
 where t.IsClass

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/BinaryModeExample.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/BinaryModeExample.cs b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/BinaryModeExample.cs
index 1cc406b..89021e6 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/BinaryModeExample.cs
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/BinaryModeExample.cs
@@ -18,7 +18,6 @@
 namespace Apache.Ignite.Examples.Datagrid
 {
     using System;
-    using System.Collections;
     using Apache.Ignite.Core;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache;
@@ -196,12 +195,12 @@ namespace Apache.Ignite.Examples.Datagrid
         /// <param name="cache">Cache.</param>
         private static void SqlFieldsQueryExample(ICache<int, IBinaryObject> cache)
         {
-            var qry = cache.QueryFields(new SqlFieldsQuery("select name from Person order by name"));
+            var qry = cache.Query(new SqlFieldsQuery("select name from Person order by name"));
 
             Console.WriteLine();
             Console.WriteLine(">>> All person names:");
 
-            foreach (IList row in qry)
+            foreach (var row in qry)
                 Console.WriteLine(">>>     " + row[0]);
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryDmlExample.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryDmlExample.cs b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryDmlExample.cs
index 10bf1dd..00486bd 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryDmlExample.cs
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryDmlExample.cs
@@ -98,7 +98,7 @@ namespace Apache.Ignite.Examples.Datagrid
                 EnableDistributedJoins = true
             };
 
-            using (var cursor = employeeCache.QueryFields(qry))
+            using (var cursor = employeeCache.Query(qry))
             {
                 foreach (var row in cursor)
                 {
@@ -116,25 +116,25 @@ namespace Apache.Ignite.Examples.Datagrid
         {
             // Insert organizations.
             var qry = new SqlFieldsQuery("insert into Organization (_key, name) values (?, ?)", 1, "ASF");
-            organizationCache.QueryFields(qry);
+            organizationCache.Query(qry);
 
             qry.Arguments = new object[] {2, "Eclipse"};
-            organizationCache.QueryFields(qry);
+            organizationCache.Query(qry);
 
             // Insert employees.
             qry = new SqlFieldsQuery("insert into Employee (_key, name, organizationId, salary) values (?, ?, ?, ?)");
 
             qry.Arguments = new object[] {1, "John Doe", 1, 4000};
-            employeeCache.QueryFields(qry);
+            employeeCache.Query(qry);
 
             qry.Arguments = new object[] {2, "Jane Roe", 1, 5000};
-            employeeCache.QueryFields(qry);
+            employeeCache.Query(qry);
 
             qry.Arguments = new object[] {3, "Mary Major", 2, 2000};
-            employeeCache.QueryFields(qry);
+            employeeCache.Query(qry);
 
             qry.Arguments = new object[] {4, "Richard Miles", 2, 3000};
-            employeeCache.QueryFields(qry);
+            employeeCache.Query(qry);
         }
 
         /// <summary>
@@ -145,7 +145,7 @@ namespace Apache.Ignite.Examples.Datagrid
         {
             var qry = new SqlFieldsQuery("update Employee set salary = salary * 1.1 where organizationId = ?", 1);
 
-            employeeCache.QueryFields(qry);
+            employeeCache.Query(qry);
         }
 
         /// <summary>
@@ -159,7 +159,7 @@ namespace Apache.Ignite.Examples.Datagrid
                 "select emp._key from Employee emp, \"{0}\".Organization org " +
                 "where org.Name != ? and org._key = emp.organizationId)", OrganizationCacheName), "ASF");
 
-            employeeCache.QueryFields(qry);
+            employeeCache.Query(qry);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryExample.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryExample.cs b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryExample.cs
index 98f9f50..23736ea 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryExample.cs
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/QueryExample.cs
@@ -18,7 +18,6 @@
 namespace Apache.Ignite.Examples.Datagrid
 {
     using System;
-    using System.Collections;
     using Apache.Ignite.Core;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Affinity;
@@ -182,12 +181,12 @@ namespace Apache.Ignite.Examples.Datagrid
         /// <param name="cache">Cache.</param>
         private static void SqlFieldsQueryExample(ICache<int, Employee> cache)
         {
-            var qry = cache.QueryFields(new SqlFieldsQuery("select name, salary from Employee"));
+            var qry = cache.Query(new SqlFieldsQuery("select name, salary from Employee"));
 
             Console.WriteLine();
             Console.WriteLine(">>> Employee names and their salaries:");
 
-            foreach (IList row in qry)
+            foreach (var row in qry)
                 Console.WriteLine(">>>     [Name=" + row[0] + ", salary=" + row[1] + ']');
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8f327a18/modules/platforms/dotnet/examples/dotnetcore/SqlExample.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/dotnetcore/SqlExample.cs b/modules/platforms/dotnet/examples/dotnetcore/SqlExample.cs
index 1fb2e90..1fe6a74 100644
--- a/modules/platforms/dotnet/examples/dotnetcore/SqlExample.cs
+++ b/modules/platforms/dotnet/examples/dotnetcore/SqlExample.cs
@@ -139,7 +139,7 @@ namespace Apache.Ignite.Examples
         /// <param name="cache">Cache.</param>
         private static void SqlFieldsQueryExample(ICache<int, Employee> cache)
         {
-            var qry = cache.QueryFields(new SqlFieldsQuery("select name, salary from Employee"));
+            var qry = cache.Query(new SqlFieldsQuery("select name, salary from Employee"));
 
             Console.WriteLine();
             Console.WriteLine(">>> Employee names and their salaries:");


[6/7] ignite git commit: Merge remote-tracking branch 'remotes/origin/master' into ignite-zk-ce

Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into ignite-zk-ce


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

Branch: refs/heads/ignite-zk-ce
Commit: 246b7655a036c792994cc7c99b1108aef4aa9c4e
Parents: 1fb53f3 8f327a1
Author: sboikov <sb...@gridgain.com>
Authored: Tue Dec 19 10:57:34 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Dec 19 10:57:34 2017 +0300

----------------------------------------------------------------------
 .../processors/igfs/IgfsDataManager.java        |  4 +-
 ...zySecondaryFileSystemPositionedReadable.java | 15 +++--
 .../query/PlatformAbstractQueryCursor.java      |  9 +++
 .../cache/query/PlatformFieldsQueryCursor.java  | 24 ++++++-
 ...fsSecondaryFileSystemPositionedReadable.java | 41 +++++++-----
 .../ExpiryCacheHolderTest.cs                    |  5 ++
 .../Binary/BinaryFooterTest.cs                  |  2 +-
 .../Binary/Serializable/SqlDmlTest.cs           |  6 +-
 .../Cache/CacheTestAsyncWrapper.cs              |  7 ++
 .../Cache/Query/CacheDmlQueriesTest.cs          | 18 ++---
 .../Query/CacheQueriesCodeConfigurationTest.cs  |  2 +-
 .../Cache/Query/CacheQueriesTest.cs             | 69 +++++++++++++++-----
 .../Query/Linq/CacheLinqTest.Introspection.cs   |  2 +-
 .../Client/Cache/SqlQueryTest.cs                |  4 +-
 .../dotnet/Apache.Ignite.Core/Cache/ICache.cs   |  8 +++
 .../Impl/Binary/BinaryReaderExtensions.cs       |  2 +-
 .../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs  | 29 +++++---
 .../Impl/Cache/ICacheInternal.cs                |  2 +-
 .../Impl/Cache/Query/FieldsQueryCursor.cs       | 39 +++++++++++
 .../Impl/Cache/Query/PlatformQueryQursorBase.cs |  8 +++
 .../Impl/Client/Cache/CacheClient.cs            |  2 +-
 .../Cache/Query/ClientFieldsQueryCursor.cs      | 12 +---
 .../NuGet/LINQPad/BinaryModeExample.linq        |  2 +-
 .../NuGet/LINQPad/QueryExample.linq             |  2 +-
 .../Apache.Ignite.Linq/CacheLinqExtensions.cs   | 10 +--
 .../Impl/CacheFieldsQueryExecutor.cs            | 10 +--
 modules/platforms/dotnet/Apache.Ignite.ndproj   |  2 +-
 .../Datagrid/BinaryModeExample.cs               |  5 +-
 .../Datagrid/QueryDmlExample.cs                 | 18 ++---
 .../Datagrid/QueryExample.cs                    |  5 +-
 .../dotnet/examples/dotnetcore/App.config       |  5 +-
 .../dotnet/examples/dotnetcore/SqlExample.cs    |  2 +-
 32 files changed, 263 insertions(+), 108 deletions(-)
----------------------------------------------------------------------



[2/7] ignite git commit: IGNITE-4862: Fixed NPE when reading data from IGFS. This closes #1706.

Posted by sb...@apache.org.
IGNITE-4862: Fixed NPE when reading data from IGFS. This closes #1706.


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

Branch: refs/heads/ignite-zk-ce
Commit: 5cd3e263b9ca1464044c1eec24fc642873a881ab
Parents: edc66af
Author: Ilya Kasnacheev <il...@gmail.com>
Authored: Mon Dec 18 15:58:10 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Dec 18 15:58:10 2017 +0300

----------------------------------------------------------------------
 .../processors/igfs/IgfsDataManager.java        |  4 +-
 ...zySecondaryFileSystemPositionedReadable.java | 15 +++++--
 ...fsSecondaryFileSystemPositionedReadable.java | 41 ++++++++++++--------
 3 files changed, 38 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5cd3e263/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
index 12765df..90b5e9b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
@@ -419,9 +419,11 @@ public class IgfsDataManager extends IgfsManager {
         int read = 0;
 
         try {
+            int r;
+
             // Delegate to the secondary file system.
             while (read < blockSize) {
-                int r = secReader.read(pos + read, res, read, blockSize - read);
+                r = secReader.read(pos + read, res, read, blockSize - read);
 
                 if (r < 0)
                     break;

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cd3e263/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsLazySecondaryFileSystemPositionedReadable.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsLazySecondaryFileSystemPositionedReadable.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsLazySecondaryFileSystemPositionedReadable.java
index 0a57c34..bbb5420 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsLazySecondaryFileSystemPositionedReadable.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsLazySecondaryFileSystemPositionedReadable.java
@@ -37,6 +37,9 @@ public class IgfsLazySecondaryFileSystemPositionedReadable implements IgfsSecond
     /** Buffer size. */
     private final int bufSize;
 
+    /** Synchronization mutex. */
+    private final Object mux = new Object();
+
     /** Target stream. */
     private IgfsSecondaryFileSystemPositionedReadable target;
 
@@ -58,16 +61,20 @@ public class IgfsLazySecondaryFileSystemPositionedReadable implements IgfsSecond
 
     /** {@inheritDoc} */
     @Override public int read(long pos, byte[] buf, int off, int len) throws IOException {
-        if (target == null)
-            target = fs.open(path, bufSize);
+        synchronized (mux) {
+            if (target == null)
+                target = fs.open(path, bufSize);
+        }
 
         return target.read(pos, buf, off, len);
     }
 
     /** {@inheritDoc} */
     @Override public void close() throws IOException {
-        if (target != null)
-            target.close();
+        synchronized (mux) {
+            if (target != null)
+                target.close();
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cd3e263/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsSecondaryFileSystemPositionedReadable.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsSecondaryFileSystemPositionedReadable.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsSecondaryFileSystemPositionedReadable.java
index 1a4add5..84f6283 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsSecondaryFileSystemPositionedReadable.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsSecondaryFileSystemPositionedReadable.java
@@ -42,6 +42,9 @@ public class HadoopIgfsSecondaryFileSystemPositionedReadable implements IgfsSeco
     /** Buffer size. */
     private final int bufSize;
 
+    /** Synchronization mutex. */
+    private final Object mux = new Object();
+
     /** Actual input stream. */
     private FSDataInputStream in;
 
@@ -69,34 +72,38 @@ public class HadoopIgfsSecondaryFileSystemPositionedReadable implements IgfsSeco
 
     /** Get input stream. */
     private PositionedReadable in() throws IOException {
-        if (opened) {
-            if (err != null)
-                throw err;
-        }
-        else {
-            opened = true;
+        synchronized (mux) {
+            if (opened) {
+                if (err != null)
+                    throw err;
+            }
+            else {
+                opened = true;
 
-            try {
-                in = fs.open(path, bufSize);
+                try {
+                    in = fs.open(path, bufSize);
 
-                if (in == null)
-                    throw new IOException("Failed to open input stream (file system returned null): " + path);
-            }
-            catch (IOException e) {
-                err = e;
+                    if (in == null)
+                        throw new IOException("Failed to open input stream (file system returned null): " + path);
+                }
+                catch (IOException e) {
+                    err = e;
 
-                throw err;
+                    throw err;
+                }
             }
-        }
 
-        return in;
+            return in;
+        }
     }
 
     /**
      * Close wrapped input stream in case it was previously opened.
      */
     @Override public void close() {
-        U.closeQuiet(in);
+        synchronized (mux) {
+            U.closeQuiet(in);
+        }
     }
 
     /** {@inheritDoc} */


[4/7] ignite git commit: IGNITE-7232 .NET: Cross-platform examples: remove localhost from config to join nodes with default config

Posted by sb...@apache.org.
IGNITE-7232 .NET: Cross-platform examples: remove localhost from config to join nodes with default config


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

Branch: refs/heads/ignite-zk-ce
Commit: a2b195ced34af644117fde7cbe43f1fd2cbf9db3
Parents: 5cd3e26
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Mon Dec 18 18:31:25 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Mon Dec 18 18:31:25 2017 +0300

----------------------------------------------------------------------
 modules/platforms/dotnet/examples/dotnetcore/App.config | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a2b195ce/modules/platforms/dotnet/examples/dotnetcore/App.config
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/dotnetcore/App.config b/modules/platforms/dotnet/examples/dotnetcore/App.config
index e653d62..32c8b31 100644
--- a/modules/platforms/dotnet/examples/dotnetcore/App.config
+++ b/modules/platforms/dotnet/examples/dotnetcore/App.config
@@ -26,10 +26,7 @@
         <gcServer enabled="true" />
     </runtime>
 
-    <igniteConfiguration xmlns="http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection" 
-                         localhost="127.0.0.1">
-        <atomicConfiguration atomicSequenceReserveSize="10" />
-
+    <igniteConfiguration xmlns="http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection">
         <discoverySpi type="TcpDiscoverySpi">
             <ipFinder type="TcpDiscoveryMulticastIpFinder">
                 <endpoints>


[7/7] ignite git commit: zk

Posted by sb...@apache.org.
zk


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

Branch: refs/heads/ignite-zk-ce
Commit: 4525b9218b17786b9ddf6a3932fc3422b8cfc735
Parents: 246b765
Author: sboikov <sb...@gridgain.com>
Authored: Tue Dec 19 13:34:22 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Dec 19 14:34:25 2017 +0300

----------------------------------------------------------------------
 .../DefaultCommunicationProblemResolver.java    | 199 +++++++++++++++++++
 .../configuration/IgniteConfiguration.java      |  12 +-
 .../apache/ignite/internal/IgniteKernal.java    |   3 +
 .../org/apache/ignite/internal/IgnitionEx.java  |   3 +
 .../internal/managers/GridManagerAdapter.java   |   8 +
 .../discovery/GridDiscoveryManager.java         |  68 +++++++
 .../managers/discovery/IgniteDiscoverySpi.java  |   4 +-
 .../org/apache/ignite/spi/IgniteSpiAdapter.java |  10 +
 .../org/apache/ignite/spi/IgniteSpiContext.java |   4 +
 .../communication/tcp/TcpCommunicationSpi.java  |  18 +-
 .../DefaultCommunicationProblemResolver.java    | 174 ----------------
 .../spi/discovery/tcp/TcpDiscoverySpi.java      |   2 +-
 .../spi/discovery/zk/ZookeeperDiscoverySpi.java |   4 +-
 .../ZkCommunicationErrorProcessFuture.java      |   2 +-
 .../zk/internal/ZookeeperDiscoveryImpl.java     |  33 +--
 .../ZookeeperDiscoverySpiBasicTest.java         | 102 ++++++++--
 .../testframework/GridSpiTestContext.java       |  10 +
 17 files changed, 433 insertions(+), 223 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/configuration/DefaultCommunicationProblemResolver.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/DefaultCommunicationProblemResolver.java b/modules/core/src/main/java/org/apache/ignite/configuration/DefaultCommunicationProblemResolver.java
new file mode 100644
index 0000000..1e973d3
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/DefaultCommunicationProblemResolver.java
@@ -0,0 +1,199 @@
+/*
+ * 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.configuration;
+
+import java.util.BitSet;
+import java.util.List;
+import org.apache.ignite.cluster.ClusterNode;
+
+/**
+ *
+ */
+public class DefaultCommunicationProblemResolver implements CommunicationProblemResolver {
+    /** {@inheritDoc} */
+    @Override public void resolve(CommunicationProblemContext ctx) {
+        ClusterGraph graph = new ClusterGraph(ctx);
+
+        BitSet cluster = graph.findLargestIndependentCluster();
+
+        List<ClusterNode> nodes = ctx.topologySnapshot();
+
+        if (graph.checkFullyConnected(cluster) && cluster.cardinality() < nodes.size()) {
+            for (int i = 0; i < nodes.size(); i++) {
+                if (!cluster.get(i))
+                    ctx.killNode(nodes.get(i));
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    private static class ClusterGraph {
+        /** */
+        private final static int WORD_IDX_SHIFT = 6;
+
+        /**
+         * @param bitIndex Bit index.
+         * @return Word index containing bit with given index.
+         */
+        private static int wordIndex(int bitIndex) {
+            return bitIndex >> WORD_IDX_SHIFT;
+        }
+
+        /** */
+        private final int nodeCnt;
+
+        /** */
+        private final long[] visitBitSet;
+
+        /** */
+        private final CommunicationProblemContext ctx;
+
+        /** */
+        private final List<ClusterNode> nodes;
+
+        /**
+         * @param ctx Context.
+         */
+        ClusterGraph(CommunicationProblemContext ctx) {
+            this.ctx = ctx;
+
+            nodes = ctx.topologySnapshot();
+
+            nodeCnt = nodes.size();
+
+            assert nodeCnt > 0;
+
+            visitBitSet = initBitSet(nodeCnt);
+        }
+
+        /**
+         * @param bitCnt Number of bits.
+         * @return Bit set words.
+         */
+        static long[] initBitSet(int bitCnt) {
+            return new long[wordIndex(bitCnt - 1) + 1];
+        }
+
+        /**
+         * @return Cluster nodes bit set.
+         */
+        BitSet findLargestIndependentCluster() {
+            BitSet maxCluster = null;
+            int maxClusterSize = 0;
+
+            for (int i = 0; i < nodeCnt; i++) {
+                if (getBit(visitBitSet, i))
+                    continue;
+
+                BitSet cluster = new BitSet(nodeCnt);
+
+                search(cluster, i);
+
+                int size = cluster.cardinality();
+
+                if (maxCluster == null || size > maxClusterSize) {
+                    maxCluster = cluster;
+                    maxClusterSize = size;
+                }
+            }
+
+            return maxCluster;
+        }
+
+        /**
+         * @param cluster Cluster nodes bit set.
+         * @return {@code True} if all cluster nodes are able to connect to each other.
+         */
+        boolean checkFullyConnected(BitSet cluster) {
+            int startIdx = 0;
+
+            int clusterNodes = cluster.cardinality();
+
+            for (;;) {
+                int idx = cluster.nextSetBit(startIdx);
+
+                if (idx == -1)
+                    break;
+
+                ClusterNode node1 = nodes.get(idx);
+
+                for (int i = 0; i < clusterNodes; i++) {
+                    if (!cluster.get(i) || i == idx)
+                        continue;
+
+                    ClusterNode node2 = nodes.get(i);
+
+                    if (cluster.get(i) && !ctx.connectionAvailable(node1, node2))
+                        return false;
+                }
+
+                startIdx = idx + 1;
+            }
+
+            return true;
+        }
+
+        /**
+         * @param cluster Current cluster bit set.
+         * @param idx Node index.
+         */
+        void search(BitSet cluster, int idx) {
+            setBit(visitBitSet, idx);
+
+            cluster.set(idx);
+
+            ClusterNode node1 = nodes.get(idx);
+
+            for (int i = 0; i < nodeCnt; i++) {
+                if (i == idx || getBit(visitBitSet, i))
+                    continue;
+
+                ClusterNode node2 = nodes.get(i);
+
+                boolean connected = ctx.connectionAvailable(node1, node2) ||
+                    ctx.connectionAvailable(node2, node1);
+
+                if (connected)
+                    search(cluster, i);
+            }
+        }
+
+        /**
+         * @param words Bit set words.
+         * @param bitIndex Bit index.
+         */
+        static void setBit(long words[], int bitIndex) {
+            int wordIndex = wordIndex(bitIndex);
+
+            words[wordIndex] |= (1L << bitIndex);
+        }
+
+        /**
+         * @param words Bit set words.
+         * @param bitIndex Bit index.
+         * @return Bit value.
+         */
+        static boolean getBit(long[] words, int bitIndex) {
+            int wordIndex = wordIndex(bitIndex);
+
+            return (words[wordIndex] & (1L << bitIndex)) != 0;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
index 8c3c818..dbf5fbb 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
@@ -595,12 +595,22 @@ public class IgniteConfiguration {
         warmupClos = cfg.getWarmupClosure();
     }
 
+    /**
+     * TODO ZK
+     * @return
+     */
     public CommunicationProblemResolver getCommunicationProblemResolver() {
         return commProblemRslvr;
     }
 
-    public void setCommunicationProblemResolver(CommunicationProblemResolver commProblemRslvr) {
+    /**
+     * TODO ZK
+     * @param commProblemRslvr
+     */
+    public IgniteConfiguration setCommunicationProblemResolver(CommunicationProblemResolver commProblemRslvr) {
         this.commProblemRslvr = commProblemRslvr;
+
+        return this;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index a641e6e..85bb7c2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -2696,6 +2696,9 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
         objs.add(cfg.getGridLogger());
         objs.add(cfg.getMBeanServer());
 
+        if (cfg.getCommunicationProblemResolver() != null)
+            objs.add(cfg.getCommunicationProblemResolver());
+
         return objs;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
index 62ebcd8..8ae6313 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
@@ -71,6 +71,7 @@ import org.apache.ignite.configuration.PersistentStoreConfiguration;
 import org.apache.ignite.configuration.TransactionConfiguration;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.managers.communication.GridIoPolicy;
+import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
 import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor;
 import org.apache.ignite.internal.processors.igfs.IgfsThreadFactory;
 import org.apache.ignite.internal.processors.igfs.IgfsUtils;
@@ -2270,6 +2271,8 @@ public class IgnitionEx {
 
             initializeDefaultSpi(myCfg);
 
+            GridDiscoveryManager.initCommunicationErrorResolveConfiguration(myCfg);
+
             initializeDefaultCacheConfiguration(myCfg);
 
             ExecutorConfiguration[] execCfgs = myCfg.getExecutorConfiguration();

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
index a151eb5..df84212 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
@@ -604,6 +604,14 @@ public abstract class GridManagerAdapter<T extends IgniteSpi> implements GridMan
                         return ctx.nodeAttributes();
                     }
 
+                    @Override public boolean communicationErrorResolveSupported() {
+                        return ctx.discovery().communicationErrorResolveSupported();
+                    }
+
+                    @Override public void resolveCommunicationError(ClusterNode node, Exception err) {
+                        ctx.discovery().resolveCommunicationError(node, err);
+                    }
+
                     /**
                      * @param e Exception to handle.
                      * @return GridSpiException Converted exception.

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
index 97441d7..172615c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
@@ -53,8 +53,11 @@ import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cluster.ClusterMetrics;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.CommunicationProblemResolver;
 import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.DefaultCommunicationProblemResolver;
+import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.Event;
 import org.apache.ignite.internal.ClusterMetricsSnapshot;
@@ -108,6 +111,8 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.plugin.security.SecurityCredentials;
 import org.apache.ignite.plugin.segmentation.SegmentationPolicy;
 import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.communication.CommunicationSpi;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
 import org.apache.ignite.spi.discovery.DiscoveryDataBag;
 import org.apache.ignite.spi.discovery.DiscoveryDataBag.JoiningNodeDiscoveryData;
 import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider;
@@ -545,6 +550,9 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
             });
         }
 
+        if (ctx.config().getCommunicationProblemResolver() != null)
+            ctx.resource().injectGeneric(ctx.config().getCommunicationProblemResolver());
+
         spi.setListener(new DiscoverySpiListener() {
             private long gridStartTime;
 
@@ -2336,6 +2344,66 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         ).start();
     }
 
+    /**
+     * @param cfg Configuration.
+     * @throws IgniteCheckedException If configuration is not valid.
+     */
+    public static void initCommunicationErrorResolveConfiguration(IgniteConfiguration cfg) throws IgniteCheckedException {
+        CommunicationProblemResolver rslvr = cfg.getCommunicationProblemResolver();
+        CommunicationSpi commSpi = cfg.getCommunicationSpi();
+        DiscoverySpi discoverySpi = cfg.getDiscoverySpi();
+
+        if (rslvr != null) {
+            if (!supportsCommunicationErrorResolve(commSpi))
+                throw new IgniteCheckedException("CommunicationProblemResolver is configured, but communication SPI does not support communication" +
+                    "problem resolve: " + commSpi.getClass().getName());
+
+            if (!supportsCommunicationErrorResolve(discoverySpi))
+                throw new IgniteCheckedException("CommunicationProblemResolver is configured, but discovery SPI does not support communication" +
+                    "problem resolve: " + discoverySpi.getClass().getName());
+        }
+        else {
+            if (supportsCommunicationErrorResolve(commSpi) && supportsCommunicationErrorResolve(discoverySpi))
+                cfg.setCommunicationProblemResolver(new DefaultCommunicationProblemResolver());
+        }
+    }
+
+    /**
+     * @param spi Discovery SPI.
+     * @return {@code True} if SPI supports communication error resolve.
+     */
+    private static boolean supportsCommunicationErrorResolve(DiscoverySpi spi) {
+        return spi instanceof IgniteDiscoverySpi && ((IgniteDiscoverySpi)spi).supportsCommunicationErrorResolve();
+    }
+
+    /**
+     * @param spi Discovery SPI.
+     * @return {@code True} if SPI supports communication error resolve.
+     */
+    private static boolean supportsCommunicationErrorResolve(CommunicationSpi spi) {
+        return spi instanceof TcpCommunicationSpi;
+    }
+
+    /**
+     * @return {@code True} if communication error resolve is supported.
+     */
+    public boolean communicationErrorResolveSupported() {
+        return ctx.config().getCommunicationProblemResolver() != null;
+    }
+
+    /**
+     * @param node Problem node.
+     * @param err Error.
+     */
+    public void resolveCommunicationError(ClusterNode node, Exception err) {
+        DiscoverySpi spi = getSpi();
+
+        if (!supportsCommunicationErrorResolve(spi) || !supportsCommunicationErrorResolve(ctx.config().getCommunicationSpi()))
+            throw new UnsupportedOperationException();
+
+        ((IgniteDiscoverySpi)spi).resolveCommunicationError(node, err);
+    }
+
     /** Worker for network segment checks. */
     private class SegmentCheckWorker extends GridWorker {
         /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoverySpi.java
index 9a1faa2..bf117f1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IgniteDiscoverySpi.java
@@ -22,7 +22,7 @@ import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.spi.discovery.DiscoverySpi;
 
 /**
- * TODO ZK
+ *
  */
 public interface IgniteDiscoverySpi extends DiscoverySpi {
     /**
@@ -63,5 +63,5 @@ public interface IgniteDiscoverySpi extends DiscoverySpi {
      * @param node Problem node.
      * @param err Connection error.
      */
-    public void onCommunicationConnectionError(ClusterNode node, Exception err);
+    public void resolveCommunicationError(ClusterNode node, Exception err);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
index 07ba214..50cf9fe 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
@@ -957,5 +957,15 @@ public abstract class IgniteSpiAdapter implements IgniteSpi {
         @Override public Map<String, Object> nodeAttributes() {
             return Collections.emptyMap();
         }
+
+        /** {@inheritDoc} */
+        @Override public boolean communicationErrorResolveSupported() {
+            return false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void resolveCommunicationError(ClusterNode node, Exception err) {
+            throw new UnsupportedOperationException();
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
index 96b3e61..f9c6ffd 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
@@ -358,4 +358,8 @@ public interface IgniteSpiContext {
      * @return Current node attributes.
      */
     public Map<String, Object> nodeAttributes();
+
+    public boolean communicationErrorResolveSupported();
+
+    public void resolveCommunicationError(ClusterNode node, Exception err);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
index 957a0e1..37be29f 100755
--- a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
@@ -3409,22 +3409,16 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter implements Communicati
 
             boolean commErrResolve = false;
 
-            if (connectionError(errs)) {
-                DiscoverySpi discoverySpi = ignite.configuration().getDiscoverySpi();
+            IgniteSpiContext ctx = getSpiContext();
 
-                if (discoverySpi instanceof IgniteDiscoverySpi) {
-                    IgniteDiscoverySpi discoverySpi0 = (IgniteDiscoverySpi)discoverySpi;
+            if (connectionError(errs) && ctx.communicationErrorResolveSupported()) {
+                commErrResolve = true;
 
-                    if (discoverySpi0.supportsCommunicationErrorResolve()) {
-                        commErrResolve = true;
-
-                        discoverySpi0.onCommunicationConnectionError(node, errs);
-                    }
-                }
+                ctx.resolveCommunicationError(node, errs);
             }
 
             if (!commErrResolve && enableForcibleNodeKill) {
-                if (getSpiContext().node(node.id()) != null
+                if (ctx.node(node.id()) != null
                     && (CU.clientNode(node) ||  !CU.clientNode(getLocalNode())) &&
                     connectionError(errs)) {
                     String msg = "TcpCommunicationSpi failed to establish connection to node, node will be dropped from " +
@@ -3435,7 +3429,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter implements Communicati
                     else
                         U.warn(log, msg);
 
-                    getSpiContext().failNode(node.id(), "TcpCommunicationSpi failed to establish connection to node [" +
+                    ctx.failNode(node.id(), "TcpCommunicationSpi failed to establish connection to node [" +
                         "rmtNode=" + node +
                         ", errs=" + errs +
                         ", connectErrs=" + Arrays.toString(errs.getSuppressed()) + ']');

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/discovery/DefaultCommunicationProblemResolver.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/DefaultCommunicationProblemResolver.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/DefaultCommunicationProblemResolver.java
deleted file mode 100644
index b2d4bf0..0000000
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/DefaultCommunicationProblemResolver.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.spi.discovery;
-
-import java.util.BitSet;
-import java.util.List;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.configuration.CommunicationProblemContext;
-import org.apache.ignite.configuration.CommunicationProblemResolver;
-
-/**
- *
- */
-public class DefaultCommunicationProblemResolver implements CommunicationProblemResolver {
-    /** {@inheritDoc} */
-    @Override public void resolve(CommunicationProblemContext ctx) {
-        ClusterGraph graph = new ClusterGraph(ctx);
-
-        BitSet cluster = graph.findLargestIndependentCluster();
-
-        List<ClusterNode> nodes = ctx.topologySnapshot();
-
-        if (graph.checkFullyConnected(cluster) && cluster.cardinality() < nodes.size()) {
-            for (int i = 0; i < nodes.size(); i++) {
-                if (!cluster.get(i))
-                    ctx.killNode(nodes.get(i));
-            }
-        }
-    }
-
-    /**
-     *
-     */
-    private static class ClusterGraph {
-        /** */
-        private final static int WORD_IDX_SHIFT = 6;
-
-        /**
-         * @param bitIndex Bit index.
-         * @return Word index containing bit with given index.
-         */
-        private static int wordIndex(int bitIndex) {
-            return bitIndex >> WORD_IDX_SHIFT;
-        }
-
-        /** */
-        private final int nodeCnt;
-
-        /** */
-        private final long[] visitBitSet;
-
-        /** */
-        private final CommunicationProblemContext ctx;
-
-        /** */
-        private final List<ClusterNode> nodes;
-
-        ClusterGraph(CommunicationProblemContext ctx) {
-            this.ctx = ctx;
-
-            nodes = ctx.topologySnapshot();
-
-            nodeCnt = nodes.size();
-
-            assert nodeCnt > 0;
-
-            visitBitSet = initBitSet(nodeCnt);
-        }
-
-        static long[] initBitSet(int bitCnt) {
-            return new long[wordIndex(bitCnt - 1) + 1];
-        }
-
-        BitSet findLargestIndependentCluster() {
-            BitSet maxCluster = null;
-            int maxClusterSize = 0;
-
-            for (int i = 0; i < nodeCnt; i++) {
-                if (getBit(visitBitSet, i))
-                    continue;
-
-                BitSet cluster = new BitSet(nodeCnt);
-
-                search(cluster, i);
-
-                int size = cluster.cardinality();
-
-                if (maxCluster == null || size > maxClusterSize) {
-                    maxCluster = cluster;
-                    maxClusterSize = size;
-                }
-            }
-
-            return maxCluster;
-        }
-
-        boolean checkFullyConnected(BitSet cluster) {
-            int startIdx = 0;
-
-            int clusterNodes = cluster.cardinality();
-
-            for (;;) {
-                int idx = cluster.nextSetBit(startIdx);
-
-                if (idx == -1)
-                    break;
-
-                ClusterNode node1 = nodes.get(idx);
-
-                for (int i = 0; i < clusterNodes; i++) {
-                    if (!cluster.get(i) || i == idx)
-                        continue;
-
-                    ClusterNode node2 = nodes.get(i);
-
-                    if (cluster.get(i) && ctx.connectionAvailable(node1, node2))
-                        return false;
-                }
-
-                startIdx = idx + 1;
-            }
-
-            return true;
-        }
-
-        void search(BitSet cluster, int idx) {
-            setBit(visitBitSet, idx);
-
-            cluster.set(idx);
-
-            ClusterNode node1 = nodes.get(idx);
-
-            for (int i = 0; i < nodeCnt; i++) {
-                if (i == idx || getBit(visitBitSet, i))
-                    continue;
-
-                ClusterNode node2 = nodes.get(i);
-
-                boolean connected = ctx.connectionAvailable(node1, node2) ||
-                    ctx.connectionAvailable(node2, node1);
-
-                if (connected)
-                    search(cluster, i);
-            }
-        }
-
-        static void setBit(long words[], int bitIndex) {
-            int wordIndex = wordIndex(bitIndex);
-
-            words[wordIndex] |= (1L << bitIndex);
-        }
-
-        static boolean getBit(long[] words, int bitIndex) {
-            int wordIndex = wordIndex(bitIndex);
-
-            return (words[wordIndex] & (1L << bitIndex)) != 0;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
index 0e2f851..ad8eca0 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
@@ -2111,7 +2111,7 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements IgniteDiscovery
     }
 
     /** {@inheritDoc} */
-    @Override public void onCommunicationConnectionError(ClusterNode node, Exception err) {
+    @Override public void resolveCommunicationError(ClusterNode node, Exception err) {
         throw new UnsupportedOperationException();
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
index 98a22d7..14bb107 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpi.java
@@ -195,8 +195,8 @@ public class ZookeeperDiscoverySpi extends IgniteSpiAdapter implements Discovery
     }
 
     /** {@inheritDoc} */
-    @Override public void onCommunicationConnectionError(ClusterNode node, Exception err) {
-        impl.onCommunicationConnectionError(node, err);
+    @Override public void resolveCommunicationError(ClusterNode node, Exception err) {
+        impl.resolveCommunicationError(node, err);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkCommunicationErrorProcessFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkCommunicationErrorProcessFuture.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkCommunicationErrorProcessFuture.java
index 0074817..e64c801 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkCommunicationErrorProcessFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkCommunicationErrorProcessFuture.java
@@ -148,7 +148,7 @@ class ZkCommunicationErrorProcessFuture extends GridFutureAdapter<Void> implemen
      * @param futPath Future path.
      * @param nodes Nodes to ping.
      */
-    void pingNodesAndNotifyFuture(final ZkRuntimeState rtState, final String futPath, List<ClusterNode> nodes) throws Exception {
+    void checkConnection(final ZkRuntimeState rtState, final String futPath, List<ClusterNode> nodes) {
         final TcpCommunicationSpi spi = (TcpCommunicationSpi)impl.spi.ignite().configuration().getCommunicationSpi();
 
         IgniteFuture<BitSet> fut = spi.checkConnection(nodes);

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java
index ef3504f..f1ad869 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java
@@ -49,6 +49,7 @@ import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteNodeAttributes;
 import org.apache.ignite.internal.IgnitionEx;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
 import org.apache.ignite.internal.managers.discovery.IgniteDiscoverySpiInternalListener;
 import org.apache.ignite.internal.util.GridIntList;
@@ -247,17 +248,17 @@ public class ZookeeperDiscoveryImpl {
      * @param node0 Problem node ID
      * @param err Connect error.
      */
-    public void onCommunicationConnectionError(ClusterNode node0, Exception err) {
-        checkState();
-
+    public void resolveCommunicationError(ClusterNode node0, Exception err) {
         ZookeeperClusterNode node = node(node0.id());
 
         if (node == null)
-            return;
+            throw new IgniteSpiException(new ClusterTopologyCheckedException("Node failed: " + node0.id()));
 
         IgniteInternalFuture<Boolean> nodeStatusFut;
 
         for (;;) {
+            checkState();
+
             ZkCommunicationErrorProcessFuture fut = commErrProcFut.get();
 
             if (fut == null || fut.isDone()) {
@@ -273,16 +274,16 @@ public class ZookeeperDiscoveryImpl {
                             ", err= " + err + ']');
                     }
 
-                    ConnectionState connState;
+                    try {
+                        checkState();
+                    }
+                    catch (Exception e) {
+                        fut.onError(e);
 
-                    synchronized (this) {
-                        connState = this.connState;
+                        throw e;
                     }
 
-                    if (connState != ConnectionState.STARTED)
-                        fut.onError(new IgniteCheckedException("Node stopped."));
-                    else
-                        fut.scheduleCheckOnTimeout();
+                    fut.scheduleCheckOnTimeout();
                 }
                 else
                     fut = commErrProcFut.get();
@@ -303,7 +304,8 @@ public class ZookeeperDiscoveryImpl {
         }
 
         try {
-            nodeStatusFut.get();
+            if (!nodeStatusFut.get())
+                throw new IgniteSpiException(new ClusterTopologyCheckedException("Node failed: " + node0.id()));
         }
         catch (IgniteCheckedException e) {
             throw new IgniteSpiException(e);
@@ -2240,7 +2242,7 @@ public class ZookeeperDiscoveryImpl {
 
         runInWorkerThread(new ZkRunnable(rtState, this) {
             @Override protected void run0() throws Exception {
-                fut0.pingNodesAndNotifyFuture(rtState, futPath, rtState.commErrProcNodes);
+                fut0.checkConnection(rtState, futPath, rtState.commErrProcNodes);
             }
         });
     }
@@ -2341,7 +2343,8 @@ public class ZookeeperDiscoveryImpl {
                             ", rslvr=" + rslvr.getClass().getSimpleName() + ']');
                     }
 
-                    ZkCommunicationProblemContext ctx = new ZkCommunicationProblemContext(topSnapshot,
+                    ZkCommunicationProblemContext ctx = new ZkCommunicationProblemContext(
+                        topSnapshot,
                         initialNodes,
                         nodesRes);
 
@@ -2352,7 +2355,7 @@ public class ZookeeperDiscoveryImpl {
 
                         if (killedNodes != null) {
                             if (log.isInfoEnabled()) {
-                                log.info("Communication error resolver forces nodes stop [reqId=" + futId +
+                                log.info("Communication error resolver forced nodes stop [reqId=" + futId +
                                     ", killNodeCnt=" + killedNodes.size() +
                                     ", nodeIds=" + U.nodeIds(killedNodes) + ']');
                             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
index 58098b9..44e48f9 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiBasicTest.java
@@ -61,6 +61,7 @@ import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.IgniteNodeAttributes;
 import org.apache.ignite.internal.IgnitionEx;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.managers.discovery.DiscoveryLocalJoinData;
 import org.apache.ignite.internal.managers.discovery.IgniteDiscoverySpi;
 import org.apache.ignite.internal.processors.cache.GridCacheAbstractFullApiSelfTest;
@@ -72,9 +73,11 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.lang.IgniteOutClosure;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.logger.java.JavaLogger;
 import org.apache.ignite.resources.IgniteInstanceResource;
+import org.apache.ignite.spi.IgniteSpiException;
 import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
 import org.apache.ignite.configuration.CommunicationProblemContext;
 import org.apache.ignite.configuration.CommunicationProblemResolver;
@@ -147,7 +150,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
     private boolean persistence;
 
     /** */
-    private CommunicationProblemResolver commProblemRslvr;
+    private IgniteOutClosure<CommunicationProblemResolver> commProblemRslvr;
 
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
@@ -248,7 +251,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
             cfg.setCommunicationSpi(new ZkTestCommunicationSpi());
 
         if (commProblemRslvr != null)
-            cfg.setCommunicationProblemResolver(commProblemRslvr);
+            cfg.setCommunicationProblemResolver(commProblemRslvr.apply());
 
         return cfg;
     }
@@ -1808,7 +1811,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
         assert nodes > 1;
 
         sesTimeout = 2000;
-        commProblemRslvr = new NoOpCommunicationProblemResolver();
+        commProblemRslvr = NoOpCommunicationProblemResolver.FACTORY;
 
         startGridsMultiThreaded(nodes);
 
@@ -1828,7 +1831,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
 
             ZookeeperDiscoverySpi spi = spi(ignite(idx1));
 
-            spi.onCommunicationConnectionError(ignite(idx2).cluster().localNode(), new Exception("test"));
+            spi.resolveCommunicationError(ignite(idx2).cluster().localNode(), new Exception("test"));
 
             checkInternalStructuresCleanup();
         }
@@ -1840,7 +1843,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
     public void testNoOpCommunicationErrorResolve_3() throws Exception {
         // One node fails before sending communication status.
         sesTimeout = 2000;
-        commProblemRslvr = new NoOpCommunicationProblemResolver();
+        commProblemRslvr = NoOpCommunicationProblemResolver.FACTORY;
 
         startGridsMultiThreaded(3);
 
@@ -1855,7 +1858,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
             @Override public Object call() {
                 ZookeeperDiscoverySpi spi = spi(ignite(0));
 
-                spi.onCommunicationConnectionError(ignite(1).cluster().localNode(), new Exception("test"));
+                spi.resolveCommunicationError(ignite(1).cluster().localNode(), new Exception("test"));
 
                 return null;
             }
@@ -1883,11 +1886,11 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     public void testNoOpCommunicationErrorResolve_4() throws Exception {
-        // Coordinator changes while resolve process is in progress.
+        // Coordinator fails while resolve process is in progress.
         testCommSpi = true;
 
         sesTimeout = 2000;
-        commProblemRslvr = new NoOpCommunicationProblemResolver();
+        commProblemRslvr = NoOpCommunicationProblemResolver.FACTORY;
 
         startGrid(0);
 
@@ -1901,7 +1904,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
             @Override public Object call() {
                 ZookeeperDiscoverySpi spi = spi(ignite(1));
 
-                spi.onCommunicationConnectionError(ignite(2).cluster().localNode(), new Exception("test"));
+                spi.resolveCommunicationError(ignite(2).cluster().localNode(), new Exception("test"));
 
                 return null;
             }
@@ -1970,6 +1973,8 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
     }
 
     /**
+     * TODO ZK: kill random, kill coordinator multiple times.
+     *
      * @param startNodes Number of nodes to start.
      * @param killNodes Nodes to kill by resolve process.
      * @throws Exception If failed.
@@ -1977,7 +1982,7 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
     private void communicationErrorResolve_KillNodes(int startNodes, Collection<Long> killNodes) throws Exception {
         testCommSpi = true;
 
-        commProblemRslvr = new TestNodeKillCommunicationProblemResolver(killNodes);
+        commProblemRslvr = TestNodeKillCommunicationProblemResolver.factory(killNodes);
 
         startGrids(startNodes);
 
@@ -1986,20 +1991,28 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
         commSpi.checkRes = new BitSet(startNodes);
 
         ZookeeperDiscoverySpi spi = null;
+        UUID killNodeId = null;
 
         for (Ignite node : G.allGrids()) {
             ZookeeperDiscoverySpi spi0 = spi(node);
 
-            if (!killNodes.contains(node.cluster().localNode().order())) {
+            if (!killNodes.contains(node.cluster().localNode().order()))
                 spi = spi0;
-
-                break;
-            }
+            else
+                killNodeId = node.cluster().localNode().id();
         }
 
         assertNotNull(spi);
+        assertNotNull(killNodeId);
 
-        spi.onCommunicationConnectionError(ignite(1).cluster().localNode(), new Exception("test"));
+        try {
+            spi.resolveCommunicationError(spi.getNode(killNodeId), new Exception("test"));
+
+            fail("Exception is not thrown");
+        }
+        catch (IgniteSpiException e) {
+            assertTrue("Unexpected exception: " + e, e.getCause() instanceof ClusterTopologyCheckedException);
+        }
 
         int expNodes = startNodes - killNodes.size();
 
@@ -2016,6 +2029,46 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
+    public void testDefaultCommunicationErrorResolver1() throws Exception {
+        testCommSpi = true;
+        sesTimeout = 5000;
+
+        startGrids(3);
+
+        {
+            ZkTestCommunicationSpi commSpi = ZkTestCommunicationSpi.forNode(ignite(0));
+            commSpi.checkRes = new BitSet(3);
+            commSpi.checkRes.set(0);
+            commSpi.checkRes.set(1);
+        }
+        {
+            ZkTestCommunicationSpi commSpi = ZkTestCommunicationSpi.forNode(ignite(1));
+            commSpi.checkRes = new BitSet(3);
+            commSpi.checkRes.set(0);
+            commSpi.checkRes.set(1);
+        }
+        {
+            ZkTestCommunicationSpi commSpi = ZkTestCommunicationSpi.forNode(ignite(2));
+            commSpi.checkRes = new BitSet(3);
+            commSpi.checkRes.set(2);
+        }
+
+        UUID killedId = nodeId(2);
+
+        assertNotNull(ignite(0).cluster().node(killedId));
+
+        ZookeeperDiscoverySpi spi = spi(ignite(0));
+
+        spi.resolveCommunicationError(spi.getNode(ignite(1).cluster().localNode().id()), new Exception("test"));
+
+        waitForTopology(2);
+
+        assertNull(ignite(0).cluster().node(killedId));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testConnectionCheck() throws Exception {
        final int NODES = 5;
 
@@ -2709,6 +2762,13 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
      *
      */
     static class NoOpCommunicationProblemResolver implements CommunicationProblemResolver {
+        /** */
+        static final IgniteOutClosure<CommunicationProblemResolver> FACTORY = new IgniteOutClosure<CommunicationProblemResolver>() {
+            @Override public CommunicationProblemResolver apply() {
+                return new NoOpCommunicationProblemResolver();
+            }
+        };
+
         /** {@inheritDoc} */
         @Override public void resolve(CommunicationProblemContext ctx) {
             // No-op.
@@ -2719,6 +2779,18 @@ public class ZookeeperDiscoverySpiBasicTest extends GridCommonAbstractTest {
      *
      */
     static class TestNodeKillCommunicationProblemResolver implements CommunicationProblemResolver {
+        /**
+         * @param killOrders Killed nodes order.
+         * @return Factory.
+         */
+        static IgniteOutClosure<CommunicationProblemResolver> factory(final Collection<Long> killOrders)  {
+            return new IgniteOutClosure<CommunicationProblemResolver>() {
+                @Override public CommunicationProblemResolver apply() {
+                    return new TestNodeKillCommunicationProblemResolver(killOrders);
+                }
+            };
+        }
+
         /** */
         final Collection<Long> killNodeOrders;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4525b921/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
index 93cd911..36403fa 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
@@ -607,6 +607,16 @@ public class GridSpiTestContext implements IgniteSpiContext {
         return Collections.emptyMap();
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean communicationErrorResolveSupported() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void resolveCommunicationError(ClusterNode node, Exception err) {
+        throw new UnsupportedOperationException();
+    }
+
     /**
      * @param cacheName Cache name.
      * @return Map representing cache.