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/02/15 10:44:26 UTC

[01/50] [abbrv] ignite git commit: IGNITE-4610 Added more informative message.

Repository: ignite
Updated Branches:
  refs/heads/ignite-3477-merge2.0 db548dc27 -> faf07d8b7


IGNITE-4610 Added more informative message.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 9ff2a8f62f7f7ce36153e317758c19b2982eecd0
Parents: b0e104e
Author: Andrey Novikov <an...@gridgain.com>
Authored: Fri Feb 3 11:58:43 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Fri Feb 3 11:58:43 2017 +0700

----------------------------------------------------------------------
 modules/web-console/frontend/views/templates/agent-download.jade | 2 +-
 modules/web-console/web-agent/README.txt                         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9ff2a8f6/modules/web-console/frontend/views/templates/agent-download.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/templates/agent-download.jade b/modules/web-console/frontend/views/templates/agent-download.jade
index 20b6b03..f57bf1d 100644
--- a/modules/web-console/frontend/views/templates/agent-download.jade
+++ b/modules/web-console/frontend/views/templates/agent-download.jade
@@ -41,7 +41,7 @@
                 p Connection to Ignite Web Agent is established, but agent failed to connect to Ignite Node
                 p Please check the following:
                 ul
-                    li Ignite Grid is up and running
+                    li Ignite Grid is up and Ignite REST server started (copy "ignite-rest-http" folder from libs/optional/ to libs/)
                     li In agent settings check URI for connect to Ignite REST server
                     li Check agent logs for errors
                     li Refer to #[b README.txt] in agent folder for more information

http://git-wip-us.apache.org/repos/asf/ignite/blob/9ff2a8f6/modules/web-console/web-agent/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/README.txt b/modules/web-console/web-agent/README.txt
index cc0c80f..81df1cb 100644
--- a/modules/web-console/web-agent/README.txt
+++ b/modules/web-console/web-agent/README.txt
@@ -32,7 +32,7 @@ Security tokens:
   3) One may specify several comma separated tokens using configuration file or command line arguments of web agent.
 
 Ignite Web agent requirements:
-  1) In order to communicate with web agent Ignite node should be started with REST server (move ignite-rest-http folder from lib/optional/ to lib/).
+  1) In order to communicate with web agent Ignite node should be started with REST server (copy "ignite-rest-http" folder from "libs/optional/" to "libs/").
   2) Configure web agent serverURI property by Ignite node REST server URI.
 
 Options:


[41/50] [abbrv] ignite git commit: Merge branch 'master' into ignite-2.0

Posted by sb...@apache.org.
Merge branch 'master' into ignite-2.0


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 2f574701995ef644bb8066a0bd99a5985adcb154
Parents: 2e421c2 262a341
Author: devozerov <vo...@gridgain.com>
Authored: Mon Feb 13 14:28:41 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Feb 13 14:28:41 2017 +0300

----------------------------------------------------------------------
 NOTICE                                          |   2 +-
 assembly/NOTICE_FABRIC                          |   2 +-
 assembly/NOTICE_HADOOP                          |   2 +-
 modules/core/src/main/java/META-INF/NOTICE      |   2 +-
 .../apache/ignite/IgniteSystemProperties.java   |   3 +
 .../org/apache/ignite/cache/QueryEntity.java    |  21 +
 .../org/apache/ignite/cache/query/SqlQuery.java |  25 +
 .../internal/GridEventConsumeHandler.java       |   5 +
 .../ignite/internal/GridKernalContext.java      |   1 +
 .../ignite/internal/GridKernalContextImpl.java  |   1 +
 .../internal/GridMessageListenHandler.java      |   5 +
 .../internal/GridPerformanceSuggestions.java    |  92 ----
 .../apache/ignite/internal/IgniteKernal.java    |   9 +
 .../ignite/internal/IgniteVersionUtils.java     |   2 +-
 .../processors/cache/EntryGetResult.java        |  65 +++
 .../processors/cache/GridCacheAdapter.java      | 125 +++--
 .../processors/cache/GridCacheContext.java      |   4 +-
 .../processors/cache/GridCacheEntryEx.java      |  42 +-
 .../processors/cache/GridCacheMapEntry.java     | 140 +++++-
 .../processors/cache/GridCacheProcessor.java    |   2 +-
 .../processors/cache/GridCacheUtils.java        |   3 +
 .../processors/cache/IgniteCacheProxy.java      |   3 +
 .../processors/cache/ReaderArguments.java       |  74 +++
 .../distributed/dht/GridDhtCacheAdapter.java    |   9 +-
 .../cache/distributed/dht/GridDhtGetFuture.java |  83 ++--
 .../distributed/dht/GridDhtGetSingleFuture.java |  75 ++-
 .../dht/GridPartitionedGetFuture.java           |  10 +-
 .../dht/GridPartitionedSingleGetFuture.java     |  10 +-
 .../dht/atomic/GridDhtAtomicCache.java          |  12 +-
 .../dht/colocated/GridDhtColocatedCache.java    |  10 +-
 .../distributed/near/GridNearGetFuture.java     |  19 +-
 .../local/atomic/GridLocalAtomicCache.java      |  11 +-
 .../cache/query/GridCacheQueryManager.java      |  83 +++-
 .../continuous/CacheContinuousQueryHandler.java |  97 +++-
 .../cache/transactions/IgniteTxHandler.java     |   2 +-
 .../transactions/IgniteTxLocalAdapter.java      |  65 +--
 .../continuous/GridContinuousHandler.java       |   5 +
 .../continuous/GridContinuousProcessor.java     |   3 +
 .../internal/processors/job/GridJobWorker.java  |   4 +
 .../processors/query/GridQueryIndexing.java     |   4 +-
 .../processors/query/GridQueryProcessor.java    |  88 ++--
 .../query/GridQueryTypeDescriptor.java          |   7 +
 .../suggestions/GridPerformanceSuggestions.java | 105 ++++
 .../JvmConfigurationSuggestions.java            | 104 ++++
 .../suggestions/OsConfigurationSuggestions.java | 127 +++++
 .../internal/suggestions/package-info.java      |  21 +
 .../ignite/internal/util/IgniteUtils.java       |  14 +
 .../communication/tcp/TcpCommunicationSpi.java  |  16 +
 .../ignite/spi/discovery/tcp/ClientImpl.java    |  90 +++-
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  63 ++-
 .../messages/TcpDiscoveryAbstractMessage.java   |  21 +
 modules/core/src/test/config/log4j-test.xml     |   6 +
 .../internal/GridContinuousTaskSelfTest.java    |  79 +++
 .../cache/CacheConcurrentReadThroughTest.java   | 184 +++++++
 .../processors/cache/GridCacheTestEntryEx.java  |  30 +-
 ...CacheAtomicReferenceApiSelfAbstractTest.java |  60 ++-
 ...idCacheAtomicStampedApiSelfAbstractTest.java |  59 +++
 .../GridCacheQueueApiSelfAbstractTest.java      |  58 +++
 .../GridCacheSetAbstractSelfTest.java           |  53 +++
 .../IgniteAtomicLongApiAbstractSelfTest.java    |  27 ++
 .../IgniteCountDownLatchAbstractSelfTest.java   |  43 ++
 .../IgniteLockAbstractSelfTest.java             |  54 ++-
 .../IgniteSemaphoreAbstractSelfTest.java        |  52 +-
 .../near/GridNearCacheStoreUpdateTest.java      | 466 ++++++++++++++++++
 .../GridNearOffheapCacheStoreUpdateTest.java    |  35 ++
 .../cache/query/IndexingSpiQuerySelfTest.java   |  69 ++-
 .../IndexingSpiQueryWithH2IndexingSelfTest.java |  36 ++
 .../ClientReconnectContinuousQueryTest.java     | 201 ++++++++
 .../tcp/TcpCommunicationSpiDropNodesTest.java   | 322 +++++++++++++
 .../TcpCommunicationSpiFaultyClientTest.java    | 265 +++++++++++
 .../startup/GridRandomCommandLineLoader.java    |   2 +-
 .../ignite/testframework/GridTestNode.java      |   1 +
 .../testframework/junits/GridAbstractTest.java  |   2 +
 .../testsuites/IgniteCacheTestSuite2.java       |   7 +
 .../IgniteSpiCommunicationSelfTestSuite.java    |   5 +
 .../IgniteSpiDiscoverySelfTestSuite.java        |   2 +-
 .../processors/query/h2/IgniteH2Indexing.java   |  30 +-
 ...CacheScanPartitionQueryFallbackSelfTest.java |   2 +-
 .../cache/IgniteCacheAbstractQuerySelfTest.java | 294 ++++++++++++
 .../cache/QueryEntityCaseMismatchTest.java      | 107 +++++
 .../IgniteCachePartitionedQuerySelfTest.java    |  85 ++++
 .../h2/GridIndexingSpiAbstractSelfTest.java     |  29 +-
 .../IgniteCacheQuerySelfTestSuite.java          |   2 +
 .../IgniteCacheQuerySelfTestSuite3.java         |   2 +
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.AspNet.nuspec                 |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Cache/Query/CacheLinqTest.cs                |  96 ++++
 .../Cache/Store/CacheStoreTest.cs               |  30 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.Core.Schema.nuspec            |   2 +-
 .../Apache.Ignite.Core.nuspec                   |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.EntityFramework.nuspec        |   2 +-
 .../Apache.Ignite.Linq.nuspec                   |   2 +-
 .../Impl/CacheQueryExpressionVisitor.cs         | 127 ++++-
 .../Impl/CacheQueryModelVisitor.cs              |   3 +
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.Log4Net.nuspec                |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.NLog.nuspec                   |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite/Properties/AssemblyInfo.cs    |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 modules/scalar-2.10/pom.xml                     |   2 +-
 modules/scalar/pom.xml                          |   2 +-
 modules/web-console/backend/app/agent.js        |  34 ++
 modules/web-console/backend/app/browser.js      |  26 +
 .../app/modules/branding/branding.provider.js   |   2 +-
 modules/web-console/frontend/package.json       |   2 +-
 .../ignite/console/agent/AgentLauncher.java     | 203 ++++----
 .../apache/ignite/console/agent/AgentUtils.java |  80 ++++
 .../console/agent/handlers/AbstractHandler.java | 110 -----
 .../agent/handlers/AbstractListener.java        | 104 ++++
 .../console/agent/handlers/DatabaseHandler.java | 298 ------------
 .../agent/handlers/DatabaseListener.java        | 316 ++++++++++++
 .../console/agent/handlers/RestHandler.java     | 276 -----------
 .../console/agent/handlers/RestListener.java    | 280 +++++++++++
 .../ignite/console/demo/AgentClusterDemo.java   | 475 +------------------
 .../ignite/console/demo/AgentDemoUtils.java     |  79 +++
 .../demo/service/DemoCachesLoadService.java     | 456 ++++++++++++++++++
 .../service/DemoRandomCacheLoadService.java     | 120 +++++
 .../service/DemoServiceClusterSingleton.java    |  41 ++
 .../demo/service/DemoServiceKeyAffinity.java    |  41 ++
 .../service/DemoServiceMultipleInstances.java   |  41 ++
 .../demo/service/DemoServiceNodeSingleton.java  |  41 ++
 modules/yardstick/DEVNOTES-standalone.txt       |  15 +
 modules/yardstick/DEVNOTES.txt                  |  20 +-
 modules/yardstick/README.txt                    | 119 +++--
 .../config/benchmark-sample.properties          |  62 +++
 modules/yardstick/pom.xml                       |   4 +-
 .../cache/IgnitePutValue8Benchmark.java         |  42 ++
 parent/pom.xml                                  |   2 +-
 pom.xml                                         |   1 +
 137 files changed, 6215 insertions(+), 1830 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index 0888be3,e274485..0ec10b4
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@@ -152,7 -152,13 +152,10 @@@ public class GridCacheUtils 
      /** Atomics system cache name. */
      public static final String ATOMICS_CACHE_NAME = "ignite-atomics-sys-cache";
  
 -    /** Marshaller system cache name. */
 -    public static final String MARSH_CACHE_NAME = "ignite-marshaller-sys-cache";
 -
      /** */
+     public static final String CONTINUOUS_QRY_LOG_CATEGORY = "org.apache.ignite.continuous.query";
+ 
+     /** */
      public static final String CACHE_MSG_LOG_CATEGORY = "org.apache.ignite.cache.msg";
  
      /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
index ddc7687,4c89a7c..4c89a7c
mode 100755,100644..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

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f574701/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index ed3d1e8,386b8fd..3ef331f
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@@ -242,8 -242,8 +243,9 @@@ public class IgniteCacheQuerySelfTestSu
          suite.addTestSuite(CacheOffheapBatchIndexingSingleTypeTest.class);
          suite.addTestSuite(CacheSqlQueryValueCopySelfTest.class);
          suite.addTestSuite(IgniteCacheQueryCacheDestroySelfTest.class);
 +        suite.addTestSuite(IgniteSqlQueryDedicatedPoolTest.class);
          suite.addTestSuite(IgniteSqlEntryCacheModeAgnosticTest.class);
+         suite.addTestSuite(QueryEntityCaseMismatchTest.class);
  
          return suite;
      }


[32/50] [abbrv] ignite git commit: IGNITE-1680: CPP: Implemented API for user entry point lookup. This closes #1430.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/ignite_binding_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/ignite_binding_impl.h b/modules/platforms/cpp/core/include/ignite/impl/ignite_binding_impl.h
new file mode 100644
index 0000000..32de2cb
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/ignite_binding_impl.h
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_IMPL_IGNITE_BINDING_IMPL
+#define _IGNITE_IMPL_IGNITE_BINDING_IMPL
+
+#include <map>
+
+#include <ignite/common/common.h>
+
+#include <ignite/impl/binary/binary_reader_impl.h>
+#include <ignite/impl/binary/binary_writer_impl.h>
+
+namespace ignite
+{
+    namespace impl
+    {
+        /**
+         * Ignite binding implementation.
+         *
+         * Used to register and invoke callbacks.
+         */
+        class IgniteBindingImpl
+        {
+            typedef void (Callback)(binary::BinaryReaderImpl&, binary::BinaryWriterImpl&);
+
+        public:
+            /**
+             * Default constructor.
+             */
+            IgniteBindingImpl() : callbacks()
+            {
+                // No-op.
+            }
+
+            /**
+             * Invoke callback using provided ID.
+             *
+             * Deserializes data and callback itself, invokes callback and
+             * serializes processing result using providede reader and writer.
+             *
+             * @param id Processor ID.
+             * @param reader Reader.
+             * @param writer Writer.
+             * @return True if callback is registered and false otherwise.
+             */
+            bool InvokeCallbackById(int64_t id, binary::BinaryReaderImpl& reader, binary::BinaryWriterImpl& writer)
+            {
+                common::concurrent::CsLockGuard guard(lock);
+
+                std::map<int64_t, Callback*>::iterator it = callbacks.find(id);
+
+                if (it != callbacks.end())
+                {
+                    Callback* callback = it->second;
+
+                    // We have found callback and does not need lock here anymore.
+                    guard.Reset();
+
+                    callback(reader, writer);
+
+                    return true;
+                }
+
+                return false;
+            }
+
+            /**
+             * Register cache entry processor and associate it with provided ID.
+             *
+             * @throw IgniteError another processor is already associated with
+             *     the given ID.
+             *
+             * @param id Identifier for processor to be associated with.
+             * @param proc Callback.
+             */
+            void RegisterCallback(int64_t id, Callback* proc, IgniteError& err)
+            {
+                common::concurrent::CsLockGuard guard(lock);
+
+                bool inserted = callbacks.insert(std::make_pair(id, proc)).second;
+
+                guard.Reset();
+
+                if (!inserted)
+                {
+                    std::stringstream builder;
+
+                    builder << "Trying to register multiple PRC callbacks with the same ID. [id=" << id << ']';
+
+                    err = IgniteError(IgniteError::IGNITE_ERR_ENTRY_PROCESSOR, builder.str().c_str());
+                }
+            }
+
+        private:
+            IGNITE_NO_COPY_ASSIGNMENT(IgniteBindingImpl);
+
+            /** Registered callbacks. */
+            std::map<int64_t, Callback*> callbacks;
+
+            /** Callback lock. */
+            common::concurrent::CriticalSection lock;
+        };
+    }
+}
+
+#endif //_IGNITE_IMPL_IGNITE_BINDING_IMPL

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/ignite_environment.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/ignite_environment.h b/modules/platforms/cpp/core/include/ignite/impl/ignite_environment.h
index 2b2a117..5fc9a27 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/ignite_environment.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/ignite_environment.h
@@ -21,10 +21,14 @@
 #include <ignite/common/concurrent.h>
 #include <ignite/jni/java.h>
 #include <ignite/jni/utils.h>
+#include <ignite/ignite_binding_context.h>
+#include <ignite/ignite_configuration.h>
 
 #include "ignite/impl/interop/interop_memory.h"
 #include "ignite/impl/binary/binary_type_manager.h"
 #include "ignite/impl/handle_registry.h"
+#include "ignite/impl/module_manager.h"
+#include "ignite/impl/ignite_binding_impl.h"
 
 namespace ignite
 {
@@ -52,9 +56,11 @@ namespace ignite
             enum { DEFAULT_SLOW_PATH_CONTAINERS_CAP = 16 };
 
             /**
-             * Default constructor.
+             * Constructor.
+             *
+             * @param cfg Node configuration.
              */
-            IgniteEnvironment();
+            IgniteEnvironment(const IgniteConfiguration& cfg);
 
             /**
              * Destructor.
@@ -62,6 +68,13 @@ namespace ignite
             ~IgniteEnvironment();
 
             /**
+             * Get node configuration.
+             *
+             * @return Node configuration.
+             */
+            const IgniteConfiguration& GetConfiguration() const;
+
+            /**
              * Populate callback handlers.
              *
              * @param target (current env wrapped into a shared pointer).
@@ -85,6 +98,7 @@ namespace ignite
              * Start callback.
              *
              * @param memPtr Memory pointer.
+             * @param proc Processor instance.
              */
             void OnStartCallback(long long memPtr, jobject proc);
 
@@ -96,6 +110,13 @@ namespace ignite
             void OnContinuousQueryListenerApply(common::concurrent::SharedPointer<interop::InteropMemory>& mem);
 
             /**
+             * Cache Invoke callback.
+             *
+             * @param mem Input-output memory.
+             */
+            void CacheInvokeCallback(common::concurrent::SharedPointer<interop::InteropMemory>& mem);
+
+            /**
              * Get name of Ignite instance.
              *
              * @return Name.
@@ -103,6 +124,13 @@ namespace ignite
             const char* InstanceName() const;
 
             /**
+             * Get processor associated with the instance.
+             *
+             * @return Processor.
+             */
+            void* GetProcessor();
+
+            /**
              * Get JNI context.
              *
              * @return Context.
@@ -158,12 +186,29 @@ namespace ignite
              */
             HandleRegistry& GetHandleRegistry();
 
+            /**
+             * Get binding.
+             *
+             * @return IgniteBinding instance.
+             */
+            IgniteBinding GetBinding() const;
+
+            /**
+             * Get binding context.
+             *
+             * @return Binding context.
+             */
+            IgniteBindingContext GetBindingContext() const;
+
         private:
+            /** Node configuration. */
+            IgniteConfiguration* cfg;
+
             /** Context to access Java. */
             common::concurrent::SharedPointer<jni::java::JniContext> ctx;
 
             /** Startup latch. */
-            common::concurrent::SingleLatch* latch;
+            common::concurrent::SingleLatch latch;
 
             /** Ignite name. */
             char* name;
@@ -171,14 +216,20 @@ namespace ignite
             /** Processor instance. */
             jni::JavaGlobalRef proc;
 
+            /** Handle registry. */
+            HandleRegistry registry;
+
             /** Type manager. */
             binary::BinaryTypeManager* metaMgr;
 
             /** Type updater. */
             binary::BinaryTypeUpdater* metaUpdater;
 
-            /** Handle registry. */
-            HandleRegistry registry;
+            /** Ignite binding */
+            common::concurrent::SharedPointer<IgniteBindingImpl> binding;
+
+            /** Module manager. */
+            common::concurrent::SharedPointer<ModuleManager> moduleMgr;
 
             IGNITE_NO_COPY_ASSIGNMENT(IgniteEnvironment);
         };

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h b/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
index aa4059e..776678d 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
@@ -24,6 +24,7 @@
 
 #include "ignite/impl/cache/cache_impl.h"
 #include "ignite/impl/transactions/transactions_impl.h"
+#include "ignite/impl/cluster/cluster_group_impl.h"
 #include "ignite/impl/ignite_environment.h"
 
 namespace ignite 
@@ -35,8 +36,9 @@ namespace ignite
          */
         class IGNITE_FRIEND_EXPORT IgniteImpl
         {
-            typedef ignite::common::concurrent::SharedPointer<IgniteEnvironment> SP_IgniteEnvironment;
-            typedef ignite::common::concurrent::SharedPointer<impl::transactions::TransactionsImpl> SP_TransactionsImpl;
+            typedef common::concurrent::SharedPointer<IgniteEnvironment> SP_IgniteEnvironment;
+            typedef common::concurrent::SharedPointer<transactions::TransactionsImpl> SP_TransactionsImpl;
+            typedef common::concurrent::SharedPointer<cluster::ClusterGroupImpl> SP_ClusterGroupImpl;
         public:
             /**
              * Constructor used to create new instance.
@@ -54,11 +56,18 @@ namespace ignite
             /**
              * Get name of the Ignite.
              *
-             * @param Name.
+             * @return Name.
              */
             const char* GetName() const;
 
             /**
+             * Get node configuration.
+             *
+             * @return Node configuration.
+             */
+            const IgniteConfiguration& GetConfiguration() const;
+
+            /**
              * Get JNI context associated with this instance.
              *
              * @return JNI context for this instance.
@@ -80,7 +89,7 @@ namespace ignite
 
                 if (!cacheJavaRef)
                 {
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     return NULL;
                 }
@@ -105,7 +114,7 @@ namespace ignite
 
                 if (!cacheJavaRef)
                 {
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     return NULL;
                 }
@@ -130,7 +139,7 @@ namespace ignite
 
                 if (!cacheJavaRef)
                 {
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     return NULL;
                 }
@@ -141,6 +150,13 @@ namespace ignite
             }
 
             /**
+             * Get ignite binding.
+             *
+             * @return IgniteBinding class instance.
+             */
+            IgniteBinding GetBinding();
+
+            /**
              * Get instance of the implementation from the proxy class.
              * Internal method. Should not be used by user.
              *
@@ -158,11 +174,21 @@ namespace ignite
              *
              * @return TransactionsImpl instance.
              */
-            SP_TransactionsImpl GetTransactions()
+            SP_TransactionsImpl GetTransactions() const
             {
                 return txImpl;
             }
 
+            /**
+             * Get projection.
+             *
+             * @return ClusterGroupImpl instance.
+             */
+            SP_ClusterGroupImpl GetProjection() const
+            {
+                return prjImpl;
+            }
+
         private:
             /**
              * Get transactions internal call.
@@ -171,6 +197,13 @@ namespace ignite
              */
             SP_TransactionsImpl InternalGetTransactions(IgniteError &err);
 
+            /**
+             * Get current projection internal call.
+             *
+             * @return ClusterGroupImpl instance.
+             */
+            SP_ClusterGroupImpl InternalGetProjection(IgniteError &err);
+
             /** Environment. */
             SP_IgniteEnvironment env;
 
@@ -180,6 +213,9 @@ namespace ignite
             /** Transactions implementaion. */
             SP_TransactionsImpl txImpl;
 
+            /** Projection implementation. */
+            SP_ClusterGroupImpl prjImpl;
+
             IGNITE_NO_COPY_ASSIGNMENT(IgniteImpl)
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
index 432d2ac..a7a3094 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
@@ -54,7 +54,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result.
                  */
-                bool OutOp(int32_t opType, InputOperation& inOp, IgniteError* err);
+                bool OutOp(int32_t opType, InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Internal out operation.
@@ -63,17 +63,26 @@ namespace ignite
                  * @param err Error.
                  * @return Result.
                  */
-                bool OutOp(int32_t opType, IgniteError* err);
+                bool OutOp(int32_t opType, IgniteError& err);
 
                 /**
-                 * Internal out operation.
+                 * Internal in operation.
                  *
                  * @param opType Operation type.
-                 * @param inOp Input.
+                 * @param outOp Output.
                  * @param err Error.
                  * @return Result.
                  */
-                bool InOp(int32_t opType, OutputOperation& outOp, IgniteError* err);
+                bool InOp(int32_t opType, OutputOperation& outOp, IgniteError& err);
+
+                /**
+                 * Internal in Object operation.
+                 *
+                 * @param opType Operation type.
+                 * @param err Error.
+                 * @return Object.
+                 */
+                jobject InOpObject(int32_t opType, IgniteError& err);
 
                 /**
                  * Internal out-in operation.
@@ -84,7 +93,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void OutInOp(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void OutInOp(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                  * Internal out-in operation.
@@ -95,7 +104,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void OutInOpX(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void OutInOpX(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                 * Internal out-in operation.
@@ -104,7 +113,7 @@ namespace ignite
                 * @param val Value.
                 * @param err Error.
                 */
-                int64_t OutInOpLong(int32_t opType, int64_t val, IgniteError* err);
+                int64_t OutInOpLong(int32_t opType, int64_t val, IgniteError& err);
 
                 /**
                  * Get environment shared pointer.
@@ -154,7 +163,7 @@ namespace ignite
                  * @param err Error.
                  * @return Memory pointer.
                  */
-                int64_t WriteTo(interop::InteropMemory* mem, InputOperation& inOp, IgniteError* err);
+                int64_t WriteTo(interop::InteropMemory* mem, InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Read data from memory.
@@ -163,9 +172,17 @@ namespace ignite
                  * @param outOp Output operation.
                  */
                 void ReadFrom(interop::InteropMemory* mem, OutputOperation& outOp);
+
+                /**
+                 * Read error data from memory.
+                 *
+                 * @param mem Memory.
+                 * @param err Error.
+                 */
+                void ReadError(interop::InteropMemory* mem, IgniteError& err);
             };
         }
     }    
 }
 
-#endif //_IGNITE_IMPL_INTEROP_INTEROP_TARGET
\ No newline at end of file
+#endif //_IGNITE_IMPL_INTEROP_INTEROP_TARGET

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/module_manager.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/module_manager.h b/modules/platforms/cpp/core/include/ignite/impl/module_manager.h
new file mode 100644
index 0000000..55e6943
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/module_manager.h
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_IMPL_MODULE_MANAGER
+#define _IGNITE_IMPL_MODULE_MANAGER
+
+#include <vector>
+
+#include <ignite/common/common.h>
+#include <ignite/common/dynamic_load_os.h>
+#include <ignite/ignite_binding_context.h>
+
+/**
+ * @def IGNITE_CACHE_ENTRY_PROCESSOR_INVOKER_NAME
+ * Function name in which user Invoke callbacks are registred.
+ */
+#define IGNITE_MODULE_INIT_CALLBACK_NAME "IgniteModuleInit"
+
+#define IGNITE_EXPORTED_CALL \
+    extern "C" IGNITE_IMPORT_EXPORT
+
+namespace ignite
+{
+    namespace impl
+    {
+        /**
+         * Module manager.
+         * Provides methods to manipulate loadable modules.
+         */
+        class ModuleManager
+        {
+            typedef common::dynamic::Module Module;
+            typedef void (ModuleInitCallback)(IgniteBindingContext&);
+
+        public:
+            /**
+             * Constructor.
+             *
+             * @param context Ignite binding context.
+             */
+            ModuleManager(const IgniteBindingContext& context) :
+                loadedModules(),
+                bindingContext(context)
+            {
+                // No-op.
+            }
+
+            /**
+             * Destructor.
+             */
+            ~ModuleManager()
+            {
+                for (std::vector<Module>::iterator it = loadedModules.begin(); it != loadedModules.end(); ++it)
+                    it->Unload();
+            }
+
+            /**
+             * Load module.
+             *
+             * @param path Module path.
+             * @param err Error.
+             */
+            void LoadModule(const std::string& path, IgniteError& err)
+            {
+                common::dynamic::Module module = common::dynamic::LoadModule(path);
+
+                if (!module.IsLoaded())
+                {
+                    err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                        ("Can not load module [path=" + path + ']').c_str());
+
+                    return;
+                }
+
+                RegisterModule(module);
+            }
+
+            /**
+             * Register module in ModuleManager.
+             *
+             * @param module Module to register.
+             */
+            void RegisterModule(Module& module)
+            {
+                loadedModules.push_back(module);
+
+                ModuleInitCallback* callback = GetModuleInitCallback(module);
+
+                if (callback)
+                    callback(bindingContext);
+            }
+
+        private:
+            IGNITE_NO_COPY_ASSIGNMENT(ModuleManager);
+
+            /**
+             * Get callback that inits Ignite module.
+             *
+             * @param module Module for which callback should be retrieved.
+             * @return Callback if found and null-pointer otherwise.
+             */
+            static ModuleInitCallback* GetModuleInitCallback(Module& module)
+            {
+                return reinterpret_cast<ModuleInitCallback*>(
+                    module.FindSymbol(IGNITE_MODULE_INIT_CALLBACK_NAME));
+            }
+
+            /** Collection of loaded modules. */
+            std::vector<Module> loadedModules;
+
+            /** Ignite environment. */
+            IgniteBindingContext bindingContext;
+        };
+    }
+}
+
+#endif //_IGNITE_IMPL_MODULE_MANAGER

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/operations.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/operations.h b/modules/platforms/cpp/core/include/ignite/impl/operations.h
index 177529d..dfaa4e8 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/operations.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/operations.h
@@ -68,18 +68,18 @@ namespace ignite
              * 
              * @param val Value.
              */
-            In1Operation(const T* val) : val(val)
+            In1Operation(const T& val) : val(val)
             {
                 // No-op.
             }
 
             virtual void ProcessInput(ignite::impl::binary::BinaryWriterImpl& writer)
             {
-                writer.WriteTopObject<T>(*val);
+                writer.WriteTopObject<T>(val);
             }
         private:
             /** Value. */
-            const T* val; 
+            const T val;
 
             IGNITE_NO_COPY_ASSIGNMENT(In1Operation)
         };
@@ -97,22 +97,22 @@ namespace ignite
              * @param val1 First value.
              * @param val2 Second value.
              */
-            In2Operation(const T1* val1, const T2* val2) : val1(val1), val2(val2)
+            In2Operation(const T1& val1, const T2& val2) : val1(val1), val2(val2)
             {
                 // No-op.
             }
 
             virtual void ProcessInput(ignite::impl::binary::BinaryWriterImpl& writer)
             {
-                writer.WriteTopObject<T1>(*val1);
-                writer.WriteTopObject<T2>(*val2);
+                writer.WriteTopObject<T1>(val1);
+                writer.WriteTopObject<T2>(val2);
             }
         private:
             /** First value. */
-            const T1* val1; 
+            const T1& val1;
 
             /** Second value. */
-            const T2* val2; 
+            const T2& val2;
 
             IGNITE_NO_COPY_ASSIGNMENT(In2Operation)
         };
@@ -131,26 +131,26 @@ namespace ignite
              * @param val2 Second value.
              * @param val3 Third value.
              */
-            In3Operation(const T1* val1, const T2* val2, const T3* val3) : val1(val1), val2(val2), val3(val3)
+            In3Operation(const T1& val1, const T2& val2, const T3& val3) : val1(val1), val2(val2), val3(val3)
             {
                 // No-op.
             }
 
             virtual void ProcessInput(ignite::impl::binary::BinaryWriterImpl& writer)
             {
-                writer.WriteTopObject<T1>(*val1);
-                writer.WriteTopObject<T2>(*val2);
-                writer.WriteTopObject<T3>(*val3);
+                writer.WriteTopObject<T1>(val1);
+                writer.WriteTopObject<T2>(val2);
+                writer.WriteTopObject<T3>(val3);
             }
         private:
             /** First value. */
-            const T1* val1;
+            const T1& val1;
 
             /** Second value. */
-            const T2* val2;
+            const T2& val2;
 
             /** Third value. */
-            const T3* val3;
+            const T3& val3;
 
             IGNITE_NO_COPY_ASSIGNMENT(In3Operation)
         };
@@ -167,21 +167,21 @@ namespace ignite
              *
              * @param val Value.
              */
-            InSetOperation(const std::set<T>* val) : val(val)
+            InSetOperation(const std::set<T>& val) : val(val)
             {
                 // No-op.
             }
 
             virtual void ProcessInput(ignite::impl::binary::BinaryWriterImpl& writer)
             {
-                writer.GetStream()->WriteInt32(static_cast<int32_t>(val->size()));
+                writer.GetStream()->WriteInt32(static_cast<int32_t>(val.size()));
 
-                for (typename std::set<T>::const_iterator it = val->begin(); it != val->end(); ++it)
+                for (typename std::set<T>::const_iterator it = val.begin(); it != val.end(); ++it)
                     writer.WriteTopObject<T>(*it);
             }
         private:
             /** Value. */
-            const std::set<T>* val; 
+            const std::set<T>& val;
 
             IGNITE_NO_COPY_ASSIGNMENT(InSetOperation)
         };
@@ -198,23 +198,23 @@ namespace ignite
              *
              * @param val Value.
              */
-            InMapOperation(const std::map<K, V>* val) : val(val)
+            InMapOperation(const std::map<K, V>& val) : val(val)
             {
                 // No-op.
             }
 
             virtual void ProcessInput(ignite::impl::binary::BinaryWriterImpl& writer)
             {
-                writer.GetStream()->WriteInt32(static_cast<int32_t>(val->size()));
+                writer.GetStream()->WriteInt32(static_cast<int32_t>(val.size()));
 
-                for (typename std::map<K, V>::const_iterator it = val->begin(); it != val->end(); ++it) {
+                for (typename std::map<K, V>::const_iterator it = val.begin(); it != val.end(); ++it) {
                     writer.WriteTopObject<K>(it->first);
                     writer.WriteTopObject<V>(it->second);
                 }
             }
         private:
             /** Value. */
-            const std::map<K, V>* val; 
+            const std::map<K, V>& val;
 
             IGNITE_NO_COPY_ASSIGNMENT(InMapOperation)
         };
@@ -232,19 +232,19 @@ namespace ignite
              * @param key Key.
              * @param peekModes Peek modes.
              */
-            InCacheLocalPeekOperation(const T* key, int32_t peekModes) : key(key), peekModes(peekModes)
+            InCacheLocalPeekOperation(const T& key, int32_t peekModes) : key(key), peekModes(peekModes)
             {
                 // No-op.
             }
 
             virtual void ProcessInput(ignite::impl::binary::BinaryWriterImpl& writer)
             {
-                writer.WriteTopObject<T>(*key);
+                writer.WriteTopObject<T>(key);
                 writer.GetStream()->WriteInt32(peekModes);
             }
         private:
             /** Key. */
-            const T* key;   
+            const T& key;
 
             /** Peek modes. */
             int32_t peekModes; 
@@ -531,7 +531,7 @@ namespace ignite
             /**
              * Constructor.
              */
-            OutQueryGetAllOperation(std::vector<ignite::cache::CacheEntry<K, V> >* res) : res(res)
+            OutQueryGetAllOperation(std::vector<ignite::cache::CacheEntry<K, V> >& res) : res(res)
             {
                 // No-op.
             }
@@ -545,22 +545,22 @@ namespace ignite
                     K key = reader.ReadTopObject<K>();
                     V val = reader.ReadTopObject<V>();
 
-                    res->push_back(ignite::cache::CacheEntry<K, V>(key, val));
+                    res.push_back(ignite::cache::CacheEntry<K, V>(key, val));
                 }
             }
 
             virtual void SetNull()
             {
-                res->clear();
+                res.clear();
             }
 
         private:
             /** Entries. */
-            std::vector<ignite::cache::CacheEntry<K, V> >* res;
+            std::vector<ignite::cache::CacheEntry<K, V> >& res;
             
             IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperation)
         };
     }
 }
 
-#endif //_IGNITE_IMPL_OPERATIONS
\ No newline at end of file
+#endif //_IGNITE_IMPL_OPERATIONS

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/project/vs/core.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj b/modules/platforms/cpp/core/project/vs/core.vcxproj
index 89a2dff..9a5a80b 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj
@@ -192,11 +192,13 @@
   <ItemGroup>
     <ClInclude Include="..\..\include\ignite\cache\cache.h" />
     <ClInclude Include="..\..\include\ignite\cache\cache_entry.h" />
+    <ClInclude Include="..\..\include\ignite\cache\cache_entry_processor.h" />
     <ClInclude Include="..\..\include\ignite\cache\cache_peek_mode.h" />
     <ClInclude Include="..\..\include\ignite\cache\event\cache_entry_event.h" />
     <ClInclude Include="..\..\include\ignite\cache\event\cache_entry_event_listener.h" />
     <ClInclude Include="..\..\include\ignite\cache\query\continuous\continuous_query.h" />
     <ClInclude Include="..\..\include\ignite\cache\query\continuous\continuous_query_handle.h" />
+    <ClInclude Include="..\..\include\ignite\cache\mutable_cache_entry.h" />
     <ClInclude Include="..\..\include\ignite\cache\query\query.h" />
     <ClInclude Include="..\..\include\ignite\cache\query\query_argument.h" />
     <ClInclude Include="..\..\include\ignite\cache\query\query_cursor.h" />
@@ -206,24 +208,30 @@
     <ClInclude Include="..\..\include\ignite\cache\query\query_sql.h" />
     <ClInclude Include="..\..\include\ignite\cache\query\query_sql_fields.h" />
     <ClInclude Include="..\..\include\ignite\cache\query\query_text.h" />
+    <ClInclude Include="..\..\include\ignite\ignite_binding_context.h" />
     <ClInclude Include="..\..\include\ignite\ignite.h" />
     <ClInclude Include="..\..\include\ignite\ignite_configuration.h" />
     <ClInclude Include="..\..\include\ignite\ignition.h" />
     <ClInclude Include="..\..\include\ignite\impl\binary\binary_type_updater_impl.h" />
+    <ClInclude Include="..\..\include\ignite\impl\cache\cache_entry_processor_holder.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\cache_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\query_batch.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\continuous\continuous_query_handle_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\continuous\continuous_query_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\query_fields_row_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\query_impl.h" />
+    <ClInclude Include="..\..\include\ignite\impl\cluster\cluster_group_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\ignite_environment.h" />
     <ClInclude Include="..\..\include\ignite\impl\ignite_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\handle_registry.h" />
     <ClInclude Include="..\..\include\ignite\impl\interop\interop_external_memory.h" />
     <ClInclude Include="..\..\include\ignite\impl\interop\interop_target.h" />
+    <ClInclude Include="..\..\include\ignite\impl\ignite_binding_impl.h" />
+    <ClInclude Include="..\..\include\ignite\impl\module_manager.h" />
     <ClInclude Include="..\..\include\ignite\impl\operations.h" />
     <ClInclude Include="..\..\include\ignite\impl\transactions\transactions_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\transactions\transaction_impl.h" />
+    <ClInclude Include="..\..\include\ignite\ignite_binding.h" />
     <ClInclude Include="..\..\include\ignite\transactions\transaction.h" />
     <ClInclude Include="..\..\include\ignite\transactions\transactions.h" />
     <ClInclude Include="..\..\include\ignite\transactions\transaction_consts.h" />
@@ -237,6 +245,7 @@
     <ClCompile Include="..\..\src\impl\cache\query\query_batch.cpp" />
     <ClCompile Include="..\..\src\impl\cache\query\continuous\continuous_query_handle_impl.cpp" />
     <ClCompile Include="..\..\src\impl\cache\query\query_impl.cpp" />
+    <ClCompile Include="..\..\src\impl\cluster\cluster_group_impl.cpp" />
     <ClCompile Include="..\..\src\impl\ignite_environment.cpp" />
     <ClCompile Include="..\..\src\impl\ignite_impl.cpp" />
     <ClCompile Include="..\..\src\impl\handle_registry.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
index 9cb5f78..fc58633 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
@@ -49,6 +49,9 @@
     <ClCompile Include="..\..\src\impl\cache\query\continuous\continuous_query_handle_impl.cpp">
       <Filter>Code\impl\cache\query\continuous</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\impl\cluster\cluster_group_impl.cpp">
+      <Filter>Code\impl\cluster</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\ignite\impl\cache\cache_impl.h">
@@ -165,6 +168,30 @@
     <ClInclude Include="..\..\include\ignite\impl\cache\query\continuous\continuous_query_impl.h">
       <Filter>Code\impl\cache\query\continuous</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\ignite\cache\mutable_cache_entry.h">
+      <Filter>Code\cache</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\ignite\impl\cache\cache_entry_processor_holder.h">
+      <Filter>Code\impl\cache</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\ignite\impl\module_manager.h">
+      <Filter>Code\impl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\ignite\impl\cluster\cluster_group_impl.h">
+      <Filter>Code\impl\cluster</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\ignite\cache\cache_entry_processor.h">
+      <Filter>Code\cache</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\ignite\ignite_binding.h">
+      <Filter>Code</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\ignite\impl\ignite_binding_impl.h">
+      <Filter>Code\impl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\ignite\ignite_binding_context.h">
+      <Filter>Code</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Code">
@@ -206,5 +233,8 @@
     <Filter Include="Code\cache\event">
       <UniqueIdentifier>{e03c3690-ff22-4c78-83a0-b77cebb7f980}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Code\impl\cluster">
+      <UniqueIdentifier>{f5b54635-91a1-447e-923a-1b4608d7e5bc}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/ignite.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/ignite.cpp b/modules/platforms/cpp/core/src/ignite.cpp
index c546ea5..2665916 100644
--- a/modules/platforms/cpp/core/src/ignite.cpp
+++ b/modules/platforms/cpp/core/src/ignite.cpp
@@ -24,7 +24,7 @@ using namespace ignite::common::concurrent;
 using namespace ignite::impl;
 
 namespace ignite
-{    
+{
     Ignite::Ignite() : impl(SharedPointer<IgniteImpl>())
     {
         // No-op.
@@ -40,6 +40,11 @@ namespace ignite
         return impl.Get()->GetName();
     }
 
+    const IgniteConfiguration& Ignite::GetConfiguration() const
+    {
+        return impl.Get()->GetConfiguration();
+    }
+
     transactions::Transactions Ignite::GetTransactions()
     {
         using ignite::common::concurrent::SharedPointer;
@@ -49,5 +54,10 @@ namespace ignite
 
         return transactions::Transactions(txImpl);
     }
+
+    IgniteBinding Ignite::GetBinding()
+    {
+        return impl.Get()->GetBinding();
+    }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/ignition.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/ignition.cpp b/modules/platforms/cpp/core/src/ignition.cpp
index cd7ad70..6a00eab 100644
--- a/modules/platforms/cpp/core/src/ignition.cpp
+++ b/modules/platforms/cpp/core/src/ignition.cpp
@@ -16,6 +16,7 @@
  */
 
 #include <sstream>
+#include <memory>
 
 #include <ignite/common/common.h>
 #include <ignite/common/concurrent.h>
@@ -56,71 +57,134 @@ namespace ignite
     std::string JvmMemoryString(const std::string& prefix, int32_t val)
     {
         std::ostringstream ss;
-        ss << val;
 
-        std::string valStr = ss.str();
+        ss << prefix << val << 'm';
 
-        std::string res = std::string(prefix);
-        res.append(valStr);
-        res.append("m");
-
-        return res;
+        return ss.str();
     }
 
     /**
-     * Create JVM options.
+     * JVM options
      *
-     * @param cfg Configuration.
-     * @param home Optional GG home.
-     * @param cp Classpath.
-     * @param opts Options.
-     * @param optsLen Options length.
-     * @return Options.
+     * Used to build JVM options in a exception-safe way.
      */
-    char** CreateJvmOptions(const IgniteConfiguration& cfg, const std::string* home, const std::string& cp, int* optsLen)
+    class JvmOptions
     {
-        *optsLen = 3 + (home ? 1 : 0) + static_cast<int>(cfg.jvmOpts.size());
-        char** opts = new char*[*optsLen];
+    public:
+        /**
+         * Constructor.
+         */
+        JvmOptions() :
+            size(0),
+            opts(0)
+        {
+            // No-op.
+        }
+
+        /**
+         * Destructor.
+         */
+        ~JvmOptions()
+        {
+            Deinit();
+        }
+
+        /**
+         * Create JVM options from configuration.
+         *
+         * @param cfg Configuration.
+         * @param home Optional GG home.
+         * @param cp Classpath.
+         */
+        void FromConfiguration(const IgniteConfiguration& cfg, const std::string& home, const std::string& cp)
+        {
+            Deinit();
 
-        int idx = 0;
+            size = 3 + static_cast<int>(cfg.jvmOpts.size());
 
-        // 1. Set classpath.
-        std::string cpFull = std::string("-Djava.class.path=") + cp;
+            if (!home.empty())
+                ++size;
 
-        *(opts + idx++) = CopyChars(cpFull.c_str());
+            // Brackets '()' here guarantee for the array to be zeroed.
+            // Important to avoid crash in case of exception.
+            opts = new char*[size]();
 
-        // 2. Set home.
-        if (home) {
-            std::string homeFull = std::string("-DIGNITE_HOME=") + *home;
+            int idx = 0;
 
-            *(opts + idx++) = CopyChars(homeFull.c_str());
+            // 1. Set classpath.
+            std::string cpFull = "-Djava.class.path=" + cp;
+
+            opts[idx++] = CopyChars(cpFull.c_str());
+
+            // 2. Set home.
+            if (!home.empty()) {
+                std::string homeFull = "-DIGNITE_HOME=" + home;
+
+                opts[idx++] = CopyChars(homeFull.c_str());
+            }
+
+            // 3. Set Xms, Xmx.
+            std::string xmsStr = JvmMemoryString("-Xms", cfg.jvmInitMem);
+            std::string xmxStr = JvmMemoryString("-Xmx", cfg.jvmMaxMem);
+
+            opts[idx++] = CopyChars(xmsStr.c_str());
+            opts[idx++] = CopyChars(xmxStr.c_str());
+
+            // 4. Set the rest options.
+            for (std::list<std::string>::const_iterator i = cfg.jvmOpts.begin(); i != cfg.jvmOpts.end(); ++i)
+                opts[idx++] = CopyChars(i->c_str());
         }
 
-        // 3. Set Xms, Xmx.
-        std::string xmsStr = JvmMemoryString(std::string("-Xms"), cfg.jvmInitMem);
-        std::string xmxStr = JvmMemoryString(std::string("-Xmx"), cfg.jvmMaxMem);
+        /**
+         * Deallocates all allocated data.
+         */
+        void Deinit()
+        {
+            if (opts)
+            {
+                for (int i = 0; i < size; ++i)
+                    ReleaseChars(opts[i]);
 
-        *(opts + idx++) = CopyChars(xmsStr.c_str());
-        *(opts + idx++) = CopyChars(xmxStr.c_str());
+                delete[] opts;
+            }
+        }
 
-        // 4. Set the rest options.
-        for (std::list<std::string>::const_iterator i = cfg.jvmOpts.begin(); i != cfg.jvmOpts.end(); ++i) {
-            char* optCopy = CopyChars(i->c_str());
+        /**
+         * Get built options.
+         *
+         * @return Built options
+         */
+        char** GetOpts() const
+        {
+            return opts;
+        }
 
-            opts[idx++] = optCopy;
+        /**
+         * Get options number.
+         *
+         * @return Options number.
+         */
+        int GetSize() const
+        {
+            return size;
         }
 
-        return opts;
-    }
+    private:
+        /** Size */
+        int size;
+
+        /** Options array. */
+        char** opts;
+    };
 
     Ignite Ignition::Start(const IgniteConfiguration& cfg)
     {
-        return Start(cfg, static_cast<const char*>(NULL));
+        return Start(cfg, static_cast<const char*>(0));
     }
 
     Ignite Ignition::Start(const IgniteConfiguration& cfg, IgniteError* err)
     {
-        return Start(cfg, NULL, err);
+        return Start(cfg, 0, err);
     }
 
     Ignite Ignition::Start(const IgniteConfiguration& cfg, const char* name)
@@ -136,153 +200,126 @@ namespace ignite
 
     Ignite Ignition::Start(const IgniteConfiguration& cfg, const char* name, IgniteError* err)
     {
-        bool failed = false;
+        CsLockGuard guard(factoryLock);
 
-        SharedPointer<IgniteEnvironment> env;
-        SharedPointer<IgniteEnvironment>* envTarget = NULL;
-
-        jobject javaRef = NULL;
-
-        factoryLock.Enter();
+        std::string jvmLib = FindJvmLibrary(cfg.jvmLibPath);
 
         // 1. Load JVM library if needed.
         if (!JVM_LIB_LOADED)
         {
-            bool jvmLibFound;
-            std::string jvmLib;
-
-            if (!cfg.jvmLibPath.empty())
-            {
-                std::string jvmLibPath = std::string(cfg.jvmLibPath);
-
-                jvmLib = FindJvmLibrary(&jvmLibPath, &jvmLibFound);
-            }
-            else
-                jvmLib = FindJvmLibrary(NULL, &jvmLibFound);
-
-            if (!jvmLibFound)
+            if (jvmLib.empty())
             {
                 *err = IgniteError(IgniteError::IGNITE_ERR_JVM_LIB_NOT_FOUND,
                     "JVM library is not found (did you set JAVA_HOME environment variable?)");
 
-                failed = true;
+                return Ignite();
             }
 
-            if (!failed) {
-                if (!LoadJvmLibrary(jvmLib))
-                {
-                    *err = IgniteError(IgniteError::IGNITE_ERR_JVM_LIB_LOAD_FAILED, "Failed to load JVM library.");
+            if (!LoadJvmLibrary(jvmLib))
+            {
+                *err = IgniteError(IgniteError::IGNITE_ERR_JVM_LIB_LOAD_FAILED, "Failed to load JVM library.");
 
-                    failed = true;
-                }
+                return Ignite();
             }
 
             JVM_LIB_LOADED = true;
         }
 
-        if (!failed)
-        {
-            // 2. Resolve IGNITE_HOME.
-            bool homeFound;
-            std::string home;
+        // 2. Resolve IGNITE_HOME.
+        std::string home;
+        bool homeFound = ResolveIgniteHome(cfg.igniteHome, home);
 
-            if (!cfg.igniteHome.empty())
-            {
-                std::string homePath = std::string(cfg.igniteHome);
+        // 3. Create classpath.
+        std::string cp;
 
-                home = ResolveIgniteHome(&homePath, &homeFound);
-            }
-            else
-                home = ResolveIgniteHome(NULL, &homeFound);
+        if (homeFound)
+            cp = CreateIgniteClasspath(cfg.jvmClassPath, home);
+        else
+            cp = CreateIgniteClasspath(cfg.jvmClassPath);
 
-            // 3. Create classpath.
-            std::string cp;
+        if (cp.empty())
+        {
+            *err = IgniteError(IgniteError::IGNITE_ERR_JVM_NO_CLASSPATH,
+                "Java classpath is empty (did you set IGNITE_HOME environment variable?)");
 
-            if (!cfg.jvmClassPath.empty())
-            {
-                std::string usrCp = cfg.jvmClassPath;
+            return Ignite();
+        }
 
-                cp = CreateIgniteClasspath(&usrCp, homeFound ? &home : NULL);
-            }
-            else
-                cp = CreateIgniteClasspath(NULL, homeFound ? &home : NULL);
+        // 4. Resolving spring config path
+        std::string springCfgPath0;
 
-            if (!cp.empty())
-            {
-                // 4. Start JVM if needed.
-                JniErrorInfo jniErr;
+        if (!cfg.springCfgPath.empty())
+            springCfgPath0 = cfg.springCfgPath;
+        else
+            springCfgPath0 = DFLT_CFG;
 
-                env = SharedPointer<IgniteEnvironment>(new IgniteEnvironment());
+        // 5. Start JVM if needed.
+        IgniteConfiguration cfg0(cfg);
 
-                int optsLen;
-                char** opts = CreateJvmOptions(cfg, homeFound ? &home : NULL, cp, &optsLen);
+        cfg0.jvmLibPath = jvmLib;
+        cfg0.igniteHome = home;
+        cfg0.jvmClassPath = cp;
+        cfg0.springCfgPath = springCfgPath0;
 
-                envTarget = new SharedPointer<IgniteEnvironment>(env);
+        JniErrorInfo jniErr;
 
-                SharedPointer<JniContext> ctx(
-                    JniContext::Create(opts, optsLen, env.Get()->GetJniHandlers(envTarget), &jniErr));
+        SharedPointer<IgniteEnvironment> env = SharedPointer<IgniteEnvironment>(new IgniteEnvironment(cfg0));
 
-                for (int i = 0; i < optsLen; i++)
-                    ReleaseChars(*(opts + i));
+        JvmOptions opts;
+        opts.FromConfiguration(cfg, home, cp);
 
-                delete[] opts;
+        std::auto_ptr< SharedPointer<IgniteEnvironment> > envTarget(new SharedPointer<IgniteEnvironment>(env));
 
-                if (!ctx.Get())
-                {
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+        SharedPointer<JniContext> ctx(
+            JniContext::Create(opts.GetOpts(), opts.GetSize(), env.Get()->GetJniHandlers(envTarget.get()), &jniErr));
 
-                    failed = true;
-                }
+        if (!ctx.Get())
+        {
+            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
 
-                env.Get()->SetContext(ctx);
+            return Ignite();
+        }
 
-                // 5. Start Ignite.
-                if (!failed)
-                {
-                    char* springCfgPath0 = NULL;
+        env.Get()->SetContext(ctx);
 
-                    if (!cfg.springCfgPath.empty())
-                        springCfgPath0 = CopyChars(cfg.springCfgPath.c_str());
-                    else
-                        springCfgPath0 = CopyChars(DFLT_CFG);
+        // 6. Start Ignite.
 
-                    char* name0 = CopyChars(name);
+        // Workaround for nullable strings as we can't use unique_ptr nor
+        // can we construct std::string from the null-pointer.
+        char* namep = 0;
 
-                    interop::InteropUnpooledMemory mem(16);
-                    interop::InteropOutputStream stream(&mem);
-                    stream.WriteBool(false);
-                    stream.Synchronize();
+        std::string name0;
+        if (name)
+        {
+            name0 = name;
 
-                    javaRef = ctx.Get()->IgnitionStart(springCfgPath0, name0, 2, mem.PointerLong(), &jniErr);
+            namep = &name0[0];
+        }
 
-                    ReleaseChars(springCfgPath0);
-                    ReleaseChars(name0);
+        interop::InteropUnpooledMemory mem(16);
+        interop::InteropOutputStream stream(&mem);
+        stream.WriteBool(false);
+        stream.Synchronize();
 
-                    if (!javaRef) {
-                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+        jobject javaRef = ctx.Get()->IgnitionStart(&springCfgPath0[0], namep, 2, mem.PointerLong(), &jniErr);
 
-                        failed = true;
-                    }
-                    else {
-                        // 6. Ignite is started at this point.
-                        env.Get()->Initialize();
+        // Releasing control over environment as it is controlled by Java at this point.
+        // Even if the call has failed environment are going to be released by the Java.
+        envTarget.release();
 
-                        started = true;
-                    }
-                }
-            }
-            else {
-                *err = IgniteError(IgniteError::IGNITE_ERR_JVM_NO_CLASSPATH,
-                    "Java classpath is empty (did you set IGNITE_HOME environment variable?)");
+        if (!javaRef)
+        {
+            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
 
-                failed = true;
-            }
+            return Ignite();
         }
 
-        factoryLock.Leave();
+        // 7. Ignite is started at this point.
+        env.Get()->Initialize();
 
-        if (failed) 
-            return Ignite();
+        started = true;
+
+        guard.Reset();
 
         env.Get()->ProcessorReleaseStart();
 
@@ -293,12 +330,12 @@ namespace ignite
 
     Ignite Ignition::Get()
     {
-        return Get(static_cast<const char*>(NULL));
+        return Get(static_cast<const char*>(0));
     }
 
     Ignite Ignition::Get(IgniteError* err)
     {
-        return Get(NULL, err);
+        return Get(0, err);
     }
 
     Ignite Ignition::Get(const char* name)
@@ -325,16 +362,16 @@ namespace ignite
             // 1. Create context for this operation.
             JniErrorInfo jniErr;
 
-            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));
+            SharedPointer<JniContext> ctx(JniContext::Create(0, 0, JniHandlers(), &jniErr));
 
-            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
 
             if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
             {
                 // 2. Get environment pointer.
                 long long ptr = ctx.Get()->IgnitionEnvironmentPointer(name0, &jniErr);
 
-                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
 
                 if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
                 {
@@ -384,12 +421,12 @@ namespace ignite
 
     bool Ignition::Stop(bool cancel)
     {
-        return Stop(NULL, cancel);
+        return Stop(0, cancel);
     }
 
     bool Ignition::Stop(bool cancel, IgniteError* err)
     {
-        return Stop(NULL, cancel, err);
+        return Stop(0, cancel, err);
     }
 
     bool Ignition::Stop(const char* name, bool cancel)
@@ -413,9 +450,9 @@ namespace ignite
         {
             JniErrorInfo jniErr;
 
-            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));
+            SharedPointer<JniContext> ctx(JniContext::Create(0, 0, JniHandlers(), &jniErr));
 
-            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
 
             if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
             {
@@ -425,7 +462,7 @@ namespace ignite
 
                 ReleaseChars(name0);
 
-                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
 
                 if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
                     res = res0;
@@ -454,15 +491,15 @@ namespace ignite
         {
             JniErrorInfo jniErr;
 
-            SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr));
+            SharedPointer<JniContext> ctx(JniContext::Create(0, 0, JniHandlers(), &jniErr));
 
-            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+            IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
 
             if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
             {
                 ctx.Get()->IgnitionStopAll(cancel, &jniErr);
 
-                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, *err);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp b/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
index ff6df9e..42d6fd0 100644
--- a/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
@@ -48,7 +48,7 @@ namespace ignite
                 JniContext::Release(javaRef);
             }
 
-            bool BinaryTypeUpdaterImpl::Update(Snap* snap, IgniteError* err)
+            bool BinaryTypeUpdaterImpl::Update(Snap* snap, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp b/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
index 5d09e46..7b98f65 100644
--- a/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
@@ -70,6 +70,9 @@ namespace ignite
             /** Operation: GetAndReplace. */
             const int32_t OP_GET_AND_REPLACE = 10;
 
+            /** Operation: Invoke. */
+            const int32_t OP_INVOKE = 12;
+
             /** Operation: LocalEvict. */
             const int32_t OP_LOCAL_EVICT = 16;
 
@@ -152,82 +155,82 @@ namespace ignite
                 return name;
             }
 
-            bool CacheImpl::ContainsKey(InputOperation& inOp, IgniteError* err)
+            bool CacheImpl::ContainsKey(InputOperation& inOp, IgniteError& err)
             {
                 return OutOp(OP_CONTAINS_KEY, inOp, err);
             }
 
-            bool CacheImpl::ContainsKeys(InputOperation& inOp, IgniteError* err)
+            bool CacheImpl::ContainsKeys(InputOperation& inOp, IgniteError& err)
             {
                 return OutOp(OP_CONTAINS_KEYS, inOp, err);
             }
 
-            void CacheImpl::LocalPeek(InputOperation& inOp, OutputOperation& outOp, int32_t peekModes, IgniteError* err)
+            void CacheImpl::LocalPeek(InputOperation& inOp, OutputOperation& outOp, int32_t peekModes, IgniteError& err)
             {
                 OutInOpX(OP_LOCAL_PEEK, inOp, outOp, err);
             }
 
-            void CacheImpl::Get(InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            void CacheImpl::Get(InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 OutInOpX(OP_GET, inOp, outOp, err);
             }
 
-            void CacheImpl::GetAll(InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            void CacheImpl::GetAll(InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 OutInOpX(OP_GET_ALL, inOp, outOp, err);
             }
 
-            void CacheImpl::Put(InputOperation& inOp, IgniteError* err)
+            void CacheImpl::Put(InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_PUT, inOp, err);
             }
 
-            void CacheImpl::PutAll(ignite::impl::InputOperation& inOp, IgniteError* err)
+            void CacheImpl::PutAll(ignite::impl::InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_PUT_ALL, inOp, err);
             }
 
-            void CacheImpl::GetAndPut(InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            void CacheImpl::GetAndPut(InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 OutInOpX(OP_GET_AND_PUT, inOp, outOp, err);
             }
 
-            void CacheImpl::GetAndReplace(InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            void CacheImpl::GetAndReplace(InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 OutInOpX(OP_GET_AND_REPLACE, inOp, outOp, err);
             }
 
-            void CacheImpl::GetAndRemove(InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            void CacheImpl::GetAndRemove(InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 OutInOpX(OP_GET_AND_REMOVE, inOp, outOp, err);
             }
 
-            bool CacheImpl::PutIfAbsent(InputOperation& inOp, IgniteError* err)
+            bool CacheImpl::PutIfAbsent(InputOperation& inOp, IgniteError& err)
             {
                 return OutOp(OP_PUT_IF_ABSENT, inOp, err);
             }
 
-            void CacheImpl::GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            void CacheImpl::GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 OutInOpX(OP_GET_AND_PUT_IF_ABSENT, inOp, outOp, err);
             }
 
-            bool CacheImpl::Replace(InputOperation& inOp, IgniteError* err)
+            bool CacheImpl::Replace(InputOperation& inOp, IgniteError& err)
             {
                 return OutOp(OP_REPLACE_2, inOp, err);
             }
 
-            bool CacheImpl::ReplaceIfEqual(InputOperation& inOp, IgniteError* err)
+            bool CacheImpl::ReplaceIfEqual(InputOperation& inOp, IgniteError& err)
             {
                 return OutOp(OP_REPLACE_3, inOp, err);
             }
 
-            void CacheImpl::LocalEvict(InputOperation& inOp, IgniteError* err)
+            void CacheImpl::LocalEvict(InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_LOCAL_EVICT, inOp, err);
             }
 
-            void CacheImpl::Clear(IgniteError* err)
+            void CacheImpl::Clear(IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -236,42 +239,42 @@ namespace ignite
                 IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
             }
 
-            void CacheImpl::Clear(InputOperation& inOp, IgniteError* err)
+            void CacheImpl::Clear(InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_CLEAR, inOp, err);
             }
 
-            void CacheImpl::ClearAll(InputOperation& inOp, IgniteError* err)
+            void CacheImpl::ClearAll(InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_CLEAR_ALL, inOp, err);
             }
 
-            void CacheImpl::LocalClear(InputOperation& inOp, IgniteError* err)
+            void CacheImpl::LocalClear(InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_LOCAL_CLEAR, inOp, err);
             }
 
-            void CacheImpl::LocalClearAll(InputOperation& inOp, IgniteError* err)
+            void CacheImpl::LocalClearAll(InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_LOCAL_CLEAR_ALL, inOp, err);
             }
 
-            bool CacheImpl::Remove(InputOperation& inOp, IgniteError* err)
+            bool CacheImpl::Remove(InputOperation& inOp, IgniteError& err)
             {
                 return OutOp(OP_REMOVE_1, inOp, err);
             }
 
-            bool CacheImpl::RemoveIfEqual(InputOperation& inOp, IgniteError* err)
+            bool CacheImpl::RemoveIfEqual(InputOperation& inOp, IgniteError& err)
             {
                 return OutOp(OP_REMOVE_2, inOp, err);
             }
 
-            void CacheImpl::RemoveAll(InputOperation& inOp, IgniteError* err)
+            void CacheImpl::RemoveAll(InputOperation& inOp, IgniteError& err)
             {
                 OutOp(OP_REMOVE_ALL, inOp, err);
             }
 
-            void CacheImpl::RemoveAll(IgniteError* err)
+            void CacheImpl::RemoveAll(IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -280,29 +283,34 @@ namespace ignite
                 IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
             }
 
-            int32_t CacheImpl::Size(int32_t peekModes, bool local, IgniteError* err)
+            int32_t CacheImpl::Size(int32_t peekModes, bool local, IgniteError& err)
             {
                 int32_t op = local ? OP_SIZE_LOC : OP_SIZE;
 
                 return static_cast<int32_t>(OutInOpLong(op, peekModes, err));
             }
 
-            QueryCursorImpl* CacheImpl::QuerySql(const SqlQuery& qry, IgniteError* err)
+            QueryCursorImpl* CacheImpl::QuerySql(const SqlQuery& qry, IgniteError& err)
             {
                 return QueryInternal(qry, OP_QRY_SQL, err);
             }
 
-            QueryCursorImpl* CacheImpl::QueryText(const TextQuery& qry, IgniteError* err)
+            QueryCursorImpl* CacheImpl::QueryText(const TextQuery& qry, IgniteError& err)
             {
                 return QueryInternal(qry, OP_QRY_TEXT, err);
             }
 
-            QueryCursorImpl* CacheImpl::QueryScan(const ScanQuery& qry, IgniteError* err)
+            QueryCursorImpl* CacheImpl::QueryScan(const ScanQuery& qry, IgniteError& err)
             {
                 return QueryInternal(qry, OP_QRY_SCAN, err);
             }
 
-            QueryCursorImpl* CacheImpl::QuerySqlFields(const SqlFieldsQuery& qry, IgniteError* err)
+            void CacheImpl::Invoke(InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
+            {
+                OutInOpX(OP_INVOKE, inOp, outOp, err);
+            }
+
+            QueryCursorImpl* CacheImpl::QuerySqlFields(const SqlFieldsQuery& qry, IgniteError& err)
             {
                 return QueryInternal(qry, OP_QRY_SQL_FIELDS, err);
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp b/modules/platforms/cpp/core/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp
index 04e64c9..b2fa1fd 100644
--- a/modules/platforms/cpp/core/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp
@@ -75,7 +75,7 @@ namespace ignite
 
                         jobject res = env.Get()->Context()->TargetOutObject(javaRef, GET_INITIAL_QUERY, &jniErr);
 
-                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                         if (jniErr.code != IGNITE_JNI_ERR_SUCCESS)
                             return 0;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
index aaeb822..018bd99 100644
--- a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
@@ -178,7 +178,7 @@ namespace ignite
 
                     env.Get()->Context()->TargetOutStream(javaRef, OP_GET_ALL, inMem.Get()->PointerLong(), &jniErr);
 
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
                     {
@@ -201,7 +201,7 @@ namespace ignite
 
                     env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR, 0, &jniErr);
 
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
                         iterCalled = true;
@@ -228,7 +228,7 @@ namespace ignite
                     env.Get()->Context()->TargetOutStream(
                         javaRef, OP_GET_BATCH, inMem.Get()->PointerLong(), &jniErr);
 
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     if (jniErr.code != IGNITE_JNI_ERR_SUCCESS)
                         return false;
@@ -251,7 +251,7 @@ namespace ignite
 
                     bool res = env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR_HAS_NEXT, 0, &jniErr) == 1;
 
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
                         return res;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/cluster/cluster_group_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cluster/cluster_group_impl.cpp b/modules/platforms/cpp/core/src/impl/cluster/cluster_group_impl.cpp
new file mode 100644
index 0000000..d30c321
--- /dev/null
+++ b/modules/platforms/cpp/core/src/impl/cluster/cluster_group_impl.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#include "ignite/impl/cluster/cluster_group_impl.h"
+
+using namespace ignite::jni::java;
+using namespace ignite::impl::cluster;
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace cluster
+        {
+            enum Command
+            {
+                FOR_SERVERS = 23
+            };
+
+            ClusterGroupImpl::ClusterGroupImpl(SP_IgniteEnvironment env, jobject javaRef) :
+                InteropTarget(env, javaRef)
+            {
+                // No-op.
+            }
+
+            ClusterGroupImpl::~ClusterGroupImpl()
+            {
+                // No-op.
+            }
+
+            ClusterGroupImpl::SP_ClusterGroupImpl ClusterGroupImpl::ForServers(IgniteError& err)
+            {
+                JniErrorInfo jniErr;
+
+                jobject res = InOpObject(FOR_SERVERS, err);
+
+                if (jniErr.code != java::IGNITE_JNI_ERR_SUCCESS)
+                    return SP_ClusterGroupImpl();
+
+                return FromTarget(res);
+            }
+
+            ClusterGroupImpl::SP_ClusterGroupImpl ClusterGroupImpl::FromTarget(jobject javaRef)
+            {
+                return SP_ClusterGroupImpl(new ClusterGroupImpl(GetEnvironmentPointer(), javaRef));
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/ignite_environment.cpp b/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
index b058f7c..1a1c80f 100644
--- a/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
+++ b/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
@@ -21,6 +21,8 @@
 #include "ignite/cache/query/continuous/continuous_query.h"
 #include "ignite/binary/binary.h"
 #include "ignite/impl/binary/binary_type_updater_impl.h"
+#include "ignite/impl/module_manager.h"
+#include "ignite/ignite_binding.h"
 
 using namespace ignite::common::concurrent;
 using namespace ignite::jni::java;
@@ -29,15 +31,16 @@ using namespace ignite::impl::binary;
 using namespace ignite::binary;
 using namespace ignite::impl::cache::query::continuous;
 
-namespace ignite 
+namespace ignite
 {
     namespace impl
     {
         /**
-        * Callback codes.
-        */
+         * Callback codes.
+         */
         enum CallbackOp
         {
+            CACHE_INVOKE = 8,
             CONTINUOUS_QUERY_LISTENER_APPLY = 18,
             CONTINUOUS_QUERY_FILTER_RELEASE = 21,
             REALLOC = 36,
@@ -80,6 +83,15 @@ namespace ignite
                     break;
                 }
 
+                case CACHE_INVOKE:
+                {
+                    SharedPointer<InteropMemory> mem = env->Get()->GetMemory(val);
+
+                    env->Get()->CacheInvokeCallback(mem);
+
+                    break;
+                }
+
                 default:
                 {
                     break;
@@ -131,24 +143,33 @@ namespace ignite
             return 0;
         }
 
-        IgniteEnvironment::IgniteEnvironment() :
+        IgniteEnvironment::IgniteEnvironment(const IgniteConfiguration& cfg) :
+            cfg(new IgniteConfiguration(cfg)),
             ctx(SharedPointer<JniContext>()),
-            latch(new SingleLatch),
+            latch(),
             name(0),
             proc(),
+            registry(DEFAULT_FAST_PATH_CONTAINERS_CAP, DEFAULT_SLOW_PATH_CONTAINERS_CAP),
             metaMgr(new BinaryTypeManager()),
             metaUpdater(0),
-            registry(DEFAULT_FAST_PATH_CONTAINERS_CAP, DEFAULT_SLOW_PATH_CONTAINERS_CAP)
+            binding(new IgniteBindingImpl()),
+            moduleMgr(new ModuleManager(GetBindingContext()))
         {
             // No-op.
         }
 
         IgniteEnvironment::~IgniteEnvironment()
         {
-            delete latch;
-            delete name;
-            delete metaMgr;
+            delete[] name;
+
             delete metaUpdater;
+            delete metaMgr;
+            delete cfg;
+        }
+
+        const IgniteConfiguration& IgniteEnvironment::GetConfiguration() const
+        {
+            return *cfg;
         }
 
         JniHandlers IgniteEnvironment::GetJniHandlers(SharedPointer<IgniteEnvironment>* target)
@@ -172,11 +193,13 @@ namespace ignite
 
         void IgniteEnvironment::Initialize()
         {
-            latch->CountDown();
+            latch.CountDown();
 
             jobject binaryProc = Context()->ProcessorBinaryProcessor(proc.Get());
-
             metaUpdater = new BinaryTypeUpdaterImpl(*this, binaryProc);
+
+            common::dynamic::Module currentModule = common::dynamic::GetCurrent();
+            moduleMgr.Get()->RegisterModule(currentModule);
         }
 
         const char* IgniteEnvironment::InstanceName() const
@@ -184,6 +207,11 @@ namespace ignite
             return name;
         }
 
+        void* IgniteEnvironment::GetProcessor()
+        {
+            return (void*)proc.Get();
+        }
+
         JniContext* IgniteEnvironment::Context()
         {
             return ctx.Get();
@@ -233,6 +261,16 @@ namespace ignite
             return metaUpdater;
         }
 
+        IgniteBinding IgniteEnvironment::GetBinding() const
+        {
+            return IgniteBinding(binding);
+        }
+
+        IgniteBindingContext IgniteEnvironment::GetBindingContext() const
+        {
+            return IgniteBindingContext(*cfg, GetBinding());
+        }
+
         void IgniteEnvironment::ProcessorReleaseStart()
         {
             if (proc.Get())
@@ -280,10 +318,38 @@ namespace ignite
                 contQry->ReadAndProcessEvents(rawReader);
             }
         }
-    }
-}
 
+        void IgniteEnvironment::CacheInvokeCallback(SharedPointer<InteropMemory>& mem)
+        {
+            if (!binding.Get())
+                throw IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, "IgniteBinding is not initialized.");
+
+            InteropInputStream inStream(mem.Get());
+            BinaryReaderImpl reader(&inStream);
 
+            InteropOutputStream outStream(mem.Get());
+            BinaryWriterImpl writer(&outStream, GetTypeManager());
 
+            bool local = reader.ReadBool();
 
+            if (local)
+                throw IgniteError(IgniteError::IGNITE_ERR_UNSUPPORTED_OPERATION, "Local invokation is not supported.");
 
+            BinaryObjectImpl binProcHolder = BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position());
+            BinaryObjectImpl binProc = binProcHolder.GetField(0);
+
+            int64_t procId = binProc.GetTypeId();
+
+            bool invoked = binding.Get()->InvokeCallbackById(procId, reader, writer);
+
+            if (!invoked)
+            {
+                IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION,
+                    "C++ entry processor is not registered on the node (did you compile your program without -rdynamic?).",
+                    "procId", procId);
+            }
+
+            outStream.Synchronize();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/ignite_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/ignite_impl.cpp b/modules/platforms/cpp/core/src/impl/ignite_impl.cpp
index fdc1008..fd9bf45 100644
--- a/modules/platforms/cpp/core/src/impl/ignite_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/ignite_impl.cpp
@@ -33,6 +33,10 @@ namespace ignite
             txImpl = InternalGetTransactions(err);
 
             IgniteError::ThrowIfNeeded(err);
+
+            prjImpl = InternalGetProjection(err);
+
+            IgniteError::ThrowIfNeeded(err);
         }
 
         IgniteImpl::~IgniteImpl()
@@ -45,11 +49,21 @@ namespace ignite
             return env.Get()->InstanceName();
         }
 
+        const IgniteConfiguration& IgniteImpl::GetConfiguration() const
+        {
+            return env.Get()->GetConfiguration();
+        }
+
         JniContext* IgniteImpl::GetContext()
         {
             return env.Get()->Context();
         }
 
+        IgniteBinding IgniteImpl::GetBinding()
+        {
+            return env.Get()->GetBinding();
+        }
+
         IgniteImpl::SP_TransactionsImpl IgniteImpl::InternalGetTransactions(IgniteError &err)
         {
             SP_TransactionsImpl res;
@@ -61,7 +75,23 @@ namespace ignite
             if (txJavaRef)
                 res = SP_TransactionsImpl(new transactions::TransactionsImpl(env, txJavaRef));
             else
-                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+
+            return res;
+        }
+
+        IgniteImpl::SP_ClusterGroupImpl IgniteImpl::InternalGetProjection(IgniteError& err)
+        {
+            SP_ClusterGroupImpl res;
+
+            JniErrorInfo jniErr;
+
+            jobject txJavaRef = env.Get()->Context()->ProcessorProjection(javaRef, &jniErr);
+
+            if (txJavaRef)
+                res = SP_ClusterGroupImpl(new cluster::ClusterGroupImpl(env, txJavaRef));
+            else
+                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
             return res;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp b/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
index 4992ccb..0133894 100644
--- a/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
+++ b/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
@@ -57,7 +57,7 @@ namespace ignite
                 JniContext::Release(javaRef);
             }
 
-            int64_t InteropTarget::WriteTo(InteropMemory* mem, InputOperation& inOp, IgniteError* err)
+            int64_t InteropTarget::WriteTo(InteropMemory* mem, InputOperation& inOp, IgniteError& err)
             {
                 BinaryTypeManager* metaMgr = env.Get()->GetTypeManager();
 
@@ -72,7 +72,7 @@ namespace ignite
 
                 if (metaMgr->IsUpdatedSince(metaVer))
                 {
-                    if (!metaMgr->ProcessPendingUpdates(env.Get()->GetTypeUpdater(), err))
+                    if (!metaMgr->ProcessPendingUpdates(env.Get()->GetTypeUpdater(), &err))
                         return 0;
                 }
 
@@ -82,13 +82,25 @@ namespace ignite
             void InteropTarget::ReadFrom(InteropMemory* mem, OutputOperation& outOp)
             {
                 InteropInputStream in(mem);
-
                 BinaryReaderImpl reader(&in);
 
                 outOp.ProcessOutput(reader);
             }
 
-            bool InteropTarget::OutOp(int32_t opType, InputOperation& inOp, IgniteError* err)
+            void InteropTarget::ReadError(InteropMemory* mem, IgniteError& err)
+            {
+                InteropInputStream in(mem);
+                BinaryReaderImpl reader(&in);
+
+                // Reading and skipping error class name.
+                reader.ReadObject<std::string>();
+
+                std::string msg = reader.ReadObject<std::string>();
+
+                err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, msg.c_str());
+            }
+
+            bool InteropTarget::OutOp(int32_t opType, InputOperation& inOp, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -109,7 +121,7 @@ namespace ignite
                 return false;
             }
 
-            bool InteropTarget::OutOp(int32_t opType, IgniteError* err)
+            bool InteropTarget::OutOp(int32_t opType, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -123,7 +135,7 @@ namespace ignite
                 return false;
             }
 
-            bool InteropTarget::InOp(int32_t opType, OutputOperation& outOp, IgniteError* err)
+            bool InteropTarget::InOp(int32_t opType, OutputOperation& outOp, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -143,7 +155,18 @@ namespace ignite
                 return false;
             }
 
-            void InteropTarget::OutInOp(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            jobject InteropTarget::InOpObject(int32_t opType, IgniteError& err)
+            {
+                JniErrorInfo jniErr;
+
+                jobject res = env.Get()->Context()->TargetOutObject(javaRef, opType, &jniErr);
+
+                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+
+                return res;
+            }
+
+            void InteropTarget::OutInOp(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -164,7 +187,7 @@ namespace ignite
                 }
             }
 
-            void InteropTarget::OutInOpX(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError* err)
+            void InteropTarget::OutInOpX(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -182,12 +205,14 @@ namespace ignite
                         ReadFrom(outInMem.Get(), outOp);
                     else if (res == ResultNull)
                         outOp.SetNull();
-
-                    //Read and process error if res == ResultError here.
+                    else if (res == ResultError)
+                        ReadError(outInMem.Get(), err);
+                    else
+                        assert(false);
                 }
             }
 
-            int64_t InteropTarget::OutInOpLong(int32_t opType, int64_t val, IgniteError* err)
+            int64_t InteropTarget::OutInOpLong(int32_t opType, int64_t val, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
@@ -199,4 +224,4 @@ namespace ignite
             }
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/src/impl/transactions/transactions_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/transactions/transactions_impl.cpp b/modules/platforms/cpp/core/src/impl/transactions/transactions_impl.cpp
index 9f43dad..79f58c5 100644
--- a/modules/platforms/cpp/core/src/impl/transactions/transactions_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/transactions/transactions_impl.cpp
@@ -148,7 +148,7 @@ namespace ignite
                 InTransactionStartOperation inOp(concurrency, isolation, timeout, txSize);
                 OutTransactionStartOperation outOp;
 
-                OutInOp(OP_START, inOp, outOp, &err);
+                OutInOp(OP_START, inOp, outOp, err);
 
                 return outOp.Get();
             }
@@ -157,7 +157,7 @@ namespace ignite
             {
                 JniErrorInfo jniErr;
 
-                int state = static_cast<int>(OutInOpLong(OP_COMMIT, id, &err));
+                int state = static_cast<int>(OutInOpLong(OP_COMMIT, id, err));
 
                 return ToTransactionState(state);
             }
@@ -166,7 +166,7 @@ namespace ignite
             {
                 JniErrorInfo jniErr;
 
-                int state = static_cast<int>(OutInOpLong(OP_ROLLBACK, id, &err));
+                int state = static_cast<int>(OutInOpLong(OP_ROLLBACK, id, err));
 
                 return ToTransactionState(state);
             }
@@ -175,7 +175,7 @@ namespace ignite
             {
                 JniErrorInfo jniErr;
 
-                int state = static_cast<int>(OutInOpLong(OP_CLOSE, id, &err));
+                int state = static_cast<int>(OutInOpLong(OP_CLOSE, id, err));
 
                 return ToTransactionState(state);
             }
@@ -184,7 +184,7 @@ namespace ignite
             {
                 JniErrorInfo jniErr;
 
-                bool rollbackOnly = OutInOpLong(OP_SET_ROLLBACK_ONLY, id, &err) == 1;
+                bool rollbackOnly = OutInOpLong(OP_SET_ROLLBACK_ONLY, id, err) == 1;
 
                 return rollbackOnly;
             }
@@ -193,7 +193,7 @@ namespace ignite
             {
                 JniErrorInfo jniErr;
 
-                int state = static_cast<int>(OutInOpLong(OP_STATE, id, &err));
+                int state = static_cast<int>(OutInOpLong(OP_STATE, id, err));
 
                 return ToTransactionState(state);
             }
@@ -248,7 +248,7 @@ namespace ignite
             {
                 OutTransactionMetricsOperation op;
 
-                InOp(OP_METRICS, op, &err);
+                InOp(OP_METRICS, op, err);
 
                 if (err.GetCode() == IgniteError::IGNITE_SUCCESS)
                     return op.Get();

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/jni/include/ignite/jni/java.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/include/ignite/jni/java.h b/modules/platforms/cpp/jni/include/ignite/jni/java.h
index b790db5..a07b844 100644
--- a/modules/platforms/cpp/jni/include/ignite/jni/java.h
+++ b/modules/platforms/cpp/jni/include/ignite/jni/java.h
@@ -347,7 +347,7 @@ namespace ignite
                 void IgnitionStopAll(bool cancel, JniErrorInfo* errInfo);
                 
                 void ProcessorReleaseStart(jobject obj);
-                jobject ProcessorProjection(jobject obj);
+                jobject ProcessorProjection(jobject obj, JniErrorInfo* errInfo = NULL);
                 jobject ProcessorCache(jobject obj, const char* name);
                 jobject ProcessorCache(jobject obj, const char* name, JniErrorInfo* errInfo);
                 jobject ProcessorCreateCache(jobject obj, const char* name);


[11/50] [abbrv] ignite git commit: IGNITE-4472 Added user activities in Web Console.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/Demo/Demo.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/Demo/Demo.module.js b/modules/web-console/frontend/app/modules/Demo/Demo.module.js
deleted file mode 100644
index a3700ca..0000000
--- a/modules/web-console/frontend/app/modules/Demo/Demo.module.js
+++ /dev/null
@@ -1,166 +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.
- */
-
-import angular from 'angular';
-
-import DEMO_INFO from 'app/data/demo-info.json';
-
-angular
-.module('ignite-console.demo', [
-    'ignite-console.socket'
-])
-.config(['$stateProvider', ($stateProvider) => {
-    $stateProvider
-        .state('demo', {
-            abstract: true,
-            template: '<ui-view></ui-view>'
-        })
-        .state('demo.resume', {
-            url: '/demo',
-            controller: ['$state', ($state) => {
-                $state.go('base.configuration.clusters');
-            }],
-            metaTags: {
-            }
-        })
-        .state('demo.reset', {
-            url: '/demo/reset',
-            controller: ['$state', '$http', 'IgniteMessages', ($state, $http, Messages) => {
-                $http.post('/api/v1/demo/reset')
-                    .then(() => $state.go('base.configuration.clusters'))
-                    .catch((res) => {
-                        $state.go('base.configuration.clusters');
-
-                        Messages.showError(res);
-                    });
-            }],
-            metaTags: {}
-        });
-}])
-.provider('Demo', ['$stateProvider', '$httpProvider', 'igniteSocketFactoryProvider', function($state, $http, socketFactory) {
-    if (/(\/demo.*)/ig.test(location.pathname))
-        sessionStorage.setItem('IgniteDemoMode', 'true');
-
-    const enabled = sessionStorage.getItem('IgniteDemoMode') === 'true';
-
-    if (enabled) {
-        socketFactory.set({query: 'IgniteDemoMode=true'});
-
-        $http.interceptors.push('demoInterceptor');
-    }
-
-    this.$get = ['$rootScope', ($root) => {
-        $root.IgniteDemoMode = enabled;
-
-        return {enabled};
-    }];
-}])
-.factory('demoInterceptor', ['Demo', (Demo) => {
-    const isApiRequest = (url) => /\/api\/v1/ig.test(url);
-
-    return {
-        request(cfg) {
-            if (Demo.enabled && isApiRequest(cfg.url))
-                cfg.headers.IgniteDemoMode = true;
-
-            return cfg;
-        }
-    };
-}])
-.controller('demoController', ['$scope', '$state', '$window', 'IgniteConfirm', ($scope, $state, $window, Confirm) => {
-    const _openTab = (stateName) => $window.open($state.href(stateName), '_blank');
-
-    $scope.startDemo = () => {
-        if (!$scope.user.demoCreated)
-            return _openTab('demo.reset');
-
-        Confirm.confirm('Would you like to continue with previous demo session?', true, false)
-            .then((resume) => {
-                if (resume)
-                    return _openTab('demo.resume');
-
-                _openTab('demo.reset');
-            });
-    };
-
-    $scope.closeDemo = () => {
-        $window.close();
-    };
-}])
-.provider('igniteDemoInfo', [function() {
-    const items = DEMO_INFO;
-
-    this.update = (data) => items[0] = data;
-
-    this.$get = [() => {
-        return items;
-    }];
-}])
-.service('DemoInfo', ['$rootScope', '$modal', '$state', '$q', 'igniteDemoInfo', 'IgniteAgentMonitor', ($rootScope, $modal, $state, $q, igniteDemoInfo, agentMonitor) => {
-    const scope = $rootScope.$new();
-
-    let closePromise = null;
-
-    function _fillPage() {
-        const model = igniteDemoInfo;
-
-        scope.title = model[0].title;
-        scope.message = model[0].message.join(' ');
-    }
-
-    const dialog = $modal({
-        templateUrl: '/templates/demo-info.html',
-        scope,
-        placement: 'center',
-        show: false,
-        backdrop: 'static'
-    });
-
-    scope.close = () => {
-        dialog.hide();
-
-        closePromise && closePromise.resolve();
-    };
-
-    scope.downloadAgent = () => {
-        const lnk = document.createElement('a');
-
-        lnk.setAttribute('href', '/api/v1/agent/download/zip');
-        lnk.setAttribute('target', '_self');
-        lnk.setAttribute('download', null);
-        lnk.style.display = 'none';
-
-        document.body.appendChild(lnk);
-
-        lnk.click();
-
-        document.body.removeChild(lnk);
-    };
-
-    return {
-        show: () => {
-            closePromise = $q.defer();
-
-            _fillPage();
-
-            return dialog.$promise
-                .then(dialog.show)
-                .then(() => Promise.race([agentMonitor.awaitAgent(), closePromise.promise]))
-                .then(() => scope.hasAgents = true);
-        }
-    };
-}]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/demo/Demo.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/demo/Demo.module.js b/modules/web-console/frontend/app/modules/demo/Demo.module.js
new file mode 100644
index 0000000..bd759df
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/demo/Demo.module.js
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+import DEMO_INFO from 'app/data/demo-info.json';
+
+angular
+.module('ignite-console.demo', [
+    'ignite-console.socket'
+])
+.config(['$stateProvider', 'AclRouteProvider', ($stateProvider, AclRoute) => {
+    $stateProvider
+        .state('demo', {
+            abstract: true,
+            url: '/demo',
+            template: '<ui-view></ui-view>'
+        })
+        .state('demo.resume', {
+            url: '/resume',
+            onEnter: AclRoute.checkAccess('demo'),
+            controller: ['$state', ($state) => {
+                $state.go('base.configuration.clusters');
+            }],
+            metaTags: {
+                title: 'Demo resume'
+            }
+        })
+        .state('demo.reset', {
+            url: '/reset',
+            onEnter: AclRoute.checkAccess('demo'),
+            controller: ['$state', '$http', 'IgniteMessages', ($state, $http, Messages) => {
+                $http.post('/api/v1/demo/reset')
+                    .then(() => $state.go('base.configuration.clusters'))
+                    .catch((res) => {
+                        $state.go('base.configuration.clusters');
+
+                        Messages.showError(res);
+                    });
+            }],
+            metaTags: {
+                title: 'Demo reset'
+            }
+        });
+}])
+.provider('Demo', ['$stateProvider', '$httpProvider', 'igniteSocketFactoryProvider', function($state, $http, socketFactory) {
+    if (/(\/demo.*)/ig.test(location.pathname))
+        sessionStorage.setItem('IgniteDemoMode', 'true');
+
+    const enabled = sessionStorage.getItem('IgniteDemoMode') === 'true';
+
+    if (enabled) {
+        socketFactory.set({query: 'IgniteDemoMode=true'});
+
+        $http.interceptors.push('demoInterceptor');
+    }
+
+    this.$get = ['$rootScope', ($root) => {
+        $root.IgniteDemoMode = enabled;
+
+        return {enabled};
+    }];
+}])
+.factory('demoInterceptor', ['Demo', (Demo) => {
+    const isApiRequest = (url) => /\/api\/v1/ig.test(url);
+
+    return {
+        request(cfg) {
+            if (Demo.enabled && isApiRequest(cfg.url))
+                cfg.headers.IgniteDemoMode = true;
+
+            return cfg;
+        }
+    };
+}])
+.controller('demoController', ['$scope', '$state', '$window', 'IgniteConfirm', ($scope, $state, $window, Confirm) => {
+    const _openTab = (stateName) => $window.open($state.href(stateName), '_blank');
+
+    $scope.startDemo = () => {
+        if (!$scope.user.demoCreated)
+            return _openTab('demo.reset');
+
+        Confirm.confirm('Would you like to continue with previous demo session?', true, false)
+            .then((resume) => {
+                if (resume)
+                    return _openTab('demo.resume');
+
+                _openTab('demo.reset');
+            });
+    };
+
+    $scope.closeDemo = () => {
+        $window.close();
+    };
+}])
+.provider('igniteDemoInfo', [function() {
+    const items = DEMO_INFO;
+
+    this.update = (data) => items[0] = data;
+
+    this.$get = [() => {
+        return items;
+    }];
+}])
+.service('DemoInfo', ['$rootScope', '$modal', '$state', '$q', 'igniteDemoInfo', 'IgniteAgentMonitor', ($rootScope, $modal, $state, $q, igniteDemoInfo, agentMonitor) => {
+    const scope = $rootScope.$new();
+
+    let closePromise = null;
+
+    function _fillPage() {
+        const model = igniteDemoInfo;
+
+        scope.title = model[0].title;
+        scope.message = model[0].message.join(' ');
+    }
+
+    const dialog = $modal({
+        templateUrl: '/templates/demo-info.html',
+        scope,
+        placement: 'center',
+        show: false,
+        backdrop: 'static'
+    });
+
+    scope.close = () => {
+        dialog.hide();
+
+        closePromise && closePromise.resolve();
+    };
+
+    scope.downloadAgent = () => {
+        const lnk = document.createElement('a');
+
+        lnk.setAttribute('href', '/api/v1/agent/download/zip');
+        lnk.setAttribute('target', '_self');
+        lnk.setAttribute('download', null);
+        lnk.style.display = 'none';
+
+        document.body.appendChild(lnk);
+
+        lnk.click();
+
+        document.body.removeChild(lnk);
+    };
+
+    return {
+        show: () => {
+            closePromise = $q.defer();
+
+            _fillPage();
+
+            return dialog.$promise
+                .then(dialog.show)
+                .then(() => Promise.race([agentMonitor.awaitAgent(), closePromise.promise]))
+                .then(() => scope.hasAgents = true);
+        }
+    };
+}]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/sql/sql.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js
index 0d0b171..4e972ef 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.controller.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js
@@ -186,8 +186,8 @@ class Paragraph {
 }
 
 // Controller for SQL notebook screen.
-export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', '$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteAgentMonitor', 'IgniteChartColors', 'IgniteNotebook', 'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion',
-    function($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, LegacyUtils, Messages, Confirm, agentMonitor, IgniteChartColors, Notebook, Nodes, uiGridExporterConstants, Version) {
+export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', '$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteAgentMonitor', 'IgniteChartColors', 'IgniteNotebook', 'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion', 'IgniteActivitiesData',
+    function($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, LegacyUtils, Messages, Confirm, agentMonitor, IgniteChartColors, Notebook, Nodes, uiGridExporterConstants, Version, ActivitiesData) {
         let stopTopology = null;
 
         const _tryStopRefresh = function(paragraph) {
@@ -965,6 +965,8 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
         $scope.addQuery = function() {
             const sz = $scope.notebook.paragraphs.length;
 
+            ActivitiesData.post({ action: '/queries/add/query' });
+
             const paragraph = new Paragraph($animate, $timeout, {
                 name: 'Query' + (sz === 0 ? '' : sz),
                 query: '',
@@ -991,6 +993,8 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
         $scope.addScan = function() {
             const sz = $scope.notebook.paragraphs.length;
 
+            ActivitiesData.post({ action: '/queries/add/scan' });
+
             const paragraph = new Paragraph($animate, $timeout, {
                 name: 'Scan' + (sz === 0 ? '' : sz),
                 query: '',
@@ -1379,6 +1383,8 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
 
                             const qry = args.maxPages ? addLimit(args.query, args.pageSize * args.maxPages) : paragraph.query;
 
+                            ActivitiesData.post({ action: '/queries/execute' });
+
                             return agentMonitor.query(nid, args.cacheName, qry, nonCollocatedJoins, local, args.pageSize);
                         })
                         .then((res) => {
@@ -1430,6 +1436,8 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
                         pageSize: paragraph.pageSize
                     };
 
+                    ActivitiesData.post({ action: '/queries/explain' });
+
                     return agentMonitor.query(nid, args.cacheName, args.query, false, false, args.pageSize);
                 })
                 .then(_processQueryResult.bind(this, paragraph, true))
@@ -1466,6 +1474,8 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
                                 localNid: local ? nid : null
                             };
 
+                            ActivitiesData.post({ action: '/queries/scan' });
+
                             return agentMonitor.query(nid, args.cacheName, query, false, local, args.pageSize);
                         })
                         .then((res) => _processQueryResult(paragraph, true, res))

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/sql/sql.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.module.js b/modules/web-console/frontend/app/modules/sql/sql.module.js
index a1ffde9..5875961 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.module.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.module.js
@@ -30,7 +30,7 @@ angular.module('ignite-console.sql', [
             // set up the states
             $stateProvider
                 .state('base.sql', {
-                    url: '/sql',
+                    url: '/queries',
                     abstract: true,
                     template: '<ui-view></ui-view>'
                 })

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/states/admin.state.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/admin.state.js b/modules/web-console/frontend/app/modules/states/admin.state.js
index c3151e1..35c6fbb 100644
--- a/modules/web-console/frontend/app/modules/states/admin.state.js
+++ b/modules/web-console/frontend/app/modules/states/admin.state.js
@@ -29,7 +29,7 @@ angular
         templateUrl: '/settings/admin.html',
         onEnter: AclRoute.checkAccess('admin_page'),
         metaTags: {
-            title: 'List of registered users'
+            title: 'Admin panel'
         }
     });
 }]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
index cfc6df9..16d2fae 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
+++ b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
@@ -21,8 +21,8 @@ import saver from 'file-saver';
 const escapeFileName = (name) => name.replace(/[\\\/*\"\[\],\.:;|=<>?]/g, '-').replace(/ /g, '_');
 
 export default [
-    '$rootScope', '$scope', '$http', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteLoading', '$filter', 'IgniteConfigurationResource', 'JavaTypes', 'IgniteVersion', 'IgniteConfigurationGenerator', 'SpringTransformer', 'JavaTransformer', 'IgniteDockerGenerator', 'IgniteMavenGenerator', 'IgnitePropertiesGenerator', 'IgniteReadmeGenerator', 'IgniteFormUtils', 'IgniteSummaryZipper',
-    function($root, $scope, $http, LegacyUtils, Messages, Loading, $filter, Resource, JavaTypes, Version, generator, spring, java, docker, pom, propsGenerator, readme, FormUtils, SummaryZipper) {
+    '$rootScope', '$scope', '$http', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteLoading', '$filter', 'IgniteConfigurationResource', 'JavaTypes', 'IgniteVersion', 'IgniteConfigurationGenerator', 'SpringTransformer', 'JavaTransformer', 'IgniteDockerGenerator', 'IgniteMavenGenerator', 'IgnitePropertiesGenerator', 'IgniteReadmeGenerator', 'IgniteFormUtils', 'IgniteSummaryZipper', 'IgniteActivitiesData',
+    function($root, $scope, $http, LegacyUtils, Messages, Loading, $filter, Resource, JavaTypes, Version, generator, spring, java, docker, pom, propsGenerator, readme, FormUtils, SummaryZipper, ActivitiesData) {
         const ctrl = this;
 
         $scope.ui = {
@@ -304,6 +304,8 @@ export default [
 
             $scope.isPrepareDownloading = true;
 
+            ActivitiesData.post({ action: '/configuration/download' });
+
             return new SummaryZipper({ cluster, data: ctrl.data || {}, IgniteDemoMode: $root.IgniteDemoMode })
                 .then((data) => {
                     saver.saveAs(data, escapeFileName(cluster.name) + '-project.zip');

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/user/AclRoute.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/user/AclRoute.provider.js b/modules/web-console/frontend/app/modules/user/AclRoute.provider.js
index 40abea5..4225bc4 100644
--- a/modules/web-console/frontend/app/modules/user/AclRoute.provider.js
+++ b/modules/web-console/frontend/app/modules/user/AclRoute.provider.js
@@ -17,31 +17,36 @@
 
 export default [() => {
     class AclRoute {
-        static checkAccess = (permissions, failState) => {
+        static checkAccess(permissions, failState) {
             failState = failState || '403';
 
-            return ['$state', 'AclService', 'User', ($state, AclService, User) => {
-                User.read()
-                    .then(() => {
-                        if (AclService.can(permissions))
-                            return;
+            return ['$q', '$state', 'AclService', 'User', 'IgniteActivitiesData', function($q, $state, AclService, User, Activities) {
+                const action = this.name ? $state.href(this.name) : null;
 
-                        return $state.go(failState);
-                    })
+                return User.read()
                     .catch(() => {
                         User.clean();
 
                         if ($state.current.name !== 'signin')
                             $state.go('signin');
+
+                        return $q.reject('Failed to detect user');
+                    })
+                    .then(() => {
+                        if (AclService.can(permissions))
+                            return Activities.post({ action });
+
+                        $state.go(failState);
+
+                        return $q.reject('User are not authorized');
                     });
             }];
         }
-    }
 
-    return {
-        checkAccess: AclRoute.checkAccess,
-        $get: () => {
+        static $get() {
             return AclRoute;
         }
-    };
+    }
+
+    return AclRoute;
 }];

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/user/Auth.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/user/Auth.service.js b/modules/web-console/frontend/app/modules/user/Auth.service.js
index e0f905d..95ff4c3 100644
--- a/modules/web-console/frontend/app/modules/user/Auth.service.js
+++ b/modules/web-console/frontend/app/modules/user/Auth.service.js
@@ -21,7 +21,7 @@ export default ['Auth', ['$http', '$rootScope', '$state', '$window', 'IgniteErro
             forgotPassword(userInfo) {
                 $http.post('/api/v1/password/forgot', userInfo)
                     .then(() => $state.go('password.send'))
-                    .cacth(({data}) => ErrorPopover.show('forgot_email', Messages.errorMessage(null, data)));
+                    .catch(({data}) => ErrorPopover.show('forgot_email', Messages.errorMessage(null, data)));
             },
             auth(action, userInfo) {
                 $http.post('/api/v1/' + action, userInfo)

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/user/permissions.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/user/permissions.js b/modules/web-console/frontend/app/modules/user/permissions.js
index e13509c..b6f7c3a 100644
--- a/modules/web-console/frontend/app/modules/user/permissions.js
+++ b/modules/web-console/frontend/app/modules/user/permissions.js
@@ -16,7 +16,7 @@
  */
 
 const guest = ['login'];
-const becomed = ['profile', 'configuration', 'query'];
+const becomed = ['profile', 'configuration', 'query', 'demo'];
 const user = becomed.concat(['logout']);
 const admin = user.concat(['admin_page']);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/modules/user/user.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/user/user.module.js b/modules/web-console/frontend/app/modules/user/user.module.js
index 11798d0..b86a62e 100644
--- a/modules/web-console/frontend/app/modules/user/user.module.js
+++ b/modules/web-console/frontend/app/modules/user/user.module.js
@@ -22,10 +22,10 @@ import Auth from './Auth.service';
 import User from './User.service';
 import AclRouteProvider from './AclRoute.provider';
 
-angular
-.module('ignite-console.user', [
+angular.module('ignite-console.user', [
     'mm.acl',
-    'ignite-console.config'
+    'ignite-console.config',
+    'ignite-console.core'
 ])
 .factory('sessionRecoverer', ['$injector', '$q', ($injector, $q) => {
     return {

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/vendor.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/vendor.js b/modules/web-console/frontend/app/vendor.js
index a9e8844..3bbb322 100644
--- a/modules/web-console/frontend/app/vendor.js
+++ b/modules/web-console/frontend/app/vendor.js
@@ -25,6 +25,7 @@ import 'angular-strap/dist/angular-strap.tpl';
 import 'angular-socket-io';
 import 'angular-retina';
 import 'angular-ui-router';
+import 'angular-translate';
 import 'ui-router-metatags/dist/ui-router-metatags';
 import 'angular-smart-table';
 import 'angular-ui-grid/ui-grid';

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/controllers/admin-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/admin-controller.js b/modules/web-console/frontend/controllers/admin-controller.js
deleted file mode 100644
index cf7fd71..0000000
--- a/modules/web-console/frontend/controllers/admin-controller.js
+++ /dev/null
@@ -1,234 +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.
- */
-
-const ICON_SORT = '<span ui-grid-one-bind-id-grid="col.uid + \'-sortdir-text\'" ui-grid-visible="col.sort.direction" aria-label="Sort Descending"><i ng-class="{ \'ui-grid-icon-up-dir\': col.sort.direction == asc, \'ui-grid-icon-down-dir\': col.sort.direction == desc, \'ui-grid-icon-blank\': !col.sort.direction }" title="" aria-hidden="true"></i></span>';
-
-const CLUSTER_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-sitemap'></i>${ICON_SORT}</div>`;
-const MODEL_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-object-group'></i>${ICON_SORT}</div>`;
-const CACHE_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-database'></i>${ICON_SORT}</div>`;
-const IGFS_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-folder-o'></i>${ICON_SORT}</div>`;
-
-const ACTIONS_TEMPLATE = `
-<div class='text-center ui-grid-cell-actions'>
-    <a class='btn btn-default dropdown-toggle' bs-dropdown='' ng-show='row.entity._id != $root.user._id' data-placement='bottom-right' data-container='.panel'>
-        <i class='fa fa-gear'></i>&nbsp;
-        <span class='caret'></span>
-    </a>
-    <ul class='dropdown-menu' role='menu'>
-        <li>
-            <a ng-click='grid.api.becomeUser(row.entity)'>Become this user</a>
-        </li>
-        <li>
-            <a ng-click='grid.api.toggleAdmin(row.entity)' ng-if='row.entity.admin && row.entity._id !== $root.user._id'>Revoke admin</a>
-            <a ng-click='grid.api.toggleAdmin(row.entity)' ng-if='!row.entity.admin && row.entity._id !== $root.user._id'>Grant admin</a>
-        </li>
-        <li>
-            <a ng-click='grid.api.removeUser(row.entity)'>Remove user</a>
-        </li>
-</div>`;
-
-const EMAIL_TEMPLATE = '<div class="ui-grid-cell-contents"><a ng-href="mailto:{{ COL_FIELD }}">{{ COL_FIELD }}</a></div>';
-
-// Controller for Admin screen.
-export default ['adminController', [
-    '$rootScope', '$scope', '$http', '$q', '$state', '$filter', 'uiGridConstants', 'IgniteMessages', 'IgniteConfirm', 'User', 'IgniteNotebookData', 'IgniteCountries',
-    ($rootScope, $scope, $http, $q, $state, $filter, uiGridConstants, Messages, Confirm, User, Notebook, Countries) => {
-        $scope.users = null;
-
-        const companySelectOptions = [];
-        const countrySelectOptions = [];
-
-        const COLUMNS_DEFS = [
-            {displayName: 'Actions', cellTemplate: ACTIONS_TEMPLATE, field: 'test', minWidth: 80, width: 80, enableFiltering: false, enableSorting: false},
-            {displayName: 'User', field: 'userName', minWidth: 65, enableFiltering: true, filter: { placeholder: 'Filter by name...' }},
-            {displayName: 'Email', field: 'email', cellTemplate: EMAIL_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by email...' }},
-            {displayName: 'Company', field: 'company', minWidth: 160, filter: {
-                selectOptions: companySelectOptions, type: uiGridConstants.filter.SELECT, condition: uiGridConstants.filter.EXACT }
-            },
-            {displayName: 'Country', field: 'countryCode', minWidth: 80, filter: {
-                selectOptions: countrySelectOptions, type: uiGridConstants.filter.SELECT, condition: uiGridConstants.filter.EXACT }
-            },
-            {displayName: 'Last login', field: 'lastLogin', cellFilter: 'date:"medium"', minWidth: 175, width: 175, enableFiltering: false, sort: { direction: 'desc', priority: 0 }},
-            {displayName: 'Clusters count', headerCellTemplate: CLUSTER_HEADER_TEMPLATE, field: '_clusters', type: 'number', headerTooltip: 'Clusters count', minWidth: 50, width: 50, enableFiltering: false},
-            {displayName: 'Models count', headerCellTemplate: MODEL_HEADER_TEMPLATE, field: '_models', type: 'number', headerTooltip: 'Models count', minWidth: 50, width: 50, enableFiltering: false},
-            {displayName: 'Caches count', headerCellTemplate: CACHE_HEADER_TEMPLATE, field: '_caches', type: 'number', headerTooltip: 'Caches count', minWidth: 50, width: 50, enableFiltering: false},
-            {displayName: 'IGFS count', headerCellTemplate: IGFS_HEADER_TEMPLATE, field: '_igfs', type: 'number', headerTooltip: 'IGFS count', minWidth: 50, width: 50, enableFiltering: false}
-        ];
-
-        const ctrl = $scope.ctrl = {};
-
-        const becomeUser = function(user) {
-            $http.get('/api/v1/admin/become', { params: {viewedUserId: user._id}})
-                .then(() => User.load())
-                .then(() => $state.go('base.configuration.clusters'))
-                .then(() => Notebook.load())
-                .catch(Messages.showError);
-        };
-
-        const removeUser = (user) => {
-            Confirm.confirm(`Are you sure you want to remove user: "${user.userName}"?`)
-                .then(() => {
-                    $http.post('/api/v1/admin/remove', {userId: user._id})
-                        .then(() => {
-                            const i = _.findIndex($scope.users, (u) => u._id === user._id);
-
-                            if (i >= 0)
-                                $scope.users.splice(i, 1);
-
-                            Messages.showInfo(`User has been removed: "${user.userName}"`);
-                        })
-                        .catch(({data, status}) => {
-                            if (status === 503)
-                                Messages.showInfo(data);
-                            else
-                                Messages.showError('Failed to remove user: ', data);
-                        });
-                });
-        };
-
-        const toggleAdmin = (user) => {
-            if (user.adminChanging)
-                return;
-
-            user.adminChanging = true;
-
-            $http.post('/api/v1/admin/save', {userId: user._id, adminFlag: !user.admin})
-                .then(() => {
-                    user.admin = !user.admin;
-
-                    Messages.showInfo(`Admin right was successfully toggled for user: "${user.userName}"`);
-                })
-                .catch((res) => {
-                    Messages.showError('Failed to toggle admin right for user: ', res);
-                })
-                .finally(() => user.adminChanging = false);
-        };
-
-
-        ctrl.gridOptions = {
-            data: [],
-            columnVirtualizationThreshold: 30,
-            columnDefs: COLUMNS_DEFS,
-            categories: [
-                {name: 'Actions', visible: true, selectable: true},
-                {name: 'User', visible: true, selectable: true},
-                {name: 'Email', visible: true, selectable: true},
-                {name: 'Company', visible: true, selectable: true},
-                {name: 'Country', visible: true, selectable: true},
-                {name: 'Last login', visible: true, selectable: true},
-
-                {name: 'Clusters count', visible: true, selectable: true},
-                {name: 'Models count', visible: true, selectable: true},
-                {name: 'Caches count', visible: true, selectable: true},
-                {name: 'IGFS count', visible: true, selectable: true}
-            ],
-            enableFiltering: true,
-            enableRowSelection: false,
-            enableRowHeaderSelection: false,
-            enableColumnMenus: false,
-            multiSelect: false,
-            modifierKeysToMultiSelect: true,
-            noUnselect: true,
-            flatEntityAccess: true,
-            fastWatch: true,
-            onRegisterApi: (api) => {
-                ctrl.gridApi = api;
-
-                api.becomeUser = becomeUser;
-                api.removeUser = removeUser;
-                api.toggleAdmin = toggleAdmin;
-            }
-        };
-
-        /**
-         * Set grid height.
-         *
-         * @param {Number} rows Rows count.
-         * @private
-         */
-        const adjustHeight = (rows) => {
-            const height = Math.min(rows, 20) * 30 + 75;
-
-            // Remove header height.
-            ctrl.gridApi.grid.element.css('height', height + 'px');
-
-            ctrl.gridApi.core.handleWindowResize();
-        };
-
-        const usersToFilterOptions = (column) => {
-            return _.sortBy(
-                _.map(
-                    _.groupBy($scope.users, (usr) => {
-                        const fld = usr[column];
-
-                        return _.isNil(fld) ? fld : fld.toUpperCase();
-                    }),
-                    (arr, value) => ({label: `${_.head(arr)[column] || 'Not set'} (${arr.length})`, value})
-                ),
-                'value');
-        };
-
-        const _reloadUsers = () => {
-            $http.post('/api/v1/admin/list')
-                .then(({ data }) => {
-                    $scope.users = data;
-
-                    companySelectOptions.length = 0;
-                    countrySelectOptions.length = 0;
-
-                    _.forEach($scope.users, (user) => {
-                        user.userName = user.firstName + ' ' + user.lastName;
-                        user.countryCode = Countries.getByName(user.country).code;
-
-                        user._clusters = user.counters.clusters;
-                        user._models = user.counters.models;
-                        user._caches = user.counters.caches;
-                        user._igfs = user.counters.igfs;
-                    });
-
-                    companySelectOptions.push(...usersToFilterOptions('company'));
-                    countrySelectOptions.push(...usersToFilterOptions('countryCode'));
-
-                    $scope.ctrl.gridOptions.data = data;
-
-                    adjustHeight(data.length);
-                })
-                .catch(Messages.showError);
-        };
-
-        _reloadUsers();
-
-        const _enableColumns = (categories, visible) => {
-            _.forEach(categories, (cat) => {
-                cat.visible = visible;
-
-                _.forEach(ctrl.gridOptions.columnDefs, (col) => {
-                    if (col.displayName === cat.name)
-                        col.visible = visible;
-                });
-            });
-
-            ctrl.gridApi.grid.refresh();
-        };
-
-        const _selectableColumns = () => _.filter(ctrl.gridOptions.categories, (cat) => cat.selectable);
-
-        ctrl.toggleColumns = (category, visible) => _enableColumns([category], visible);
-        ctrl.selectAllColumns = () => _enableColumns(_selectableColumns(), true);
-        ctrl.clearAllColumns = () => _enableColumns(_selectableColumns(), false);
-    }
-]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/controllers/domains-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/domains-controller.js b/modules/web-console/frontend/controllers/domains-controller.js
index 303110e..bfffe92 100644
--- a/modules/web-console/frontend/controllers/domains-controller.js
+++ b/modules/web-console/frontend/controllers/domains-controller.js
@@ -17,8 +17,8 @@
 
 // Controller for Domain model screen.
 export default ['domainsController', [
-    '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteClone', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteAgentMonitor', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'JavaTypes', 'SqlTypes',
-    function($root, $scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Focus, Confirm, ConfirmBatch, Clone, Loading, ModelNormalizer, UnsavedChangesGuard, IgniteAgentMonitor, LegacyTable, Resource, ErrorPopover, FormUtils, JavaTypes, SqlTypes) {
+    '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteClone', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteAgentMonitor', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'JavaTypes', 'SqlTypes', 'IgniteActivitiesData',
+    function($root, $scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Focus, Confirm, ConfirmBatch, Clone, Loading, ModelNormalizer, UnsavedChangesGuard, IgniteAgentMonitor, LegacyTable, Resource, ErrorPopover, FormUtils, JavaTypes, SqlTypes, ActivitiesData) {
         UnsavedChangesGuard.install($scope);
 
         const emptyDomain = {empty: true};
@@ -460,6 +460,14 @@ export default ['domainsController', [
                 $scope.importDomain.loadingOptions = LOADING_JDBC_DRIVERS;
 
                 IgniteAgentMonitor.startWatch({text: 'Back to Domain models', goal: 'import domain model from database'})
+                    .then(() => {
+                        ActivitiesData.post({
+                            group: 'configuration',
+                            action: 'configuration/import/model'
+                        });
+
+                        return true;
+                    })
                     .then(importDomainModal.$promise)
                     .then(importDomainModal.show)
                     .then(() => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json
index fd50d5b..ff52ba4 100644
--- a/modules/web-console/frontend/package.json
+++ b/modules/web-console/frontend/package.json
@@ -44,6 +44,7 @@
     "angular-socket-io": "~0.7.0",
     "angular-strap": "~2.3.8",
     "angular-touch": "~1.5.9",
+    "angular-translate": "~2.13.1",
     "angular-tree-control": "~0.2.26",
     "angular-ui-grid": "~3.2.9",
     "angular-ui-router": "~0.3.1",

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss b/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss
index bfa6c6c..47555a7 100644
--- a/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss
+++ b/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss
@@ -69,3 +69,31 @@ $fa-font-path: '~font-awesome/fonts';
 
   cursor: default;
 }
+
+.icon-user {
+  @extend .fa;
+  @extend .fa-user-o;
+
+  cursor: default;
+}
+
+.icon-admin {
+  @extend .fa;
+  @extend .fa-user-secret;
+
+  cursor: default;
+}
+
+.icon-datepicker-left {
+  @extend .fa;
+  @extend .fa-chevron-left;
+
+  margin: 0;
+}
+
+.icon-datepicker-right {
+  @extend .fa;
+  @extend .fa-chevron-right;
+  
+  margin: 0;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/style.scss b/modules/web-console/frontend/public/stylesheets/style.scss
index 4318fc2..67cfed1 100644
--- a/modules/web-console/frontend/public/stylesheets/style.scss
+++ b/modules/web-console/frontend/public/stylesheets/style.scss
@@ -2302,12 +2302,13 @@ html,body,.splash-screen {
         cursor: default;
 
         i {
+            margin-top: 2px;
             margin-right: 10px;
         }
 
         label {
             cursor: default;
-            line-height: 24px;
+            line-height: 28px;
         }
 
         sub {
@@ -2326,4 +2327,40 @@ html,body,.splash-screen {
     .ui-grid-filter-select {
         width: calc(100% - 10px);
     }
+
+    .ui-grid-cell-contents > i {
+        line-height: $line-height-base;
+    }
+
+    .ui-grid-row:nth-child(odd):hover .ui-grid-cell {
+        background: $ignite-row-hover;
+    }
+    
+    .ui-grid-row:nth-child(even):hover .ui-grid-cell {
+        background: $ignite-row-hover;
+    }
 }
+
+.datepicker.dropdown-menu {
+    width: 250px;
+    height: 270px;
+
+    button {
+        outline: none;
+        border: 0;
+    }
+
+    tbody {
+        height: 180px;
+    }
+
+    tbody button {
+        padding: 6px;
+    }
+
+    &.datepicker-mode-1, &.datepicker-mode-2 {
+        tbody button {
+            height: 65px;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/public/stylesheets/variables.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/variables.scss b/modules/web-console/frontend/public/stylesheets/variables.scss
index 8500eac..e30bbdd 100644
--- a/modules/web-console/frontend/public/stylesheets/variables.scss
+++ b/modules/web-console/frontend/public/stylesheets/variables.scss
@@ -26,3 +26,4 @@ $ignite-border-bottom-color: $brand-primary;
 $ignite-background-color: #fff;
 $ignite-header-color: #555;
 $ignite-invalid-color: $brand-primary;
+$ignite-row-hover: #c9dde1;

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/views/settings/admin.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/settings/admin.jade b/modules/web-console/frontend/views/settings/admin.jade
index c985826..a09fda9 100644
--- a/modules/web-console/frontend/views/settings/admin.jade
+++ b/modules/web-console/frontend/views/settings/admin.jade
@@ -14,38 +14,12 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-mixin grid-settings()
-    i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
-    ul.select.dropdown-menu(role='menu')
-        li(ng-repeat='item in ctrl.gridOptions.categories|filter:{selectable:true}')
-            a(ng-click='ctrl.toggleColumns(item, !item.visible)')
-                i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
-                i.fa.fa-square-o.pull-left(ng-if='!item.visible')
-                span {{::item.name}}
-        li.divider
-        li
-            a(ng-click='ctrl.selectAllColumns()') Select all
-        li
-            a(ng-click='ctrl.clearAllColumns()') Clear all
-        li.divider
-        li
-            a(ng-click='$hide()') Close
-
-.admin-page.row(ng-controller='adminController')
+.admin-page.row
     .docs-content.greedy
         .docs-header
-            h1 List of registered users
+            h1 Admin panel
             hr
         .docs-body
             .row
                 .col-xs-12
-                    .panel.panel-default
-                        .panel-heading.ui-grid-settings
-                            +grid-settings
-                            label Total users: 
-                                strong {{ users.length }}&nbsp;&nbsp;&nbsp;
-                            label Showing users: 
-                                strong {{ ctrl.gridApi.grid.getVisibleRows().length }}
-                                sub(ng-show='users.length === ctrl.gridApi.grid.getVisibleRows().length') all
-                        .panel-collapse
-                            .grid(ui-grid='ctrl.gridOptions' ui-grid-resize-columns ui-grid-selection ui-grid-pinning)
+                    ignite-list-of-registered-users(data-options='ctrl.data')

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/sql/sql.jade b/modules/web-console/frontend/views/sql/sql.jade
index 03015e8..61d5b30 100644
--- a/modules/web-console/frontend/views/sql/sql.jade
+++ b/modules/web-console/frontend/views/sql/sql.jade
@@ -15,7 +15,7 @@
     limitations under the License.
 
 include /app/helpers/jade/mixins.jade
-include /app/directives/ui-grid-settings/ui-grid-settings.jade
+include /app/components/ui-grid-settings/ui-grid-settings.jade
 
 mixin btn-toolbar(btn, click, tip, focusId)
     i.btn.btn-default.fa(class=btn ng-click=click bs-tooltip='' data-title=tip ignite-on-click-focus=focusId data-trigger='hover' data-placement='bottom')
@@ -195,7 +195,7 @@ mixin paragraph-scan
                 +table-result-body
             .footer.clearfix()
                 .pull-left
-                    | Showing results for scan of #[b{{ paragraph.queryArgs.cacheName | defaultName }}]
+                    | Showing results for scan of #[b {{ paragraph.queryArgs.cacheName | defaultName }}]
                     span(ng-if='paragraph.queryArgs.filter') &nbsp; with filter: #[b {{ paragraph.queryArgs.filter }}]
                     span(ng-if='paragraph.queryArgs.localNid') &nbsp; on node: #[b {{ paragraph.queryArgs.localNid | limitTo:8 }}]
 


[50/50] [abbrv] ignite git commit: Merge remote-tracking branch 'remotes/origin/ignite-2.0' into ignite-3477-merge2.0

Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/origin/ignite-2.0' into ignite-3477-merge2.0


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: faf07d8b7320bcb868eb3b02466d2bb18867cf0d
Parents: 1748e22
Author: sboikov <sb...@gridgain.com>
Authored: Wed Feb 15 13:42:18 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Feb 15 13:42:18 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/internal/GridCachePluginContext.java | 13 ++++++++++++-
 .../internal/processors/cache/GridCacheProcessor.java  | 12 +++++++-----
 .../cache/IgniteCacheOffheapManagerImpl.java           |  4 ++--
 .../distributed/dht/GridClientPartitionTopology.java   |  1 +
 .../internal/processors/cluster/ClusterProcessor.java  |  1 -
 .../apache/ignite/plugin/CachePluginConfiguration.java |  7 +++++++
 .../org/apache/ignite/plugin/CachePluginProvider.java  |  3 ++-
 ...ridCacheAtomicInvalidPartitionHandlingSelfTest.java |  9 ++++-----
 modules/web-console/web-agent/bin/ignite-web-agent.bat |  4 +++-
 modules/web-console/web-agent/bin/ignite-web-agent.sh  |  2 ++
 10 files changed, 40 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/main/java/org/apache/ignite/internal/GridCachePluginContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridCachePluginContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridCachePluginContext.java
index 8579ba7..552dffa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridCachePluginContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridCachePluginContext.java
@@ -35,12 +35,18 @@ public class GridCachePluginContext<C extends CachePluginConfiguration> implemen
     /** */
     private final CacheConfiguration igniteCacheCfg;
 
+    /** */
+    private final CachePluginConfiguration cachePluginCfg;
+
     /**
      * @param ctx Kernal context.
+     * @param cachePluginCfg Cache plugin config.
      * @param igniteCacheCfg Ignite config.
      */
-    public GridCachePluginContext(GridKernalContext ctx, CacheConfiguration igniteCacheCfg) {
+    public GridCachePluginContext(GridKernalContext ctx, CacheConfiguration igniteCacheCfg,
+        CachePluginConfiguration cachePluginCfg) {
         this.ctx = ctx;
+        this.cachePluginCfg = cachePluginCfg;
         this.igniteCacheCfg = igniteCacheCfg;
     }
 
@@ -49,6 +55,11 @@ public class GridCachePluginContext<C extends CachePluginConfiguration> implemen
     }
 
     /** {@inheritDoc} */
+    @Override public C cacheConfiguration() {
+        return (C)cachePluginCfg;
+    }
+
+    /** {@inheritDoc} */
     @Override public CacheConfiguration igniteCacheConfiguration() {
         return igniteCacheCfg;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 0456539..d5a7bf6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -2085,7 +2085,9 @@ public class GridCacheProcessor extends GridProcessorAdapter {
      */
     private void collectDataOnGridNode(Collection<DynamicCacheChangeRequest> reqs) {
         for (DynamicCacheDescriptor desc : registeredCaches.values()) {
-            DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(desc.cacheConfiguration().getName(), null);
+            DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(null,
+                desc.cacheConfiguration().getName(),
+                null);
 
             req.startCacheConfiguration(desc.cacheConfiguration());
 
@@ -2099,7 +2101,9 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         }
 
         for (DynamicCacheDescriptor desc : registeredTemplates.values()) {
-            DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(desc.cacheConfiguration().getName(), null);
+            DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(null,
+                desc.cacheConfiguration().getName(),
+                null);
 
             req.startCacheConfiguration(desc.cacheConfiguration());
 
@@ -2125,7 +2129,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
             if (desc == null)
                 continue;
 
-            DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(cache.name(), null);
+            DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(null, cache.name(), null);
 
             req.startCacheConfiguration(desc.cacheConfiguration());
 
@@ -2757,8 +2761,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
         if (CU.isUtilityCache(cacheName))
             req.cacheType(CacheType.UTILITY);
-        else if (CU.isMarshallerCache(cacheName))
-            req.cacheType(CacheType.MARSHALLER);
         else if (internalCaches.contains(cacheName))
             req.cacheType(CacheType.INTERNAL);
         else

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index 5df99b6..1240264 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -259,7 +259,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
 
             for (GridDhtLocalPartition locPart : cctx.topology().currentLocalPartitions()) {
                 if (primary) {
-                    if (cctx.affinity().primary(locNode, locPart.id(), topVer)) {
+                    if (cctx.affinity().primaryByPartition(locNode, locPart.id(), topVer)) {
                         cnt += locPart.size();
 
                         continue;
@@ -267,7 +267,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
                 }
 
                 if (backup) {
-                    if (cctx.affinity().backup(locNode, locPart.id(), topVer))
+                    if (cctx.affinity().primaryByPartition(locNode, locPart.id(), topVer))
                         cnt += locPart.size();
                 }
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
index 0076b36..ca71f51 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
@@ -38,6 +38,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.Gri
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap2;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture;
+import org.apache.ignite.internal.util.F0;
 import org.apache.ignite.internal.util.GridAtomicLong;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.F;

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
index a32b9d8..fa5c982 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
@@ -115,7 +115,6 @@ public class ClusterProcessor extends GridProcessorAdapter {
         dataBag.addNodeSpecificData(CLUSTER_PROC.ordinal(), getDiscoveryData());
     }
 
-
     /**
      * @return Discovery data.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginConfiguration.java b/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginConfiguration.java
index 0c94348..d4331b5 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginConfiguration.java
@@ -25,4 +25,11 @@ import org.apache.ignite.configuration.CacheConfiguration;
  * and extend existing functionality of cache.
  */
 public interface CachePluginConfiguration<K, V> extends Serializable {
+    /**
+     * Creates cache plugin provider.
+     *
+     * @return Cache plugin provider class.
+     * @param ctx Plugin context.
+     */
+    public CachePluginProvider createProvider(CachePluginContext ctx);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginProvider.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginProvider.java b/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginProvider.java
index b56e546..86afc1b 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginProvider.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/CachePluginProvider.java
@@ -85,9 +85,10 @@ public interface CachePluginProvider<C extends CachePluginConfiguration> {
      * Checks that remote caches has configuration compatible with the local.
      *
      * @param locCfg Local configuration.
+     * @param locPluginCcfg Local plugin configuration.
      * @param rmtCfg Remote configuration.
      * @param rmtNode Remote node.
      */
-    public void validateRemote(CacheConfiguration locCfg, CacheConfiguration rmtCfg, ClusterNode rmtNode)
+    public void validateRemote(CacheConfiguration locCfg, C locPluginCcfg, CacheConfiguration rmtCfg, ClusterNode rmtNode)
         throws IgniteCheckedException;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
index 04f00c2..fd310c4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
@@ -387,11 +387,10 @@ public class GridCacheAtomicInvalidPartitionHandlingSelfTest extends GridCommonA
                     try {
                         entry = c.entryEx(k);
 
-                            entry.unswap();
-                        }
-                        catch (GridDhtInvalidPartitionException ignored) {
-                            // Skip key.
-                        }
+                        entry.unswap();
+                    }
+                    catch (GridDhtInvalidPartitionException ignored) {
+                        // Skip key.
                     }
 
                     for (int r = 0; r < 10; r++) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/web-console/web-agent/bin/ignite-web-agent.bat
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/bin/ignite-web-agent.bat b/modules/web-console/web-agent/bin/ignite-web-agent.bat
index 8291b55..1f1b52d 100644
--- a/modules/web-console/web-agent/bin/ignite-web-agent.bat
+++ b/modules/web-console/web-agent/bin/ignite-web-agent.bat
@@ -60,7 +60,9 @@ if %ERRORLEVEL% equ 0 (
     if "%JVM_OPTS%" == "" set JVM_OPTS=-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxMetaspaceSize=256m
 )
 
-"%JAVA_HOME%\bin\java.exe" %JVM_OPTS% -cp "*" org.apache.ignite.console.agent.AgentLauncher  %*
+set JVM_OPTS=%JVM_OPTS% -Djava.net.useSystemProxies=true
+
+"%JAVA_HOME%\bin\java.exe" %JVM_OPTS% -cp "*" org.apache.ignite.console.agent.AgentLauncher %*
 
 set JAVA_ERRORLEVEL=%ERRORLEVEL%
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/faf07d8b/modules/web-console/web-agent/bin/ignite-web-agent.sh
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/bin/ignite-web-agent.sh b/modules/web-console/web-agent/bin/ignite-web-agent.sh
index 2e9f041..c2958fc 100644
--- a/modules/web-console/web-agent/bin/ignite-web-agent.sh
+++ b/modules/web-console/web-agent/bin/ignite-web-agent.sh
@@ -88,4 +88,6 @@ if [ -z "$JVM_OPTS" ] ; then
     fi
 fi
 
+JVM_OPTS="${JVM_OPTS} -Djava.net.useSystemProxies=true"
+
 "$JAVA" ${JVM_OPTS} -cp "*" org.apache.ignite.console.agent.AgentLauncher "$@"


[44/50] [abbrv] ignite git commit: IGNITE-1495 Uppercase index fields in metadata. This closes #1474.

Posted by sb...@apache.org.
IGNITE-1495 Uppercase index fields in metadata. This closes #1474.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 7d3c046e58a160132655a7b8f90830d69a16e2ab
Parents: d8ad967
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Tue Feb 14 14:56:24 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Feb 14 14:56:24 2017 +0300

----------------------------------------------------------------------
 .../cache/query/GridCacheQueryManager.java      | 11 +++++++---
 .../IgniteCacheAbstractFieldsQuerySelfTest.java | 21 ++++++++++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3c046e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
index 2b31e2d..c434401 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
@@ -2484,12 +2484,17 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
 
                             // Add only SQL indexes.
                             if (desc.type() == GridQueryIndexType.SORTED) {
-                                Collection<String> idxFields = e.getValue().fields();
+                                Collection<String> idxFields = new LinkedList<>();
                                 Collection<String> descendings = new LinkedList<>();
 
-                                for (String idxField : idxFields)
+                                for (String idxField : e.getValue().fields()) {
+                                    String idxFieldUpper = idxField.toUpperCase();
+
+                                    idxFields.add(idxFieldUpper);
+
                                     if (desc.descending(idxField))
-                                        descendings.add(idxField);
+                                        descendings.add(idxFieldUpper);
+                                }
 
                                 indexesCol.add(new CacheSqlIndexMetadata(e.getKey().toUpperCase(),
                                     idxFields, descendings, false));

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3c046e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractFieldsQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractFieldsQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractFieldsQuerySelfTest.java
index d5f02eb..0170fc7 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractFieldsQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractFieldsQuerySelfTest.java
@@ -326,8 +326,29 @@ public abstract class IgniteCacheAbstractFieldsQuerySelfTest extends GridCommonA
 
                     Collection<GridCacheSqlIndexMetadata> indexes = meta.indexes("Person");
 
+                    assertNotNull("Indexes should be defined", indexes);
                     assertEquals(2, indexes.size());
 
+                    Iterator<GridCacheSqlIndexMetadata> it = indexes.iterator();
+
+                    Collection<String> indFlds = it.next().fields();
+
+                    assertNotNull("Fields for first index should be defined", indFlds);
+                    assertEquals("First index should have one field", indFlds.size(), 1);
+
+                    Iterator<String> indFldIt = indFlds.iterator();
+
+                    assertEquals(indFldIt.next(), "AGE");
+
+                    indFlds = it.next().fields();
+
+                    assertNotNull("Fields for second index should be defined", indFlds);
+                    assertEquals("Second index should have one field", indFlds.size(), 1);
+
+                    indFldIt = indFlds.iterator();
+
+                    assertEquals(indFldIt.next(), "ORGID");
+
                     wasNull = true;
                 }
                 else if (CACHE.equals(meta.cacheName()))


[26/50] [abbrv] ignite git commit: Merge branch 'master' of https://github.com/apache/ignite

Posted by sb...@apache.org.
Merge branch 'master' of https://github.com/apache/ignite


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 3bf880c16e2787c44f62c4f1daf4c9f0fdab2dba
Parents: aaeda72 605d946
Author: agura <ag...@apache.org>
Authored: Thu Feb 9 20:34:53 2017 +0300
Committer: agura <ag...@apache.org>
Committed: Thu Feb 9 20:34:53 2017 +0300

----------------------------------------------------------------------
 modules/yardstick/DEVNOTES-standalone.txt       |  15 +++
 modules/yardstick/DEVNOTES.txt                  |  20 ++--
 modules/yardstick/README.txt                    | 119 +++++++++++++------
 .../config/benchmark-sample.properties          |  62 ++++++++++
 modules/yardstick/pom.xml                       |   4 +-
 pom.xml                                         |   1 +
 6 files changed, 172 insertions(+), 49 deletions(-)
----------------------------------------------------------------------



[38/50] [abbrv] ignite git commit: IGNITE-4688: Changed copyrights to 2017.

Posted by sb...@apache.org.
IGNITE-4688: Changed copyrights to 2017.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: cff20e794cdf8e0e0ff89ea17ab1d2c7f1de4663
Parents: 5245214
Author: devozerov <vo...@gridgain.com>
Authored: Mon Feb 13 13:13:13 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Feb 13 13:13:13 2017 +0300

----------------------------------------------------------------------
 .../dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs     | 2 +-
 .../Apache.Ignite.Core.Tests.TestDll/Properties/AssemblyInfo.cs    | 2 +-
 .../dotnet/Apache.Ignite.Core.Tests/Properties/AssemblyInfo.cs     | 2 +-
 .../Apache.Ignite.EntityFramework.nuspec                           | 2 +-
 .../platforms/dotnet/Apache.Ignite.Linq/Properties/AssemblyInfo.cs | 2 +-
 modules/platforms/dotnet/Apache.Ignite/Properties/AssemblyInfo.cs  | 2 +-
 .../examples/Apache.Ignite.Examples/Properties/AssemblyInfo.cs     | 2 +-
 .../examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs  | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs
index 7da0a1d..ce82281 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Properties/AssemblyInfo.cs
index 26caa82..e9f93bd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Properties/AssemblyInfo.cs
index 1fc6c59..28f6e72 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/Apache.Ignite.EntityFramework/Apache.Ignite.EntityFramework.nuspec
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.EntityFramework/Apache.Ignite.EntityFramework.nuspec b/modules/platforms/dotnet/Apache.Ignite.EntityFramework/Apache.Ignite.EntityFramework.nuspec
index b8bcd46..477dcf8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.EntityFramework/Apache.Ignite.EntityFramework.nuspec
+++ b/modules/platforms/dotnet/Apache.Ignite.EntityFramework/Apache.Ignite.EntityFramework.nuspec
@@ -47,7 +47,7 @@ More info: https://apacheignite-net.readme.io/
             Apache Ignite EntityFramework Integration
         </summary>
         <releaseNotes></releaseNotes>
-        <copyright>Copyright 2016</copyright>
+        <copyright>Copyright 2017</copyright>
         <tags>EntityFramework Second-Level Apache Ignite In-Memory Distributed Computing SQL NoSQL Grid Map Reduce Cache</tags>
         <dependencies>
             <dependency id="Apache.Ignite" version="[$version$]" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/Apache.Ignite.Linq/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Properties/AssemblyInfo.cs
index a1dae5e..561674a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Properties/AssemblyInfo.cs
@@ -24,7 +24,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/Apache.Ignite/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite/Properties/AssemblyInfo.cs
index 97a78d5..3e0e305 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Properties/AssemblyInfo.cs
index a75ee0e..f6323e0 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/cff20e79/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
index cc78a5c..6d28b2b 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 


[18/50] [abbrv] ignite git commit: ignite-3537 Added tests. This closes #1441

Posted by sb...@apache.org.
ignite-3537 Added tests.
This closes #1441


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: db5da76a57734b0509c70cc3afc284310a35fe0f
Parents: 46ff66e
Author: javaller <vo...@gmail.com>
Authored: Wed Feb 8 21:49:57 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Feb 8 21:49:57 2017 +0300

----------------------------------------------------------------------
 ...CacheAtomicReferenceApiSelfAbstractTest.java | 60 +++++++++++++++++++-
 ...idCacheAtomicStampedApiSelfAbstractTest.java | 59 +++++++++++++++++++
 .../GridCacheQueueApiSelfAbstractTest.java      | 58 +++++++++++++++++++
 .../GridCacheSetAbstractSelfTest.java           | 53 +++++++++++++++++
 .../IgniteAtomicLongApiAbstractSelfTest.java    | 27 +++++++++
 .../IgniteCountDownLatchAbstractSelfTest.java   | 43 ++++++++++++++
 .../IgniteLockAbstractSelfTest.java             | 54 +++++++++++++++++-
 .../IgniteSemaphoreAbstractSelfTest.java        | 52 ++++++++++++++++-
 8 files changed, 403 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicReferenceApiSelfAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicReferenceApiSelfAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicReferenceApiSelfAbstractTest.java
index 278bcf9..3c4b3a7 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicReferenceApiSelfAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicReferenceApiSelfAbstractTest.java
@@ -18,8 +18,15 @@
 package org.apache.ignite.internal.processors.cache.datastructures;
 
 import java.util.UUID;
+import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteAtomicReference;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.transactions.Transaction;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
  * Basic tests for atomic reference.
@@ -127,4 +134,55 @@ public abstract class GridCacheAtomicReferenceApiSelfAbstractTest extends Ignite
         assertTrue(success);
         assertEquals("newVal", atomic.get());
     }
-}
+
+    /**
+     * Implementation of ignite data structures internally uses special system caches, need make sure
+     * that transaction on these system caches do not intersect with transactions started by user.
+     *
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        Ignite ignite = grid(0);
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName("myCache");
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        IgniteCache<Integer, Integer> cache = ignite.getOrCreateCache(cfg);
+
+        try {
+            String atomicName = UUID.randomUUID().toString();
+
+            String initValue = "qazwsx";
+
+            IgniteAtomicReference<String> atomicReference = ignite.atomicReference(atomicName, initValue, true);
+
+            try (Transaction tx = ignite.transactions().txStart()) {
+                cache.put(1, 1);
+
+                assertEquals(initValue, atomicReference.get());
+
+                assertTrue(atomicReference.compareAndSet(initValue, "aaa"));
+
+                assertEquals("aaa", atomicReference.get());
+
+                tx.rollback();
+
+                assertEquals(0, cache.size());
+            }
+
+            assertTrue(atomicReference.compareAndSet("aaa", null));
+
+            assertNull(atomicReference.get());
+
+            atomicReference.close();
+
+            assertTrue(atomicReference.removed());
+        }
+        finally {
+            ignite.destroyCache(cfg.getName());
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicStampedApiSelfAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicStampedApiSelfAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicStampedApiSelfAbstractTest.java
index 7474330..81300e4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicStampedApiSelfAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAtomicStampedApiSelfAbstractTest.java
@@ -18,8 +18,15 @@
 package org.apache.ignite.internal.processors.cache.datastructures;
 
 import java.util.UUID;
+import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteAtomicStamped;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.transactions.Transaction;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
  * Basic tests for atomic stamped.
@@ -120,4 +127,56 @@ public abstract class GridCacheAtomicStampedApiSelfAbstractTest extends IgniteAt
         assertEquals(null, atomic.value());
         assertEquals(null, atomic.stamp());
     }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        Ignite ignite = grid(0);
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName("MyCache");
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        IgniteCache<Integer, Integer> cache = ignite.getOrCreateCache(cfg);
+
+        try {
+            String atomicName = UUID.randomUUID().toString();
+
+            String initVal = "qwerty";
+            String initStamp = "asdf";
+
+            IgniteAtomicStamped<String, String> atomicStamped = ignite.atomicStamped(atomicName,
+                initVal,
+                initStamp,
+                true);
+
+            try (Transaction tx = ignite.transactions().txStart()) {
+                cache.put(1,1);
+
+                assertEquals(initVal, atomicStamped.value());
+                assertEquals(initStamp, atomicStamped.stamp());
+                assertEquals(initVal, atomicStamped.get().get1());
+                assertEquals(initStamp, atomicStamped.get().get2());
+
+                assertTrue(atomicStamped.compareAndSet(initVal, "b", initStamp, "d"));
+
+                tx.rollback();
+            }
+
+            assertEquals(0, cache.size());
+
+            assertEquals("b", atomicStamped.value());
+            assertEquals("d", atomicStamped.stamp());
+
+            atomicStamped.close();
+
+            assertTrue(atomicStamped.removed());
+        }
+        finally {
+            ignite.destroyCache(cfg.getName());
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheQueueApiSelfAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheQueueApiSelfAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheQueueApiSelfAbstractTest.java
index 93d0989..3e7eff9 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheQueueApiSelfAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheQueueApiSelfAbstractTest.java
@@ -25,6 +25,8 @@ import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteQueue;
 import org.apache.ignite.cache.CacheMode;
@@ -38,9 +40,11 @@ import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.lang.IgniteRunnable;
 import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.transactions.Transaction;
 
 import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
 import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
  * Queue basic tests.
@@ -772,6 +776,60 @@ public abstract class GridCacheQueueApiSelfAbstractTest extends IgniteCollection
     }
 
     /**
+     * Implementation of ignite data structures internally uses special system caches, need make sure
+     * that transaction on these system caches do not intersect with transactions started by user.
+     *
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        Ignite ignite = grid(0);
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName("myCache");
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        IgniteCache<Integer, Integer> cache = ignite.getOrCreateCache(cfg);
+
+        try {
+            String queueName = UUID.randomUUID().toString();
+
+            IgniteQueue<String> queue = grid(0).queue(queueName, 0, config(false));
+
+            try (Transaction tx = ignite.transactions().txStart()) {
+                cache.put(1, 1);
+
+                for (int i = 0; i < QUEUE_CAPACITY; i++)
+                    queue.put("Item-" + i);
+
+                tx.rollback();
+            }
+
+            assertEquals(0, cache.size());
+
+            assertEquals(QUEUE_CAPACITY, queue.size());
+
+            queue.remove("Item-1");
+
+            assertEquals(QUEUE_CAPACITY - 1, queue.size());
+
+            assertEquals("Item-0", queue.peek());
+            assertEquals("Item-0", queue.poll());
+            assertEquals("Item-2", queue.poll());
+
+            assertEquals(0, queue.size());
+
+            queue.clear();
+
+            assertTrue(queue.isEmpty());
+        }
+        finally {
+            ignite.destroyCache(cfg.getName());
+        }
+    }
+
+    /**
      *  Test class with the same hash code.
      */
     private static class SameHashItem implements Serializable {

http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheSetAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheSetAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheSetAbstractSelfTest.java
index 9973b27..5ccb830 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheSetAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheSetAbstractSelfTest.java
@@ -28,11 +28,13 @@ import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import junit.framework.AssertionFailedError;
+import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteSet;
 import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.CollectionConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -47,9 +49,12 @@ import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.lang.IgniteRunnable;
 import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.transactions.Transaction;
 
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
 import static org.apache.ignite.cache.CacheMode.LOCAL;
 import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
  * Cache set tests.
@@ -948,6 +953,54 @@ public abstract class GridCacheSetAbstractSelfTest extends IgniteCollectionAbstr
     }
 
     /**
+     * Implementation of ignite data structures internally uses special system caches, need make sure
+     * that transaction on these system caches do not intersect with transactions started by user.
+     *
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        CollectionConfiguration colCfg = collectionConfiguration();
+
+        Ignite ignite = grid(0);
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName("myCache");
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        IgniteCache<Integer, Integer> cache = ignite.getOrCreateCache(cfg);
+
+        try {
+            IgniteSet<Integer> set0 = ignite.set(SET_NAME, colCfg);
+
+            assertNotNull(set0);
+
+            try (Transaction tx = ignite.transactions().txStart()) {
+                cache.put(1, 1);
+
+                Collection<Integer> items = new ArrayList<>(100);
+
+                for (int i = 0; i < 100; i++)
+                    items.add(i);
+
+                set0.addAll(items);
+
+                tx.rollback();
+            }
+
+            assertEquals(0, cache.size());
+
+            assertEquals(100, set0.size());
+
+            set0.close();
+        }
+        finally {
+            ignite.destroyCache(cfg.getName());
+        }
+    }
+
+    /**
      * @param set Set.
      * @param size Expected size.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteAtomicLongApiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteAtomicLongApiAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteAtomicLongApiAbstractSelfTest.java
index 9672265..49a1c72 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteAtomicLongApiAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteAtomicLongApiAbstractSelfTest.java
@@ -265,4 +265,31 @@ public abstract class IgniteAtomicLongApiAbstractSelfTest extends IgniteAtomicsA
             assert newVal == atomic.get();
         }
     }
+
+    /**
+     * Implementation of ignite data structures internally uses special system caches, need make sure that
+     * transaction on these system caches do not intersect with transactions started by user.
+     *
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        Ignite ignite = grid(0);
+
+        IgniteCache<Object, Object> cache = ignite.cache(TRANSACTIONAL_CACHE_NAME);
+
+        IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
+
+        long curAtomicVal = atomic.get();
+
+        try (Transaction tx = ignite.transactions().txStart()) {
+            atomic.getAndIncrement();
+
+            cache.put(1, 1);
+
+            tx.rollback();
+        }
+
+        assertEquals(0, cache.size());
+        assertEquals(curAtomicVal + 1, atomic.get());
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteCountDownLatchAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteCountDownLatchAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteCountDownLatchAbstractSelfTest.java
index e9b83d9..88966b0 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteCountDownLatchAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteCountDownLatchAbstractSelfTest.java
@@ -35,6 +35,7 @@ import org.apache.ignite.IgniteCountDownLatch;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cluster.ClusterGroup;
 import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.util.typedef.G;
@@ -45,11 +46,14 @@ import org.apache.ignite.lang.IgniteRunnable;
 import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.resources.LoggerResource;
 import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.transactions.Transaction;
 import org.jetbrains.annotations.Nullable;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.MINUTES;
 import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
  * Cache count down latch self test.
@@ -78,6 +82,45 @@ public abstract class IgniteCountDownLatchAbstractSelfTest extends IgniteAtomics
     }
 
     /**
+     * Implementation of ignite data structures internally uses special system caches, need make sure
+     * that transaction on these system caches do not intersect with transactions started by user.
+     *
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        Ignite ignite = grid(0);
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName("myCache");
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        IgniteCache<Integer, Integer> cache = ignite.getOrCreateCache(cfg);
+
+        try {
+            IgniteCountDownLatch latch = ignite.countDownLatch("latch1", 10, false, true);
+
+            assertNotNull(latch);
+
+            try (Transaction tx = ignite.transactions().txStart()) {
+                cache.put(1, 1);
+
+                assertEquals(8, latch.countDown(2));
+
+                tx.rollback();
+            }
+
+            assertEquals(0, cache.size());
+
+            assertEquals(7, latch.countDown(1));
+        }
+        finally {
+            ignite.destroyCache(cfg.getName());
+        }
+    }
+
+    /**
      * @throws Exception If failed.
      */
     private void checkLatch() throws Exception {

http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteLockAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteLockAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteLockAbstractSelfTest.java
index 388f167..27e05b9 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteLockAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteLockAbstractSelfTest.java
@@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteCompute;
 import org.apache.ignite.IgniteCondition;
@@ -42,6 +43,7 @@ import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteInterruptedException;
 import org.apache.ignite.IgniteLock;
 import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
@@ -54,6 +56,7 @@ import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.resources.LoggerResource;
 import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.transactions.Transaction;
 import org.jetbrains.annotations.Nullable;
 import org.junit.Rule;
 import org.junit.rules.ExpectedException;
@@ -61,7 +64,9 @@ import org.junit.rules.ExpectedException;
 import static java.util.concurrent.TimeUnit.MICROSECONDS;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
 import static org.apache.ignite.cache.CacheMode.LOCAL;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
  * Cache reentrant lock self test.
@@ -112,8 +117,55 @@ public abstract class IgniteLockAbstractSelfTest extends IgniteAtomicsAbstractTe
     }
 
     /**
+     * Implementation of ignite data structures internally uses special system caches, need make sure
+     * that transaction on these system caches do not intersect with transactions started by user.
+     *
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        Ignite ignite = grid(0);
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName("myCache");
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        IgniteCache<Integer, Integer> cache = ignite.getOrCreateCache(cfg);
+
+        try {
+            IgniteLock lock = ignite.reentrantLock("lock", true, true, true);
+
+            try (Transaction tx = ignite.transactions().txStart()) {
+                cache.put(1, 1);
+
+                boolean success = lock.tryLock(1, MILLISECONDS);
+
+                assertTrue(success);
+
+                tx.rollback();
+            }
+
+            assertEquals(0, cache.size());
+
+            assertTrue(lock.isLocked());
+
+            lock.unlock();
+
+            assertFalse(lock.isLocked());
+
+            lock.close();
+
+            assertTrue(lock.removed());
+        }
+        finally {
+            ignite.destroyCache(cfg.getName());
+        }
+    }
+
+    /**
      * @param failoverSafe Failover safe flag.
-     * @throws Exception
+     * @throws Exception If failed.
      */
     private void checkFailover(final boolean failoverSafe, final boolean fair) throws Exception {
         IgniteEx g = startGrid(NODES_CNT + 1);

http://git-wip-us.apache.org/repos/asf/ignite/blob/db5da76a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java
index 5241dd1..8ad8631 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java
@@ -26,10 +26,12 @@ import java.util.List;
 import java.util.Random;
 import java.util.concurrent.Callable;
 import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteCompute;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.IgniteSemaphore;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -42,6 +44,7 @@ import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.resources.LoggerResource;
 import org.apache.ignite.testframework.GridStringLogger;
 import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.transactions.Transaction;
 import org.jetbrains.annotations.Nullable;
 import org.junit.Rule;
 import org.junit.rules.ExpectedException;
@@ -49,7 +52,9 @@ import org.junit.rules.ExpectedException;
 import static java.util.concurrent.TimeUnit.MICROSECONDS;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
 import static org.apache.ignite.cache.CacheMode.LOCAL;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
  * Cache semaphore self test.
@@ -94,8 +99,53 @@ public abstract class IgniteSemaphoreAbstractSelfTest extends IgniteAtomicsAbstr
     }
 
     /**
+     * Implementation of ignite data structures internally uses special system caches, need make sure
+     * that transaction on these system caches do not intersect with transactions started by user.
+     *
+     * @throws Exception If failed.
+     */
+    public void testIsolation() throws Exception {
+        Ignite ignite = grid(0);
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName("myCache");
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        IgniteCache<Integer, Integer> cache = ignite.getOrCreateCache(cfg);
+
+        try {
+            IgniteSemaphore semaphore = ignite.semaphore("testIsolation", 1, true, true);
+
+            assertNotNull(semaphore);
+
+            try (Transaction tx = ignite.transactions().txStart()) {
+                cache.put(1, 1);
+
+                assertEquals(1, semaphore.availablePermits());
+
+                semaphore.acquire();
+
+                tx.rollback();
+            }
+
+            assertEquals(0, cache.size());
+
+            assertEquals(0, semaphore.availablePermits());
+
+            semaphore.close();
+
+            assertTrue(semaphore.removed());
+        }
+        finally {
+            ignite.destroyCache(cfg.getName());
+        }
+    }
+
+    /**
      * @param failoverSafe Failover safe flag.
-     * @throws Exception
+     * @throws Exception If failed.
      */
     private void checkFailover(boolean failoverSafe) throws Exception {
         IgniteEx g = startGrid(NODES_CNT + 1);


[48/50] [abbrv] ignite git commit: Megre 2.0

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 6dc1d04,942ae21..81296e1
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@@ -98,6 -100,15 +98,9 @@@ public abstract class GridCacheMapEntr
      private static final byte IS_UNSWAPPED_MASK = 0x02;
  
      /** */
 -    private static final byte IS_OFFHEAP_PTR_MASK = 0x04;
 -
 -    /** */
 -    private static final byte IS_SWAPPING_REQUIRED = 0x08;
 -
 -    /** */
 -    private static final byte IS_EVICT_DISABLED = 0x10;
++    private static final byte IS_EVICT_DISABLED = 0x04;
+ 
+     /** */
      public static final GridCacheAtomicVersionComparator ATOMIC_VER_COMPARATOR = new GridCacheAtomicVersionComparator();
  
      /**
@@@ -478,20 -783,50 +483,44 @@@
      }
  
      /** {@inheritDoc} */
-     @Nullable @Override public T2<CacheObject, GridCacheVersion> innerGetVersioned(
 -    @Override public EntryGetResult innerGetAndReserveForLoad(boolean readSwap,
 -        boolean updateMetrics,
++    @Override public EntryGetResult innerGetAndReserveForLoad(boolean updateMetrics,
+         boolean evt,
+         UUID subjId,
+         String taskName,
+         @Nullable IgniteCacheExpiryPolicy expiryPlc,
+         boolean keepBinary,
+         @Nullable ReaderArguments readerArgs) throws IgniteCheckedException, GridCacheEntryRemovedException {
+         return (EntryGetResult)innerGet0(
+             /*ver*/null,
+             /*tx*/null,
 -            readSwap,
+             /*readThrough*/false,
+             evt,
+             updateMetrics,
 -            /*tmp*/false,
+             subjId,
+             /*transformClo*/null,
+             taskName,
+             expiryPlc,
+             true,
+             keepBinary,
+             /*reserve*/true,
+             readerArgs);
+     }
+ 
+     /** {@inheritDoc} */
+     @Override public EntryGetResult innerGetVersioned(
          @Nullable GridCacheVersion ver,
          IgniteInternalTx tx,
 -        boolean readSwap,
 -        boolean unmarshal,
          boolean updateMetrics,
          boolean evt,
          UUID subjId,
          Object transformClo,
          String taskName,
          @Nullable IgniteCacheExpiryPolicy expiryPlc,
-         boolean keepBinary)
+         boolean keepBinary,
+         @Nullable ReaderArguments readerArgs)
          throws IgniteCheckedException, GridCacheEntryRemovedException {
-         return (T2<CacheObject, GridCacheVersion>)innerGet0(
-             ver,
+         return (EntryGetResult)innerGet0(ver,
              tx,
 -            readSwap,
              false,
              evt,
              updateMetrics,
@@@ -619,14 -966,28 +653,27 @@@
  
              // Cache version for optimistic check.
              startVer = ver;
-         }
+ 
+             addReaderIfNeed(readerArgs);
  
 -            if (ret != null) {
 -                assert tmp || !(ret instanceof BinaryObjectOffheapImpl);
 -                assert !obsolete;
 -                assert !deferred;
 +        if (ret != null) {
 +            assert !obsolete;
 +            assert !deferred;
  
-             // If return value is consistent, then done.
-             return retVer ? new T2<>(ret, resVer) : ret;
+                 // If return value is consistent, then done.
+                 res = retVer ? new EntryGetResult(ret, resVer, false) : ret;
+             }
+             else if (reserveForLoad && !obsolete) {
+                 assert !readThrough;
+                 assert retVer;
+ 
+                 boolean reserve = !evictionDisabled();
+ 
+                 if (reserve)
+                     flags |= IS_EVICT_DISABLED;
+ 
+                 res = new EntryGetResult(null, resVer, reserve);
+             }
          }
  
          if (obsolete) {
@@@ -677,8 -1047,20 +729,10 @@@
  
                      update(ret, expTime, ttl, nextVer, true);
  
 -                    if (hadValPtr && cctx.offheapTiered()) {
 -                        if (log.isTraceEnabled()) {
 -                            log.trace("innerGet removeOffheap [key=" + key +
 -                                ", entry=" + System.identityHashCode(this) +
 -                                ", ptr=" + offHeapPointer() + ']');
 -                        }
 -
 -                        cctx.swap().removeOffheap(key);
 -                    }
 -
                      if (cctx.deferredDelete() && deletedUnlocked() && !isInternal() && !detached())
                          deletedUnlocked(false);
+ 
+                     assert readerArgs == null;
                  }
  
                  if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) {
@@@ -2593,8 -3064,21 +2647,9 @@@
              value(null);
  
              ver = newVer;
+             flags &= ~IS_EVICT_DISABLED;
  
 -            if (log.isTraceEnabled()) {
 -                log.trace("invalidate releaseSwap [key=" + key +
 -                    ", entry=" + System.identityHashCode(this) +
 -                    ", val=" + val +
 -                    ", ptr=" + offHeapPointer() +
 -                    ']');
 -            }
 -
 -            releaseSwap();
 -
 -            clearIndex(val);
 +            removeValue();
  
              onInvalidate();
          }
@@@ -2672,9 -3155,10 +2727,10 @@@
          ttlAndExpireTimeExtras(ttl, expireTime);
  
          this.ver = ver;
+         flags &= ~IS_EVICT_DISABLED;
  
 -        if (addTracked && expireTime != 0 && (expireTime != oldExpireTime || isStartVersion()) && cctx.config().isEagerTtl())
 -            cctx.ttl().addTrackedEntry(this);
 +        if (trackNear && expireTime != 0 && (expireTime != oldExpireTime || isStartVersion()))
 +            cctx.ttl().addTrackedEntry((GridNearCacheEntry)this);
      }
  
      /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 987d696,0ce4404..0456539
mode 100644,100755..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@@ -585,146 -616,99 +593,144 @@@ public class GridCacheProcessor extend
  
          CacheConfiguration[] cfgs = ctx.config().getCacheConfiguration();
  
 -        sharedCtx = createSharedContext(ctx, CU.startStoreSessionListeners(ctx,
 -            ctx.config().getCacheStoreSessionListenerFactories()));
 +        registerCacheFromConfig(cfgs);
 +
 +        registerCacheFromPersistentStore(cfgs);
 +
 +        if (log.isDebugEnabled())
 +            log.debug("Started cache processor.");
 +    }
  
 +    /**
 +     * @param cfgs Cache configurations.
 +     * @throws IgniteCheckedException If failed.
 +     */
 +    private void registerCacheFromConfig(CacheConfiguration[] cfgs) throws IgniteCheckedException {
          for (int i = 0; i < cfgs.length; i++) {
-             if (ctx.config().isDaemon() && !CU.isMarshallerCache(cfgs[i].getName()))
+             if (ctx.config().isDaemon())
                  continue;
  
 -            cloneCheckSerializable(cfgs[i]);
 -
              CacheConfiguration<?, ?> cfg = new CacheConfiguration(cfgs[i]);
  
 -            CacheObjectContext cacheObjCtx = ctx.cacheObjects().contextForCache(cfg);
 +            cfgs[i] = cfg; // Replace original configuration value.
  
 -            // Initialize defaults.
 -            initialize(cfg, cacheObjCtx);
 +            registerCache(cfg);
 +        }
 +    }
  
 -            cfgs[i] = cfg; // Replace original configuration value.
 +    /**
 +     * @param cfgs Cache configurations.
 +     * @throws IgniteCheckedException If failed.
 +     */
 +    private void registerCacheFromPersistentStore(CacheConfiguration[] cfgs) throws IgniteCheckedException {
 +        if (sharedCtx.pageStore() != null &&
 +            sharedCtx.database().persistenceEnabled() &&
 +            !ctx.config().isDaemon()) {
  
 -            String masked = maskNull(cfg.getName());
 +            Set<String> savedCacheNames = sharedCtx.pageStore().savedCacheNames();
  
 -            if (registeredCaches.containsKey(masked)) {
 -                String cacheName = cfg.getName();
 +            for (CacheConfiguration cfg : cfgs)
 +                savedCacheNames.remove(cfg.getName());
  
 -                if (cacheName != null)
 -                    throw new IgniteCheckedException("Duplicate cache name found (check configuration and " +
 -                        "assign unique name to each cache): " + U.maskName(cacheName));
 -                else
 -                    throw new IgniteCheckedException("Default cache has already been configured (check configuration and " +
 -                        "assign unique name to each cache).");
 +            for (String name : internalCaches)
 +                savedCacheNames.remove(name);
 +
 +            if (!F.isEmpty(savedCacheNames)) {
 +                log.info("Registrate persistent caches: " + savedCacheNames);
 +
 +                for (String name : savedCacheNames) {
 +                    CacheConfiguration cfg = sharedCtx.pageStore().readConfiguration(name);
 +
 +                    if (cfg != null)
 +                        registerCache(cfg);
 +                }
              }
 +        }
 +    }
  
 -            CacheType cacheType;
 +    /**
 +     * @param cfg Cache configuration.
 +     * @throws IgniteCheckedException If failed.
 +     */
 +    private void registerCache(CacheConfiguration<?, ?> cfg) throws IgniteCheckedException {
 +        cloneCheckSerializable(cfg);
  
 -            if (CU.isUtilityCache(cfg.getName()))
 -                cacheType = CacheType.UTILITY;
 -            else if (internalCaches.contains(maskNull(cfg.getName())))
 -                cacheType = CacheType.INTERNAL;
 -            else
 -                cacheType = CacheType.USER;
 +        CacheObjectContext cacheObjCtx = ctx.cacheObjects().contextForCache(cfg);
  
 -            boolean template = cfg.getName() != null && cfg.getName().endsWith("*");
 +        // Initialize defaults.
 +        initialize(cfg, cacheObjCtx);
  
 -            DynamicCacheDescriptor desc = new DynamicCacheDescriptor(ctx, cfg, cacheType, template,
 -                IgniteUuid.randomUuid());
 +        String masked = maskNull(cfg.getName());
  
 -            desc.locallyConfigured(true);
 -            desc.staticallyConfigured(true);
 -            desc.receivedFrom(ctx.localNodeId());
 +        if (registeredCaches.containsKey(masked)) {
 +            String cacheName = cfg.getName();
  
 -            if (!template) {
 -                registeredCaches.put(masked, desc);
 +            if (cacheName != null)
 +                throw new IgniteCheckedException("Duplicate cache name found (check configuration and " +
 +                    "assign unique name to each cache): " + U.maskName(cacheName));
 +            else
 +                throw new IgniteCheckedException("Default cache has already been configured (check configuration and " +
 +                    "assign unique name to each cache).");
 +        }
  
 -                ctx.discovery().setCacheFilter(
 -                    cfg.getName(),
 -                    cfg.getNodeFilter(),
 -                    cfg.getNearConfiguration() != null && cfg.getCacheMode() == PARTITIONED,
 -                    cfg.getCacheMode());
 +        CacheType cacheType;
  
 -                ctx.discovery().addClientNode(cfg.getName(),
 -                    ctx.localNodeId(),
 -                    cfg.getNearConfiguration() != null);
 +        if (CU.isUtilityCache(cfg.getName()))
 +            cacheType = CacheType.UTILITY;
-         else if (CU.isMarshallerCache(cfg.getName()))
-             cacheType = CacheType.MARSHALLER;
 +        else if (internalCaches.contains(maskNull(cfg.getName())))
 +            cacheType = CacheType.INTERNAL;
 +        else
 +            cacheType = CacheType.USER;
  
 -                if (!cacheType.userCache())
 -                    stopSeq.addLast(cfg.getName());
 -                else
 -                    stopSeq.addFirst(cfg.getName());
 -            }
 -            else {
 -                if (log.isDebugEnabled())
 -                    log.debug("Use cache configuration as template: " + cfg);
 +        boolean template = cfg.getName() != null && cfg.getName().endsWith("*");
  
 -                registeredTemplates.put(masked, desc);
 -            }
 +        DynamicCacheDescriptor desc = new DynamicCacheDescriptor(ctx,
 +            cfg,
 +            cacheType,
 +            template,
 +            IgniteUuid.randomUuid());
  
 -            if (cfg.getName() == null) { // Use cache configuration with null name as template.
 -                DynamicCacheDescriptor desc0 =
 -                    new DynamicCacheDescriptor(ctx, cfg, cacheType, true, IgniteUuid.randomUuid());
 +        desc.locallyConfigured(true);
 +        desc.staticallyConfigured(true);
 +        desc.receivedFrom(ctx.localNodeId());
  
 -                desc0.locallyConfigured(true);
 -                desc0.staticallyConfigured(true);
 +        if (!template) {
 +            registeredCaches.put(masked, desc);
  
 -                registeredTemplates.put(masked, desc0);
 -            }
 +            ctx.discovery().setCacheFilter(
 +                cfg.getName(),
 +                cfg.getNodeFilter(),
 +                cfg.getNearConfiguration() != null && cfg.getCacheMode() == PARTITIONED,
 +                cfg.getCacheMode());
 +
 +            ctx.discovery().addClientNode(cfg.getName(),
 +                ctx.localNodeId(),
 +                cfg.getNearConfiguration() != null);
 +
 +            if (!cacheType.userCache())
 +                stopSeq.addLast(cfg.getName());
 +            else
 +                stopSeq.addFirst(cfg.getName());
          }
 +        else {
 +            if (log.isDebugEnabled())
 +                log.debug("Use cache configuration as template: " + cfg);
  
 -        // Start shared managers.
 -        for (GridCacheSharedManager mgr : sharedCtx.managers())
 -            mgr.start(sharedCtx);
 +            registeredTemplates.put(masked, desc);
 +        }
  
 -        transactions = new IgniteTransactionsImpl(sharedCtx);
 +        if (cfg.getName() == null) { // Use cache configuration with null name as template.
 +            DynamicCacheDescriptor desc0 = new DynamicCacheDescriptor(ctx,
 +                cfg,
 +                cacheType,
 +                true,
 +                IgniteUuid.randomUuid());
  
 -        if (log.isDebugEnabled())
 -            log.debug("Started cache processor.");
 +            desc0.locallyConfigured(true);
 +            desc0.staticallyConfigured(true);
 +
 +            registeredTemplates.put(masked, desc0);
 +        }
      }
  
      /**
@@@ -776,27 -769,11 +782,27 @@@
                          }
                      }
                  }
 +
 +                if (!tmpCacheCfg.isEmpty()) {
 +                    CacheConfiguration[] newCacheCfg = new CacheConfiguration[tmpCacheCfg.size()];
 +
 +                    tmpCacheCfg.toArray(newCacheCfg);
 +
 +                    ctx.config().setCacheConfiguration(newCacheCfg);
 +                }
 +
 +                activeOnStart = currStatus;
              }
  
 +            if (activeOnStart && !ctx.clientNode() && !ctx.isDaemon())
 +                sharedCtx.database().lock();
 +
 +            // Must start database before start first cache.
 +            sharedCtx.database().onKernalStart(false);
 +
              // Start dynamic caches received from collect discovery data.
              for (DynamicCacheDescriptor desc : registeredCaches.values()) {
-                 if (ctx.config().isDaemon() && !CU.isMarshallerCache(desc.cacheConfiguration().getName()))
+                 if (ctx.config().isDaemon())
                      continue;
  
                  desc.clearRemoteConfigurations();
@@@ -878,50 -848,34 +882,60 @@@
              }
          }
  
-         assert caches.containsKey(CU.MARSH_CACHE_NAME) : "Marshaller cache should be started";
          assert ctx.config().isDaemon() || caches.containsKey(CU.UTILITY_CACHE_NAME) : "Utility cache should be started";
+ 
+         if (!ctx.clientNode() && !ctx.isDaemon())
+             addRemovedItemsCleanupTask(Long.getLong(IGNITE_CACHE_REMOVED_ENTRIES_TTL, 10_000));
+ 
+     }
+ 
+     /**
+      * @param timeout Cleanup timeout.
+      */
+     private void addRemovedItemsCleanupTask(long timeout) {
+         ctx.timeout().addTimeoutObject(new RemovedItemsCleanupTask(timeout));
      }
  
 -    /** {@inheritDoc} */
 -    @SuppressWarnings("unchecked")
 -    @Override public void stop(boolean cancel) throws IgniteCheckedException {
 -        for (String cacheName : stopSeq) {
 -            GridCacheAdapter<?, ?> cache = stoppedCaches.remove(maskNull(cacheName));
 +    /**
 +     *
 +     */
 +    private void checkConsistency() throws IgniteCheckedException {
 +        if (!ctx.config().isDaemon() && !getBoolean(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK)) {
 +            for (ClusterNode n : ctx.discovery().remoteNodes()) {
 +                if (n.attribute(ATTR_CONSISTENCY_CHECK_SKIPPED))
 +                    continue;
  
 -            if (cache != null)
 -                stopCache(cache, cancel);
 -        }
 +                checkTransactionConfiguration(n);
  
 -        for (GridCacheAdapter<?, ?> cache : stoppedCaches.values()) {
 -            if (cache == stoppedCaches.remove(maskNull(cache.name())))
 -                stopCache(cache, cancel);
 +                DeploymentMode locDepMode = ctx.config().getDeploymentMode();
 +                DeploymentMode rmtDepMode = n.attribute(IgniteNodeAttributes.ATTR_DEPLOYMENT_MODE);
 +
 +                CU.checkAttributeMismatch(
 +                    log, null, n.id(), "deploymentMode", "Deployment mode",
 +                    locDepMode, rmtDepMode, true);
 +
 +                for (DynamicCacheDescriptor desc : registeredCaches.values()) {
 +                    CacheConfiguration rmtCfg = desc.remoteConfiguration(n.id());
 +
 +                    if (rmtCfg != null) {
 +                        CacheConfiguration locCfg = desc.cacheConfiguration();
 +
 +                        checkCache(locCfg, rmtCfg, n);
 +
 +                        // Check plugin cache configurations.
 +                        CachePluginManager pluginMgr = desc.pluginManager();
 +
 +                        pluginMgr.validateRemotes(rmtCfg, n);
 +                    }
 +                }
 +            }
          }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Override public void stop(boolean cancel) throws IgniteCheckedException {
 +        stopCaches(cancel);
  
          List<? extends GridCacheSharedManager<?, ?>> mgrs = sharedCtx.managers();
  
@@@ -2032,83 -1932,93 +2058,93 @@@
  
              clientNodesMap = U.newHashMap(caches.size());
  
-             for (GridCacheAdapter<?, ?> cache : caches.values()) {
-                 DynamicCacheDescriptor desc = cachesOnDisconnect.get(maskNull(cache.name()));
+             collectDataOnReconnectingNode(reqs, clientNodesMap, joiningNodeId);
+         }
+         else {
 -            reqs = new ArrayList<>(registeredCaches.size() + registeredTemplates.size());
++            reqs = new ArrayList<>(registeredCaches.size() + registeredTemplates.size() + 1);
  
-                 if (desc == null)
-                     continue;
+             clientNodesMap = ctx.discovery().clientNodesMap();
  
-                 // RequestId must be null because on different node will be different byte [] and
-                 // we get duplicate discovery data, for more details see
-                 // TcpDiscoveryNodeAddedMessage#addDiscoveryData.
-                 DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(
-                     null, cache.name(), null);
+             collectDataOnGridNode(reqs);
+         }
  
-                 req.startCacheConfiguration(desc.cacheConfiguration());
+         DynamicCacheChangeBatch batch = new DynamicCacheChangeBatch(reqs);
  
-                 req.cacheType(desc.cacheType());
+         batch.clientNodes(clientNodesMap);
  
-                 req.deploymentId(desc.deploymentId());
+         batch.clientReconnect(reconnect);
  
-                 req.receivedFrom(desc.receivedFrom());
+         // Reset random batch ID so that serialized batches with the same descriptors will be exactly the same.
+         batch.id(null);
  
-                 reqs.add(req);
+         return batch;
+     }
  
-                 Boolean nearEnabled = cache.isNear();
+     /**
+      * @param reqs requests.
+      */
+     private void collectDataOnGridNode(Collection<DynamicCacheChangeRequest> reqs) {
+         for (DynamicCacheDescriptor desc : registeredCaches.values()) {
+             DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(desc.cacheConfiguration().getName(), null);
  
-                 Map<UUID, Boolean> map = U.newHashMap(1);
+             req.startCacheConfiguration(desc.cacheConfiguration());
  
-                 map.put(nodeId, nearEnabled);
+             req.cacheType(desc.cacheType());
  
-                 clientNodesMap.put(cache.name(), map);
-             }
-         }
-         else {
-             reqs = new ArrayList<>(registeredCaches.size() + registeredTemplates.size() + 1);
+             req.deploymentId(desc.deploymentId());
  
-             for (DynamicCacheDescriptor desc : registeredCaches.values()) {
-                 DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(
-                     null, desc.cacheConfiguration().getName(), null);
+             req.receivedFrom(desc.receivedFrom());
  
-                 req.startCacheConfiguration(desc.cacheConfiguration());
+             reqs.add(req);
+         }
  
-                 req.cacheType(desc.cacheType());
+         for (DynamicCacheDescriptor desc : registeredTemplates.values()) {
+             DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(desc.cacheConfiguration().getName(), null);
  
-                 req.deploymentId(desc.deploymentId());
+             req.startCacheConfiguration(desc.cacheConfiguration());
  
-                 req.receivedFrom(desc.receivedFrom());
+             req.template(true);
  
-                 reqs.add(req);
-             }
+             reqs.add(req);
+         }
+     }
  
-             for (DynamicCacheDescriptor desc : registeredTemplates.values()) {
-                 DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(
-                     null, desc.cacheConfiguration().getName(), null);
+     /**
+      * @param reqs requests.
+      * @param clientNodesMap Client nodes map.
+      * @param nodeId Node id.
+      */
+     private void collectDataOnReconnectingNode(
+             Collection<DynamicCacheChangeRequest> reqs,
+             Map<String, Map<UUID, Boolean>> clientNodesMap,
+             UUID nodeId
+     ) {
+         for (GridCacheAdapter<?, ?> cache : caches.values()) {
+             DynamicCacheDescriptor desc = cachesOnDisconnect.get(maskNull(cache.name()));
  
-                 req.startCacheConfiguration(desc.cacheConfiguration());
+             if (desc == null)
+                 continue;
  
-                 req.template(true);
+             DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(cache.name(), null);
  
-                 //todo check why id removed
-                /* req.deploymentId(desc.deploymentId());*/
+             req.startCacheConfiguration(desc.cacheConfiguration());
  
-                 reqs.add(req);
-             }
+             req.cacheType(desc.cacheType());
  
-             clientNodesMap = ctx.discovery().clientNodesMap();
-         }
+             req.deploymentId(desc.deploymentId());
  
-         DynamicCacheChangeBatch batch = new DynamicCacheChangeBatch(reqs);
+             req.receivedFrom(desc.receivedFrom());
  
-         batch.clientNodes(clientNodesMap);
+             reqs.add(req);
  
-         batch.clientReconnect(reconnect);
+             Boolean nearEnabled = cache.isNear();
  
-         //todo check
-         // Reset random batch ID so that serialized batches with the same descriptors will be exactly the same.
-         batch.id(null);
+             Map<UUID, Boolean> map = U.newHashMap(1);
  
-         return batch;
+             map.put(nodeId, nearEnabled);
+ 
+             clientNodesMap.put(cache.name(), map);
+         }
      }
  
      /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheTtlManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
index 89c54c4,7e4deff..bd4c4ac
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
@@@ -260,51 -263,6 +264,51 @@@ public abstract class GridDistributedCa
      }
  
      /** {@inheritDoc} */
 +    @Override public long localSizeLong(CachePeekMode[] peekModes) throws IgniteCheckedException {
 +        PeekModes modes = parsePeekModes(peekModes, true);
 +
 +        long size = 0;
 +
 +        if (modes.near)
 +            size += nearSize();
 +
 +        // Swap and offheap are disabled for near cache.
 +        if (modes.primary || modes.backup) {
 +            AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
 +
 +            IgniteCacheOffheapManager offheap = ctx.offheap();
 +
 +            if (modes.offheap)
 +                size += offheap.entriesCount(modes.primary, modes.backup, topVer);
 +        }
 +
 +        return size;
 +    }
 +
 +    /** {@inheritDoc} */
-     @Override public long localSizeLong(int partition, CachePeekMode[] peekModes) throws IgniteCheckedException {
++    @Override public long localSizeLong(int part, CachePeekMode[] peekModes) throws IgniteCheckedException {
 +        PeekModes modes = parsePeekModes(peekModes, true);
 +
 +        long size = 0;
 +
 +        if (modes.near)
 +            size += nearSize();
 +
 +        // Swap and offheap are disabled for near cache.
 +        if (modes.offheap) {
 +            AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
 +
 +            IgniteCacheOffheapManager offheap = ctx.offheap();
 +
-             if (ctx.affinity().primary(ctx.localNode(), partition, topVer) && modes.primary ||
-                 ctx.affinity().backup(ctx.localNode(), partition, topVer) && modes.backup)
-                 size += offheap.entriesCount(partition);
++            if (ctx.affinity().primaryByPartition(ctx.localNode(), part, topVer) && modes.primary ||
++                ctx.affinity().backupByPartition(ctx.localNode(), part, topVer) && modes.backup)
++                size += offheap.entriesCount(part);
 +        }
 +
 +        return size;
 +    }
 +
 +    /** {@inheritDoc} */
      @Override public String toString() {
          return S.toString(GridDistributedCacheAdapter.class, this, "super", super.toString());
      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
index fba1877,f5865e6..0c935ec
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
@@@ -650,10 -657,10 +654,11 @@@ public abstract class GridDhtCacheAdapt
          String taskName,
          @Nullable IgniteCacheExpiryPolicy expiry,
          boolean skipVals,
 -        boolean canRemap
 +        boolean canRemap,
 +        boolean recovery
      ) {
          return getAllAsync0(keys,
+             readerArgs,
              readThrough,
              /*don't check local tx. */false,
              subjId,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
index 2c3435d,f6db669..bbf0cb5
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
@@@ -395,29 -393,19 +398,20 @@@ public final class GridDhtGetFuture<K, 
          IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> fut;
  
          if (txFut == null || txFut.isDone()) {
-             if (tx == null) {
-                 fut = cache().getDhtAllAsync(
-                     keys.keySet(),
-                     readThrough,
-                     subjId,
-                     taskName,
-                     expiryPlc,
-                     skipVals,
-                     /*can remap*/true,
-                     recovery);
-             }
-             else {
-                 fut = tx.getAllAsync(cctx,
-                     null,
-                     keys.keySet(),
-                     /*deserialize binary*/false,
-                     skipVals,
-                     /*keep cache objects*/true,
-                     /*skip store*/!readThrough,
-                     false);
-             }
+             fut = cache().getDhtAllAsync(
+                 keys.keySet(),
+                 readerArgs,
+                 readThrough,
+                 subjId,
+                 taskName,
+                 expiryPlc,
+                 skipVals,
 -                /*can remap*/true);
++                /*can remap*/true,
++                recovery);
          }
          else {
+             final ReaderArguments args = readerArgs;
+ 
              // If we are here, then there were active transactions for some entries
              // when we were adding the reader. In that case we must wait for those
              // transactions to complete.
@@@ -428,27 -416,15 +422,16 @@@
                          if (e != null)
                              throw new GridClosureException(e);
  
-                         if (tx == null) {
-                             return cache().getDhtAllAsync(
-                                 keys.keySet(),
-                                 readThrough,
-                                 subjId,
-                                 taskName,
-                                 expiryPlc,
-                                 skipVals,
-                                 /*can remap*/true,
-                                 recovery);
-                         }
-                         else {
-                             return tx.getAllAsync(cctx,
-                                 null,
-                                 keys.keySet(),
-                                 /*deserialize binary*/false,
-                                 skipVals,
-                                 /*keep cache objects*/true,
-                                 /*skip store*/!readThrough,
-                                 false);
-                         }
+                         return cache().getDhtAllAsync(
+                             keys.keySet(),
+                             args,
+                             readThrough,
+                             subjId,
+                             taskName,
+                             expiryPlc,
+                             skipVals,
 -                            /*can remap*/true);
++                            /*can remap*/true,
++                            recovery);
                      }
                  }
              );

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetSingleFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetSingleFuture.java
index 81d2570,0cb3920..ccccd76
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetSingleFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetSingleFuture.java
@@@ -353,29 -351,19 +356,20 @@@ public final class GridDhtGetSingleFutu
          IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> fut;
  
          if (rdrFut == null || rdrFut.isDone()) {
-             if (tx == null) {
-                 fut = cache().getDhtAllAsync(
-                     Collections.singleton(key),
-                     readThrough,
-                     subjId,
-                     taskName,
-                     expiryPlc,
-                     skipVals,
-                     /*can remap*/true,
-                     recovery);
-             }
-             else {
-                 fut = tx.getAllAsync(cctx,
-                     null,
-                     Collections.singleton(key),
-                     /*deserialize binary*/false,
-                     skipVals,
-                     /*keep cache objects*/true,
-                     /*skip store*/!readThrough,
-                     false);
-             }
+             fut = cache().getDhtAllAsync(
+                 Collections.singleton(key),
+                 readerArgs,
+                 readThrough,
+                 subjId,
+                 taskName,
+                 expiryPlc,
+                 skipVals,
 -                /*can remap*/true);
++                /*can remap*/true,
++                recovery);
          }
          else {
+             final ReaderArguments args = readerArgs;
+ 
              rdrFut.listen(
                  new IgniteInClosure<IgniteInternalFuture<Boolean>>() {
                      @Override public void apply(IgniteInternalFuture<Boolean> fut) {
@@@ -397,20 -384,7 +390,8 @@@
                                  taskName,
                                  expiryPlc,
                                  skipVals,
 -                                /*can remap*/true);
 +                                /*can remap*/true,
 +                                recovery);
-                         }
-                         else {
-                             fut0 = tx.getAllAsync(cctx,
-                                 null,
-                                 Collections.singleton(key),
-                                 /*deserialize binary*/false,
-                                 skipVals,
-                                 /*keep cache objects*/true,
-                                 /*skip store*/!readThrough,
-                                 false
-                             );
-                         }
  
                          fut0.listen(createGetFutureListener());
                      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
index 9b30593,9f8498a..444fcdb
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
@@@ -49,24 -44,23 +49,25 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader;
  import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntryExtras;
  import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
- import org.apache.ignite.internal.util.GridCircularBuffer;
+ import org.apache.ignite.internal.processors.query.GridQueryProcessor;
  import org.apache.ignite.internal.util.future.GridFutureAdapter;
 -import org.apache.ignite.internal.util.lang.GridCloseableIterator;
 +import org.apache.ignite.internal.util.lang.GridIterator;
  import org.apache.ignite.internal.util.tostring.GridToStringExclude;
- import org.apache.ignite.internal.util.typedef.CI1;
- import org.apache.ignite.internal.util.typedef.T2;
+ import org.apache.ignite.internal.util.typedef.F;
  import org.apache.ignite.internal.util.typedef.internal.CU;
  import org.apache.ignite.internal.util.typedef.internal.S;
  import org.apache.ignite.internal.util.typedef.internal.U;
  import org.apache.ignite.lang.IgniteUuid;
  import org.jetbrains.annotations.NotNull;
  import org.jetbrains.annotations.Nullable;
+ import org.jsr166.ConcurrentLinkedDeque8;
  
  import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE;
+ import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_REMOVED_ENTRIES_TTL;
  import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_OBJECT_UNLOADED;
 +import static org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager.CacheDataStore;
  import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.EVICTED;
 +import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.LOST;
  import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.MOVING;
  import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING;
  import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.RENTING;
@@@ -160,22 -149,9 +166,24 @@@ public class GridDhtLocalPartition impl
          int delQueueSize = CU.isSystemCache(cctx.name()) ? 100 :
              Math.max(MAX_DELETE_QUEUE_SIZE / cctx.affinity().partitions(), 20);
  
-         rmvQueue = new GridCircularBuffer<>(U.ceilPow2(delQueueSize));
+         rmvQueueMaxSize = U.ceilPow2(delQueueSize);
+ 
+         rmvdEntryTtl = Long.getLong(IGNITE_CACHE_REMOVED_ENTRIES_TTL, 10_000);
 +
 +        try {
 +            store = cctx.offheap().createCacheDataStore(id);
 +        }
 +        catch (IgniteCheckedException e) {
 +            // TODO ignite-db
 +            throw new IgniteException(e);
 +        }
 +    }
 +
 +    /**
 +     * @return Data store.
 +     */
 +    public CacheDataStore dataStore() {
 +        return store;
      }
  
      /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
index 322bbe3,75a275c..e11a770
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
@@@ -761,14 -691,12 +761,14 @@@ class GridDhtPartitionTopologyImpl impl
          try {
              loc = locParts.get(p);
  
 +            state = loc != null ? loc.state() : null;
 +
-             boolean belongs = cctx.affinity().localNode(p, topVer);
+             boolean belongs = cctx.affinity().partitionLocalNode(p, topVer);
  
 -            if (loc != null && loc.state() == EVICTED) {
 +            if (loc != null && state == EVICTED) {
                  locParts.set(p, loc = null);
  
 -                if (!belongs)
 +                if (!treatAllPartAsLoc && !belongs)
                      throw new GridDhtInvalidPartitionException(p, "Adding entry to evicted partition " +
                          "(often may be caused by inconsistent 'key.hashCode()' implementation) " +
                          "[part=" + p + ", topVer=" + topVer + ", this.topVer=" + this.topVer + ']');

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
index debf8b6,67e1993..842a70b
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
@@@ -583,21 -585,25 +585,21 @@@ public abstract class GridDhtTxLocalAda
                  if (txEntry == null) {
                      GridDhtCacheEntry cached;
  
 -                    if (dhtCache.context().isSwapOrOffheapEnabled()) {
 -                        while (true) {
 -                            try {
 -                                cached = dhtCache.entryExx(key, topVer);
 +                    while (true) {
 +                        try {
 +                            cached = dhtCache.entryExx(key, topVer);
  
 -                                cached.unswap(read);
 +                            cached.unswap(read);
  
 -                                break;
 -                            }
 -                            catch (GridCacheEntryRemovedException ignored) {
 -                                if (log.isDebugEnabled())
 -                                    log.debug("Get removed entry: " + key);
 -                            }
 +                            break;
 +                        }
-                         catch (GridCacheEntryRemovedException ignore) {
++                        catch (GridCacheEntryRemovedException ignored) {
 +                            if (log.isDebugEnabled())
 +                                log.debug("Get removed entry: " + key);
                          }
                      }
 -                    else
 -                        cached = dhtCache.entryExx(key, topVer);
  
 -                    addActiveCache(dhtCache.context());
 +                    addActiveCache(dhtCache.context(), false);
  
                      txEntry = addEntry(NOOP,
                          null,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
index 6c4da68,1fe2d69..a088adf
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
@@@ -353,10 -341,10 +354,11 @@@ public class GridPartitionedGetFuture<K
                      topVer,
                      subjId,
                      taskName == null ? 0 : taskName.hashCode(),
+                     expiryPlc != null ? expiryPlc.forCreate() : -1L,
                      expiryPlc != null ? expiryPlc.forAccess() : -1L,
                      skipVals,
 -                    cctx.deploymentEnabled());
 +                    cctx.deploymentEnabled(),
 +                    recovery);
  
                  add(fut); // Append new future.
  
@@@ -461,9 -451,11 +463,9 @@@
                      GridCacheVersion ver = null;
  
                      if (needVer) {
-                         T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                         EntryGetResult res = entry.innerGetVersioned(
                              null,
                              null,
 -                            /*swap*/true,
 -                            /*unmarshal*/true,
                              /**update-metrics*/false,
                              /*event*/!skipVals,
                              subjId,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
index ea69743,bdccaa3..a46b7f6
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
@@@ -316,10 -301,10 +318,11 @@@ public class GridPartitionedSingleGetFu
                      topVer,
                      subjId,
                      taskName == null ? 0 : taskName.hashCode(),
+                     expiryPlc != null ? expiryPlc.forCreate() : -1L,
                      expiryPlc != null ? expiryPlc.forAccess() : -1L,
                      skipVals,
 -                    cctx.deploymentEnabled());
 +                    cctx.deploymentEnabled(),
 +                    recovery);
              }
  
              try {
@@@ -388,9 -376,11 +391,9 @@@
                      GridCacheVersion ver = null;
  
                      if (needVer) {
-                         T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                         EntryGetResult res = entry.innerGetVersioned(
                              null,
                              null,
 -                            /*swap*/true,
 -                            /*unmarshal*/true,
                              /**update-metrics*/false,
                              /*event*/!skipVals,
                              subjId,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index 72489fd,1b6179e..cdb19a4
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@@ -555,11 -548,8 +556,10 @@@ public class GridDhtAtomicCache<K, V> e
      /** {@inheritDoc} */
      @Override protected Map<K, V> getAll0(Collection<? extends K> keys, boolean deserializeBinary, boolean needVer)
          throws IgniteCheckedException {
 +        CacheOperationContext opCtx = ctx.operationContextPerCall();
 +
          return getAllAsyncInternal(keys,
              !ctx.config().isReadFromBackup(),
-             true,
              null,
              ctx.kernalContext().job().currentTaskName(),
              deserializeBinary,
@@@ -1607,10 -1584,12 +1605,10 @@@
                              GridCacheVersion ver = null;
  
                              if (needVer) {
-                                 T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                                 EntryGetResult res = entry.innerGetVersioned(
                                      null,
                                      null,
 -                                    /*swap*/true,
 -                                    /*unmarshal*/true,
 -                                    /**update-metrics*/false,
 +                                    /*update-metrics*/false,
                                      /*event*/!skipVals,
                                      subjId,
                                      null,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicFullUpdateRequest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
index d5e8389,4b090ad..73d46c4
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
@@@ -476,9 -472,11 +477,9 @@@ public class GridDhtColocatedCache<K, V
                              GridCacheVersion ver = null;
  
                              if (needVer) {
-                                 T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                                 EntryGetResult res = entry.innerGetVersioned(
                                      null,
                                      null,
 -                                    /*swap*/true,
 -                                    /*unmarshal*/true,
                                      /**update-metrics*/false,
                                      /*event*/!skipVals,
                                      subjId,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
index 358ec8f,79ca108..b7d6a2b
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
@@@ -911,37 -911,38 +917,38 @@@ public final class GridDhtColocatedLock
                                          !topLocked &&
                                          (tx == null || !tx.hasRemoteLocks());
  
 -                                        first = false;
 -                                    }
 +                                    first = false;
 +                                }
  
-                                 req = new GridNearLockRequest(
-                                     cctx.cacheId(),
-                                     topVer,
-                                     cctx.nodeId(),
-                                     threadId,
-                                     futId,
-                                     lockVer,
-                                     inTx(),
-                                     implicitTx(),
-                                     implicitSingleTx(),
-                                     read,
-                                     retval,
-                                     isolation(),
-                                     isInvalidate(),
-                                     timeout,
-                                     mappedKeys.size(),
-                                     inTx() ? tx.size() : mappedKeys.size(),
-                                     inTx() && tx.syncMode() == FULL_SYNC,
-                                     inTx() ? tx.subjectId() : null,
-                                     inTx() ? tx.taskNameHash() : 0,
-                                     read ? accessTtl : -1L,
-                                     skipStore,
-                                     keepBinary,
-                                     clientFirst,
-                                     cctx.deploymentEnabled());
+                                     req = new GridNearLockRequest(
+                                         cctx.cacheId(),
+                                         topVer,
+                                         cctx.nodeId(),
+                                         threadId,
+                                         futId,
+                                         lockVer,
+                                         inTx(),
+                                         implicitTx(),
+                                         implicitSingleTx(),
+                                         read,
+                                         retval,
+                                         isolation(),
+                                         isInvalidate(),
+                                         timeout,
+                                         mappedKeys.size(),
+                                         inTx() ? tx.size() : mappedKeys.size(),
+                                         inTx() && tx.syncMode() == FULL_SYNC,
+                                         inTx() ? tx.subjectId() : null,
+                                         inTx() ? tx.taskNameHash() : 0,
+                                         read ? createTtl : -1L,
+                                         read ? accessTtl : -1L,
+                                         skipStore,
+                                         keepBinary,
+                                         clientFirst,
+                                         cctx.deploymentEnabled());
  
 -                                    mapping.request(req);
 -                                }
 +                                mapping.request(req);
 +                            }
  
                              distributedKeys.add(key);
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionMap2.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
index 97d768a,9942423..b80ad04
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
@@@ -272,24 -288,22 +272,24 @@@ class GridDhtPartitionSupplier 
                      boolean partMissing = false;
  
                      if (phase == SupplyContextPhase.NEW)
 -                        phase = SupplyContextPhase.ONHEAP;
 +                        phase = SupplyContextPhase.OFFHEAP;
 +
 +                    if (phase == SupplyContextPhase.OFFHEAP) {
 +                        IgniteRebalanceIterator iter;
 +
 +                        if (sctx == null || sctx.entryIt == null) {
 +                            iter = cctx.offheap().rebalanceIterator(part, d.topologyVersion(), d.partitionCounter(part));
  
 -                    if (phase == SupplyContextPhase.ONHEAP) {
 -                        Iterator<GridCacheMapEntry> entIt = sctx != null ?
 -                            (Iterator<GridCacheMapEntry>)sctx.entryIt : loc.allEntries().iterator();
 +                            if (!iter.historical())
 +                                s.clean(part);
 +                        }
 +                        else
 +                            iter = (IgniteRebalanceIterator)sctx.entryIt;
  
 -                        while (entIt.hasNext()) {
 +                        while (iter.hasNext()) {
-                             if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
+                             if (!cctx.affinity().partitionBelongs(node, part, d.topologyVersion())) {
 -                                // Demander no longer needs this partition, so we send '-1' partition and move on.
 +                                // Demander no longer needs this partition,
 +                                // so we send '-1' partition and move on.
                                  s.missed(part);
  
                                  if (log.isDebugEnabled())

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index af0085d,a334fd5..68ce5ea
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@@ -1402,11 -1183,10 +1407,13 @@@ public class GridDhtPartitionsExchangeF
  
              if (crd.isLocal()) {
                  if (remaining.remove(node.id())) {
-                     updatePartitionSingleMap(node, msg);
+                     updateSingleMap = true;
+ 
+                     pendingSingleUpdates++;
  
 +                    if (exchangeOnChangeGlobalState && msg.getException() != null)
 +                        changeGlobalStateExceptions.put(node.id(), msg.getException());
 +
                      allReceived = remaining.isEmpty();
                  }
              }
@@@ -1414,8 -1194,42 +1421,42 @@@
                  singleMsgs.put(node, msg);
          }
  
-         if (allReceived)
+         if (updateSingleMap) {
+             try {
 -                updatePartitionSingleMap(msg);
++                updatePartitionSingleMap(node, msg);
+             }
+             finally {
+                 synchronized (mux) {
+                     assert pendingSingleUpdates > 0;
+ 
+                     pendingSingleUpdates--;
+ 
+                     if (pendingSingleUpdates == 0)
+                         mux.notifyAll();
+                 }
+             }
+         }
+ 
+         if (allReceived) {
+             awaitSingleMapUpdates();
+ 
              onAllReceived();
+         }
+     }
+ 
+     /**
+      *
+      */
+     private void awaitSingleMapUpdates() {
+         synchronized (mux) {
+             try {
+                 while (pendingSingleUpdates > 0)
+                     U.wait(mux);
+             }
+             catch (IgniteInterruptedCheckedException e) {
+                 U.warn(log, "Failed to wait for partition map updates, thread was interrupted: " + e);
+             }
+         }
      }
  
      /**
@@@ -1937,10 -1613,9 +1978,12 @@@
                          }
  
                          if (crd0.isLocal()) {
 +                            if (exchangeOnChangeGlobalState && changeGlobalStateE !=null)
 +                                changeGlobalStateExceptions.put(crd0.id(), changeGlobalStateE);
 +
                              if (allReceived) {
+                                 awaitSingleMapUpdates();
+ 
                                  onAllReceived();
  
                                  return;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index ff4e838,480b323..641f73d
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@@ -377,10 -375,10 +378,11 @@@ public final class GridNearGetFuture<K
                      topVer,
                      subjId,
                      taskName == null ? 0 : taskName.hashCode(),
+                     expiryPlc != null ? expiryPlc.forCreate() : -1L,
                      expiryPlc != null ? expiryPlc.forAccess() : -1L,
                      skipVals,
 -                    cctx.deploymentEnabled());
 +                    cctx.deploymentEnabled(),
 +                    recovery);
  
                  add(fut); // Append new future.
  
@@@ -441,9 -439,11 +443,9 @@@
                  // First we peek into near cache.
                  if (isNear) {
                      if (needVer) {
-                         T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                         EntryGetResult res = entry.innerGetVersioned(
                              null,
                              null,
 -                            /*swap*/true,
 -                            /*unmarshal*/true,
                              /**update-metrics*/true,
                              /*event*/!skipVals,
                              subjId,
@@@ -577,9 -580,11 +580,9 @@@
                      boolean isNew = dhtEntry.isNewLocked() || !dhtEntry.valid(topVer);
  
                      if (needVer) {
-                         T2<CacheObject, GridCacheVersion> res = dhtEntry.innerGetVersioned(
+                         EntryGetResult res = dhtEntry.innerGetVersioned(
                              null,
                              null,
 -                            /*swap*/true,
 -                            /*unmarshal*/true,
                              /**update-metrics*/false,
                              /*event*/!nearRead && !skipVals,
                              subjId,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
index b096d5d,7ca2635..c5aec19
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
@@@ -137,10 -138,10 +141,11 @@@ public class GridNearGetRequest extend
          @NotNull AffinityTopologyVersion topVer,
          UUID subjId,
          int taskNameHash,
+         long createTtl,
          long accessTtl,
          boolean skipVals,
 -        boolean addDepInfo
 +        boolean addDepInfo,
 +        boolean recovery
      ) {
          assert futId != null;
          assert miniId != null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
index f09b6c8,976f05f..1d610c7
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
@@@ -62,6 -62,19 +62,19 @@@ public abstract class GridNearOptimisti
          }
  
          if (topVer != null) {
+             try {
 -                IgniteCheckedException err = tx.txState().validateTopology(cctx, topologyReadLock());
++                IgniteCheckedException err = tx.txState().validateTopology(cctx, false, topologyReadLock());
+ 
+                 if (err != null) {
+                     onDone(err);
+ 
+                     return;
+                 }
+             }
+             finally {
+                 topologyReadUnlock();
+             }
+ 
              tx.topologyVersion(topVer);
  
              cctx.mvcc().addFuture(this);

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index ba48e7a,197792b..cc2c090
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@@ -329,17 -329,20 +329,22 @@@ public class GridNearTxLocal extends Gr
          final boolean skipVals,
          final boolean needVer,
          boolean keepBinary,
 +        boolean recovery,
+         final ExpiryPolicy expiryPlc,
          final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c
      ) {
+         IgniteCacheExpiryPolicy expiryPlc0 = optimistic() ?
+             accessPolicy(cacheCtx, keys) :
+             cacheCtx.cache().expiryPolicy(expiryPlc);
+ 
          if (cacheCtx.isNear()) {
              return cacheCtx.nearTx().txLoadAsync(this,
                  topVer,
                  keys,
                  readThrough,
                  /*deserializeBinary*/false,
 +                recovery,
-                 accessPolicy(cacheCtx, keys),
+                 expiryPlc0,
                  skipVals,
                  needVer).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
                  @Override public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
@@@ -402,8 -404,7 +407,8 @@@
                      CU.subjectId(this, cctx),
                      resolveTaskName(),
                      /*deserializeBinary*/false,
 +                    recovery,
-                     accessPolicy(cacheCtx, keys),
+                     expiryPlc0,
                      skipVals,
                      /*can remap*/true,
                      needVer,
@@@ -437,7 -438,7 +442,8 @@@
                  skipVals,
                  keepBinary,
                  needVer,
 +                recovery,
+                 expiryPlc,
                  c);
          }
      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCache.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
index 7aaa476,695fdcb..d687d50
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
@@@ -410,9 -415,11 +411,9 @@@ public class GridLocalAtomicCache<K, V
                          GridCacheVersion ver;
  
                          if (needVer) {
-                             T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                             EntryGetResult res = entry.innerGetVersioned(
                                  null,
                                  null,
 -                                /*swap*/swapOrOffheap,
 -                                /*unmarshal*/true,
                                  /**update-metrics*/false,
                                  /*event*/!skipVals,
                                  subjId,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
index 6731179,c434401..f7608c9
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
@@@ -365,12 -380,22 +377,22 @@@ public abstract class GridCacheQueryMan
       * @param key Key.
       * @throws IgniteCheckedException If failed.
       */
 -    public void onSwap(CacheObject key) throws IgniteCheckedException {
 +    public void onSwap(KeyCacheObject key, int partId) throws IgniteCheckedException {
+         if(!enabled)
+             return;
+ 
          if (!enterBusy())
              return; // Ignore index update when node is stopping.
  
          try {
-             qryProc.onSwap(space, key, partId);
+             if (isIndexingSpiEnabled()) {
+                 Object key0 = unwrapIfNeeded(key, cctx.cacheObjectContext());
+ 
+                 cctx.kernalContext().indexing().onSwap(space, key0);
+             }
+ 
 -            if(qryProcEnabled)
 -                qryProc.onSwap(space, key);
++            if (qryProcEnabled)
++                qryProc.onSwap(space, key, partId);
          }
          finally {
              leaveBusy();
@@@ -384,12 -417,26 +414,26 @@@
       * @param val Value
       * @throws IgniteCheckedException If failed.
       */
 -    public void onUnswap(CacheObject key, CacheObject val) throws IgniteCheckedException {
 -        if(!enabled)
 +    public void onUnswap(KeyCacheObject key, int partId, CacheObject val) throws IgniteCheckedException {
++        if (!enabled)
+             return;
+ 
          if (!enterBusy())
              return; // Ignore index update when node is stopping.
  
          try {
-             qryProc.onUnswap(space, key, partId, val);
+             if (isIndexingSpiEnabled()) {
+                 CacheObjectContext coctx = cctx.cacheObjectContext();
+ 
+                 Object key0 = unwrapIfNeeded(key, coctx);
+ 
+                 Object val0 = unwrapIfNeeded(val, coctx);
+ 
+                 cctx.kernalContext().indexing().onUnswap(space, key0, val0);
+             }
+ 
+             if(qryProcEnabled)
 -                qryProc.onUnswap(space, key, val);
++                qryProc.onUnswap(space, key, partId, val);
          }
          finally {
              leaveBusy();
@@@ -434,10 -470,21 +478,21 @@@
              return; // No-op.
  
          if (!enterBusy())
 -            return; // Ignore index update when node is stopping.
 +            throw new NodeStoppingException("Operation has been cancelled (node is stopping).");
  
          try {
-             qryProc.store(space, key, partId, prevVal, prevVer, val, ver, expirationTime, link);
+             if (isIndexingSpiEnabled()) {
+                 CacheObjectContext coctx = cctx.cacheObjectContext();
+ 
+                 Object key0 = unwrapIfNeeded(key, coctx);
+ 
+                 Object val0 = unwrapIfNeeded(val, coctx);
+ 
+                 cctx.kernalContext().indexing().store(space, key0, val0, expirationTime);
+             }
+ 
+             if(qryProcEnabled)
 -                qryProc.store(space, key, val, CU.versionToBytes(ver), expirationTime);
++                qryProc.store(space, key, partId, prevVal, prevVer, val, ver, expirationTime, link);
          }
          finally {
              invalidateResultCache();
@@@ -464,7 -509,14 +519,14 @@@
              return; // Ignore index update when node is stopping.
  
          try {
-             qryProc.remove(space, key, partId, val, ver);
+             if (isIndexingSpiEnabled()) {
+                 Object key0 = unwrapIfNeeded(key, cctx.cacheObjectContext());
+ 
+                 cctx.kernalContext().indexing().remove(space, key0);
+             }
+ 
 -            if(qryProcEnabled)
 -                qryProc.remove(space, key, val);
++            if (qryProcEnabled)
++                qryProc.remove(space, key, partId, val, ver);
          }
          finally {
              invalidateResultCache();

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
index 41eec6a,b3f0684..1eb9e10
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
@@@ -864,21 -882,21 +885,21 @@@ public class CacheContinuousQueryHandle
                  GridCacheAffinityManager aff = cctx.affinity();
  
                  if (initUpdCntrsPerNode != null) {
-                     for (ClusterNode node : aff.nodes(partId, initTopVer)) {
+                     for (ClusterNode node : aff.nodesByPartition(partId, initTopVer)) {
 -                        Map<Integer, Long> map = initUpdCntrsPerNode.get(node.id());
 +                        Map<Integer, T2<Long, Long>> map = initUpdCntrsPerNode.get(node.id());
  
                          if (map != null) {
 -                            partCntr = map.get(partId);
 +                            partCntrs = map.get(partId);
  
                              break;
                          }
                      }
                  }
                  else if (initUpdCntrs != null)
 -                    partCntr = initUpdCntrs.get(partId);
 +                    partCntrs = initUpdCntrs.get(partId);
              }
  
-             rec = new PartitionRecovery(ctx.log(getClass()), initTopVer0, partCntrs != null ? partCntrs.get2() : null);
 -            rec = new PartitionRecovery(ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY), initTopVer0, partCntr);
++            rec = new PartitionRecovery(ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY), initTopVer0, partCntrs != null ? partCntrs.get2() : null);
  
              PartitionRecovery oldRec = rcvs.putIfAbsent(partId, rec);
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index ba2ab3c,af87dfe..b4d58df
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@@ -1502,20 -1490,19 +1502,20 @@@ public class IgniteTxHandler 
                                          /*expiryPlc*/null,
                                          /*keepBinary*/true);
  
 -                                    if (val == null)
 -                                        val = cacheCtx.toCacheObject(cacheCtx.store().load(null, entry.key()));
 +                                        if (val == null)
 +                                            val = cacheCtx.toCacheObject(cacheCtx.store().load(null, entry.key()));
  
 -                                    if (val != null)
 -                                        entry.readValue(val);
 +                                        if (val != null)
 +                                            entry.readValue(val);
  
-                                         break;
-                                     }
-                                     catch (GridCacheEntryRemovedException ignore) {
-                                         if (log.isDebugEnabled())
-                                             log.debug("Got entry removed exception, will retry: " + entry.txKey());
+                                     break;
+                                 }
+                                 catch (GridCacheEntryRemovedException ignored) {
+                                     if (log.isDebugEnabled())
+                                         log.debug("Got entry removed exception, will retry: " + entry.txKey());
  
 -                                    entry.cached(cacheCtx.cache().entryEx(entry.key(), req.topologyVersion()));
 +                                        entry.cached(cacheCtx.cache().entryEx(entry.key(), req.topologyVersion()));
 +                                    }
                                  }
                              }
                          }


[15/50] [abbrv] ignite git commit: Merge branch 'master' into ignite-2.0

Posted by sb...@apache.org.
Merge branch 'master' into ignite-2.0


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 68ef21157c099f84b64f78237c86d97149d87037
Parents: af98efd bb1ac0a
Author: devozerov <vo...@gridgain.com>
Authored: Wed Feb 8 13:42:08 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Feb 8 13:42:08 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/IgniteSystemProperties.java   |   3 +
 .../processors/cache/GridCacheProcessor.java    |  85 +++++++
 .../distributed/dht/GridDhtCacheAdapter.java    |  10 +-
 .../distributed/dht/GridDhtLocalPartition.java  | 120 ++++++++--
 .../cache/CacheDeferredDeleteQueueTest.java     | 134 +++++++++++
 .../ignite/testsuites/IgniteCacheTestSuite.java |   2 +
 .../Apache.Ignite.Examples.csproj               |   1 +
 .../Datagrid/TransactionExample.cs              |  75 ++++--
 modules/web-console/backend/app/agent.js        |  10 +-
 modules/web-console/backend/app/mongo.js        |  49 ++--
 modules/web-console/backend/app/routes.js       |   5 +-
 .../web-console/backend/routes/activities.js    |  52 +++++
 modules/web-console/backend/routes/admin.js     |   2 +-
 modules/web-console/backend/routes/agent.js     |  10 +-
 modules/web-console/backend/routes/public.js    |   1 -
 .../web-console/backend/services/activities.js  | 136 +++++++++++
 modules/web-console/backend/services/users.js   |  13 +-
 modules/web-console/frontend/app/app.config.js  |   9 +
 modules/web-console/frontend/app/app.js         |  29 ++-
 .../activities-user-dialog.controller.js        |  60 +++++
 .../activities-user-dialog.jade                 |  36 +++
 .../components/activities-user-dialog/index.js  |  36 +++
 .../form-field-datepicker.jade                  |  55 +++++
 .../form-field-datepicker.scss                  |  20 ++
 .../list-of-registered-users/index.js           |  28 +++
 .../list-of-registered-users.categories.js      |  30 +++
 .../list-of-registered-users.column-defs.js     |  80 +++++++
 .../list-of-registered-users.controller.js      | 207 ++++++++++++++++
 .../list-of-registered-users.jade               |  54 +++++
 .../ui-grid-header/ui-grid-header.jade          |  27 +++
 .../ui-grid-header/ui-grid-header.scss          |  84 +++++++
 .../ui-grid-settings/ui-grid-settings.jade      |  33 +++
 .../ui-grid-settings/ui-grid-settings.scss      |  70 ++++++
 .../app/core/activities/Activities.data.js      |  39 ++++
 .../frontend/app/core/admin/Admin.data.js       |  77 ++++++
 modules/web-console/frontend/app/core/index.js  |  25 ++
 modules/web-console/frontend/app/data/i18n.js   |  38 +++
 .../ui-grid-settings/ui-grid-settings.jade      |  33 ---
 .../ui-grid-settings/ui-grid-settings.scss      |  38 ---
 .../app/filters/uiGridSubcategories.filter.js   |  24 ++
 .../frontend/app/modules/Demo/Demo.module.js    | 166 -------------
 .../frontend/app/modules/demo/Demo.module.js    | 172 ++++++++++++++
 .../frontend/app/modules/sql/sql.controller.js  |  14 +-
 .../frontend/app/modules/sql/sql.module.js      |   2 +-
 .../frontend/app/modules/states/admin.state.js  |   2 +-
 .../configuration/summary/summary.controller.js |   6 +-
 .../app/modules/user/AclRoute.provider.js       |  31 +--
 .../frontend/app/modules/user/Auth.service.js   |   2 +-
 .../frontend/app/modules/user/permissions.js    |   2 +-
 .../frontend/app/modules/user/user.module.js    |   6 +-
 modules/web-console/frontend/app/vendor.js      |   1 +
 .../frontend/controllers/admin-controller.js    | 234 -------------------
 .../frontend/controllers/domains-controller.js  |  12 +-
 modules/web-console/frontend/package.json       |   1 +
 .../stylesheets/_font-awesome-custom.scss       |  28 +++
 .../frontend/public/stylesheets/style.scss      |  39 +++-
 .../frontend/public/stylesheets/variables.scss  |   1 +
 .../frontend/views/settings/admin.jade          |  32 +--
 modules/web-console/frontend/views/sql/sql.jade |   4 +-
 59 files changed, 1984 insertions(+), 611 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/68ef2115/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 42f44cf,87f5236..a204e01
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@@ -118,11 -121,9 +121,12 @@@ import org.apache.ignite.lifecycle.Life
  import org.apache.ignite.marshaller.Marshaller;
  import org.apache.ignite.marshaller.MarshallerUtils;
  import org.apache.ignite.spi.IgniteNodeValidationResult;
 +import org.apache.ignite.spi.discovery.DiscoveryDataBag;
 +import org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData;
 +import org.apache.ignite.spi.discovery.DiscoveryDataBag.JoiningNodeDiscoveryData;
  import org.jetbrains.annotations.Nullable;
  
+ import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_REMOVED_ENTRIES_TTL;
  import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK;
  import static org.apache.ignite.IgniteSystemProperties.getBoolean;
  import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
@@@ -844,7 -848,19 +848,18 @@@ public class GridCacheProcessor extend
              }
          }
  
 -        assert caches.containsKey(CU.MARSH_CACHE_NAME) : "Marshaller cache should be started";
          assert ctx.config().isDaemon() || caches.containsKey(CU.UTILITY_CACHE_NAME) : "Utility cache should be started";
+ 
+         if (!ctx.clientNode() && !ctx.isDaemon())
+             addRemovedItemsCleanupTask(Long.getLong(IGNITE_CACHE_REMOVED_ENTRIES_TTL, 10_000));
+ 
+     }
+ 
+     /**
+      * @param timeout Cleanup timeout.
+      */
+     private void addRemovedItemsCleanupTask(long timeout) {
+         ctx.timeout().addTimeoutObject(new RemovedItemsCleanupTask(timeout));
      }
  
      /** {@inheritDoc} */


[24/50] [abbrv] ignite git commit: IGNITE-4212 Ignite Benchmarking Simplification and Automation / IGNITE-4478 Fixing documentation and resolving lack of usability

Posted by sb...@apache.org.
IGNITE-4212 Ignite Benchmarking Simplification and Automation / IGNITE-4478 Fixing documentation and resolving lack of usability


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 605d946ada5ca4e562e256fa0edb29cc25dea7dc
Parents: e1c3dda
Author: oleg-ostanin <oo...@gridgain.com>
Authored: Thu Feb 9 20:08:57 2017 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Thu Feb 9 20:08:57 2017 +0300

----------------------------------------------------------------------
 modules/yardstick/DEVNOTES-standalone.txt       |  15 +++
 modules/yardstick/DEVNOTES.txt                  |  20 ++--
 modules/yardstick/README.txt                    | 119 +++++++++++++------
 .../config/benchmark-sample.properties          |  62 ++++++++++
 modules/yardstick/pom.xml                       |   4 +-
 pom.xml                                         |   1 +
 6 files changed, 172 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/605d946a/modules/yardstick/DEVNOTES-standalone.txt
----------------------------------------------------------------------
diff --git a/modules/yardstick/DEVNOTES-standalone.txt b/modules/yardstick/DEVNOTES-standalone.txt
new file mode 100644
index 0000000..d14dde2
--- /dev/null
+++ b/modules/yardstick/DEVNOTES-standalone.txt
@@ -0,0 +1,15 @@
+Building from standalone sources
+================================
+
+Run
+
+mvn clean package
+
+Artifacts can be found in `/target/assembly directory.`
+
+
+Writing Ignite Benchmarks
+=========================
+
+All benchmarks extend `AbstractBenchmark` class. A new benchmark should also extend this abstract class
+and implement `test` method. This is the method which actually tests performance.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/605d946a/modules/yardstick/DEVNOTES.txt
----------------------------------------------------------------------
diff --git a/modules/yardstick/DEVNOTES.txt b/modules/yardstick/DEVNOTES.txt
index 6921243..b8b1f53 100644
--- a/modules/yardstick/DEVNOTES.txt
+++ b/modules/yardstick/DEVNOTES.txt
@@ -1,16 +1,20 @@
-Yardstick Ignite Maven Build Instructions
+Building from Ignite sources
 =========================================
 
-Yardstick can be build from standalone sources using following maven command:
+Run
 
-mvn clean package
+mvn clean package -Pyardstick -pl modules/yardstick -am -DskipTests
 
-Artifacts can be found in /target/assembly directory.
+in the Apache Ignite root directory.
 
-To build yardstick from Apache Ignite sources use:
+This command will compile the project and also unpack scripts from `yardstick-resources.zip` file to
+`modules/yardstick/target/assembly/bin` directory.
 
-mvn clean package -Pyardstick -pl modules/yardstick -am -DskipTests
+Artifacts can be found in `modules/yardstick/target/assembly` directory.
+
+Writing Ignite Benchmarks
+=========================
 
-in Apache Ignite root directory
+All benchmarks extend `AbstractBenchmark` class. A new benchmark should also extend this abstract class
+and implement `test` method. This is the method which actually tests performance.
 
-Artifacts can be found in modules/yardstick/target/assembly directory.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/605d946a/modules/yardstick/README.txt
----------------------------------------------------------------------
diff --git a/modules/yardstick/README.txt b/modules/yardstick/README.txt
index 353ddd8..dcfe0e6 100644
--- a/modules/yardstick/README.txt
+++ b/modules/yardstick/README.txt
@@ -1,55 +1,92 @@
 Yardstick Ignite Benchmarks
 ===========================
-Yardstick Ignite is a set of Ignite Grid (http://ignite.apache.org/) benchmarks written on top of Yardstick framework.
+Apache Ignite benchmarks are written on top of Yardstick Framework (https://github.com/gridgain/yardstick) and allow
+you to measure performance of various Apache Ignite components and modules.
 
-Yardstick Framework
-===================
-Visit Yardstick Repository (https://github.com/gridgain/yardstick) for detailed information on how to run Yardstick benchmarks and how to generate graphs.
+The documentation below describes how to execute and configure already assembled benchmarks. If you need to add new
+benchmarks or build existing one then refer to instruction from `DEVNOTES.txt` in source directory.
 
-The documentation below describes configuration parameters in addition to standard Yardstick parameters.
+Visit Yardstick Repository (https://github.com/gridgain/yardstick) for detailed information in regards resulting graphs
+generation and how the frameworks works.
 
-Building from Ignite sources
-============
-1. Create a local clone of Ignite repository
-2. Run
 
-mvn package
+Running Ignite Benchmarks Locally
+==========================================
 
-command for Yardstick Ignite POM
+The simplest way to start with benchmarking is to use one of the executable scripts available under `benchmarks\bin` directory:
 
-Building from standalone sources
-=====================
-Run
+./bin/benchmark-run-all.sh config/benchmark-atomic-put.properties
 
-mvn package
+The command above will benchmark the cache put operation for a distributed atomic cache. The results of the benchmark will be added
+to auto-generated `results-{DATE-TIME}` directory.
 
-command for Yardstick Ignite POM
+If `./bin/benchmark-run-all.sh` command is executed as is without any parameters and modifications in configurations files then
+all the available benchmarks will be executed on a local machine using `config/benchmark.properties` configuration.
 
-Provided Benchmarks
-===================
-The following benchmarks are provided:
+To get more information about available benchmarks and configuration parameters refer to \u201cProvided Benchmarks\u201d and
+\u201cProperties And Command Line Arguments\u201d sections below.
+
+
+Running Ignite Benchmarks Remotely
+=========================================
+
+For running Ignite benchmarks on remote hosts you need to upload Ignite-Yardstick to each one of your remote hosts.
+
+NOTE: The path to the uploaded Ignite-Yardstick should be exactly the same on each host.
+
+Then you need to make some changes in config files:
 
-1. `GetBenchmark` - benchmarks atomic distributed cache get operation
-2. `PutBenchmark` - benchmarks atomic distributed cache put operation
-3. `PutGetBenchmark` - benchmarks atomic distributed cache put and get operations together
-4. `PutTxBenchmark` - benchmarks transactional distributed cache put operation
-5. `PutGetTxBenchmark` - benchmarks transactional distributed cache put and get operations together
-6. `SqlQueryBenchmark` - benchmarks distributed SQL query over cached data
-7. `SqlQueryJoinBenchmark` - benchmarks distributed SQL query with a Join over cached data
-8. `SqlQueryPutBenchmark` - benchmarks distributed SQL query with simultaneous cache updates
+1. You need to comment or delete the
+        <property name="localHost" value="127.0.0.1"/>
+line in `config/ignite-localhost-config.xml` file.
 
-Writing Ignite Benchmarks
-=========================
-All benchmarks extend `AbstractBenchmark` class. A new benchmark should also extend this abstract class
-and implement `test` method. This is the method that is actually benchmarked.
+2. You need to replace all the `127.0.0.1` addresses in `ignite-localhost-config.xml` file by actual IPs of your remote
+servers. You can add or delete lines with IP addresses if you want to run benchmarks on different number of hosts.
+There must be at least one IP address in the list.
 
-Running Ignite Benchmarks
-=========================
-Before running Ignite benchmarks, run:
+3. You need to replace the `localhost` strings by actual IP of your servers in the lines
+SERVERS='localhost,localhost'
+DRIVERS='localhost'
+in `config/benchmark-atomic-put.properties` file.
+
+Then use the following command:
+
+./bin/benchmark-run-all.sh config/benchmark-atomic-put.properties
+
+
+It is recommended to create some copies of original config files, edit these copies and then use as a
+parameter for `./bin/benchmark-run-all.sh` script.
+
+
+Provided Benchmarks
+===================
+The following benchmarks are provided:
 
-mvn package
+1.  `GetBenchmark` - benchmarks atomic distributed cache get operation
+2.  `PutBenchmark` - benchmarks atomic distributed cache put operation
+3.  `PutGetBenchmark` - benchmarks atomic distributed cache put and get operations together
+4.  `PutTxBenchmark` - benchmarks transactional distributed cache put operation
+5.  `PutGetTxBenchmark` - benchmarks transactional distributed cache put and get operations together
+6.  `SqlQueryBenchmark` - benchmarks distributed SQL query over cached data
+7.  `SqlQueryJoinBenchmark` - benchmarks distributed SQL query with a Join over cached data
+8.  `SqlQueryPutBenchmark` - benchmarks distributed SQL query with simultaneous cache updates
+9.  `AffinityCallBenchmark` - benchmarks affinity call operation
+10. `ApplyBenchmark` - benchmarks apply operation
+11. `BroadcastBenchmark` - benchmarks broadcast operations
+12. `ExecuteBenchmark` - benchmarks execute operations
+13. `RunBenchmark` - benchmarks running task operations
+14. `PutGetOffHeapBenchmark` - benchmarks atomic distributed cache put and get operations together off heap
+15. `PutGetOffHeapValuesBenchmark` - benchmarks atomic distributed cache put value operations off heap
+16. `PutOffHeapBenchmark` - benchmarks atomic distributed cache put operations off heap
+17. `PutOffHeapValuesBenchmark` - benchmarks atomic distributed cache get value operations off heap
+18. `PutTxOffHeapBenchmark` - benchmarks transactional distributed cache put operation off heap
+19. `PutTxOffHeapValuesBenchmark` - benchmarks transactional distributed cache put value operation off heap
+20. `SqlQueryOffHeapBenchmark` -benchmarks distributed SQL query over cached data off heap
+21. `SqlQueryJoinOffHeapBenchmark` - benchmarks distributed SQL query with a Join over cached data off heap
+22. `SqlQueryPutOffHeapBenchmark` - benchmarks distributed SQL query with simultaneous cache updates off heap
+23. `PutAllBenchmark` - benchmarks atomic distributed cache batch put operation
+24. `PutAllTxBenchmark` - benchmarks transactional distributed cache batch put operation
 
-command. This command will compile the project and also will unpack scripts from `yardstick-resources.zip` file to `bin` directory.
 
 Properties And Command Line Arguments
 =====================================
@@ -67,15 +104,19 @@ The following Ignite benchmark properties can be defined in the benchmark config
 * `-cs` or `--cacheStore` - Enable or disable cache store readThrough, writeThrough
 * `-cl` or `--client` - Client flag
 * `-nc` or `--nearCache` - Near cache flag
-* `-nn <num>` or `--nodeNumber <num>` - Number of nodes (automatically set in `benchmark.properties`), used to wait for the specified number of nodes to start
+* `-nn <num>` or `--nodeNumber <num>` - Number of nodes (automatically set in `benchmark.properties`), used to wait for
+    the specified number of nodes to start
 * `-sm <mode>` or `-syncMode <mode>` - Synchronization mode (defined in `CacheWriteSynchronizationMode`)
 * `-ot` or `--offheapTiered` - Flag indicating whether tiered off-heap mode is on
 * `-ov` or `--offheapValuesOnly` - Flag indicating whether off-heap mode is on and only cache values are stored off-heap
 * `-r <num>` or `--range` - Range of keys that are randomly generated for cache operations
+* `-rd or --restartdelay` - Restart delay in seconds
+* `-rs or --restartsleep` - Restart sleep in seconds
 * `-rth <host>` or `--restHost <host>` - REST TCP host
 * `-rtp <num>` or `--restPort <num>` - REST TCP port, indicates that a Ignite node is ready to process Ignite Clients
 * `-ss` or `--syncSend` - Flag indicating whether synchronous send is used in `TcpCommunicationSpi`
-* `-txc <value>` or `--txConcurrency <value>` - Cache transaction concurrency control, either `OPTIMISTIC` or `PESSIMISTIC` (defined in `CacheTxConcurrency`)
+* `-txc <value>` or `--txConcurrency <value>` - Cache transaction concurrency control, either `OPTIMISTIC` or
+    `PESSIMISTIC` (defined in `CacheTxConcurrency`)
 * `-txi <value>` or `--txIsolation <value>` - Cache transaction isolation (defined in `CacheTxIsolation`)
 * `-wb` or `--writeBehind` - Enable or disable writeBehind for cache store
 * `-wom <mode>` or `--writeOrderMode <mode>` - Write order mode for ATOMIC caches (defined in `CacheAtomicWriteOrderMode`)
@@ -91,7 +132,7 @@ SERVER_HOSTS=localhost,localhost
 Note that -dn and -sn, which stand for data node and server node, are native Yardstick parameters and are documented in Yardstick framework.
 ===========================================================================================================================================
 
-CONFIGS="-b 1 -sm PRIMARY_SYNC -dn PutBenchmark -sn IgniteNode"
+CONFIGS="-b 1 -sm PRIMARY_SYNC -dn PutBenchmark`IgniteNode"
 ```
 
 Issues

http://git-wip-us.apache.org/repos/asf/ignite/blob/605d946a/modules/yardstick/config/benchmark-sample.properties
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/benchmark-sample.properties b/modules/yardstick/config/benchmark-sample.properties
new file mode 100644
index 0000000..fee7cbb
--- /dev/null
+++ b/modules/yardstick/config/benchmark-sample.properties
@@ -0,0 +1,62 @@
+# 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.
+
+#
+# Contains benchmarks for ATOMIC cache.
+#
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+# JVM_OPTS=${JVM_OPTS}" \
+#  -XX:+UseParNewGC \
+#  -XX:+UseConcMarkSweepGC \
+#  -XX:+UseTLAB \
+#  -XX:NewSize=128m \
+#  -XX:MaxNewSize=128m \
+#  -XX:MaxTenuringThreshold=0 \
+#  -XX:SurvivorRatio=1024 \
+#  -XX:+UseCMSInitiatingOccupancyOnly \
+#  -XX:CMSInitiatingOccupancyFraction=60 \
+#"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# Comma-separated list of the hosts to run BenchmarkServers on. 2 nodes on local host are enabled by default.
+SERVER_HOSTS=localhost,localhost
+
+# Comma-separated list of the hosts to run BenchmarkDrivers on. 1 node on local host is enabled by default.
+DRIVER_HOSTS=localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Run configuration.
+# Note that each benchmark is set to run for 300 seconds (5 mins) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgnitePutBenchmark -sn IgniteNode -ds atomic-put-1-backup,\
+"

http://git-wip-us.apache.org/repos/asf/ignite/blob/605d946a/modules/yardstick/pom.xml
----------------------------------------------------------------------
diff --git a/modules/yardstick/pom.xml b/modules/yardstick/pom.xml
index 4c4d138..d96fcc6 100644
--- a/modules/yardstick/pom.xml
+++ b/modules/yardstick/pom.xml
@@ -35,7 +35,7 @@
     <url>http://ignite.apache.org</url>
 
     <properties>
-        <yardstick.version>0.8.0</yardstick.version>
+        <yardstick.version>0.8.2</yardstick.version>
         <spring.version>4.1.0.RELEASE</spring.version>
     </properties>
 
@@ -56,7 +56,7 @@
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-indexing</artifactId>
             <version>${project.version}</version>
-          </dependency>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.ignite</groupId>

http://git-wip-us.apache.org/repos/asf/ignite/blob/605d946a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 790cd4b..ea76053 100644
--- a/pom.xml
+++ b/pom.xml
@@ -506,6 +506,7 @@
                                             <fileset dir="${basedir}/target/release-package/benchmarks/config/">
                                                 <include name="*.*" />
                                                 <exclude name="benchmark.properties"/>
+                                                <exclude name="benchmark-sample.properties"/>
                                                 <exclude name="benchmark-multicast.properties"/>
                                                 <exclude name="ignite-base-config.xml"/>
                                                 <exclude name="ignite-localhost-config.xml"/>


[05/50] [abbrv] ignite git commit: IGNITE-4630 org.apache.ignite.lang.IgniteProductVersion.releaseDate returns not valid date

Posted by sb...@apache.org.
IGNITE-4630 org.apache.ignite.lang.IgniteProductVersion.releaseDate returns not valid date


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 96527d92f003dbb5010e155d4f2e7f394640a6c1
Parents: 26562d3
Author: Evgenii Zhuravlev <ez...@gridgain.com>
Authored: Fri Feb 3 12:45:17 2017 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Fri Feb 3 12:45:17 2017 +0300

----------------------------------------------------------------------
 .../src/main/java/org/apache/ignite/lang/IgniteProductVersion.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/96527d92/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java
index 0abe64f..457ec55 100644
--- a/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java
+++ b/modules/core/src/main/java/org/apache/ignite/lang/IgniteProductVersion.java
@@ -159,7 +159,7 @@ public class IgniteProductVersion implements Comparable<IgniteProductVersion>, E
      * @return Release date.
      */
     public Date releaseDate() {
-        return new Date(revTs);
+        return new Date(revTs * 1000);
     }
 
     /**


[33/50] [abbrv] ignite git commit: IGNITE-1680: CPP: Implemented API for user entry point lookup. This closes #1430.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp b/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
new file mode 100644
index 0000000..3ab6f2b9
--- /dev/null
+++ b/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
@@ -0,0 +1,553 @@
+/*
+ * 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.
+ */
+
+#ifndef _MSC_VER
+    #define BOOST_TEST_DYN_LINK
+#endif
+
+#include <sstream>
+#include <algorithm>
+
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/common/utils.h"
+#include "ignite/ignite.h"
+#include "ignite/ignition.h"
+
+#include "ignite/ignite_binding_context.h"
+#include "ignite/cache/cache_entry_processor.h"
+
+using namespace boost::unit_test;
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::common;
+
+/**
+ * CacheEntryModifier class for invoke tests.
+ */
+class CacheEntryModifier : public CacheEntryProcessor<CacheEntryModifier, int, int, int, int>
+{
+public:
+    /**
+     * Constructor.
+     */
+    CacheEntryModifier() : num(0)
+    {
+        // No-op.
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param num Number to substract from the entry.
+     */
+    CacheEntryModifier(int num) : num(num)
+    {
+        // No-op.
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param other Other instance.
+     */
+    CacheEntryModifier(const CacheEntryModifier& other) : num(other.num)
+    {
+        // No-op.
+    }
+
+    /**
+     * Assignment operator.
+     *
+     * @param other Other instance.
+     * @return This instance.
+     */
+    CacheEntryModifier& operator=(const CacheEntryModifier& other)
+    {
+        num = other.num;
+
+        return *this;
+    }
+
+    /**
+     * Call instance.
+     *
+     * @return New value of entry multiplied by two.
+     */
+    virtual int Process(MutableCacheEntry<int, int>& entry, const int& arg)
+    {
+        if (entry.IsExists())
+            entry.SetValue(entry.GetValue() - arg - num);
+        else
+            entry.SetValue(42);
+
+        return entry.GetValue() * 2;
+    }
+
+    /**
+     * Get number.
+     *
+     * @return Number to substract from entry value.
+     */
+    int GetNum() const
+    {
+        return num;
+    }
+
+private:
+    /** Number to substract. */
+    int num;
+};
+
+namespace ignite
+{
+    namespace binary
+    {
+        /**
+         * Binary type definition for CacheEntryModifier.
+         */
+        IGNITE_BINARY_TYPE_START(CacheEntryModifier)
+            IGNITE_BINARY_GET_TYPE_ID_AS_HASH(CacheEntryModifier)
+            IGNITE_BINARY_GET_TYPE_NAME_AS_IS(CacheEntryModifier)
+            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+            IGNITE_BINARY_GET_HASH_CODE_ZERO(CacheEntryModifier)
+            IGNITE_BINARY_IS_NULL_FALSE(CacheEntryModifier)
+            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(CacheEntryModifier)
+
+            void Write(BinaryWriter& writer, CacheEntryModifier obj)
+            {
+                writer.WriteInt32("num", obj.GetNum());
+            }
+
+            CacheEntryModifier Read(BinaryReader& reader)
+            {
+                int num = reader.ReadInt32("num");
+
+                return CacheEntryModifier(num);
+            }
+        IGNITE_BINARY_TYPE_END
+    }
+}
+
+/**
+ * Divisor class for invoke tests.
+ */
+class Divisor : public CacheEntryProcessor<Divisor, int, int, double, double>
+{
+public:
+    /**
+     * Constructor.
+     */
+    Divisor() : scale(1.0)
+    {
+        // No-op.
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param scale Scale.
+     */
+    Divisor(double scale) : scale(scale)
+    {
+        // No-op.
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param other Other instance.
+     */
+    Divisor(const Divisor& other) : scale(other.scale)
+    {
+        // No-op.
+    }
+
+    /**
+     * Assignment operator.
+     *
+     * @param other Other instance.
+     * @return This instance.
+     */
+    Divisor& operator=(const Divisor& other)
+    {
+        scale = other.scale;
+
+        return *this;
+    }
+
+    /**
+     * Call instance.
+     *
+     * @return New value before cast to int.
+     */
+    virtual double Process(MutableCacheEntry<int, int>& entry, const double& arg)
+    {
+        double res = 0.0;
+
+        if (entry.IsExists())
+        {
+            res = (entry.GetValue() / arg) * scale;
+
+            entry.SetValue(static_cast<int>(res));
+        }
+
+        return res;
+    }
+
+    /**
+     * Get scale.
+     *
+     * @return Scale.
+     */
+    double GetScale() const
+    {
+        return scale;
+    }
+
+private:
+    /** Scale. */
+    double scale;
+};
+
+namespace ignite
+{
+    namespace binary
+    {
+        /**
+         * Binary type definition for Divisor.
+         */
+        IGNITE_BINARY_TYPE_START(Divisor)
+            IGNITE_BINARY_GET_TYPE_ID_AS_HASH(Divisor)
+            IGNITE_BINARY_GET_TYPE_NAME_AS_IS(Divisor)
+            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+            IGNITE_BINARY_GET_HASH_CODE_ZERO(Divisor)
+            IGNITE_BINARY_IS_NULL_FALSE(Divisor)
+            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(Divisor)
+
+            void Write(BinaryWriter& writer, Divisor obj)
+            {
+                writer.WriteDouble("scale", obj.GetScale());
+            }
+
+            Divisor Read(BinaryReader& reader)
+            {
+                double scale = reader.ReadDouble("scale");
+
+                return Divisor(scale);
+            }
+        IGNITE_BINARY_TYPE_END
+    }
+}
+
+/**
+ * Character remover class for invoke tests.
+ */
+class CharRemover : public CacheEntryProcessor<CharRemover, std::string, std::string, int, bool>
+{
+public:
+    /**
+     * Constructor.
+     */
+    CharRemover() : toRemove(0)
+    {
+        // No-op.
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param toRemove Char to remove.
+     */
+    CharRemover(char toRemove) : toRemove(toRemove)
+    {
+        // No-op.
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param other Other instance.
+     */
+    CharRemover(const CharRemover& other) : toRemove(other.toRemove)
+    {
+        // No-op.
+    }
+
+    /**
+     * Assignment operator.
+     *
+     * @param other Other instance.
+     * @return This instance.
+     */
+    CharRemover& operator=(const CharRemover& other)
+    {
+        toRemove = other.toRemove;
+
+        return *this;
+    }
+
+    /**
+     * Call instance.
+     *
+     * @return New value before cast to int.
+     */
+    virtual int Process(MutableCacheEntry<std::string, std::string>& entry, const bool& replaceWithSpace)
+    {
+        int res = 0;
+
+        if (entry.IsExists())
+        {
+            std::string val(entry.GetValue());
+
+            res = static_cast<int>(std::count(val.begin(), val.end(), toRemove));
+
+            if (replaceWithSpace)
+                std::replace(val.begin(), val.end(), toRemove, ' ');
+            else
+                val.erase(std::remove(val.begin(), val.end(), toRemove), val.end());
+
+            if (val.empty())
+                entry.Remove();
+            else
+                entry.SetValue(val);
+        }
+
+        return res;
+    }
+
+    /**
+     * Get scale.
+     *
+     * @return Scale.
+     */
+    char GetCharToRemove() const
+    {
+        return toRemove;
+    }
+
+private:
+    /** Char to remove. */
+    char toRemove;
+};
+
+namespace ignite
+{
+    namespace binary
+    {
+        /**
+         * Binary type definition for CharRemover.
+         */
+        IGNITE_BINARY_TYPE_START(CharRemover)
+            IGNITE_BINARY_GET_TYPE_ID_AS_HASH(CharRemover)
+            IGNITE_BINARY_GET_TYPE_NAME_AS_IS(CharRemover)
+            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+            IGNITE_BINARY_GET_HASH_CODE_ZERO(CharRemover)
+            IGNITE_BINARY_IS_NULL_FALSE(CharRemover)
+            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(CharRemover)
+
+            void Write(BinaryWriter& writer, CharRemover obj)
+            {
+                writer.WriteInt8("toRemove", obj.GetCharToRemove());
+            }
+
+            CharRemover Read(BinaryReader& reader)
+            {
+                char toRemove = static_cast<char>(reader.ReadInt8("toRemove"));
+
+                return CharRemover(toRemove);
+            }
+        IGNITE_BINARY_TYPE_END
+    }
+}
+
+IGNITE_EXPORTED_CALL void IgniteModuleInit(ignite::IgniteBindingContext& context)
+{
+    IgniteBinding binding = context.GetBingding();
+
+    binding.RegisterCacheEntryProcessor<CacheEntryModifier>();
+    binding.RegisterCacheEntryProcessor<Divisor>();
+}
+
+/**
+ * Test setup fixture.
+ */
+struct CacheInvokeTestSuiteFixture {
+
+    Ignite CreateGrid()
+    {
+        IgniteConfiguration cfg;
+
+        cfg.jvmOpts.push_back("-Xdebug");
+        cfg.jvmOpts.push_back("-Xnoagent");
+        cfg.jvmOpts.push_back("-Djava.compiler=NONE");
+        cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
+        cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
+        cfg.jvmOpts.push_back("-DIGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE=1000");
+
+#ifdef IGNITE_TESTS_32
+        cfg.jvmInitMem = 256;
+        cfg.jvmMaxMem = 512;
+#else
+        cfg.jvmInitMem = 512;
+        cfg.jvmMaxMem = 2048;
+#endif
+
+        cfg.springCfgPath = std::string(getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH")) + "/cache-query.xml";
+
+        IgniteError err;
+
+        Ignite grid0 = Ignition::Start(cfg, &err);
+
+        if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
+            BOOST_ERROR(err.GetText());
+
+        return grid0;
+    }
+
+    /**
+     * Constructor.
+     */
+    CacheInvokeTestSuiteFixture()
+    {
+        grid = CreateGrid();
+    }
+
+    /**
+     * Destructor.
+     */
+    ~CacheInvokeTestSuiteFixture()
+    {
+        Ignition::Stop(grid.GetName(), true);
+    }
+
+    Ignite grid;
+};
+
+BOOST_FIXTURE_TEST_SUITE(CacheInvokeTestSuite, CacheInvokeTestSuiteFixture)
+
+/**
+ * Test cache invoke on existing entry.
+ */
+BOOST_AUTO_TEST_CASE(TestExisting)
+{
+    Cache<int, int> cache = grid.GetOrCreateCache<int, int>("TestCache");
+
+    cache.Put(5, 20);
+
+    CacheEntryModifier ced(5);
+
+    int res = cache.Invoke<int>(5, ced, 4);
+
+    BOOST_CHECK_EQUAL(res, 22);
+
+    BOOST_CHECK_EQUAL(cache.Get(5), 11);
+}
+
+/**
+ * Test cache invoke on non-existing entry.
+ */
+BOOST_AUTO_TEST_CASE(TestNonExisting)
+{
+    Cache<int, int> cache = grid.GetOrCreateCache<int, int>("TestCache");
+
+    CacheEntryModifier ced;
+
+    int res = cache.Invoke<int>(4, ced, 4);
+
+    BOOST_CHECK_EQUAL(res, 84);
+
+    BOOST_CHECK_EQUAL(cache.Get(4), 42);
+}
+
+/**
+ * Test cache several invokes on the same entry.
+ */
+BOOST_AUTO_TEST_CASE(TestSeveral)
+{
+    Cache<int, int> cache = grid.GetOrCreateCache<int, int>("TestCache");
+
+    CacheEntryModifier ced(2);
+    Divisor div(10.0);
+
+    int res1 = cache.Invoke<int>(100, ced, 0);
+
+    BOOST_CHECK_EQUAL(res1, 84);
+
+    BOOST_CHECK_EQUAL(cache.Get(100), 42);
+
+    double res2 = cache.Invoke<double>(100, div, 200.0);
+
+    BOOST_CHECK_CLOSE(res2, 2.1, 1E-6);
+
+    BOOST_CHECK_EQUAL(cache.Get(100), 2);
+
+    res2 = cache.Invoke<double>(100, div, 3.0);
+
+    BOOST_CHECK_CLOSE(res2, 6.6666666, 1E-6);
+
+    BOOST_CHECK_EQUAL(cache.Get(100), 6);
+
+    res1 = cache.Invoke<int>(100, ced, -12);
+
+    BOOST_CHECK_EQUAL(res1, 32);
+
+    BOOST_CHECK_EQUAL(cache.Get(100), 16);
+}
+
+/**
+ * Test cache several invokes on the string entry.
+ */
+BOOST_AUTO_TEST_CASE(TestStrings)
+{
+    IgniteBinding binding = grid.GetBinding();
+
+    binding.RegisterCacheEntryProcessor<CharRemover>();
+
+    Cache<std::string, std::string> cache = grid.GetOrCreateCache<std::string, std::string>("TestCache");
+
+    CharRemover cr('.');
+
+    int res = cache.Invoke<int>("some key", cr, false);
+
+    BOOST_CHECK_EQUAL(res, 0);
+    BOOST_CHECK(!cache.ContainsKey("some key"));
+
+    cache.Put("some key", "Some.Value.Separated.By.Dots");
+
+    res = cache.Invoke<int>("some key", cr, false);
+
+    BOOST_CHECK_EQUAL(res, 4);
+    BOOST_CHECK_EQUAL(cache.Get("some key"), std::string("SomeValueSeparatedByDots"));
+
+    cache.Put("some key", "Some.Other.Weird.Value");
+
+    res = cache.Invoke<int>("some key", cr, true);
+
+    BOOST_CHECK_EQUAL(res, 3);
+    BOOST_CHECK_EQUAL(cache.Get("some key"), std::string("Some Other Weird Value"));
+
+    cache.Put("some key", "...........");
+
+    res = cache.Invoke<int>("some key", cr, false);
+
+    BOOST_CHECK_EQUAL(res, 11);
+    BOOST_CHECK(!cache.ContainsKey("some key"));
+}
+
+BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/cache_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_test.cpp b/modules/platforms/cpp/core-test/src/cache_test.cpp
index 1aa7277..f38eecc 100644
--- a/modules/platforms/cpp/core-test/src/cache_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_test.cpp
@@ -103,11 +103,10 @@ struct CacheTestSuiteFixture {
      */
     ~CacheTestSuiteFixture()
     {
-        Ignition::Stop(grid0.GetName(), true);
-        Ignition::Stop(grid1.GetName(), true);
-
         grid0 = Ignite();
         grid1 = Ignite();
+
+        Ignition::StopAll(true);
     }
 };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/cluster_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cluster_test.cpp b/modules/platforms/cpp/core-test/src/cluster_test.cpp
new file mode 100644
index 0000000..660ff59
--- /dev/null
+++ b/modules/platforms/cpp/core-test/src/cluster_test.cpp
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#ifndef _MSC_VER
+    #define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include <ignite/ignition.h>
+
+using namespace ignite;
+using namespace ignite::common::concurrent;
+
+using namespace boost::unit_test;
+
+/*
+ * Test setup fixture.
+ */
+struct ClusterTestSuiteFixture {
+    /*
+     * Constructor.
+     */
+    ClusterTestSuiteFixture()
+    {
+        IgniteConfiguration cfg;
+
+        cfg.jvmOpts.push_back("-Xdebug");
+        cfg.jvmOpts.push_back("-Xnoagent");
+        cfg.jvmOpts.push_back("-Djava.compiler=NONE");
+        cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
+        cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
+
+#ifdef IGNITE_TESTS_32
+        cfg.jvmInitMem = 256;
+        cfg.jvmMaxMem = 768;
+#else
+        cfg.jvmInitMem = 1024;
+        cfg.jvmMaxMem = 4096;
+#endif
+
+        cfg.springCfgPath.assign(getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH")).append("/cache-test.xml");
+
+        grid = Ignition::Start(cfg, "ClusterTest");
+    }
+
+    /*
+     * Destructor.
+     */
+    ~ClusterTestSuiteFixture()
+    {
+        Ignition::StopAll(true);
+        grid = Ignite();
+    }
+
+    Ignite grid;
+};
+
+BOOST_FIXTURE_TEST_SUITE(ClusterTestSuite, ClusterTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(IgniteImplProjection)
+{
+    impl::IgniteImpl* impl = impl::IgniteImpl::GetFromProxy(grid);
+
+    BOOST_REQUIRE(impl != 0);
+    BOOST_REQUIRE(impl->GetProjection().IsValid());
+}
+
+BOOST_AUTO_TEST_CASE(IgniteImplForServers)
+{
+    impl::IgniteImpl* impl = impl::IgniteImpl::GetFromProxy(grid);
+
+    BOOST_REQUIRE(impl != 0);
+
+    SharedPointer<impl::cluster::ClusterGroupImpl> clusterGroup = impl->GetProjection();
+
+    BOOST_REQUIRE(clusterGroup.IsValid());
+
+    IgniteError err;
+
+    BOOST_REQUIRE(clusterGroup.Get()->ForServers(err).IsValid());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/interop_memory_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/interop_memory_test.cpp b/modules/platforms/cpp/core-test/src/interop_memory_test.cpp
index 1c782b5..3abc82d 100644
--- a/modules/platforms/cpp/core-test/src/interop_memory_test.cpp
+++ b/modules/platforms/cpp/core-test/src/interop_memory_test.cpp
@@ -35,7 +35,8 @@ BOOST_AUTO_TEST_CASE(MemoryReallocationTest)
     using impl::interop::InteropMemory;
     using common::concurrent::SharedPointer;
 
-    IgniteEnvironment env;
+    IgniteConfiguration cfg;
+    IgniteEnvironment env(cfg);
 
     SharedPointer<InteropMemory> mem = env.AllocateMemory();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/Makefile.am b/modules/platforms/cpp/core/Makefile.am
index 56e0c0a..46d6bc9 100644
--- a/modules/platforms/cpp/core/Makefile.am
+++ b/modules/platforms/cpp/core/Makefile.am
@@ -67,6 +67,7 @@ libignite_la_SOURCES = \
     src/impl/interop/interop_target.cpp \
     src/impl/transactions/transaction_impl.cpp \
     src/impl/transactions/transactions_impl.cpp \
+    src/impl/cluster/cluster_group_impl.cpp \
     src/impl/ignite_impl.cpp \
     src/transactions/transaction.cpp \
     src/transactions/transactions.cpp

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/Makefile.am b/modules/platforms/cpp/core/include/Makefile.am
index fb84bc5..650f230 100644
--- a/modules/platforms/cpp/core/include/Makefile.am
+++ b/modules/platforms/cpp/core/include/Makefile.am
@@ -27,12 +27,16 @@ nobase_include_HEADERS = \
     ignite/impl/cache/query/query_fields_row_impl.h \
     ignite/impl/cache/query/query_impl.h \
     ignite/impl/cache/cache_impl.h \
+    ignite/impl/cache/cache_entry_processor_holder.h \
     ignite/impl/cache/query/query_batch.h \
     ignite/impl/interop/interop_target.h \
     ignite/impl/interop/interop_external_memory.h \
     ignite/impl/handle_registry.h \
     ignite/impl/transactions/transaction_impl.h \
     ignite/impl/transactions/transactions_impl.h \
+    ignite/impl/cluster/cluster_group_impl.h \
+    ignite/impl/ignite_binding_impl.h \
+    ignite/impl/module_manager.h \
     ignite/cache/query/query_fields_row.h \
     ignite/cache/query/query_fields_cursor.h \
     ignite/cache/query/query_scan.h \
@@ -45,7 +49,11 @@ nobase_include_HEADERS = \
     ignite/cache/cache.h \
     ignite/cache/cache_entry.h \
     ignite/cache/cache_peek_mode.h \
+    ignite/cache/cache_entry_processor.h \
+    ignite/cache/mutable_cache_entry.h \
     ignite/ignition.h \
+    ignite/ignite_binding.h \
+    ignite/ignite_binding_context.h \
     ignite/transactions/transaction.h \
     ignite/transactions/transaction_consts.h \
     ignite/transactions/transactions.h \

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/cache/cache.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache.h b/modules/platforms/cpp/core/include/ignite/cache/cache.h
index 54c0f96..36a0470 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/cache.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/cache.h
@@ -40,7 +40,10 @@
 #include "ignite/cache/query/continuous/continuous_query_handle.h"
 #include "ignite/cache/query/continuous/continuous_query.h"
 #include "ignite/impl/cache/cache_impl.h"
+#include "ignite/impl/cache/cache_entry_processor_holder.h"
 #include "ignite/impl/operations.h"
+#include "ignite/impl/module_manager.h"
+#include "ignite/ignite_error.h"
 
 namespace ignite
 {
@@ -150,9 +153,9 @@ namespace ignite
              */
             bool ContainsKey(const K& key, IgniteError& err)
             {
-                impl::In1Operation<K> op(&key);
+                impl::In1Operation<K> op(key);
 
-                return impl.Get()->ContainsKey(op, &err);
+                return impl.Get()->ContainsKey(op, err);
             }
 
             /**
@@ -185,9 +188,9 @@ namespace ignite
              */
             bool ContainsKeys(const std::set<K>& keys, IgniteError& err)
             {
-                impl::InSetOperation<K> op(&keys);
+                impl::InSetOperation<K> op(keys);
 
-                return impl.Get()->ContainsKeys(op, &err);
+                return impl.Get()->ContainsKeys(op, err);
             }
 
             /**
@@ -230,10 +233,10 @@ namespace ignite
              */
             V LocalPeek(const K& key, int32_t peekModes, IgniteError& err)
             {
-                impl::InCacheLocalPeekOperation<K> inOp(&key, peekModes);
+                impl::InCacheLocalPeekOperation<K> inOp(key, peekModes);
                 impl::Out1Operation<V> outOp;
 
-                impl.Get()->LocalPeek(inOp, outOp, peekModes, &err);
+                impl.Get()->LocalPeek(inOp, outOp, peekModes, err);
 
                 return outOp.GetResult();
             }
@@ -276,10 +279,10 @@ namespace ignite
              */
             V Get(const K& key, IgniteError& err)
             {
-                impl::In1Operation<K> inOp(&key);
+                impl::In1Operation<K> inOp(key);
                 impl::Out1Operation<V> outOp;
 
-                impl.Get()->Get(inOp, outOp, &err);
+                impl.Get()->Get(inOp, outOp, err);
 
                 return outOp.GetResult();
             }
@@ -322,10 +325,10 @@ namespace ignite
              */
             std::map<K, V> GetAll(const std::set<K>& keys, IgniteError& err)
             {
-                impl::InSetOperation<K> inOp(&keys);
+                impl::InSetOperation<K> inOp(keys);
                 impl::OutMapOperation<K, V> outOp;
 
-                impl.Get()->GetAll(inOp, outOp, &err);
+                impl.Get()->GetAll(inOp, outOp, err);
 
                 return outOp.GetResult();
             }
@@ -362,9 +365,9 @@ namespace ignite
              */
             void Put(const K& key, const V& val, IgniteError& err)
             {
-                impl::In2Operation<K, V> op(&key, &val);
+                impl::In2Operation<K, V> op(key, val);
 
-                impl.Get()->Put(op, &err);
+                impl.Get()->Put(op, err);
             }
 
             /**
@@ -397,9 +400,9 @@ namespace ignite
              */
             void PutAll(const std::map<K, V>& vals, IgniteError& err)
             {
-                impl::InMapOperation<K, V> op(&vals);
+                impl::InMapOperation<K, V> op(vals);
 
-                impl.Get()->PutAll(op, &err);
+                impl.Get()->PutAll(op, err);
             }
 
             /**
@@ -438,10 +441,10 @@ namespace ignite
              */
             V GetAndPut(const K& key, const V& val, IgniteError& err)
             {
-                impl::In2Operation<K, V> inOp(&key, &val);
+                impl::In2Operation<K, V> inOp(key, val);
                 impl::Out1Operation<V> outOp;
 
-                impl.Get()->GetAndPut(inOp, outOp, &err);
+                impl.Get()->GetAndPut(inOp, outOp, err);
 
                 return outOp.GetResult();
             }
@@ -482,10 +485,10 @@ namespace ignite
              */
             V GetAndReplace(const K& key, const V& val, IgniteError& err)
             {
-                impl::In2Operation<K, V> inOp(&key, &val);
+                impl::In2Operation<K, V> inOp(key, val);
                 impl::Out1Operation<V> outOp;
 
-                impl.Get()->GetAndReplace(inOp, outOp, &err);
+                impl.Get()->GetAndReplace(inOp, outOp, err);
 
                 return outOp.GetResult();
             }
@@ -520,10 +523,10 @@ namespace ignite
              */
             V GetAndRemove(const K& key, IgniteError& err)
             {
-                impl::In1Operation<K> inOp(&key);
+                impl::In1Operation<K> inOp(key);
                 impl::Out1Operation<V> outOp;
 
-                impl.Get()->GetAndRemove(inOp, outOp, &err);
+                impl.Get()->GetAndRemove(inOp, outOp, err);
 
                 return outOp.GetResult();
             }
@@ -562,9 +565,9 @@ namespace ignite
              */
             bool PutIfAbsent(const K& key, const V& val, IgniteError& err)
             {
-                impl::In2Operation<K, V> op(&key, &val);
+                impl::In2Operation<K, V> op(key, val);
 
-                return impl.Get()->PutIfAbsent(op, &err);
+                return impl.Get()->PutIfAbsent(op, err);
             }
 
             /**
@@ -617,10 +620,10 @@ namespace ignite
              */
             V GetAndPutIfAbsent(const K& key, const V& val, IgniteError& err)
             {
-                impl::In2Operation<K, V> inOp(&key, &val);
+                impl::In2Operation<K, V> inOp(key, val);
                 impl::Out1Operation<V> outOp;
 
-                impl.Get()->GetAndPutIfAbsent(inOp, outOp, &err);
+                impl.Get()->GetAndPutIfAbsent(inOp, outOp, err);
 
                 return outOp.GetResult();
             }
@@ -669,9 +672,9 @@ namespace ignite
              */
             bool Replace(const K& key, const V& val, IgniteError& err)
             {
-                impl::In2Operation<K, V> op(&key, &val);
+                impl::In2Operation<K, V> op(key, val);
 
-                return impl.Get()->Replace(op, &err);
+                return impl.Get()->Replace(op, err);
             }
 
             /**
@@ -712,9 +715,9 @@ namespace ignite
              */
             bool Replace(const K& key, const V& oldVal, const V& newVal, IgniteError& err)
             {
-                impl::In3Operation<K, V, V> op(&key, &oldVal, &newVal);
+                impl::In3Operation<K, V, V> op(key, oldVal, newVal);
 
-                return impl.Get()->ReplaceIfEqual(op, &err);
+                return impl.Get()->ReplaceIfEqual(op, err);
             }
 
             /**
@@ -749,9 +752,9 @@ namespace ignite
              */
             void LocalEvict(const std::set<K>& keys, IgniteError& err)
             {
-                impl::InSetOperation<K> op(&keys);
+                impl::InSetOperation<K> op(keys);
 
-                impl.Get()->LocalEvict(op, &err);
+                impl.Get()->LocalEvict(op, err);
             }
 
             /**
@@ -777,7 +780,7 @@ namespace ignite
              */
             void Clear(IgniteError& err)
             {
-                impl.Get()->Clear(&err);
+                impl.Get()->Clear(err);
             }
 
             /**
@@ -808,9 +811,9 @@ namespace ignite
              */
             void Clear(const K& key, IgniteError& err)
             {
-                impl::In1Operation<K> op(&key);
+                impl::In1Operation<K> op(key);
 
-                impl.Get()->Clear(op, &err);
+                impl.Get()->Clear(op, err);
             }
 
             /**
@@ -841,9 +844,9 @@ namespace ignite
              */
             void ClearAll(const std::set<K>& keys, IgniteError& err)
             {
-                impl::InSetOperation<K> op(&keys);
+                impl::InSetOperation<K> op(keys);
 
-                impl.Get()->ClearAll(op, &err);
+                impl.Get()->ClearAll(op, err);
             }
 
             /**
@@ -880,9 +883,9 @@ namespace ignite
              */
             void LocalClear(const K& key, IgniteError& err)
             {
-                impl::In1Operation<K> op(&key);
+                impl::In1Operation<K> op(key);
 
-                impl.Get()->LocalClear(op, &err);
+                impl.Get()->LocalClear(op, err);
             }
 
             /**
@@ -919,9 +922,9 @@ namespace ignite
              */
             void LocalClearAll(const std::set<K>& keys, IgniteError& err)
             {
-                impl::InSetOperation<K> op(&keys);
+                impl::InSetOperation<K> op(keys);
 
-                impl.Get()->LocalClearAll(op, &err);
+                impl.Get()->LocalClearAll(op, err);
             }
 
             /**
@@ -968,9 +971,9 @@ namespace ignite
              */
             bool Remove(const K& key, IgniteError& err)
             {
-                impl::In1Operation<K> op(&key);
+                impl::In1Operation<K> op(key);
 
-                return impl.Get()->Remove(op, &err);
+                return impl.Get()->Remove(op, err);
             }
 
             /**
@@ -1009,9 +1012,9 @@ namespace ignite
              */
             bool Remove(const K& key, const V& val, IgniteError& err)
             {
-                impl::In2Operation<K, V> op(&key, &val);
+                impl::In2Operation<K, V> op(key, val);
 
-                return impl.Get()->RemoveIfEqual(op, &err);
+                return impl.Get()->RemoveIfEqual(op, err);
             }
 
             /**
@@ -1044,9 +1047,9 @@ namespace ignite
              */
             void RemoveAll(const std::set<K>& keys, IgniteError& err)
             {
-                impl::InSetOperation<K> op(&keys);
+                impl::InSetOperation<K> op(keys);
 
-                impl.Get()->RemoveAll(op, &err);
+                impl.Get()->RemoveAll(op, err);
             }
 
             /**
@@ -1077,7 +1080,7 @@ namespace ignite
              */
             void RemoveAll(IgniteError& err)
             {
-                return impl.Get()->RemoveAll(&err);
+                return impl.Get()->RemoveAll(err);
             }
 
             /**
@@ -1135,7 +1138,7 @@ namespace ignite
              */
             int32_t LocalSize(int32_t peekModes, IgniteError& err)
             {
-                return impl.Get()->Size(peekModes, true, &err);
+                return impl.Get()->Size(peekModes, true, err);
             }
 
             /**
@@ -1197,7 +1200,7 @@ namespace ignite
              */
             int32_t Size(int32_t peekModes, IgniteError& err)
             {
-                return impl.Get()->Size(peekModes, false, &err);
+                return impl.Get()->Size(peekModes, false, err);
             }
 
             /**
@@ -1230,7 +1233,7 @@ namespace ignite
              */
             query::QueryCursor<K, V> Query(const query::SqlQuery& qry, IgniteError& err)
             {
-                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySql(qry, &err);
+                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySql(qry, err);
 
                 return query::QueryCursor<K, V>(cursorImpl);
             }
@@ -1265,7 +1268,7 @@ namespace ignite
              */
             query::QueryCursor<K, V> Query(const query::TextQuery& qry, IgniteError& err)
             {
-                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryText(qry, &err);
+                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryText(qry, err);
 
                 return query::QueryCursor<K, V>(cursorImpl);
             }
@@ -1300,7 +1303,7 @@ namespace ignite
              */
             query::QueryCursor<K, V> Query(const query::ScanQuery& qry, IgniteError& err)
             {
-                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryScan(qry, &err);
+                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryScan(qry, err);
 
                 return query::QueryCursor<K, V>(cursorImpl);
             }
@@ -1335,12 +1338,122 @@ namespace ignite
              */
             query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry, IgniteError& err)
             {
-                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySqlFields(qry, &err);
+                impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySqlFields(qry, err);
 
                 return query::QueryFieldsCursor(cursorImpl);
             }
 
             /**
+             * Invokes an CacheEntryProcessor against the MutableCacheEntry
+             * specified by the provided key. If an entry does not exist for the
+             * specified key, an attempt is made to load it (if a loader is
+             * configured) or a surrogate entry, consisting of the key with a
+             * null value is used instead.
+             *
+             * Return value, processor and argument classes should all be
+             * default-constructable, copy-constructable and assignable. Also,
+             * BinaryType class template should be specialized for every custom
+             * class.
+             *
+             * Processor class should be registered as a cache entry processor using
+             * IgniteBinding::RegisterCacheEntryProcessor() method. You can declare
+             * #IgniteModuleInit() function to register your cache processors upon
+             * module loading. There should be at most one instance of such function
+             * per module.
+             *
+             * See the example below for details:
+             * @code{.cpp}
+             * IGNITE_EXPORTED_CALL void IgniteModuleInit(ignite::IgniteBindingContext& context)
+             * {
+             *     IgniteBinding binding = context.GetBingding();
+             *
+             *     binding.RegisterCacheEntryProcessor<MyProcessor1>();
+             *     binding.RegisterCacheEntryProcessor<MyProcessor2>();
+             *     // ...
+             *     binding.RegisterCacheEntryProcessor<MyProcessorN>();
+             * }
+             * @endcode
+             *
+             * Additionally, processor class should be derived from the
+             * ignite::CacheEntryProcessor class.
+             *
+             * @throw IgniteError on fail.
+             *
+             * @param key The key.
+             * @param processor The processor.
+             * @param arg The argument.
+             * @return Result of the processing.
+             */
+            template<typename R, typename P, typename A>
+            R Invoke(const K& key, const P& processor, const A& arg)
+            {
+                IgniteError err;
+
+                R res = Invoke<R>(key, processor, arg, err);
+
+                IgniteError::ThrowIfNeeded(err);
+
+                return res;
+            }
+
+            /**
+             * Invokes an CacheEntryProcessor against the MutableCacheEntry
+             * specified by the provided key. If an entry does not exist for the
+             * specified key, an attempt is made to load it (if a loader is
+             * configured) or a surrogate entry, consisting of the key with a
+             * null value is used instead.
+             *
+             * Return value, processor and argument classes should all be
+             * default-constructable, copy-constructable and assignable. Also,
+             * BinaryType class template should be specialized for every custom
+             * class.
+             *
+             * Processor class should be registered as a cache entry processor using
+             * IgniteBinding::RegisterCacheEntryProcessor() method. You can declare
+             * #IgniteModuleInit() function to register your cache processors upon
+             * module loading. There should be at most one instance of such function
+             * per module.
+             *
+             * See the example below for details:
+             * @code{.cpp}
+             * IGNITE_EXPORTED_CALL void IgniteModuleInit(ignite::IgniteBindingContext& context)
+             * {
+             *     IgniteBinding binding = context.GetBingding();
+             *
+             *     binding.RegisterCacheEntryProcessor<MyProcessor1>();
+             *     binding.RegisterCacheEntryProcessor<MyProcessor2>();
+             *     // ...
+             *     binding.RegisterCacheEntryProcessor<MyProcessorN>();
+             * }
+             * @endcode
+             *
+             * Additionally, processor class should be derived from the
+             * ignite::CacheEntryProcessor class.
+             *
+             * Sets err param which should be checked for the operation result.
+             *
+             * @param key The key.
+             * @param processor The processor.
+             * @param arg The argument.
+             * @param err Error.
+             * @return Result of the processing. Default-constructed value on error.
+             */
+            template<typename R, typename P, typename A>
+            R Invoke(const K& key, const P& processor, const A& arg, IgniteError& err)
+            {
+                typedef impl::cache::CacheEntryProcessorHolder<P, A> ProcessorHolder;
+
+                ProcessorHolder procHolder(processor, arg);
+
+                impl::In2Operation<K, ProcessorHolder> inOp(key, procHolder);
+                impl::Out1Operation<R> outOp;
+
+                impl.Get()->Invoke(inOp, outOp, err);
+
+                return outOp.GetResult();
+            }
+
+            /**
              * Start continuous query execution.
              *
              * @param qry Continuous query.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/cache/cache_entry_processor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache_entry_processor.h b/modules/platforms/cpp/core/include/ignite/cache/cache_entry_processor.h
new file mode 100644
index 0000000..7fa1550
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/cache/cache_entry_processor.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file
+ * Declares ignite::cache::CacheEntryProcessor class.
+ */
+
+#ifndef _IGNITE_CACHE_CACHE_ENTRY_PROCESSOR
+#define _IGNITE_CACHE_CACHE_ENTRY_PROCESSOR
+
+#include <ignite/common/common.h>
+#include <ignite/impl/binary/binary_reader_impl.h>
+#include <ignite/impl/binary/binary_writer_impl.h>
+#include <ignite/impl/cache/cache_entry_processor_holder.h>
+
+namespace ignite
+{
+    class IgniteBinding;
+
+    namespace cache
+    {
+        /**
+         * %Cache entry processor class template.
+         *
+         * Any cache processor should inherit from this class.
+         *
+         * All templated types should be default-constructable,
+         * copy-constructable and assignable.
+         *
+         * @tparam P The processor itself which inherits from CacheEntryProcessor.
+         * @tparam K Key type.
+         * @tparam V Value type.
+         * @tparam R Process method return type.
+         * @tparam A Process method argument type.
+         */
+        template<typename P, typename K, typename V, typename R, typename A>
+        class CacheEntryProcessor
+        {
+            friend class ignite::IgniteBinding;
+
+        public:
+            /**
+             * Destructor.
+             */
+            virtual ~CacheEntryProcessor()
+            {
+                // No-op.
+            }
+
+            /**
+             * Process entry, using input argument and return result.
+             *
+             * @param entry Entry to process.
+             * @param arg Argument.
+             * @return Processing result.
+             */
+            virtual R Process(MutableCacheEntry<K, V>& entry, const A& arg) = 0;
+
+        private:
+            /**
+             * Process input streaming data to produce output streaming data.
+             *
+             * Deserializes cache entry and processor using provided reader, invokes
+             * cache entry processor, gets result and serializes it using provided
+             * writer.
+             *
+             * @param reader Reader.
+             * @param writer Writer.
+             */
+            static void InternalProcess(impl::binary::BinaryReaderImpl& reader, impl::binary::BinaryWriterImpl& writer)
+            {
+                typedef impl::cache::CacheEntryProcessorHolder<P, A> ProcessorHolder;
+
+                ProcessorHolder procHolder = reader.ReadObject<ProcessorHolder>();
+
+                K key = reader.ReadObject<K>();
+
+                V value;
+                bool exists = reader.TryReadObject<V>(value);
+
+                impl::cache::MutableCacheEntryState entryState;
+
+                R res = procHolder.template Process<R, K, V>(key, value, exists, entryState);
+
+                writer.WriteInt8(static_cast<int8_t>(entryState));
+
+                if (entryState == impl::cache::ENTRY_STATE_VALUE_SET)
+                    writer.WriteTopObject(value);
+
+                writer.WriteTopObject(res);
+            }
+        };
+    }
+}
+
+#endif //_IGNITE_CACHE_CACHE_ENTRY_PROCESSOR

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/cache/mutable_cache_entry.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/mutable_cache_entry.h b/modules/platforms/cpp/core/include/ignite/cache/mutable_cache_entry.h
new file mode 100644
index 0000000..0481a5e
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/cache/mutable_cache_entry.h
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_CACHE_MUTABLE_CACHE_ENTRY
+#define _IGNITE_CACHE_MUTABLE_CACHE_ENTRY
+
+#include <ignite/common/common.h>
+#include <ignite/cache/cache_entry.h>
+
+namespace ignite
+{
+    namespace cache
+    {
+        /**
+         * Mutable representation of CacheEntry class template.
+         *
+         * Both key and value types should be default-constructable,
+         * copy-constructable and assignable.
+         *
+         * Additionally, equality operator should be defined for
+         * the value type.
+         */
+        template<typename K, typename V>
+        class MutableCacheEntry
+        {
+        public:
+            /**
+             * Default constructor.
+             */
+            MutableCacheEntry() :
+                key(),
+                val(),
+                exists(false)
+            {
+                // No-op.
+            }
+
+            /**
+             * Constructor for non-existing entry.
+             *
+             * @param key Key.
+             */
+            MutableCacheEntry(const K& key) :
+                key(key),
+                val(),
+                exists(false)
+            {
+                // No-op.
+            }
+
+            /**
+             * Constructor for existing entry.
+             *
+             * @param key Key.
+             * @param val Value.
+             */
+            MutableCacheEntry(const K& key, const V& val) :
+                key(key),
+                val(val),
+                exists(true)
+            {
+                // No-op.
+            }
+
+            /**
+             * Copy constructor.
+             *
+             * @param other Other instance.
+             */
+            MutableCacheEntry(const MutableCacheEntry& other) :
+                key(other.key),
+                val(other.val),
+                exists(other.exists)
+            {
+                // No-op.
+            }
+
+            /**
+             * Assignment operator.
+             *
+             * @param other Other instance.
+             * @return *this.
+             */
+            MutableCacheEntry& operator=(const MutableCacheEntry& other)
+            {
+                if (this != &other)
+                {
+                    key = other.key;
+                    val = other.val;
+                    exists = other.exists;
+                }
+
+                return *this;
+            }
+
+            /**
+             * Check whether cache entry exists in cache.
+             *
+             * @return True if the cache entry exists in cache and false
+             *     otherwise.
+             */
+            bool IsExists() const
+            {
+                return exists;
+            }
+
+            /**
+             * Removes the entry from the Cache.
+             */
+            void Remove()
+            {
+                exists = false;
+            }
+
+            /**
+             * Get key.
+             *
+             * @return Key.
+             */
+            const K& GetKey() const
+            {
+                return key;
+            }
+
+            /**
+             * Get value.
+             *
+             * @return Value.
+             */
+            const V& GetValue() const
+            {
+                return val;
+            }
+
+            /**
+             * Sets or replaces the value associated with the key.
+             *
+             * After setter invocation "IsExists" will return true.
+             *
+             * @param val Value to set.
+             */
+            void SetValue(const V& val)
+            {
+                this->val = val;
+
+                exists = true;
+            }
+
+        private:
+            /** Key. */
+            K key;
+
+            /** Value. */
+            V val;
+
+            /** Exists. */
+            bool exists;
+        };
+    }
+}
+
+#endif //_IGNITE_CACHE_MUTABLE_CACHE_ENTRY

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
index 9057a03..61fd7ec 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
@@ -213,7 +213,7 @@ namespace ignite
                     impl::cache::query::QueryCursorImpl* impl0 = impl.Get();
 
                     if (impl0) {
-                        impl::OutQueryGetAllOperation<K, V> outOp(&res);
+                        impl::OutQueryGetAllOperation<K, V> outOp(res);
 
                         impl0->GetAll(outOp, err);
                     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/ignite.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/ignite.h b/modules/platforms/cpp/core/include/ignite/ignite.h
index 311dff2..140ee53 100644
--- a/modules/platforms/cpp/core/include/ignite/ignite.h
+++ b/modules/platforms/cpp/core/include/ignite/ignite.h
@@ -60,6 +60,15 @@ namespace ignite
         const char* GetName() const;
 
         /**
+         * Get node configuration.
+         *
+         * This method should only be used on the valid instance.
+         *
+         * @return Node configuration.
+         */
+        const IgniteConfiguration& GetConfiguration() const;
+
+        /**
          * Get cache.
          *
          * This method should only be used on the valid instance.
@@ -180,6 +189,15 @@ namespace ignite
         transactions::Transactions GetTransactions();
 
         /**
+         * Get ignite binding.
+         *
+         * This method should only be used on the valid instance.
+         *
+         * @return IgniteBinding class instance.
+         */
+        IgniteBinding GetBinding();
+
+        /**
          * Check if the instance is valid.
          *
          * Invalid instance can be returned if some of the previous

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/ignite_binding.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/ignite_binding.h b/modules/platforms/cpp/core/include/ignite/ignite_binding.h
new file mode 100644
index 0000000..a8decf9
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/ignite_binding.h
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_IGNITE_BINDING
+#define _IGNITE_IGNITE_BINDING
+
+#include <ignite/common/common.h>
+#include <ignite/common/concurrent.h>
+
+#include <ignite/impl/ignite_binding_impl.h>
+
+namespace ignite
+{
+    /**
+     * %Ignite Binding.
+     * Used to register callable classes.
+     */
+    class IGNITE_IMPORT_EXPORT IgniteBinding
+    {
+    public:
+        /**
+         * Default constructor.
+         */
+        IgniteBinding() :
+            impl()
+        {
+            // No-op.
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param impl Implementation.
+         */
+        IgniteBinding(common::concurrent::SharedPointer<impl::IgniteBindingImpl> impl) :
+            impl(impl)
+        {
+            // No-op.
+        }
+
+        /**
+         * Register Type as Cache Entry Processor.
+         *
+         * Registred type should be a child of ignite::cache::CacheEntryProcessor
+         * class.
+         *
+         * This method should only be used on the valid instance.
+         */
+        template<typename P>
+        void RegisterCacheEntryProcessor()
+        {
+            IgniteError err;
+
+            RegisterCacheEntryProcessor<P>(err);
+
+            IgniteError::ThrowIfNeeded(err);
+        }
+
+        /**
+         * Register Type as Cache Entry Processor.
+         *
+         * Registred type should be a child of ignite::cache::CacheEntryProcessor
+         * class.
+         *
+         * This method should only be used on the valid instance.
+         *
+         * @param err Error.
+         */
+        template<typename P>
+        void RegisterCacheEntryProcessor(IgniteError& err)
+        {
+            binary::BinaryType<P> bt;
+            impl::IgniteBindingImpl *im = impl.Get();
+
+            if (im)
+                im->RegisterCallback(bt.GetTypeId(), &P::CacheEntryProcessor::InternalProcess, err);
+            else
+            {
+                err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                    "Instance is not usable (did you check for error?).");
+            }
+        }
+
+        /**
+         * Check if the instance is valid.
+         *
+         * Invalid instance can be returned if some of the previous operations
+         * have resulted in a failure. For example invalid instance can be
+         * returned by not-throwing version of method in case of error. Invalid
+         * instances also often can be created using default constructor.
+         *
+         * @return True if the instance is valid and can be used.
+         */
+        bool IsValid() const
+        {
+            return impl.IsValid();
+        }
+
+    private:
+        /** Registered cache entry processors. */
+        common::concurrent::SharedPointer<impl::IgniteBindingImpl> impl;
+    };
+}
+
+#endif //_IGNITE_IGNITE_BINDING

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/ignite_binding_context.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/ignite_binding_context.h b/modules/platforms/cpp/core/include/ignite/ignite_binding_context.h
new file mode 100644
index 0000000..1a6d26d
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/ignite_binding_context.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file
+ * Declares ignite::IgniteBindingContext class.
+ */
+
+#ifndef _IGNITE_IGNITE_BINDING_CONTEXT
+#define _IGNITE_IGNITE_BINDING_CONTEXT
+
+#include <ignite/ignite_binding.h>
+#include <ignite/ignite_configuration.h>
+
+namespace ignite
+{
+    namespace impl
+    {
+        class IgniteEnvironment;
+    }
+
+    /**
+     * %Ignite binding context.
+     *
+     * Provides methods that can be used to get Ignite components which may be
+     * needed for initial module initialization.
+     */
+    class IgniteBindingContext
+    {
+        friend class impl::IgniteEnvironment;
+    public:
+        /**
+         * Get binding.
+         *
+         * @return IgniteBinding instance.
+         */
+        IgniteBinding GetBingding() const
+        {
+            return binding;
+        }
+
+        /**
+         * Get configuration for current node.
+         *
+         * @return Configuration.
+         */
+        const IgniteConfiguration& GetConfiguration() const
+        {
+            return cfg;
+        }
+
+    private:
+        /**
+         * Constructor.
+         *
+         * @param cfg Configuration.
+         * @param binding Binding.
+         */
+        IgniteBindingContext(const IgniteConfiguration& cfg, IgniteBinding binding) :
+            cfg(cfg),
+            binding(binding)
+        {
+            // No-op.
+        }
+
+        /** Configuration */
+        const IgniteConfiguration& cfg;
+
+        /** Binding. */
+        IgniteBinding binding;
+    };
+}
+
+#endif //_IGNITE_IGNITE_BINDING_CONTEXT
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/ignite_configuration.h b/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
index 65c4550..885ffab 100644
--- a/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
+++ b/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
@@ -27,8 +27,6 @@
 #include <string>
 #include <list>
 
-#include <ignite/common/utils.h>
-
 namespace ignite
 {
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h b/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
index bd21751..02ecd06 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
@@ -48,7 +48,7 @@ namespace ignite
                  */
                 ~BinaryTypeUpdaterImpl();
 
-                bool Update(Snap* snapshot, IgniteError* err);
+                bool Update(Snap* snapshot, IgniteError& err);
             private:
                 /** Environment. */
                 IgniteEnvironment& env;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/cache/cache_entry_processor_holder.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/cache_entry_processor_holder.h b/modules/platforms/cpp/core/include/ignite/impl/cache/cache_entry_processor_holder.h
new file mode 100644
index 0000000..23b57c3
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/cache_entry_processor_holder.h
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_IMPL_CACHE_CACHE_ENTRY_PROCESSOR_HOLDER
+#define _IGNITE_IMPL_CACHE_CACHE_ENTRY_PROCESSOR_HOLDER
+
+#include <ignite/common/common.h>
+#include <ignite/cache/mutable_cache_entry.h>
+#include <ignite/binary/binary.h>
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace cache
+        {
+            /**
+             * Mutable Cache entry state.
+             */
+            enum MutableCacheEntryState
+            {
+                /** No changes have been committed to entry. */
+                ENTRY_STATE_INTACT = 0,
+
+                /** Value of the entry has been changed. */
+                ENTRY_STATE_VALUE_SET = 1,
+
+                /** Entry has been removed from cache. */
+                ENTRY_STATE_VALUE_REMOVED = 2,
+
+                /** Error occured. Represented in portable form. */
+                ENTRY_STATE_ERR_PORTABLE = 3,
+
+                /** Error occured. Represented in string form. */
+                ENTRY_STATE_ERR_STRING = 4
+            };
+
+            /**
+             * Get state of the mutable cache entry.
+             *
+             * @param valueBefore Cache entry value before mutation.
+             * @param existsBefore Flag for entry existence before mutation.
+             * @param valueBefore Cache entry value after mutation.
+             * @param existsBefore Flag for entry existence after mutation.
+             * @return Cache entry state.
+             */
+            template<typename V>
+            MutableCacheEntryState GetMutableCacheEntryState(const V& valueBefore, bool existsBefore,
+                                                             const V& valueAfter, bool existsAfter)
+            {
+                if ((!existsBefore && existsAfter) ||
+                    (existsBefore && existsAfter && !(valueBefore == valueAfter)))
+                    return ENTRY_STATE_VALUE_SET;
+
+                if (existsBefore && !existsAfter)
+                    return ENTRY_STATE_VALUE_REMOVED;
+
+                return ENTRY_STATE_INTACT;
+            }
+
+            /**
+             * Holder for the Cache Entry Processor and its argument. Used as a convenient way to
+             * transmit Cache Entry Processor between nodes.
+             *
+             * Both key and value types should be default-constructable,
+             * copy-constructable and assignable.
+             *
+             * Additionally, for the processor class public methods with the
+             * following signatures should be defined:
+             * @code{.cpp}
+             * // Should return unique ID for every class.
+             * static int64_t GetJobId();
+             *
+             * // Main processing method. Takes cache entry and argument and
+             * // returns processing result.
+             * R Process(ignite::cache::MutableCacheEntry<K, V>&, const A&);
+             * @endcode
+             */
+            template<typename P, typename A>
+            class CacheEntryProcessorHolder
+            {
+            public:
+                typedef P ProcessorType;
+                typedef A ArgumentType;
+
+                /**
+                 * Default constructor.
+                 */
+                CacheEntryProcessorHolder() :
+                    proc(),
+                    arg()
+                {
+                    // No-op.
+                }
+
+                /**
+                 * Constructor.
+                 *
+                 * @param proc Processor.
+                 * @param arg Argument.
+                 */
+                CacheEntryProcessorHolder(const P& proc, const A& arg) :
+                    proc(proc),
+                    arg(arg)
+                {
+                    // No-op.
+                }
+
+                /**
+                 * Destructor.
+                 */
+                ~CacheEntryProcessorHolder()
+                {
+                    // No-op.
+                }
+
+                /**
+                 * Get processor.
+                 *
+                 * @return Processor.
+                 */
+                const ProcessorType& getProcessor() const
+                {
+                    return proc;
+                }
+
+                /**
+                 * Get argument.
+                 *
+                 * @return Argument.
+                 */
+                const ArgumentType& getArgument() const
+                {
+                    return arg;
+                }
+
+                /**
+                 * Process key-value pair by the underlying Cache Entry Processor
+                 * using binded argument.
+                 *
+                 * Equality operator should be defined for the value type.
+                 *
+                 * @param key Cache entry key.
+                 * @param value Cache entry value. New value is stored here upon completion.
+                 * @param exists Entry existance indicator.
+                 * @param state State of the entry after the processing.
+                 * @return Result of the processing.
+                 */
+                template<typename R, typename K, typename V>
+                R Process(const K& key, V& value, bool exists, MutableCacheEntryState &state)
+                {
+                    typedef ignite::cache::MutableCacheEntry<K, V> Entry;
+
+                    Entry entry;
+
+                    if (exists)
+                        entry = Entry(key, value);
+                    else
+                        entry = Entry(key);
+
+                    R res = proc.Process(entry, arg);
+
+                    state = GetMutableCacheEntryState(value, exists, entry.GetValue(), entry.IsExists());
+
+                    value = entry.GetValue();
+
+                    return res;
+                }
+
+            private:
+                /** Stored processor. */
+                ProcessorType proc;
+
+                /** Stored argument. */
+                ArgumentType  arg;
+            };
+        }
+    }
+
+    namespace binary
+    {
+        /**
+         * Binary type specialization for CacheEntryProcessorHolder.
+         */
+        template<typename P, typename A>
+        struct BinaryType<impl::cache::CacheEntryProcessorHolder<P, A> >
+        {
+            typedef impl::cache::CacheEntryProcessorHolder<P, A> UnderlyingType;
+
+            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+            IGNITE_BINARY_GET_HASH_CODE_ZERO(UnderlyingType)
+            IGNITE_BINARY_IS_NULL_FALSE(UnderlyingType)
+            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(UnderlyingType)
+
+            int32_t GetTypeId()
+            {
+                static bool typeIdInited = false;
+                static int32_t typeId;
+                static common::concurrent::CriticalSection initLock;
+
+                if (typeIdInited)
+                    return typeId;
+
+                common::concurrent::CsLockGuard guard(initLock);
+
+                if (typeIdInited)
+                    return typeId;
+
+                typeId = GetBinaryStringHashCode(GetTypeName().c_str());
+                typeIdInited = true;
+
+                return typeId;
+            }
+
+            std::string GetTypeName()
+            {
+                // Using static variable and only initialize it once for better
+                // performance. Type name can't change in the course of the
+                // program flow.
+                static std::string name;
+                static common::concurrent::CriticalSection initLock;
+
+                // Name has been constructed already. Return it.
+                if (!name.empty())
+                    return name;
+
+                common::concurrent::CsLockGuard guard(initLock);
+
+                if (!name.empty())
+                    return name;
+
+                // Constructing name here.
+                BinaryType<P> p;
+
+                std::string procName = p.GetTypeName();
+
+                // -1 is for unnessecary null byte at the end of the C-string.
+                name.reserve(sizeof("CacheEntryProcessorHolder<>") - 1 + procName.size());
+
+                // Processor name is enough for identification as it is
+                // forbidden to register the same processor type several times.
+                name.append("CacheEntryProcessorHolder<").append(procName).push_back('>');
+
+                return name;
+            }
+
+            void Write(BinaryWriter& writer, UnderlyingType obj)
+            {
+                BinaryRawWriter raw = writer.RawWriter();
+
+                raw.WriteObject(obj.getProcessor());
+                raw.WriteObject(obj.getArgument());
+            }
+
+            UnderlyingType Read(BinaryReader& reader)
+            {
+                BinaryRawReader raw = reader.RawReader();
+
+                const P& proc = raw.ReadObject<P>();
+                const A& arg = raw.ReadObject<A>();
+
+                return UnderlyingType(proc, arg);
+            }
+        };
+    }
+}
+
+#endif //_IGNITE_IMPL_CACHE_CACHE_ENTRY_PROCESSOR_HOLDER

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
index 535e3ec..e6d49ef 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
@@ -69,7 +69,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result.
                  */
-                bool ContainsKey(InputOperation& inOp, IgniteError* err);
+                bool ContainsKey(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform ContainsKeys.
@@ -78,7 +78,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result.
                  */
-                bool ContainsKeys(InputOperation& inOp, IgniteError* err);
+                bool ContainsKeys(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform LocalPeek.
@@ -89,7 +89,7 @@ namespace ignite
                  * @param err Error.
                  */
                 void LocalPeek(InputOperation& inOp, OutputOperation& outOp, 
-                    int32_t peekModes, IgniteError* err);
+                    int32_t peekModes, IgniteError& err);
 
                 /**
                  * Perform Get.
@@ -98,7 +98,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void Get(InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void Get(InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
                 
                 /**
                  * Perform GetAll.
@@ -107,7 +107,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void GetAll(InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void GetAll(InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                  * Perform Put.
@@ -115,7 +115,7 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void Put(InputOperation& inOp, IgniteError* err);
+                void Put(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform PutAll.
@@ -123,7 +123,7 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void PutAll(InputOperation& inOp, IgniteError* err);
+                void PutAll(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform GetAndPut.
@@ -132,7 +132,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void GetAndPut(InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void GetAndPut(InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                  * Perform GetAndReplace.
@@ -141,7 +141,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void GetAndReplace(InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void GetAndReplace(InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                  * Perform GetAndRemove.
@@ -150,7 +150,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void GetAndRemove(InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void GetAndRemove(InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                  * Perform PutIfAbsent.
@@ -159,7 +159,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result
                  */
-                bool PutIfAbsent(InputOperation& inOp, IgniteError* err);
+                bool PutIfAbsent(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform GetAndPutIfAbsent.
@@ -168,7 +168,7 @@ namespace ignite
                  * @param outOp Output.
                  * @param err Error.
                  */
-                void GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, IgniteError* err);
+                void GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                  * Perform Replace(K, V).
@@ -177,7 +177,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result
                  */
-                bool Replace(InputOperation& inOp, IgniteError* err);
+                bool Replace(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform Replace(K, V, V).
@@ -186,7 +186,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result
                  */
-                bool ReplaceIfEqual(InputOperation& inOp, IgniteError* err);
+                bool ReplaceIfEqual(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform LocalEvict.
@@ -194,14 +194,14 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void LocalEvict(InputOperation& inOp, IgniteError* err);
+                void LocalEvict(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform Clear.
                  *
                  * @param err Error.
                  */
-                void Clear(IgniteError* err);
+                void Clear(IgniteError& err);
 
                 /**
                  * Perform Clear.
@@ -209,7 +209,7 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void Clear(InputOperation& inOp, IgniteError* err);
+                void Clear(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform ClearAll.
@@ -217,7 +217,7 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void ClearAll(InputOperation& inOp, IgniteError* err);
+                void ClearAll(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform LocalClear.
@@ -225,7 +225,7 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void LocalClear(InputOperation& inOp, IgniteError* err);
+                void LocalClear(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform LocalClearAll.
@@ -233,7 +233,7 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void LocalClearAll(InputOperation& inOp, IgniteError* err);
+                void LocalClearAll(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform Remove(K).
@@ -242,7 +242,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result
                  */
-                bool Remove(InputOperation& inOp, IgniteError* err);
+                bool Remove(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform Remove(K, V).
@@ -251,7 +251,7 @@ namespace ignite
                  * @param err Error.
                  * @return Result
                  */
-                bool RemoveIfEqual(InputOperation& inOp, IgniteError* err);
+                bool RemoveIfEqual(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform RemoveAll.
@@ -259,14 +259,14 @@ namespace ignite
                  * @param inOp Input.
                  * @param err Error.
                  */
-                void RemoveAll(InputOperation& inOp, IgniteError* err);
+                void RemoveAll(InputOperation& inOp, IgniteError& err);
 
                 /**
                  * Perform RemoveAll.
                  *
                  * @param err Error.
                  */
-                void RemoveAll(IgniteError* err);
+                void RemoveAll(IgniteError& err);
 
                 /**
                 * Perform Size.
@@ -275,7 +275,7 @@ namespace ignite
                 * @param local Local flag.
                 * @param err Error.
                 */
-                int32_t Size(int32_t peekModes, bool local, IgniteError* err);
+                int32_t Size(int32_t peekModes, bool local, IgniteError& err);
 
                 /**
                  * Invoke query.
@@ -284,7 +284,7 @@ namespace ignite
                  * @param err Error.
                  * @return Query cursor.
                  */
-                query::QueryCursorImpl* QuerySql(const ignite::cache::query::SqlQuery& qry, IgniteError* err);
+                query::QueryCursorImpl* QuerySql(const ignite::cache::query::SqlQuery& qry, IgniteError& err);
 
                 /**
                  * Invoke text query.
@@ -293,7 +293,7 @@ namespace ignite
                  * @param err Error.
                  * @return Query cursor.
                  */
-                query::QueryCursorImpl* QueryText(const ignite::cache::query::TextQuery& qry, IgniteError* err);
+                query::QueryCursorImpl* QueryText(const ignite::cache::query::TextQuery& qry, IgniteError& err);
 
                 /**
                  * Invoke scan query.
@@ -302,7 +302,7 @@ namespace ignite
                  * @param err Error.
                  * @return Query cursor.
                  */
-                query::QueryCursorImpl* QueryScan(const ignite::cache::query::ScanQuery& qry, IgniteError* err);
+                query::QueryCursorImpl* QueryScan(const ignite::cache::query::ScanQuery& qry, IgniteError& err);
 
                 /**
                  * Invoke sql fields query.
@@ -311,7 +311,16 @@ namespace ignite
                  * @param err Error.
                  * @return Query cursor.
                  */
-                query::QueryCursorImpl* QuerySqlFields(const ignite::cache::query::SqlFieldsQuery& qry, IgniteError* err);
+                query::QueryCursorImpl* QuerySqlFields(const ignite::cache::query::SqlFieldsQuery& qry, IgniteError& err);
+
+                /**
+                 * Perform Invoke.
+                 *
+                 * @param inOp Input.
+                 * @param outOp Output.
+                 * @param err Error.
+                 */
+                void Invoke(InputOperation& inOp, OutputOperation& outOp, IgniteError& err);
 
                 /**
                  * Start continuous query execution.
@@ -374,7 +383,7 @@ namespace ignite
                  * @param err Error.
                  */
                 template<typename T>
-                query::QueryCursorImpl* QueryInternal(const T& qry, int32_t typ, IgniteError* err)
+                query::QueryCursorImpl* QueryInternal(const T& qry, int32_t typ, IgniteError& err)
                 {
                     ignite::jni::java::JniErrorInfo jniErr;
 
@@ -447,7 +456,7 @@ namespace ignite
                     jobject qryJavaRef = GetEnvironment().Context()->CacheOutOpContinuousQuery(GetTarget(),
                         cmd, mem.Get()->PointerLong(), &jniErr);
 
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
                     if (jniErr.code == java::IGNITE_JNI_ERR_SUCCESS)
                         return new query::continuous::ContinuousQueryHandleImpl(GetEnvironmentPointer(), handle, qryJavaRef);

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core/include/ignite/impl/cluster/cluster_group_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cluster/cluster_group_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cluster/cluster_group_impl.h
new file mode 100644
index 0000000..2bff0d8
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/cluster/cluster_group_impl.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_IMPL_CLUSTER_CLUSTER_GROUP_IMPL
+#define _IGNITE_IMPL_CLUSTER_CLUSTER_GROUP_IMPL
+
+#include <ignite/common/concurrent.h>
+#include <ignite/jni/java.h>
+
+#include <ignite/impl/interop/interop_target.h>
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace cluster
+        {
+            /**
+             * Cluster group implementation.
+             */
+            class IGNITE_FRIEND_EXPORT ClusterGroupImpl : private interop::InteropTarget
+            {
+                typedef common::concurrent::SharedPointer<IgniteEnvironment> SP_IgniteEnvironment;
+                typedef common::concurrent::SharedPointer<ClusterGroupImpl> SP_ClusterGroupImpl;
+            public:
+                /**
+                 * Constructor used to create new instance.
+                 *
+                 * @param env Environment.
+                 * @param javaRef Reference to java object.
+                 */
+                ClusterGroupImpl(SP_IgniteEnvironment env, jobject javaRef);
+
+                /**
+                 * Destructor.
+                 */
+                ~ClusterGroupImpl();
+
+                /**
+                 * Get server nodes cluster group implementation.
+                 *
+                 * @param err Error.
+                 * @return Server nodes cluster group implementation.
+                 */
+                SP_ClusterGroupImpl ForServers(IgniteError& err);
+
+            private:
+                /**
+                 * Make cluster group implementation using java reference and
+                 * internal state of this cluster group.
+                 *
+                 * @param javaRef Java reference to cluster group to be created.
+                 * @return New cluster group implementation.
+                 */
+                SP_ClusterGroupImpl FromTarget(jobject javaRef);
+
+                IGNITE_NO_COPY_ASSIGNMENT(ClusterGroupImpl)
+            };
+        }
+    }
+}
+
+#endif //_IGNITE_IMPL_CLUSTER_CLUSTER_GROUP_IMPL
\ No newline at end of file


[45/50] [abbrv] ignite git commit: IGNITE-4663: BinaryMarshaller: class is no longer required when object is unmarshalled to BinaryObject w/o deserialization. This closes #1507.

Posted by sb...@apache.org.
IGNITE-4663: BinaryMarshaller: class is no longer required when object is unmarshalled to BinaryObject w/o deserialization. This closes #1507.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 85b08c5a546d79535cb9178677832ff8233034fd
Parents: 7d3c046
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Tue Feb 14 16:18:45 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Feb 14 16:18:45 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/binary/BinaryUtils.java     | 39 ++++++++++++++++++--
 1 file changed, 36 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/85b08c5a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index 2b55b6c..78bc31a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -1474,12 +1474,37 @@ public class BinaryUtils {
     }
 
     /**
-     * @return Value.
+     * @param in Binary input stream.
+     * @param ctx Binary context.
+     * @param ldr Class loader.
+     * @return Class object specified at the input stream.
+     * @throws BinaryObjectException If failed.
      */
     public static Class doReadClass(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr)
         throws BinaryObjectException {
+        return doReadClass(in, ctx, ldr, true);
+    }
+
+    /**
+     * @param in Binary input stream.
+     * @param ctx Binary context.
+     * @param ldr Class loader.
+     * @param deserialize Doesn't load the class when the flag is {@code false}. Class information is skipped.
+     * @return Class object specified at the input stream if {@code deserialize == true}. Otherwise returns {@code null}
+     * @throws BinaryObjectException If failed.
+     */
+    public static Class doReadClass(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, boolean deserialize)
+        throws BinaryObjectException {
         int typeId = in.readInt();
 
+        if (!deserialize) {
+            // Skip class name at the stream.
+            if (typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID)
+                doReadClassName(in);
+
+            return null;
+        }
+
         return doReadClass(in, ctx, ldr, typeId);
     }
 
@@ -1531,8 +1556,12 @@ public class BinaryUtils {
     }
 
     /**
+     * @param in Binary input stream.
+     * @param ctx Binary context.
+     * @param ldr Class loader.
      * @param typeId Type id.
-     * @return Value.
+     * @return Class object specified at the input stream.
+     * @throws BinaryObjectException If failed.
      */
     public static Class doReadClass(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, int typeId)
         throws BinaryObjectException {
@@ -1896,6 +1925,10 @@ public class BinaryUtils {
     }
 
     /**
+     * @param in Binary input stream.
+     * @param ctx Binary context.
+     * @param ldr Class loader.
+     * @param handles Holder for handles.
      * @param deserialize Deep flag.
      * @return Value.
      * @throws BinaryObjectException In case of error.
@@ -1904,7 +1937,7 @@ public class BinaryUtils {
         BinaryReaderHandlesHolder handles, boolean deserialize) throws BinaryObjectException {
         int hPos = positionForHandle(in);
 
-        Class compType = doReadClass(in, ctx, ldr);
+        Class compType = doReadClass(in, ctx, ldr, deserialize);
 
         int len = in.readInt();
 


[02/50] [abbrv] ignite git commit: IGNITE-4196: Added means to specify port for H2 debug console. This closes #1486.

Posted by sb...@apache.org.
IGNITE-4196: Added means to specify port for H2 debug console. This closes #1486.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: b2462607d726608a39033e9b7c7327c59cb28c73
Parents: 9ff2a8f
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Fri Feb 3 11:41:14 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Feb 3 11:41:14 2017 +0300

----------------------------------------------------------------------
 .../main/java/org/apache/ignite/IgniteSystemProperties.java  | 8 ++++++++
 .../internal/processors/query/h2/IgniteH2Indexing.java       | 8 +++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b2462607/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 083bb72..c479076 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -318,6 +318,14 @@ public final class IgniteSystemProperties {
     public static final String IGNITE_H2_DEBUG_CONSOLE = "IGNITE_H2_DEBUG_CONSOLE";
 
     /**
+     * This property allows to specify user defined port which H2 indexing SPI will use
+     * to start H2 debug console on. If this property is not set or set to 0, H2 debug
+     * console will use system-provided dynamic port.
+     * This property is only relevant when {@link #IGNITE_H2_DEBUG_CONSOLE} property is set.
+     */
+    public static final String IGNITE_H2_DEBUG_CONSOLE_PORT = "IGNITE_H2_DEBUG_CONSOLE_PORT";
+
+    /**
      * If this property is set to {@code true} then shared memory space native debug will be enabled.
      */
     public static final String IGNITE_IPC_SHMEM_SPACE_DEBUG = "IGNITE_IPC_SHMEM_SPACE_DEBUG";

http://git-wip-us.apache.org/repos/asf/ignite/blob/b2462607/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 505a3af..69a65fe 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -174,8 +174,10 @@ import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_H2_DEBUG_CONSOLE;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_H2_DEBUG_CONSOLE_PORT;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_H2_INDEXING_CACHE_CLEANUP_PERIOD;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_H2_INDEXING_CACHE_THREAD_USAGE_TIMEOUT;
+import static org.apache.ignite.IgniteSystemProperties.getInteger;
 import static org.apache.ignite.IgniteSystemProperties.getString;
 import static org.apache.ignite.internal.processors.query.GridQueryIndexType.FULLTEXT;
 import static org.apache.ignite.internal.processors.query.GridQueryIndexType.GEO_SPATIAL;
@@ -1754,11 +1756,15 @@ public class IgniteH2Indexing implements GridQueryIndexing {
             if (getString(IGNITE_H2_DEBUG_CONSOLE) != null) {
                 Connection c = DriverManager.getConnection(dbUrl);
 
+                int port = getInteger(IGNITE_H2_DEBUG_CONSOLE_PORT, 0);
+
                 WebServer webSrv = new WebServer();
-                Server web = new Server(webSrv, "-webPort", "0");
+                Server web = new Server(webSrv, "-webPort", Integer.toString(port));
                 web.start();
                 String url = webSrv.addSession(c);
 
+                U.quietAndInfo(log, "H2 debug console URL: " + url);
+
                 try {
                     Server.openBrowser(url);
                 }


[22/50] [abbrv] ignite git commit: minor

Posted by sb...@apache.org.
minor


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 4a62232fc95f482ac1610263330b5ef103179b9d
Parents: 3459bdd
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Thu Feb 9 20:29:36 2017 +0700
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Thu Feb 9 20:29:36 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/suggestions/GridPerformanceSuggestions.java     | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4a62232f/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java
index c51a136..291840c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java
@@ -93,6 +93,7 @@ public class GridPerformanceSuggestions {
 
             perfs.clear();
         }
+
         U.quietAndInfo(log, "Refer to this page for more performance suggestions: " + SUGGESTIONS_LINK);
         U.quietAndInfo(log, "");
     }


[08/50] [abbrv] ignite git commit: Merge branch 'master' into ignite-2.0

Posted by sb...@apache.org.
Merge branch 'master' into ignite-2.0

# Conflicts:
#	modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: af98efd5487dc2f6177b245d3d4c369f8ec4fe81
Parents: aa46bc7 0726d32
Author: devozerov <vo...@gridgain.com>
Authored: Mon Feb 6 17:55:58 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Feb 6 17:55:58 2017 +0300

----------------------------------------------------------------------
 assembly/LICENSE_FABRIC                         |  35 +++--
 assembly/LICENSE_HADOOP                         |  17 ++-
 examples/schema-import/bin/h2-server.bat        |   2 +-
 examples/schema-import/bin/h2-server.sh         |   4 +-
 .../schema-import/bin/schema-import.properties  |   2 +-
 .../src/main/resources/META-INF/licenses.txt.vm |   7 +-
 .../apache/ignite/IgniteSystemProperties.java   |   8 ++
 .../ignite/lang/IgniteProductVersion.java       |   2 +-
 .../processors/query/h2/IgniteH2Indexing.java   |   8 +-
 .../h2/twostep/GridReduceQueryExecutor.java     |   2 +-
 .../IgniteSqlEntryCacheModeAgnosticTest.java    | 140 +++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite.java          |   2 +
 .../Cache/CacheAbstractTransactionalTest.cs     | 105 +++++++-------
 .../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs  |   9 +-
 .../views/templates/agent-download.jade         |   2 +-
 modules/web-console/web-agent/README.txt        |   2 +-
 .../cache/IgnitePutRemoveBenchmark.java         |  42 ++++++
 .../cache/IgnitePutRemoveTxBenchmark.java       |  30 ++++
 18 files changed, 323 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/af98efd5/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/af98efd5/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 49fb269,d85e111..ed3d1e8
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@@ -95,7 -95,7 +95,8 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.cache.query.IgniteCacheQueryCacheDestroySelfTest;
  import org.apache.ignite.internal.processors.cache.query.IndexingSpiQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.query.IndexingSpiQueryTxSelfTest;
 +import org.apache.ignite.internal.processors.query.IgniteSqlQueryDedicatedPoolTest;
+ import org.apache.ignite.internal.processors.query.IgniteSqlEntryCacheModeAgnosticTest;
  import org.apache.ignite.internal.processors.query.IgniteSqlSchemaIndexingTest;
  import org.apache.ignite.internal.processors.query.IgniteSqlSplitterSelfTest;
  import org.apache.ignite.internal.processors.query.h2.GridH2IndexRebuildTest;
@@@ -241,7 -241,7 +242,8 @@@ public class IgniteCacheQuerySelfTestSu
          suite.addTestSuite(CacheOffheapBatchIndexingSingleTypeTest.class);
          suite.addTestSuite(CacheSqlQueryValueCopySelfTest.class);
          suite.addTestSuite(IgniteCacheQueryCacheDestroySelfTest.class);
 +        suite.addTestSuite(IgniteSqlQueryDedicatedPoolTest.class);
+         suite.addTestSuite(IgniteSqlEntryCacheModeAgnosticTest.class);
  
          return suite;
      }


[47/50] [abbrv] ignite git commit: Megre 2.0

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index f05fdf7,cd4c55c..0309fa7
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@@ -403,7 -400,7 +404,8 @@@ public abstract class IgniteTxLocalAdap
          boolean skipVals,
          boolean needVer,
          boolean keepBinary,
 +        boolean recovery,
+         final ExpiryPolicy expiryPlc,
          final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c
      ) {
          assert cacheCtx.isLocal() : cacheCtx.name();
@@@ -431,9 -430,11 +435,9 @@@
                          continue;
  
                      try {
-                         T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                         EntryGetResult res = entry.innerGetVersioned(
                              null,
                              this,
 -                            /*readSwap*/true,
 -                            /*unmarshal*/true,
                              /*update-metrics*/!skipVals,
                              /*event*/!skipVals,
                              CU.subjectId(this, cctx),
@@@ -1246,9 -1222,11 +1254,9 @@@
                                      F.first(txEntry.entryProcessors()) : null;
  
                              if (needVer) {
-                                 T2<CacheObject, GridCacheVersion> res = txEntry.cached().innerGetVersioned(
+                                 EntryGetResult res = txEntry.cached().innerGetVersioned(
                                      null,
                                      this,
 -                                    /*swap*/true,
 -                                    /*unmarshal*/true,
                                      /*update-metrics*/true,
                                      /*event*/!skipVals,
                                      CU.subjectId(this, cctx),
@@@ -1499,7 -1486,7 +1511,8 @@@
                  skipVals,
                  needReadVer,
                  !deserializeBinary,
 +                recovery,
+                 expiryPlc,
                  new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
                      @Override public void apply(KeyCacheObject key, Object val, GridCacheVersion loadVer) {
                          if (isRollbackOnly()) {
@@@ -1675,10 -1665,12 +1692,10 @@@
                                              F.first(txEntry.entryProcessors()) : null;
  
                                      if (needVer) {
-                                         T2<CacheObject, GridCacheVersion> res = cached.innerGetVersioned(
+                                         EntryGetResult res = cached.innerGetVersioned(
                                              null,
                                              IgniteTxLocalAdapter.this,
 -                                            /*swap*/cacheCtx.isSwapOrOffheapEnabled(),
 -                                            /*unmarshal*/true,
 -                                            /*update-metrics*/true,
 +                                            /**update-metrics*/true,
                                              /*event*/!skipVals,
                                              CU.subjectId(IgniteTxLocalAdapter.this, cctx),
                                              transformClo,
@@@ -2041,7 -2035,7 +2061,8 @@@
                      /*read through*/(entryProcessor != null || cacheCtx.config().isLoadPreviousValue()) && !skipStore,
                      retval,
                      keepBinary,
 -                    expiryPlc);
++                    expiryPlc,
 +                    recovery);
              }
  
              return new GridFinishedFuture<>();
@@@ -2212,7 -2205,7 +2233,8 @@@
                      /*read through*/(invokeMap != null || cacheCtx.config().isLoadPreviousValue()) && !skipStore,
                      retval,
                      keepBinary,
 -                    expiryPlc);
++                    expiryPlc,
 +                    recovery);
              }
  
              return new GridFinishedFuture<>();
@@@ -2232,8 -2225,7 +2254,9 @@@
       * @param hasFilters {@code True} if filters not empty.
       * @param readThrough Read through flag.
       * @param retval Return value flag.
 +     * @param keepBinary Keep binary flag.
+      * @param expiryPlc Expiry policy.
 +     * @param recovery Recovery flag.
       * @return Load future.
       */
      private IgniteInternalFuture<Void> loadMissing(
@@@ -2248,8 -2240,7 +2271,9 @@@
          final boolean readThrough,
          final boolean retval,
          final boolean keepBinary,
 -        final ExpiryPolicy expiryPlc) {
++        final ExpiryPolicy expiryPlc,
 +        final boolean recovery
 +    ) {
          GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c =
              new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
                  @Override public void apply(KeyCacheObject key,
@@@ -2323,7 -2314,7 +2347,8 @@@
              /*skipVals*/singleRmv,
              needReadVer,
              keepBinary,
 +            recovery,
+             expiryPlc,
              c);
      }
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
index d6b09e4,f5687a0..cf1e7e2
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
@@@ -192,6 -194,6 +194,7 @@@ public interface IgniteTxLocalEx extend
          boolean skipVals,
          boolean needVer,
          boolean keepBinary,
 +        boolean recovery,
+         final ExpiryPolicy expiryPlc,
          GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c);
  }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
index 124cb4b,d1c8b2d..a32b9d8
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
@@@ -121,8 -139,27 +139,27 @@@ public class ClusterProcessor extends G
          }
      }
  
+ 
+     /**
+      * @param vals collection to seek through.
+      */
+     private Boolean findLastFlag(Collection<Serializable> vals) {
+         Boolean flag = null;
+ 
+         for (Serializable ser : vals) {
+             if (ser != null) {
+                 Map<String, Object> map = (Map<String, Object>) ser;
+ 
+                 if (map.containsKey(ATTR_UPDATE_NOTIFIER_STATUS))
+                     flag = (Boolean) map.get(ATTR_UPDATE_NOTIFIER_STATUS);
+             }
+         }
+ 
+         return flag;
+     }
+ 
      /** {@inheritDoc} */
 -    @Override public void onKernalStart() throws IgniteCheckedException {
 +    @Override public void onKernalStart(boolean activeOnStart) throws IgniteCheckedException {
          if (notifyEnabled.get()) {
              try {
                  verChecker = new GridUpdateNotifier(ctx.gridName(),

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
index 87d54a1,0000000..247d469
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
@@@ -1,947 -1,0 +1,955 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements. See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License. You may obtain a copy of the License at
 + *
 + * http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.processors.cluster;
 +
 +import java.io.Serializable;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.UUID;
 +import java.util.concurrent.atomic.AtomicReference;
 +import org.apache.ignite.Ignite;
 +import org.apache.ignite.IgniteCheckedException;
 +import org.apache.ignite.IgniteCompute;
 +import org.apache.ignite.IgniteException;
 +import org.apache.ignite.IgniteLogger;
 +import org.apache.ignite.cluster.ClusterNode;
 +import org.apache.ignite.configuration.CacheConfiguration;
 +import org.apache.ignite.events.DiscoveryEvent;
 +import org.apache.ignite.events.Event;
 +import org.apache.ignite.internal.GridKernalContext;
 +import org.apache.ignite.internal.IgniteInternalFuture;
 +import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 +import org.apache.ignite.internal.cluster.ClusterGroupAdapter;
 +import org.apache.ignite.internal.managers.discovery.CustomEventListener;
 +import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
 +import org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager;
 +import org.apache.ignite.internal.processors.GridProcessorAdapter;
 +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 +import org.apache.ignite.internal.processors.cache.ClusterState;
 +import org.apache.ignite.internal.processors.cache.ChangeGlobalStateMessage;
 +import org.apache.ignite.internal.processors.cache.DynamicCacheChangeBatch;
 +import org.apache.ignite.internal.processors.cache.DynamicCacheChangeRequest;
 +import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
 +import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 +import org.apache.ignite.internal.processors.cache.GridChangeGlobalStateMessageResponse;
 +import org.apache.ignite.internal.util.future.GridFinishedFuture;
 +import org.apache.ignite.internal.util.future.GridFutureAdapter;
 +import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 +import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 +import org.apache.ignite.internal.util.typedef.CI1;
 +import org.apache.ignite.internal.util.typedef.CI2;
 +import org.apache.ignite.internal.util.typedef.F;
 +import org.apache.ignite.internal.util.typedef.internal.CU;
 +import org.apache.ignite.internal.util.typedef.internal.S;
 +import org.apache.ignite.internal.util.typedef.internal.U;
 +import org.apache.ignite.lang.IgniteFuture;
 +import org.apache.ignite.lang.IgniteRunnable;
 +import org.apache.ignite.resources.IgniteInstanceResource;
++import org.apache.ignite.spi.discovery.DiscoveryDataBag;
 +import org.jetbrains.annotations.Nullable;
 +
 +import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
 +import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
 +import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
 +import static org.apache.ignite.internal.processors.cache.ClusterState.ACTIVE;
 +import static org.apache.ignite.internal.processors.cache.ClusterState.INACTIVE;
 +import static org.apache.ignite.internal.processors.cache.ClusterState.TRANSITION;
 +
 +/**
 + *
 + */
 +public class GridClusterStateProcessor extends GridProcessorAdapter {
 +    /** Global status. */
 +    private volatile ClusterState globalState;
 +
 +    /** Action context. */
 +    private volatile ChangeGlobalStateContext lastCgsCtx;
 +
 +    /** Local action future. */
 +    private final AtomicReference<GridChangeGlobalStateFuture> cgsLocFut = new AtomicReference<>();
 +
 +    /** Process. */
 +    @GridToStringExclude
 +    private GridCacheProcessor cacheProc;
 +
 +    /** Shared context. */
 +    @GridToStringExclude
 +    private GridCacheSharedContext<?, ?> sharedCtx;
 +
 +    //todo may be add init latch
 +
 +    /** Listener. */
 +    private final GridLocalEventListener lsr = new GridLocalEventListener() {
 +        @Override public void onEvent(Event evt) {
 +            assert evt != null;
 +
 +            final DiscoveryEvent e = (DiscoveryEvent)evt;
 +
 +            assert e.type() == EVT_NODE_LEFT || e.type() == EVT_NODE_FAILED : this;
 +
 +            final GridChangeGlobalStateFuture f = cgsLocFut.get();
 +
 +            if (f != null)
 +                f.initFut.listen(new CI1<IgniteInternalFuture>() {
 +                    @Override public void apply(IgniteInternalFuture fut) {
 +                        f.onDiscoveryEvent(e);
 +                    }
 +                });
 +        }
 +    };
 +
 +    /**
 +     * @param ctx Kernal context.
 +     */
 +    public GridClusterStateProcessor(GridKernalContext ctx) {
 +        super(ctx);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void start(boolean activeOnStart) throws IgniteCheckedException {
 +        super.start(activeOnStart);
 +
 +        globalState = activeOnStart ? ACTIVE : INACTIVE;
 +        cacheProc = ctx.cache();
 +        sharedCtx = cacheProc.context();
 +
 +        sharedCtx.io().addHandler(0,
 +            GridChangeGlobalStateMessageResponse.class,
 +            new CI2<UUID, GridChangeGlobalStateMessageResponse>() {
 +                @Override public void apply(UUID nodeId, GridChangeGlobalStateMessageResponse msg) {
 +                    processChangeGlobalStateResponse(nodeId, msg);
 +                }
 +            });
 +
 +        ctx.discovery().setCustomEventListener(
 +            ChangeGlobalStateMessage.class, new CustomEventListener<ChangeGlobalStateMessage>() {
 +                @Override public void onCustomEvent(
 +                    AffinityTopologyVersion topVer, ClusterNode snd, ChangeGlobalStateMessage msg) {
 +                    assert topVer != null;
 +                    assert snd != null;
 +                    assert msg != null;
 +
 +                    boolean activate = msg.activate();
 +
 +                    ChangeGlobalStateContext actx = lastCgsCtx;
 +
 +                    if (actx != null && globalState == TRANSITION) {
 +                        GridChangeGlobalStateFuture f = cgsLocFut.get();
 +
 +                        if (log.isDebugEnabled())
 +                            log.debug("Concurrent " + prettyStr(activate) + " [id=" +
 +                                ctx.localNodeId() + " topVer=" + topVer + " actx=" + actx + ", msg=" + msg + "]");
 +
 +                        if (f != null && f.requestId.equals(msg.requestId()))
 +                            f.onDone(new IgniteCheckedException(
 +                                "Concurrent change state, now in progress=" + (activate)
 +                                    + ", initiatingNodeId=" + actx.initiatingNodeId
 +                                    + ", you try=" + (prettyStr(activate)) + ", locNodeId=" + ctx.localNodeId()
 +                            ));
 +
 +                        msg.concurrentChangeState();
 +                    }
 +                    else {
 +                        if (log.isInfoEnabled())
 +                            log.info("Create " + prettyStr(activate) + " context [id=" +
 +                                ctx.localNodeId() + " topVer=" + topVer + ", reqId=" +
 +                                msg.requestId() + ", initiatingNodeId=" + msg.initiatorNodeId() + "]");
 +
 +                        lastCgsCtx = new ChangeGlobalStateContext(
 +                            msg.requestId(),
 +                            msg.initiatorNodeId(),
 +                            msg.getDynamicCacheChangeBatch(),
 +                            msg.activate());
 +
 +                        globalState = TRANSITION;
 +                    }
 +                }
 +            });
 +
 +        ctx.event().addLocalEventListener(lsr, EVT_NODE_LEFT, EVT_NODE_FAILED);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void stop(boolean cancel) throws IgniteCheckedException {
 +        super.stop(cancel);
 +
 +        sharedCtx.io().removeHandler(0, GridChangeGlobalStateMessageResponse.class);
 +        ctx.event().removeLocalEventListener(lsr, EVT_NODE_LEFT, EVT_NODE_FAILED);
 +
 +        IgniteCheckedException stopErr = new IgniteInterruptedCheckedException(
 +            "Node is stopping: " + ctx.gridName());
 +
 +        GridChangeGlobalStateFuture f = cgsLocFut.get();
 +
 +        if (f != null)
 +            f.onDone(stopErr);
 +
 +        cgsLocFut.set(null);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public DiscoveryDataExchangeType discoveryDataType() {
 +        return DiscoveryDataExchangeType.STATE_PROC;
 +    }
 +
 +    /** {@inheritDoc} */
-     @Nullable @Override public Serializable collectDiscoveryData(UUID nodeId) {
-         return globalState;
++    @Override public void collectJoiningNodeData(DiscoveryDataBag dataBag) {
++        dataBag.addJoiningNodeData(DiscoveryDataExchangeType.STATE_PROC.ordinal(), globalState);
 +    }
 +
 +    /** {@inheritDoc} */
-     @Override public void onDiscoveryDataReceived(UUID joiningNodeId, UUID rmtNodeId, Serializable data) {
-         if (ctx.localNodeId().equals(joiningNodeId))
-             globalState = (ClusterState)data;
++    @Override public void collectGridNodeData(DiscoveryDataBag dataBag) {
++        dataBag.addGridCommonData(DiscoveryDataExchangeType.STATE_PROC.ordinal(), globalState);
++    }
++
++    /** {@inheritDoc} */
++    @Override public void onGridDataReceived(DiscoveryDataBag.GridDiscoveryData data) {
++        globalState = (ClusterState)data.commonData();
++    }
++
++    /** {@inheritDoc} */
++    @Override public void onJoiningNodeDataReceived(DiscoveryDataBag.JoiningNodeDiscoveryData data) {
++        // No-op.
 +    }
 +
 +    /**
 +     *
 +     */
 +    public IgniteInternalFuture<?> changeGlobalState(final boolean activate) {
 +        if (cacheProc.transactions().tx() != null || sharedCtx.lockedTopologyVersion(null) != null)
 +            throw new IgniteException("Cannot " + prettyStr(activate) + " cluster, because cache locked on transaction.");
 +
 +        if ((this.globalState == ACTIVE && activate) || (this.globalState == INACTIVE && !activate))
 +            return new GridFinishedFuture<>();
 +
 +        final UUID requestId = UUID.randomUUID();
 +
 +        final GridChangeGlobalStateFuture cgsFut = new GridChangeGlobalStateFuture(requestId, activate, ctx);
 +
 +        if (!cgsLocFut.compareAndSet(null, cgsFut)) {
 +            GridChangeGlobalStateFuture locF = cgsLocFut.get();
 +
 +            if (locF.activate == activate)
 +                return locF;
 +            else
 +                return new GridFinishedFuture<>(new IgniteException(
 +                    "fail " + prettyStr(activate) + ", because now in progress" + prettyStr(locF.activate)));
 +        }
 +
 +        try {
 +            if (ctx.clientNode()) {
 +                AffinityTopologyVersion topVer = ctx.discovery().topologyVersionEx();
 +
 +                IgniteCompute comp = ((ClusterGroupAdapter)ctx.cluster().get().forServers())
 +                    .compute().withAsync();
 +
 +                if (log.isInfoEnabled())
 +                    log.info("Send " + prettyStr(activate) + " request from client node [id=" +
 +                        ctx.localNodeId() + " topVer=" + topVer + " ]");
 +
 +                comp.run(new ClientChangeGlobalStateComputeRequest(activate));
 +
 +                comp.future().listen(new CI1<IgniteFuture>() {
 +                    @Override public void apply(IgniteFuture fut) {
 +                        try {
 +                            fut.get();
 +
 +                            cgsFut.onDone();
 +                        }
 +                        catch (Exception e) {
 +                            cgsFut.onDone(e);
 +                        }
 +                    }
 +                });
 +            }
 +            else {
 +                List<DynamicCacheChangeRequest> reqs = new ArrayList<>();
 +
 +                DynamicCacheChangeRequest changeGlobalStateReq = new DynamicCacheChangeRequest(
 +                    requestId, null, ctx.localNodeId());
 +
 +                changeGlobalStateReq.state(activate ? ACTIVE : INACTIVE);
 +
 +                reqs.add(changeGlobalStateReq);
 +
 +                reqs.addAll(activate ? cacheProc.startAllCachesRequests() : cacheProc.stopAllCachesRequests());
 +
 +                ChangeGlobalStateMessage changeGlobalStateMsg = new ChangeGlobalStateMessage(
 +                    requestId, ctx.localNodeId(), activate, new DynamicCacheChangeBatch(reqs));
 +
 +                try {
 +                    ctx.discovery().sendCustomEvent(changeGlobalStateMsg);
 +
 +                    if (ctx.isStopping())
 +                        cgsFut.onDone(new IgniteCheckedException("Failed to execute " + prettyStr(activate) + " request, " +
 +                            "node is stopping."));
 +                }
 +                catch (IgniteCheckedException e) {
 +                    log.error("Fail create or send change global state request." + cgsFut, e);
 +
 +                    cgsFut.onDone(e);
 +                }
 +            }
 +        }
 +        catch (IgniteCheckedException e) {
 +            log.error("Fail create or send change global state request." + cgsFut, e);
 +
 +            cgsFut.onDone(e);
 +        }
 +
 +        return cgsFut;
 +    }
 +
 +    /**
 +     *
 +     */
 +    public boolean active() {
 +        ChangeGlobalStateContext actx = lastCgsCtx;
 +
 +        if (actx != null && !actx.activate && globalState == TRANSITION)
 +            return true;
 +
 +        if (actx != null && actx.activate && globalState == TRANSITION)
 +            return false;
 +
 +        return globalState == ACTIVE;
 +    }
 +
 +    /**
 +     * @param reqs Requests.
 +     */
 +    public boolean changeGlobalState(
 +        Collection<DynamicCacheChangeRequest> reqs,
 +        AffinityTopologyVersion topVer
 +    ) {
 +        assert !F.isEmpty(reqs);
 +        assert topVer != null;
 +
 +        for (DynamicCacheChangeRequest req : reqs)
 +            if (req.globalStateChange()) {
 +                ChangeGlobalStateContext cgsCtx = lastCgsCtx;
 +
 +                assert cgsCtx != null : "reqs: " + Arrays.toString(reqs.toArray());
 +
 +                cgsCtx.topologyVersion(topVer);
 +
 +                return true;
 +            }
 +
 +
 +        return false;
 +    }
 +
 +    /**
 +     * Invoke from exchange future.
 +     */
 +    public Exception onChangeGlobalState() {
 +        GridChangeGlobalStateFuture f = cgsLocFut.get();
 +
 +        ChangeGlobalStateContext cgsCtx = lastCgsCtx;
 +
 +        assert cgsCtx != null;
 +
 +        if (f != null)
 +            f.setRemaining(cgsCtx.topVer);
 +
 +        return cgsCtx.activate ? onActivate(cgsCtx) : onDeActivate(cgsCtx);
 +    }
 +
 +    /**
 +     * @param exs Exs.
 +     */
 +    public void onFullResponseMessage(Map<UUID, Exception> exs) {
 +        assert !F.isEmpty(exs);
 +
 +        ChangeGlobalStateContext actx = lastCgsCtx;
 +
 +        actx.setFail();
 +
 +        // revert change if activation request fail
 +        if (actx.activate) {
 +            try {
 +                cacheProc.onKernalStopCaches(true);
 +
 +                cacheProc.stopCaches(true);
 +
 +                sharedCtx.affinity().removeAllCacheInfo();
 +
 +                if (!ctx.clientNode()) {
 +                    sharedCtx.database().onDeActivate(ctx);
 +
 +                    if (sharedCtx.pageStore() != null)
 +                        sharedCtx.pageStore().onDeActivate(ctx);
 +
 +                    if (sharedCtx.wal() != null)
 +                        sharedCtx.wal().onDeActivate(ctx);
 +                }
 +            }
 +            catch (Exception e) {
 +                for (Map.Entry<UUID, Exception> entry : exs.entrySet())
 +                    e.addSuppressed(entry.getValue());
 +
 +                log.error("Fail while revert activation request changes", e);
 +            }
 +        }
 +        else {
 +            //todo revert change if deactivate request fail
 +        }
 +
 +        globalState = actx.activate ? INACTIVE : ACTIVE;
 +
 +        GridChangeGlobalStateFuture af = cgsLocFut.get();
 +
 +        if (af != null && af.requestId.equals(actx.requestId)) {
 +            IgniteCheckedException e = new IgniteCheckedException("see suppressed");
 +
 +            for (Map.Entry<UUID, Exception> entry : exs.entrySet())
 +                e.addSuppressed(entry.getValue());
 +
 +            af.onDone(e);
 +        }
 +    }
 +
 +    /**
 +     *
 +     */
 +    private Exception onActivate(ChangeGlobalStateContext cgsCtx) {
 +        final boolean client = ctx.clientNode();
 +
 +        if (log.isInfoEnabled())
 +            log.info("Start activation process [nodeId=" + this.ctx.localNodeId() + ", client=" + client +
 +                ", topVer=" + cgsCtx.topVer + "]");
 +
 +        Collection<CacheConfiguration> cfgs = new ArrayList<>();
 +
 +        for (DynamicCacheChangeRequest req : cgsCtx.batch.requests()) {
 +            if (req.startCacheConfiguration() != null)
 +                cfgs.add(req.startCacheConfiguration());
 +        }
 +
 +        try {
 +            if (!client) {
 +                sharedCtx.database().lock();
 +
 +                IgnitePageStoreManager pageStore = sharedCtx.pageStore();
 +
 +                if (pageStore != null)
 +                    pageStore.onActivate(ctx);
 +
 +                if (sharedCtx.wal() != null)
 +                    sharedCtx.wal().onActivate(ctx);
 +
 +                sharedCtx.database().initDataBase();
 +
 +                for (CacheConfiguration cfg : cfgs) {
 +                    if (CU.isSystemCache(cfg.getName()))
 +                        if (pageStore != null)
 +                            pageStore.initializeForCache(cfg);
 +                }
 +
 +                for (CacheConfiguration cfg : cfgs) {
 +                    if (!CU.isSystemCache(cfg.getName()))
 +                        if (pageStore != null)
 +                            pageStore.initializeForCache(cfg);
 +                }
 +
 +                sharedCtx.database().onActivate(ctx);
 +            }
 +
 +            if (log.isInfoEnabled())
 +                log.info("Success activate wal, dataBase, pageStore [nodeId="
 +                    + ctx.localNodeId() + ", client=" + client + ", topVer=" + cgsCtx.topVer + "]");
 +
 +            return null;
 +        }
 +        catch (Exception e) {
 +            log.error("Fail activate wal, dataBase, pageStore [nodeId=" + ctx.localNodeId() + ", client=" + client +
 +                ", topVer=" + cgsCtx.topVer + "]", e);
 +
 +            if (!ctx.clientNode())
 +                sharedCtx.database().unLock();
 +
 +            return e;
 +        }
 +    }
 +
 +    /**
 +     *
 +     */
 +    public Exception onDeActivate(ChangeGlobalStateContext cgsCtx) {
 +        final boolean client = ctx.clientNode();
 +
 +        if (log.isInfoEnabled())
 +            log.info("Start deactivate process [id=" + ctx.localNodeId() + ", client=" +
 +                client + ", topVer=" + cgsCtx.topVer + "]");
 +
 +        try {
 +            ctx.dataStructures().onDeActivate(ctx);
 +
 +            ctx.service().onDeActivate(ctx);
 +
 +            if (log.isInfoEnabled())
 +                log.info("Success deactivate services, dataStructures, database, pageStore, wal [id=" + ctx.localNodeId() + ", client=" +
 +                    client + ", topVer=" + cgsCtx.topVer + "]");
 +
 +            return null;
 +        }
 +        catch (Exception e) {
 +            log.error("DeActivation fail [nodeId=" + ctx.localNodeId() + ", client=" + client +
 +                ", topVer=" + cgsCtx.topVer + "]", e);
 +
 +            return e;
 +        }
 +        finally {
 +            if (!client)
 +                sharedCtx.database().unLock();
 +        }
 +    }
 +
 +    /**
 +     *
 +     */
 +    private void onFinalActivate(final ChangeGlobalStateContext cgsCtx) {
 +        IgniteInternalFuture<?> asyncActivateFut = ctx.closure().runLocalSafe(new Runnable() {
 +            @Override public void run() {
 +                boolean client = ctx.clientNode();
 +
 +                Exception e = null;
 +
 +                try {
-                     ctx.marshallerContext().onMarshallerCacheStarted(ctx);
- 
 +                    if (!ctx.config().isDaemon())
 +                        ctx.cacheObjects().onUtilityCacheStarted();
 +
 +                    ctx.service().onUtilityCacheStarted();
 +
 +                    ctx.service().onActivate(ctx);
 +
 +                    ctx.dataStructures().onActivate(ctx);
 +
 +                    if (log.isInfoEnabled())
 +                        log.info("Success final activate [nodeId="
 +                            + ctx.localNodeId() + ", client=" + client + ", topVer=" + cgsCtx.topVer + "]");
 +                }
 +                catch (Exception ex) {
 +                    e = ex;
 +
 +                    log.error("Fail activate finished [nodeId=" + ctx.localNodeId() + ", client=" + client +
 +                        ", topVer=" + GridClusterStateProcessor.this.lastCgsCtx.topVer + "]", ex);
 +                }
 +                finally {
 +                    globalState = ACTIVE;
 +
 +                    sendChangeGlobalStateResponse(cgsCtx.requestId, cgsCtx.initiatingNodeId, e);
 +
 +                    GridClusterStateProcessor.this.lastCgsCtx = null;
 +                }
 +            }
 +        });
 +
 +        cgsCtx.setAsyncActivateFut(asyncActivateFut);
 +    }
 +
 +    /**
 +     *
 +     */
 +    public void onFinalDeActivate(ChangeGlobalStateContext cgsCtx) {
 +        final boolean client = ctx.clientNode();
 +
 +        if (log.isInfoEnabled())
 +            log.info("Success final deactivate [nodeId="
 +                + ctx.localNodeId() + ", client=" + client + ", topVer=" + cgsCtx.topVer + "]");
 +
 +        Exception ex = null;
 +
 +        try {
 +            if (!client) {
 +                sharedCtx.database().onDeActivate(ctx);
 +
 +                if (sharedCtx.pageStore() != null)
 +                    sharedCtx.pageStore().onDeActivate(ctx);
 +
 +                if (sharedCtx.wal() != null)
 +                    sharedCtx.wal().onDeActivate(ctx);
 +
 +                sharedCtx.affinity().removeAllCacheInfo();
 +            }
 +        }
 +        catch (Exception e) {
 +            ex = e;
 +        }
 +        finally {
 +            globalState = INACTIVE;
 +        }
 +
 +        sendChangeGlobalStateResponse(cgsCtx.requestId, cgsCtx.initiatingNodeId, ex);
 +
 +        this.lastCgsCtx = null;
 +    }
 +
 +    /**
 +     *
 +     */
 +    public void onExchangeDone() {
 +        ChangeGlobalStateContext cgsCtx = lastCgsCtx;
 +
 +        assert cgsCtx != null;
 +
 +        if (!cgsCtx.isFail()) {
 +            if (cgsCtx.activate)
 +                onFinalActivate(cgsCtx);
 +            else
 +                onFinalDeActivate(cgsCtx);
 +        }
 +        else
 +            lastCgsCtx = null;
 +    }
 +
 +    /**
 +     * @param initNodeId Initialize node id.
 +     * @param ex Exception.
 +     */
 +    private void sendChangeGlobalStateResponse(UUID requestId, UUID initNodeId, Exception ex) {
 +        assert requestId != null;
 +        assert initNodeId != null;
 +
 +        try {
 +            GridChangeGlobalStateMessageResponse actResp = new GridChangeGlobalStateMessageResponse(requestId, ex);
 +
 +            if (log.isDebugEnabled())
 +                log.debug("Send change global state response [nodeId=" + ctx.localNodeId() +
 +                    ", topVer=" + ctx.discovery().topologyVersionEx() + ", response=" + actResp + "]");
 +
 +            if (ctx.localNodeId().equals(initNodeId))
 +                processChangeGlobalStateResponse(ctx.localNodeId(), actResp);
 +            else
 +                sharedCtx.io().send(initNodeId, actResp, SYSTEM_POOL);
 +        }
 +        catch (IgniteCheckedException e) {
 +            log.error("Fail send change global state response to " + initNodeId, e);
 +        }
 +    }
 +
 +    /**
 +     * @param msg Message.
 +     */
 +    private void processChangeGlobalStateResponse(final UUID nodeId, final GridChangeGlobalStateMessageResponse msg) {
 +        assert nodeId != null;
 +        assert msg != null;
 +
 +        if (log.isDebugEnabled())
 +            log.debug("Received activation response [requestId=" + msg.getRequestId() +
 +                ", nodeId=" + nodeId + "]");
 +
 +        ClusterNode node = ctx.discovery().node(nodeId);
 +
 +        if (node == null) {
 +            U.warn(log, "Received activation response from unknown node (will ignore) [requestId=" +
 +                msg.getRequestId() + ']');
 +
 +            return;
 +        }
 +
 +        UUID requestId = msg.getRequestId();
 +
 +        final GridChangeGlobalStateFuture fut = cgsLocFut.get();
 +
 +        if (fut != null && !fut.isDone() && requestId.equals(fut.requestId)) {
 +            fut.initFut.listen(new CI1<IgniteInternalFuture<?>>() {
 +                @Override public void apply(IgniteInternalFuture<?> f) {
 +                    fut.onResponse(nodeId, msg);
 +                }
 +            });
 +        }
 +    }
 +
 +
 +
 +    /**
 +     * @param activate Activate.
 +     */
 +    private String prettyStr(boolean activate) {
 +        return activate ? "activate" : "deactivate";
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public String toString() {
 +        return S.toString(GridClusterStateProcessor.class, this);
 +    }
 +
 +    /**
 +     *
 +     */
 +    private static class GridChangeGlobalStateFuture extends GridFutureAdapter {
 +        /** Request id. */
 +        @GridToStringInclude
 +        private final UUID requestId;
 +
 +        /** Activate. */
 +        private final boolean activate;
 +
 +        /** Nodes. */
 +        @GridToStringInclude
 +        private final Set<UUID> remaining = new HashSet<>();
 +
 +        /** Responses. */
 +        @GridToStringInclude
 +        private final Map<UUID, GridChangeGlobalStateMessageResponse> resps = new HashMap<>();
 +
 +        /** Context. */
 +        @GridToStringExclude
 +        private final GridKernalContext ctx;
 +
 +        /** */
 +        @GridToStringExclude
 +        private final Object mux = new Object();
 +
 +        /** */
 +        @GridToStringInclude
 +        private final GridFutureAdapter initFut = new GridFutureAdapter();
 +
 +        /** Grid logger. */
 +        @GridToStringExclude
 +        private final IgniteLogger log;
 +
 +        /**
 +         *
 +         */
 +        public GridChangeGlobalStateFuture(UUID requestId, boolean activate, GridKernalContext ctx) {
 +            this.requestId = requestId;
 +            this.activate = activate;
 +            this.ctx = ctx;
 +            this.log = ctx.log(getClass());
 +        }
 +
 +        /**
 +         * @param event Event.
 +         */
 +        public void onDiscoveryEvent(DiscoveryEvent event) {
 +            assert event != null;
 +
 +            if (isDone())
 +                return;
 +
 +            boolean allReceived = false;
 +
 +            synchronized (mux) {
 +                if (remaining.remove(event.eventNode().id()))
 +                    allReceived = remaining.isEmpty();
 +            }
 +
 +            if (allReceived)
 +                onAllReceived();
 +        }
 +
 +        /**
 +         *
 +         */
 +        public void setRemaining(AffinityTopologyVersion topVer) {
 +            Collection<ClusterNode> nodes = ctx.discovery().nodes(topVer);
 +
 +            List<UUID> ids = new ArrayList<>(nodes.size());
 +
 +            for (ClusterNode n : nodes)
 +                ids.add(n.id());
 +
 +            if (log.isDebugEnabled())
 +                log.debug("Setup remaining node [id=" + ctx.localNodeId() + ", client=" +
 +                    ctx.clientNode() + ", topVer=" + ctx.discovery().topologyVersionEx() +
 +                    ", nodes=" + Arrays.toString(ids.toArray()) + "]");
 +
 +            synchronized (mux) {
 +                remaining.addAll(ids);
 +            }
 +
 +            initFut.onDone();
 +        }
 +
 +        /**
 +         * @param msg Activation message response.
 +         */
 +        public void onResponse(UUID nodeId, GridChangeGlobalStateMessageResponse msg) {
 +            assert msg != null;
 +
 +            if (isDone())
 +                return;
 +
 +            boolean allReceived = false;
 +
 +            synchronized (mux) {
 +                if (remaining.remove(nodeId))
 +                    allReceived = remaining.isEmpty();
 +
 +                resps.put(nodeId, msg);
 +            }
 +
 +            if (allReceived)
 +                onAllReceived();
 +        }
 +
 +        /**
 +         *
 +         */
 +        private void onAllReceived() {
 +            Throwable e = new Throwable();
 +
 +            boolean fail = false;
 +
 +            for (Map.Entry<UUID, GridChangeGlobalStateMessageResponse> entry : resps.entrySet()) {
 +                GridChangeGlobalStateMessageResponse r = entry.getValue();
 +
 +                if (r.getError() != null) {
 +                    fail = true;
 +
 +                    e.addSuppressed(r.getError());
 +                }
 +            }
 +
 +            if (fail)
 +                onDone(e);
 +            else
 +                onDone();
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public boolean onDone(@Nullable Object res, @Nullable Throwable err) {
 +            ctx.state().cgsLocFut.set(null);
 +
 +            return super.onDone(res, err);
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public String toString() {
 +            return S.toString(GridChangeGlobalStateFuture.class, this);
 +        }
 +    }
 +
 +    /**
 +     *
 +     *
 +     */
 +    private static class ChangeGlobalStateContext {
 +        /** Request id. */
 +        private final UUID requestId;
 +
 +        /** Initiating node id. */
 +        private final UUID initiatingNodeId;
 +
 +        /** Batch requests. */
 +        private final DynamicCacheChangeBatch batch;
 +
 +        /** Activate. */
 +        private final boolean activate;
 +
 +        /** Topology version. */
 +        private AffinityTopologyVersion topVer;
 +
 +        /** Fail. */
 +        private boolean fail;
 +
 +        /** Async activate future. */
 +        private IgniteInternalFuture<?> asyncActivateFut;
 +
 +        /**
 +         *
 +         */
 +        public ChangeGlobalStateContext(
 +            UUID requestId,
 +            UUID initiatingNodeId,
 +            DynamicCacheChangeBatch batch,
 +            boolean activate
 +        ) {
 +            this.requestId = requestId;
 +            this.batch = batch;
 +            this.activate = activate;
 +            this.initiatingNodeId = initiatingNodeId;
 +        }
 +
 +        /**
 +         * @param topVer Topology version.
 +         */
 +        public void topologyVersion(AffinityTopologyVersion topVer) {
 +            this.topVer = topVer;
 +        }
 +
 +        /**
 +         *
 +         */
 +        private void setFail() {
 +            fail = true;
 +        }
 +
 +        /**
 +         *
 +         */
 +        private boolean isFail() {
 +            return fail;
 +        }
 +
 +        /**
 +         *
 +         */
 +        public IgniteInternalFuture<?> getAsyncActivateFut() {
 +            return asyncActivateFut;
 +        }
 +
 +        /**
 +         * @param asyncActivateFut Async activate future.
 +         */
 +        public void setAsyncActivateFut(IgniteInternalFuture<?> asyncActivateFut) {
 +            this.asyncActivateFut = asyncActivateFut;
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public String toString() {
 +            return S.toString(ChangeGlobalStateContext.class, this);
 +        }
 +    }
 +
 +    /**
 +     *
 +     */
 +    private static class ClientChangeGlobalStateComputeRequest implements IgniteRunnable {
 +        /** */
 +        private static final long serialVersionUID = 0L;
 +
 +        /** Activation. */
 +        private final boolean activation;
 +
 +        /** Ignite. */
 +        @IgniteInstanceResource
 +        private Ignite ignite;
 +
 +        /**
 +         *
 +         */
 +        private ClientChangeGlobalStateComputeRequest(boolean activation) {
 +            this.activation = activation;
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public void run() {
 +            ignite.active(activation);
 +        }
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
index 9012214,f97fc14..df2f7d9
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
@@@ -1925,59 -1920,24 +1923,59 @@@ public class DataStreamerImpl<K, V> imp
  
              ExpiryPolicy plc = cctx.expiry();
  
 -            for (Entry<KeyCacheObject, CacheObject> e : entries) {
 -                try {
 -                    e.getKey().finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader());
 +            Collection<Integer> reservedParts = new HashSet<>();
 +            Collection<Integer> ignoredParts = new HashSet<>();
  
 -                    GridCacheEntryEx entry = internalCache.entryEx(e.getKey(), topVer);
 +            try {
 +                for (Entry<KeyCacheObject, CacheObject> e : entries) {
 +                    cctx.shared().database().checkpointReadLock();
  
 -                    if (plc != null) {
 -                        ttl = CU.toTtl(plc.getExpiryForCreation());
 +                    try {
 +                        e.getKey().finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader());
  
 -                        if (ttl == CU.TTL_ZERO)
 -                            continue;
 -                        else if (ttl == CU.TTL_NOT_CHANGED)
 -                            ttl = 0;
 +                        if (!cctx.isLocal()) {
 +                            int p = cctx.affinity().partition(e.getKey());
  
 -                        expiryTime = CU.toExpireTime(ttl);
 -                    }
 +                            if (ignoredParts.contains(p))
 +                                continue;
 +
 +                            if (!reservedParts.contains(p)) {
 +                                GridDhtLocalPartition part = cctx.topology().localPartition(p, topVer, true);
 +
 +                                if (!part.reserve()) {
 +                                    ignoredParts.add(p);
 +
 +                                    continue;
 +                                }
 +                                else {
 +                                    // We must not allow to read from RENTING partitions.
 +                                    if (part.state() == GridDhtPartitionState.RENTING) {
 +                                        part.release();
 +
 +                                        ignoredParts.add(p);
 +
 +                                        continue;
 +                                    }
 +
 +                                    reservedParts.add(p);
 +                                }
 +                            }
 +                        }
 +
 +                        GridCacheEntryEx entry = internalCache.entryEx(e.getKey(), topVer);
 +
 +                        if (plc != null) {
 +                            ttl = CU.toTtl(plc.getExpiryForCreation());
 +
 +                            if (ttl == CU.TTL_ZERO)
 +                                continue;
 +                            else if (ttl == CU.TTL_NOT_CHANGED)
 +                                ttl = 0;
 +
 +                            expiryTime = CU.toExpireTime(ttl);
 +                        }
  
-                     boolean primary = cctx.affinity().primary(cctx.localNode(), entry.key(), topVer);
+                     boolean primary = cctx.affinity().primaryByKey(cctx.localNode(), entry.key(), topVer);
  
                      entry.initialValue(e.getValue(),
                          ver,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
index 0000000,fdea869..3d2f86e
mode 000000,100644..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
@@@ -1,0 -1,363 +1,363 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ 
+ package org.apache.ignite.internal.processors.marshaller;
+ 
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.UUID;
+ import java.util.concurrent.ConcurrentMap;
+ import java.util.concurrent.CopyOnWriteArrayList;
+ import java.util.concurrent.ExecutorService;
+ import org.apache.ignite.IgniteCheckedException;
+ import org.apache.ignite.cluster.ClusterNode;
+ import org.apache.ignite.events.DiscoveryEvent;
+ import org.apache.ignite.events.Event;
+ import org.apache.ignite.internal.GridKernalContext;
+ import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
+ import org.apache.ignite.internal.MarshallerContextImpl;
+ import org.apache.ignite.internal.managers.communication.GridIoManager;
+ import org.apache.ignite.internal.managers.communication.GridMessageListener;
+ import org.apache.ignite.internal.managers.discovery.CustomEventListener;
+ import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+ import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
+ import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
+ import org.apache.ignite.internal.processors.GridProcessorAdapter;
+ import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+ import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
+ import org.apache.ignite.internal.util.future.GridFutureAdapter;
+ import org.apache.ignite.internal.util.typedef.internal.U;
+ import org.apache.ignite.lang.IgniteFuture;
+ import org.apache.ignite.spi.discovery.DiscoveryDataBag;
+ import org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData;
+ import org.jetbrains.annotations.Nullable;
+ import org.jsr166.ConcurrentHashMap8;
+ 
+ import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
+ import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
+ import static org.apache.ignite.internal.GridComponent.DiscoveryDataExchangeType.MARSHALLER_PROC;
+ import static org.apache.ignite.internal.GridTopic.TOPIC_MAPPING_MARSH;
+ import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
+ 
+ /**
+  * Processor responsible for managing custom {@link DiscoveryCustomMessage}
+  * events for exchanging marshalling mappings between nodes in grid.
+  *
+  * In particular it processes two flows:
+  * <ul>
+  *     <li>
+  *         Some node, server or client, wants to add new mapping for some class.
+  *         In that case a pair of {@link MappingProposedMessage} and {@link MappingAcceptedMessage} events is used.
+  *     </li>
+  *     <li>
+  *         As discovery events are delivered to clients asynchronously,
+  *         client node may not have some mapping when server nodes in the grid are already allowed to use the mapping.
+  *         In that situation client sends a {@link MissingMappingRequestMessage} request
+  *         and processor handles it as well as {@link MissingMappingResponseMessage} message.
+  *     </li>
+  * </ul>
+  */
+ public class GridMarshallerMappingProcessor extends GridProcessorAdapter {
+     /** */
+     private final MarshallerContextImpl marshallerCtx;
+ 
+     /** */
+     private final GridClosureProcessor closProc;
+ 
+     /** */
+     private final List<MappingUpdatedListener> mappingUpdatedLsnrs = new CopyOnWriteArrayList<>();
+ 
+     /** */
+     private final ConcurrentMap<MarshallerMappingItem, GridFutureAdapter<MappingExchangeResult>> mappingExchangeSyncMap
+             = new ConcurrentHashMap8<>();
+ 
+     /** */
+     private final ConcurrentMap<MarshallerMappingItem, ClientRequestFuture> clientReqSyncMap = new ConcurrentHashMap8<>();
+ 
+     /**
+      * @param ctx Kernal context.
+      */
+     public GridMarshallerMappingProcessor(GridKernalContext ctx) {
+         super(ctx);
+ 
+         marshallerCtx = ctx.marshallerContext();
+ 
+         closProc = ctx.closure();
+     }
+ 
+     /** {@inheritDoc} */
 -    @Override public void start() throws IgniteCheckedException {
++    @Override public void start(boolean activeOnStart) throws IgniteCheckedException {
+         GridDiscoveryManager discoMgr = ctx.discovery();
+         GridIoManager ioMgr = ctx.io();
+ 
+         MarshallerMappingTransport transport = new MarshallerMappingTransport(
+                 ctx,
+                 mappingExchangeSyncMap,
+                 clientReqSyncMap
+         );
+         marshallerCtx.onMarshallerProcessorStarted(ctx, transport);
+ 
+         discoMgr.setCustomEventListener(MappingProposedMessage.class, new MarshallerMappingExchangeListener());
+ 
+         discoMgr.setCustomEventListener(MappingAcceptedMessage.class, new MappingAcceptedListener());
+ 
+         if (ctx.clientNode())
+             ioMgr.addMessageListener(TOPIC_MAPPING_MARSH, new MissingMappingResponseListener());
+         else
+             ioMgr.addMessageListener(TOPIC_MAPPING_MARSH, new MissingMappingRequestListener(ioMgr));
+ 
+         if (ctx.clientNode())
+             ctx.event().addLocalEventListener(new GridLocalEventListener() {
+                 @Override public void onEvent(Event evt) {
+                     DiscoveryEvent evt0 = (DiscoveryEvent) evt;
+ 
+                     if (!ctx.isStopping()) {
+                         for (ClientRequestFuture fut : clientReqSyncMap.values())
+                             fut.onNodeLeft(evt0.eventNode().id());
+                     }
+                 }
+             }, EVT_NODE_LEFT, EVT_NODE_FAILED);
+     }
+ 
+     /**
+      * Adds a listener to be notified when mapping changes.
+      *
+      * @param mappingUpdatedListener listener for mapping updated events.
+      */
+     public void addMappingUpdatedListener(MappingUpdatedListener mappingUpdatedListener) {
+         mappingUpdatedLsnrs.add(mappingUpdatedListener);
+     }
+ 
+     /**
+      * Gets an iterator over all current mappings.
+      *
+      * @return Iterator over current mappings.
+      */
+     public Iterator<Map.Entry<Byte, Map<Integer, String>>> currentMappings() {
+         return marshallerCtx.currentMappings();
+     }
+ 
+     /**
+      *
+      */
+     private final class MissingMappingRequestListener implements GridMessageListener {
+         /** */
+         private final GridIoManager ioMgr;
+ 
+         /**
+          * @param ioMgr Io manager.
+          */
+         MissingMappingRequestListener(GridIoManager ioMgr) {
+             this.ioMgr = ioMgr;
+         }
+ 
+         /** {@inheritDoc} */
+         @Override public void onMessage(UUID nodeId, Object msg) {
+             assert msg instanceof MissingMappingRequestMessage : msg;
+ 
+             MissingMappingRequestMessage msg0 = (MissingMappingRequestMessage) msg;
+ 
+             byte platformId = msg0.platformId();
+             int typeId = msg0.typeId();
+ 
+             String resolvedClsName = marshallerCtx.resolveMissedMapping(platformId, typeId);
+ 
+             try {
+                 ioMgr.send(
+                         nodeId,
+                         TOPIC_MAPPING_MARSH,
+                         new MissingMappingResponseMessage(platformId, typeId, resolvedClsName),
+                         SYSTEM_POOL);
+             }
+             catch (IgniteCheckedException e) {
+                 U.error(log, "Failed to send missing mapping response.", e);
+             }
+         }
+     }
+ 
+     /**
+      *
+      */
+     private final class MissingMappingResponseListener implements GridMessageListener {
+         /** {@inheritDoc} */
+         @Override public void onMessage(UUID nodeId, Object msg) {
+             assert msg instanceof MissingMappingResponseMessage : msg;
+ 
+             MissingMappingResponseMessage msg0 = (MissingMappingResponseMessage) msg;
+ 
+             byte platformId = msg0.platformId();
+             int typeId = msg0.typeId();
+             String resolvedClsName = msg0.className();
+ 
+             MarshallerMappingItem item = new MarshallerMappingItem(platformId, typeId, null);
+ 
+             GridFutureAdapter<MappingExchangeResult> fut = clientReqSyncMap.get(item);
+ 
+             if (fut != null) {
+                 if (resolvedClsName != null) {
+                     marshallerCtx.onMissedMappingResolved(item, resolvedClsName);
+ 
+                     fut.onDone(MappingExchangeResult.createSuccessfulResult(resolvedClsName));
+                 }
+                 else
+                     fut.onDone(MappingExchangeResult.createFailureResult(
+                             new IgniteCheckedException(
+                                     "Failed to resolve mapping [platformId: "
+                                             + platformId
+                                             + ", typeId: "
+                                             + typeId + "]")));
+             }
+         }
+     }
+ 
+     /**
+      *
+      */
+     private final class MarshallerMappingExchangeListener implements CustomEventListener<MappingProposedMessage> {
+         /** {@inheritDoc} */
+         @Override public void onCustomEvent(
+                 AffinityTopologyVersion topVer,
+                 ClusterNode snd,
+                 MappingProposedMessage msg
+         ) {
+             if (!ctx.isStopping()) {
+                 if (msg.duplicated())
+                     return;
+ 
+                 if (!msg.inConflict()) {
+                     MarshallerMappingItem item = msg.mappingItem();
+                     String conflictingName = marshallerCtx.onMappingProposed(item);
+ 
+                     if (conflictingName != null) {
+                         if (conflictingName.equals(item.className()))
+                             msg.markDuplicated();
+                         else
+                             msg.conflictingWithClass(conflictingName);
+                     }
+                 }
+                 else {
+                     UUID origNodeId = msg.origNodeId();
+ 
+                     if (origNodeId.equals(ctx.localNodeId())) {
+                         GridFutureAdapter<MappingExchangeResult> fut = mappingExchangeSyncMap.get(msg.mappingItem());
+ 
+                         assert fut != null: msg;
+ 
+                         fut.onDone(MappingExchangeResult.createFailureResult(
+                                 duplicateMappingException(msg.mappingItem(), msg.conflictingClassName())));
+                     }
+                 }
+             }
+         }
+ 
+         /**
+          * @param mappingItem Mapping item.
+          * @param conflictingClsName Conflicting class name.
+          */
+         private IgniteCheckedException duplicateMappingException(
+                 MarshallerMappingItem mappingItem,
+                 String conflictingClsName
+         ) {
+             return new IgniteCheckedException("Duplicate ID [platformId="
+                     + mappingItem.platformId()
+                     + ", typeId="
+                     + mappingItem.typeId()
+                     + ", oldCls="
+                     + conflictingClsName
+                     + ", newCls="
+                     + mappingItem.className() + "]");
+         }
+     }
+ 
+     /**
+      *
+      */
+     private final class MappingAcceptedListener implements CustomEventListener<MappingAcceptedMessage> {
+         /** {@inheritDoc} */
+         @Override public void onCustomEvent(
+                 AffinityTopologyVersion topVer,
+                 ClusterNode snd,
+                 MappingAcceptedMessage msg
+         ) {
+             final MarshallerMappingItem item = msg.getMappingItem();
+             marshallerCtx.onMappingAccepted(item);
+ 
+             closProc.runLocalSafe(new Runnable() {
+                 @Override public void run() {
+                     for (MappingUpdatedListener lsnr : mappingUpdatedLsnrs)
+                         lsnr.mappingUpdated(item.platformId(), item.typeId(), item.className());
+                 }
+             });
+ 
+             GridFutureAdapter<MappingExchangeResult> fut = mappingExchangeSyncMap.get(item);
+ 
+             if (fut != null)
+                 fut.onDone(MappingExchangeResult.createSuccessfulResult(item.className()));
+         }
+     }
+ 
+     /** {@inheritDoc} */
+     @Override public void collectGridNodeData(DiscoveryDataBag dataBag) {
+         if (!dataBag.commonDataCollectedFor(MARSHALLER_PROC.ordinal()))
+             dataBag.addGridCommonData(MARSHALLER_PROC.ordinal(), marshallerCtx.getCachedMappings());
+     }
+ 
+     /** {@inheritDoc} */
+     @Override public void onGridDataReceived(GridDiscoveryData data) {
+         List<Map<Integer, MappedName>> mappings = (List<Map<Integer, MappedName>>) data.commonData();
+ 
+         if (mappings != null) {
+             for (int i = 0; i < mappings.size(); i++) {
+                 Map<Integer, MappedName> map;
+ 
+                 if ((map = mappings.get(i)) != null)
+                     marshallerCtx.onMappingDataReceived((byte) i, map);
+             }
+         }
+     }
+ 
+     /** {@inheritDoc} */
+     @Override public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException {
+         cancelFutures(MappingExchangeResult.createFailureResult(new IgniteClientDisconnectedCheckedException(
+                 ctx.cluster().clientReconnectFuture(),
+                 "Failed to propose or request mapping, client node disconnected.")));
+     }
+ 
+     /** {@inheritDoc} */
+     @Override public void onKernalStop(boolean cancel) {
+         marshallerCtx.onMarshallerProcessorStop();
+ 
+         cancelFutures(MappingExchangeResult.createExchangeDisabledResult());
+     }
+ 
+     /** {@inheritDoc} */
+     @Nullable @Override public DiscoveryDataExchangeType discoveryDataType() {
+         return MARSHALLER_PROC;
+     }
+ 
+     /**
+      * @param res Response.
+      */
+     private void cancelFutures(MappingExchangeResult res) {
+         for (GridFutureAdapter<MappingExchangeResult> fut : mappingExchangeSyncMap.values())
+             fut.onDone(res);
+ 
+         for (GridFutureAdapter<MappingExchangeResult> fut : clientReqSyncMap.values())
+             fut.onDone(res);
+     }
+ }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
index 5fcd2eb,ea8f361..efd1926
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
@@@ -55,15 -44,12 +55,17 @@@ import org.apache.ignite.configuration.
  import org.apache.ignite.configuration.IgniteConfiguration;
  import org.apache.ignite.configuration.NearCacheConfiguration;
  import org.apache.ignite.configuration.TransactionConfiguration;
 -import org.apache.ignite.internal.binary.*;
 +import org.apache.ignite.internal.binary.BinaryRawReaderEx;
 +import org.apache.ignite.internal.binary.BinaryRawWriterEx;
  import org.apache.ignite.internal.processors.platform.cache.affinity.PlatformAffinityFunction;
  import org.apache.ignite.internal.processors.platform.cache.expiry.PlatformExpiryPolicyFactory;
+ import org.apache.ignite.internal.processors.platform.plugin.cache.PlatformCachePluginConfiguration;
 -import org.apache.ignite.platform.dotnet.*;
 +import org.apache.ignite.platform.dotnet.PlatformDotNetAffinityFunction;
 +import org.apache.ignite.platform.dotnet.PlatformDotNetBinaryConfiguration;
 +import org.apache.ignite.platform.dotnet.PlatformDotNetBinaryTypeConfiguration;
 +import org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactoryNative;
 +import org.apache.ignite.platform.dotnet.PlatformDotNetConfiguration;
+ import org.apache.ignite.plugin.CachePluginConfiguration;
  import org.apache.ignite.spi.communication.CommunicationSpi;
  import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
  import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpiMBean;
@@@ -821,19 -865,19 +850,19 @@@ public class PlatformConfigurationUtil
       * Write query entity.
       *
       * @param writer Writer.
--     * @param queryEntity Query entity.
++     * @param qryEntity Query entity.
       */
--    private static void writeQueryEntity(BinaryRawWriter writer, QueryEntity queryEntity) {
--        assert queryEntity != null;
++    private static void writeQueryEntity(BinaryRawWriter writer, QueryEntity qryEntity) {
++        assert qryEntity != null;
  
--        writer.writeString(queryEntity.getKeyType());
--        writer.writeString(queryEntity.getValueType());
++        writer.writeString(qryEntity.getKeyType());
++        writer.writeString(qryEntity.getValueType());
  
          // Fields
--        LinkedHashMap<String, String> fields = queryEntity.getFields();
++        LinkedHashMap<String, String> fields = qryEntity.getFields();
  
          if (fields != null) {
--            Set<String> keyFields = queryEntity.getKeyFields();
++            Set<String> keyFields = qryEntity.getKeyFields();
  
              writer.writeInt(fields.size());
  
@@@ -847,7 -891,7 +876,7 @@@
              writer.writeInt(0);
  
          // Aliases
--        Map<String, String> aliases = queryEntity.getAliases();
++        Map<String, String> aliases = qryEntity.getAliases();
  
          if (aliases != null) {
              writer.writeInt(aliases.size());
@@@ -861,7 -905,7 +890,7 @@@
              writer.writeInt(0);
  
          // Indexes
--        Collection<QueryIndex> indexes = queryEntity.getIndexes();
++        Collection<QueryIndex> indexes = qryEntity.getIndexes();
  
          if (indexes != null) {
              writer.writeInt(indexes.size());

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/CachePluginManager.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/CachePluginManager.java
index 772813f,fa33d3a..456bb86
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/CachePluginManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/CachePluginManager.java
@@@ -67,13 -65,13 +67,13 @@@ public class CachePluginManager extend
      public CachePluginManager(GridKernalContext ctx, CacheConfiguration cfg) {
          this.ctx = ctx;
          this.cfg = cfg;
 -        
 +
-         for (PluginProvider p : ctx.plugins().allProviders()) {
-             CachePluginContext pluginCtx = new GridCachePluginContext(ctx, cfg);
+         if (cfg.getPluginConfigurations() != null) {
+             for (CachePluginConfiguration cachePluginCfg : cfg.getPluginConfigurations()) {
+                 CachePluginContext pluginCtx = new GridCachePluginContext(ctx, cfg, cachePluginCfg);
  
-             CachePluginProvider provider = p.createCacheProvider(pluginCtx);
+                 CachePluginProvider provider = cachePluginCfg.createProvider(pluginCtx);
  
-             if (provider != null) {
                  providersList.add(provider);
                  providersMap.put(pluginCtx, provider);
              }
@@@ -99,9 -97,9 +99,9 @@@
      }
  
      /** {@inheritDoc} */
 -    @Override protected void stop0(boolean cancel) {
 +    @Override protected void stop0(boolean cancel, boolean destroy) {
-         for (ListIterator<CachePluginProvider> iter = providersList.listIterator(); iter.hasPrevious();)
-             iter.previous().stop(cancel);
+         for (int i = providersList.size() - 1; i >= 0; i--)
+             providersList.get(i).stop(cancel);
      }
  
      /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/IgnitePluginProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index cf85a52,0ff6d8b..8b282ab
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@@ -62,9 -62,9 +62,10 @@@ import org.apache.ignite.configuration.
  import org.apache.ignite.events.CacheQueryExecutedEvent;
  import org.apache.ignite.internal.GridKernalContext;
  import org.apache.ignite.internal.IgniteInternalFuture;
 +import org.apache.ignite.internal.NodeStoppingException;
  import org.apache.ignite.internal.binary.BinaryMarshaller;
  import org.apache.ignite.internal.binary.BinaryObjectEx;
+ import org.apache.ignite.internal.binary.BinaryObjectExImpl;
  import org.apache.ignite.internal.processors.GridProcessorAdapter;
  import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
  import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
@@@ -742,83 -685,40 +742,70 @@@ public class GridQueryProcessor extend
          if (log.isDebugEnabled())
              log.debug("Store [space=" + space + ", key=" + key + ", val=" + val + "]");
  
--        CacheObjectContext coctx = null;
- 
-         if (ctx.indexing().enabled()) {
-             coctx = cacheObjectContext(space);
- 
-             Object key0 = unwrap(key, coctx);
- 
-             Object val0 = unwrap(val, coctx);
- 
-             ctx.indexing().store(space, key0, val0, expirationTime);
-         }
--
          if (idx == null)
              return;
  
          if (!busyLock.enterBusy())
 -            return;
 +            throw new NodeStoppingException("Operation has been cancelled (node is stopping).");
  
          try {
--            if (coctx == null)
--                coctx = cacheObjectContext(space);
++            CacheObjectContext coctx = cacheObjectContext(space);
  
 -            Class<?> valCls = null;
 +            TypeDescriptor desc = typeByValue(coctx, key, val, true);
  
 -            TypeId id;
 +            if (prevVal != null) {
 +                TypeDescriptor prevValDesc = typeByValue(coctx, key, prevVal, false);
  
 -            boolean binaryVal = ctx.cacheObjects().isBinaryObject(val);
 +                if (prevValDesc != null && prevValDesc != desc)
 +                    idx.remove(space, prevValDesc, key, partId, prevVal, prevVer);
 +            }
  
 -            if (binaryVal) {
 -                int typeId = ctx.cacheObjects().typeId(val);
 +            if (desc == null)
 +                return;
  
 -                id = new TypeId(space, typeId);
 -            }
 -            else {
 -                valCls = val.value(coctx, false).getClass();
 +            idx.store(space, desc, key, partId, val, ver, expirationTime, link);
 +        }
 +        finally {
 +            busyLock.leaveBusy();
 +        }
 +    }
  
 -                id = new TypeId(space, valCls);
 -            }
 +    /**
 +     * @param coctx Cache context.
 +     * @param key Key.
 +     * @param val Value.
 +     * @param checkType If {@code true} checks that key and value type correspond to found TypeDescriptor.
 +     * @return Type descriptor if found.
 +     * @throws IgniteCheckedException If type check failed.
 +     */
 +    @Nullable private TypeDescriptor typeByValue(CacheObjectContext coctx,
 +        KeyCacheObject key,
 +        CacheObject val,
 +        boolean checkType)
 +        throws IgniteCheckedException {
 +        Class<?> valCls = null;
  
 -            TypeDescriptor desc = types.get(id);
 +        TypeId id;
  
 -            if (desc == null || !desc.registered())
 -                return;
 +        boolean binaryVal = ctx.cacheObjects().isBinaryObject(val);
 +
 +        if (binaryVal) {
 +            int typeId = ctx.cacheObjects().typeId(val);
  
 +            id = new TypeId(coctx.cacheName(), typeId);
 +        }
 +        else {
 +            valCls = val.value(coctx, false).getClass();
 +
 +            id = new TypeId(coctx.cacheName(), valCls);
 +        }
 +
 +        TypeDescriptor desc = types.get(id);
 +
 +        if (desc == null || !desc.registered())
 +            return null;
 +
 +        if (checkType) {
              if (!binaryVal && !desc.valueClass().isAssignableFrom(valCls))
                  throw new IgniteCheckedException("Failed to update index due to class name conflict" +
                      "(multiple classes with same simple name are stored in the same cache) " +
@@@ -1143,33 -1039,14 +1124,21 @@@
          if (log.isDebugEnabled())
              log.debug("Remove [space=" + space + ", key=" + key + ", val=" + val + "]");
  
-         CacheObjectContext coctx = null;
- 
-         if (ctx.indexing().enabled()) {
-             coctx = cacheObjectContext(space);
- 
-             Object key0 = unwrap(key, coctx);
- 
-             ctx.indexing().remove(space, key0);
-         }
- 
-         // If val == null we only need to call SPI.
 -        if (idx == null)
 +        if (idx == null || val == null)
              return;
  
          if (!busyLock.enterBusy())
              throw new IllegalStateException("Failed to remove from index (grid is stopping).");
  
          try {
-             if (coctx == null)
-                 coctx = cacheObjectContext(space);
 -            idx.remove(space, key, val);
++            CacheObjectContext coctx = cacheObjectContext(space);
 +
 +            TypeDescriptor desc = typeByValue(coctx, key, val, false);
 +
 +            if (desc == null)
 +                return;
 +
 +            idx.remove(space, desc, key, partId, val, ver);
          }
          finally {
              busyLock.leaveBusy();

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
index 914c3a3,986fff7..096c531
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
@@@ -1666,26 -1651,24 +1671,26 @@@ public class GridServiceProcessor exten
                                  onReassignmentFailed(topVer, retries);
                          }
  
 +                        Iterator<Cache.Entry<Object, Object>> it = serviceEntries(ServiceAssignmentsPredicate.INSTANCE);
 +
                          // Clean up zombie assignments.
 -                        for (Cache.Entry<Object, Object> e :
 -                            cache.entrySetx(CU.cachePrimary(ctx.grid().affinity(cache.name()), ctx.grid().localNode()))) {
 -                            if (!(e.getKey() instanceof GridServiceAssignmentsKey))
 -                                continue;
 +                        while (it.hasNext()) {
 +                            Cache.Entry<Object, Object> e = it.next();
  
-                             if (cache.context().affinity().primary(ctx.grid().localNode(), e.getKey(), topVer)) {
 -                            String name = ((GridServiceAssignmentsKey)e.getKey()).name();
++                            if (cache.context().affinity().primaryByKey(ctx.grid().localNode(), e.getKey(), topVer)) {
 +                                String name = ((GridServiceAssignmentsKey)e.getKey()).name();
  
 -                            try {
 -                                if (cache.get(new GridServiceDeploymentKey(name)) == null) {
 -                                    if (log.isDebugEnabled())
 -                                        log.debug("Removed zombie assignments: " + e.getValue());
 +                                try {
 +                                    if (cache.get(new GridServiceDeploymentKey(name)) == null) {
 +                                        if (log.isDebugEnabled())
 +                                            log.debug("Removed zombie assignments: " + e.getValue());
  
 -                                    cache.getAndRemove(e.getKey());
 +                                        cache.getAndRemove(e.getKey());
 +                                    }
 +                                }
 +                                catch (IgniteCheckedException ex) {
 +                                    U.error(log, "Failed to clean up zombie assignments for service: " + name, ex);
                                  }
 -                            }
 -                            catch (IgniteCheckedException ex) {
 -                                U.error(log, "Failed to clean up zombie assignments for service: " + name, ex);
                              }
                          }
                      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 389d058,1cca9d3..d2e0714
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@@ -74,7 -74,7 +74,8 @@@ import java.nio.channels.SelectionKey
  import java.nio.channels.Selector;
  import java.nio.charset.Charset;
  import java.nio.file.Files;
 +import java.nio.file.Path;
+ import java.nio.file.Paths;
  import java.security.AccessController;
  import java.security.KeyManagementException;
  import java.security.MessageDigest;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
index 4b140be,4c89a7c..00ca409
mode 100644,100755..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

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreAbstractSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreAbstractMultithreadedSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGetEntryAbstractTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
index 2c86322,7a0b713..1343151
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
@@@ -5869,14 -5869,15 +5869,14 @@@ public abstract class GridCacheAbstract
          @Override public void run(int idx) throws Exception {
              GridCacheContext<String, Integer> ctx = ((IgniteKernal)ignite).<String, Integer>internalCache().context();
  
 -            if (ctx.cache().configuration().getMemoryMode() == OFFHEAP_TIERED)
 -                return;
 -
              int size = 0;
  
 +            if (ctx.isNear())
 +                ctx = ctx.near().dht().context();
 +
              for (String key : keys) {
-                 if (ctx.affinity().localNode(key, ctx.discovery().topologyVersionEx())) {
+                 if (ctx.affinity().keyLocalNode(key, ctx.discovery().topologyVersionEx())) {
 -                    GridCacheEntryEx e =
 -                        ctx.isNear() ? ctx.near().dht().peekEx(key) : ctx.cache().peekEx(key);
 +                    GridCacheEntryEx e = ctx.cache().entryEx(key);
  
                      assert e != null : "Entry is null [idx=" + idx + ", key=" + key + ", ctx=" + ctx + ']';
                      assert !e.deleted() : "Entry is deleted: " + e;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheStopSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
index be3933f,e76ab40..691100f
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
@@@ -411,9 -417,31 +410,28 @@@ public class GridCacheTestEntryEx exten
      }
  
      /** @inheritDoc */
-     @Nullable @Override public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+     @Override public void clearReserveForLoad(GridCacheVersion ver) {
+         assert false;
+     }
+ 
+     /** @inheritDoc */
+     @Override public EntryGetResult innerGetAndReserveForLoad(
 -        boolean readSwap,
+         boolean updateMetrics,
+         boolean evt,
+         UUID subjId,
+         String taskName,
+         @Nullable IgniteCacheExpiryPolicy expiryPlc,
+         boolean keepBinary,
+         @Nullable ReaderArguments args) throws IgniteCheckedException, GridCacheEntryRemovedException {
+         assert false;
+ 
+         return null;
+     }
+ 
+     /** @inheritDoc */
+     @Nullable @Override public EntryGetResult innerGetVersioned(
          @Nullable GridCacheVersion ver,
          IgniteInternalTx tx,
 -        boolean readSwap,
 -        boolean unmarshal,
          boolean updateMetrics,
          boolean evt,
          UUID subjId,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigVariationsFullApiTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigVariationsFullApiTest.java
index b746883,e47a18d..a78d8ef
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigVariationsFullApiTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigVariationsFullApiTest.java
@@@ -5553,12 -5545,10 +5551,12 @@@ public class IgniteCacheConfigVariation
  
              int size = 0;
  
 +            if (ctx.isNear())
 +                ctx = ctx.near().dht().context();
 +
              for (String key : keys) {
-                 if (ctx.affinity().localNode(key, ctx.discovery().topologyVersionEx())) {
+                 if (ctx.affinity().keyLocalNode(key, ctx.discovery().topologyVersionEx())) {
 -                    GridCacheEntryEx e =
 -                        ctx.isNear() ? ctx.near().dht().peekEx(key) : ctx.cache().peekEx(key);
 +                    GridCacheEntryEx e = ctx.cache().entryEx(key);
  
                      assert e != null : "Entry is null [idx=" + idx + ", key=" + key + ", ctx=" + ctx + ']';
                      assert !e.deleted() : "Entry is deleted: " + e;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCachePeekModesAbstractTest.java
----------------------------------------------------------------------


[46/50] [abbrv] ignite git commit: Megre 2.0

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClassNameConflictTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClassNameConflictTest.java
index 0000000,50107e4..48b2b98
mode 000000,100644..100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClassNameConflictTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClassNameConflictTest.java
@@@ -1,0 -1,273 +1,277 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ 
+ package org.apache.ignite.internal.processors.cache;
+ 
+ import java.util.Collection;
+ import java.util.Map;
+ import java.util.concurrent.CountDownLatch;
+ import java.util.concurrent.ExecutorService;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.atomic.AtomicInteger;
+ import org.apache.ignite.Ignite;
+ import org.apache.ignite.Ignition;
+ import org.apache.ignite.cache.CachePeekMode;
+ import org.apache.ignite.cluster.ClusterNode;
+ import org.apache.ignite.configuration.CacheConfiguration;
+ import org.apache.ignite.configuration.IgniteConfiguration;
+ import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+ import org.apache.ignite.internal.util.typedef.internal.U;
+ import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage;
+ import org.apache.ignite.spi.discovery.DiscoverySpiListener;
+ import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+ import org.jetbrains.annotations.Nullable;
+ 
+ import static org.apache.ignite.cache.CacheMode.REPLICATED;
+ import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
+ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+ 
+ /**
+  * Tests situation when two nodes in cluster simultaneously propose different classes with the same typeId
+  * (which is actually class name's <b>hashCode</b> ).
+  *
+  * In that case one of the propose requests should be rejected
+  * and {@link org.apache.ignite.internal.processors.marshaller.MappingProposedMessage} is sent
+  * with not-null <b>conflictingClsName</b> field.
+  */
+ public class IgniteMarshallerCacheClassNameConflictTest extends GridCommonAbstractTest {
+     /** */
+     private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+ 
+     /** */
+     private volatile boolean bbClsRejected;
+ 
+     /** */
+     private volatile boolean aaClsRejected;
+ 
+     /** */
+     private volatile boolean rejectObserved;
+ 
+     /**
+      * Latch used to synchronize two nodes on sending mapping requests for classes with conflicting names.
+      */
+     private static final CountDownLatch startLatch = new CountDownLatch(3);
+ 
+     /** */
+     private static volatile boolean busySpinFlag;
+ 
+     /** {@inheritDoc} */
+     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+         IgniteConfiguration cfg = super.getConfiguration(gridName);
+ 
+         TcpDiscoverySpi disco = new TestTcpDiscoverySpi();
+         disco.setIpFinder(ipFinder);
+ 
+         cfg.setDiscoverySpi(disco);
+ 
+         CacheConfiguration ccfg = new CacheConfiguration();
+ 
+         ccfg.setCacheMode(REPLICATED);
+         ccfg.setRebalanceMode(SYNC);
+         ccfg.setWriteSynchronizationMode(FULL_SYNC);
+ 
+         cfg.setCacheConfiguration(ccfg);
+ 
+         return cfg;
+     }
+ 
+     /** {@inheritDoc} */
+     @Override protected void afterTest() throws Exception {
+         stopAllGrids();
+     }
+     /**
+      * @throws Exception If failed.
+      */
+     public void testCachePutGetClassesWithNameConflict() throws Exception {
+         Ignite srv1 = startGrid(0);
+         Ignite srv2 = startGrid(1);
+         ExecutorService exec1 = srv1.executorService();
+         ExecutorService exec2 = srv2.executorService();
+ 
+         final AtomicInteger trickCompilerVar = new AtomicInteger(1);
+ 
+         final Organization aOrg1 = new Organization(1, "Microsoft", "One Microsoft Way Redmond, WA 98052-6399, USA");
+         final OrganizatioN bOrg2 = new OrganizatioN(2, "Apple", "1 Infinite Loop, Cupertino, CA 95014, USA");
+ 
+         exec1.submit(new Runnable() {
+             @Override public void run() {
+                 startLatch.countDown();
+ 
+                 try {
+                     startLatch.await();
+                 } catch (InterruptedException e) {
+                     e.printStackTrace();
+                 }
+ 
+                 //busy spinning after waking up from startLatch.await
+                 // to reduce probability that one thread starts significantly earlier than the other
+                 while (!busySpinFlag) {
+                     if (trickCompilerVar.get() < 0)
+                         break;
+                 }
+ 
+                 Ignition.localIgnite().cache(null).put(1, aOrg1);
+             }
+         });
+ 
+         exec2.submit(new Runnable() {
+             @Override public void run() {
+                 startLatch.countDown();
+ 
+                 try {
+                     startLatch.await();
+                 } catch (InterruptedException e) {
+                     e.printStackTrace();
+                 }
+ 
+                 //busy spinning after waking up from startLatch.await
+                 // to reduce probability that one thread starts significantly earlier than the other
+                 while (!busySpinFlag) {
+                     if (trickCompilerVar.get() < 0)
+                         break;
+                 }
+ 
+                 Ignition.localIgnite().cache(null).put(2, bOrg2);
+             }
+         });
+         startLatch.countDown();
+ 
+         busySpinFlag = true;
+ 
+         exec1.shutdown();
+         exec2.shutdown();
+ 
+         exec1.awaitTermination(100, TimeUnit.MILLISECONDS);
+         exec2.awaitTermination(100, TimeUnit.MILLISECONDS);
+ 
+         Ignite ignite = startGrid(2);
+ 
+         int cacheSize = ignite.cache(null).size(CachePeekMode.PRIMARY);
+ 
+         assertTrue("Expected cache size 1 but was " + cacheSize, cacheSize == 1);
+ 
+         if (rejectObserved)
+             assertTrue(aaClsRejected || bbClsRejected);
+     }
+ 
+     /** */
+     private class TestTcpDiscoverySpi extends TcpDiscoverySpi {
 -
+         /** */
+         private class DiscoverySpiListenerWrapper implements DiscoverySpiListener {
+             /** */
+             private DiscoverySpiListener delegate;
+ 
+             /**
+              * @param delegate Delegate.
+              */
+             private DiscoverySpiListenerWrapper(DiscoverySpiListener delegate) {
+                 this.delegate = delegate;
+             }
+ 
+             /** {@inheritDoc} */
++            @Override public void onLocalNodeInitialized(ClusterNode locNode) {
++                // No-op.
++            }
++
++            /** {@inheritDoc} */
+             @Override public void onDiscovery(
+                     int type,
+                     long topVer,
+                     ClusterNode node,
+                     Collection<ClusterNode> topSnapshot,
+                     @Nullable Map<Long, Collection<ClusterNode>> topHist,
+                     @Nullable DiscoverySpiCustomMessage spiCustomMsg
+             ) {
+                 DiscoveryCustomMessage customMsg = spiCustomMsg == null ? null
+                         : (DiscoveryCustomMessage) U.field(spiCustomMsg, "delegate");
+ 
+                 if (customMsg != null)
+                     //don't want to make this class public, using equality of class name instead of instanceof operator
+                     if ("MappingProposedMessage".equals(customMsg.getClass().getSimpleName())) {
+                         String conflClsName = U.field(customMsg, "conflictingClsName");
+                         if (conflClsName != null && !conflClsName.isEmpty()) {
+                             rejectObserved = true;
+                             if (conflClsName.contains("Organization"))
+                                 bbClsRejected = true;
+                             else if (conflClsName.contains("OrganizatioN"))
+                                 aaClsRejected = true;
+                         }
+                     }
+ 
+                 delegate.onDiscovery(type, topVer, node, topSnapshot, topHist, spiCustomMsg);
+             }
+         }
+ 
+         /** {@inheritDoc} */
+         @Override public void setListener(@Nullable DiscoverySpiListener lsnr) {
+             super.setListener(new DiscoverySpiListenerWrapper(lsnr));
+         }
+     }
+ 
+     /**
+      * Class name is chosen to be in conflict with other class name this test put to cache.
+      */
+     private static class Organization {
+         /** */
+         private final int id;
+ 
+         /** */
+         private final String name;
+ 
+         /** */
+         private final String addr;
+ 
+         /**
+          * @param id Id.
+          * @param name Name.
+          * @param addr Address.
+          */
+         Organization(int id, String name, String addr) {
+             this.id = id;
+             this.name = name;
+             this.addr = addr;
+         }
+     }
+ 
+     /**
+      * Class name is chosen to be in conflict with other class name this test put to cache.
+      */
+     private static class OrganizatioN {
+         /** */
+         private final int id;
+ 
+         /** */
+         private final String name;
+ 
+         /** */
+         private final String addr;
+ 
+         /**
+          * @param id Id.
+          * @param name Name.
+          * @param addr Address.
+          */
+         OrganizatioN(int id, String name, String addr) {
+             this.id = id;
+             this.name = name;
+             this.addr = addr;
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractQueueFailoverDataConsistencySelfTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractQueueFailoverDataConsistencySelfTest.java
index 4f02fa2,aeca2fb..c0d7745
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractQueueFailoverDataConsistencySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractQueueFailoverDataConsistencySelfTest.java
@@@ -364,14 -363,10 +364,14 @@@ public abstract class GridCacheAbstract
  
          GridCacheAffinityManager aff = cctx.affinity();
  
 +        CachePeekMode[] modes = new CachePeekMode[]{CachePeekMode.ALL};
 +
          for (int i = 0; i < gridCount(); i++) {
 -            for (GridCacheEntryEx e : ((IgniteKernal)grid(i)).context().cache().internalCache(cctx.name()).allEntries()) {
 -                if (aff.primaryByKey(grid(i).localNode(), e.key(), AffinityTopologyVersion.NONE)
 -                    && e.key().value(cctx.cacheObjectContext(), false) instanceof GridCacheQueueHeaderKey)
 +            for (Cache.Entry e : grid(i).context().cache().internalCache(cctx.name()).localEntries(modes)) {
 +                Object key = e.getKey();
 +
-                 if (aff.primary(grid(i).localNode(), key, AffinityTopologyVersion.NONE)
++                if (aff.primaryByKey(grid(i).localNode(), key, AffinityTopologyVersion.NONE)
 +                    && key instanceof GridCacheQueueHeaderKey)
                      return i;
              }
          }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLateAffinityAssignmentTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionNotLoadedEventSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteTxCacheWriteSynchronizationModesMultithreadedTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
index 177c878,3fd4dd8..04f00c2
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
@@@ -384,13 -384,17 +384,14 @@@ public class GridCacheAtomicInvalidPart
  
                      GridCacheEntryEx entry = null;
  
 -                    if (memMode == TestMemoryMode.HEAP)
 -                        entry = c.peekEx(k);
 -                    else {
 -                        try {
 -                            entry = c.entryEx(k);
 +                    try {
 +                        entry = c.entryEx(k);
  
-                         entry.unswap();
-                     }
-                     catch (GridDhtInvalidPartitionException e) {
-                         // Skip key.
+                             entry.unswap();
+                         }
+                         catch (GridDhtInvalidPartitionException ignored) {
+                             // Skip key.
+                         }
                      }
  
                      for (int r = 0; r < 10; r++) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearOnlyMultiNodeFullApiSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedMultiNodeFullApiSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyAbstractTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyWithStoreAbstractTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyWithStoreAbstractTest.java
index fe53fc7,1f6ec2d..b5ca2de
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyWithStoreAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyWithStoreAbstractTest.java
@@@ -36,9 -40,11 +40,12 @@@ import org.apache.ignite.internal.Ignit
  import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
  import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
  import org.apache.ignite.internal.processors.cache.IgniteCacheAbstractTest;
 +import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException;
  import org.apache.ignite.internal.util.typedef.F;
  import org.apache.ignite.internal.util.typedef.internal.U;
+ import org.apache.ignite.transactions.Transaction;
+ import org.apache.ignite.transactions.TransactionConcurrency;
+ import org.apache.ignite.transactions.TransactionIsolation;
  
  /**
   *

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAbstractSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxOptimisticDeadlockDetectionTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/spi/discovery/AbstractDiscoverySelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
index b032717,e37a8a1..12b7523
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
@@@ -270,6 -272,11 +273,10 @@@ public class IgniteCacheTestSuite2 exte
          suite.addTest(new TestSuite(IgniteNoCustomEventsOnNodeStart.class));
  
          suite.addTest(new TestSuite(CacheExchangeMessageDuplicatedStateTest.class));
 -        suite.addTest(new TestSuite(OffheapCacheOnClientsTest.class));
+         suite.addTest(new TestSuite(CacheConcurrentReadThroughTest.class));
+ 
+         suite.addTest(new TestSuite(GridNearCacheStoreUpdateTest.class));
+         suite.addTest(new TestSuite(GridNearOffheapCacheStoreUpdateTest.class));
  
          return suite;
      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
index ea7173c,bab219c..65c4d62
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
@@@ -17,8 -17,18 +17,18 @@@
  
  package org.apache.ignite.internal.processors.query.h2.opt;
  
- import java.util.*;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Comparator;
+ import java.util.HashMap;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
++import java.util.NoSuchElementException;
+ import java.util.UUID;
  import java.util.concurrent.BlockingQueue;
 -import java.util.concurrent.ConcurrentNavigableMap;
  import java.util.concurrent.Future;
  import java.util.concurrent.LinkedBlockingQueue;
  import java.util.concurrent.TimeUnit;
@@@ -42,8 -52,8 +52,9 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowRangeBounds;
  import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessage;
  import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessageFactory;
- import org.apache.ignite.internal.util.*;
- import org.apache.ignite.internal.util.lang.*;
+ import org.apache.ignite.internal.util.GridSpinBusyLock;
 -import org.apache.ignite.internal.util.lang.GridFilteredIterator;
++import org.apache.ignite.internal.util.IgniteTree;
++import org.apache.ignite.internal.util.lang.GridCursor;
  import org.apache.ignite.internal.util.typedef.CIX2;
  import org.apache.ignite.internal.util.typedef.F;
  import org.apache.ignite.internal.util.typedef.internal.CU;
@@@ -1555,97 -1534,5 +1566,97 @@@ public abstract class GridH2IndexBase e
  
              return fltr.apply(key, val);
          }
 +
 +        /** {@inheritDoc} */
 +        @Override public boolean next() throws IgniteCheckedException {
 +            next = null;
 +
 +            while (cursor.next()) {
 +                GridH2Row t = cursor.get();
 +
 +                if (accept(t)) {
 +                    next = t;
 +                    return true;
 +                }
 +            }
 +
 +            return false;
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public GridH2Row get() throws IgniteCheckedException {
 +            if (next == null)
 +                throw new NoSuchElementException();
 +
 +            return next;
 +        }
      }
 +
 +    /**
 +     *
 +     */
 +    private static final class CursorIteratorWrapper implements Iterator<GridH2Row> {
 +        /** */
 +        private final GridCursor<GridH2Row> cursor;
 +
 +        /** Next element. */
 +        private GridH2Row next;
 +
 +        /**
 +         * @param cursor Cursor.
 +         */
 +        private CursorIteratorWrapper(GridCursor<GridH2Row> cursor) {
 +            assert cursor != null;
 +
 +            this.cursor = cursor;
 +
 +            try {
 +                if (cursor.next())
 +                    next = cursor.get();
 +            }
 +            catch (IgniteCheckedException e) {
 +                throw U.convertException(e);
 +            }
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public boolean hasNext() {
 +            return next != null;
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public GridH2Row next() {
 +            try {
 +                GridH2Row res = next;
 +
 +                if (cursor.next())
 +                    next = cursor.get();
 +                else
 +                    next = null;
 +
 +                return res;
 +            }
 +            catch (IgniteCheckedException e) {
 +                throw U.convertException(e);
 +            }
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public void remove() {
 +            throw new UnsupportedOperationException("operation is not supported");
 +        }
 +    }
 +
 +    /** Empty cursor. */
 +    protected static final GridCursor<GridH2Row> EMPTY_CURSOR = new GridCursor<GridH2Row>() {
 +        /** {@inheritDoc} */
 +        @Override public boolean next() {
 +            return false;
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public GridH2Row get() {
 +            return null;
 +        }
 +    };
- }
+ }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
index 4576cec,0e19a75..5a71bc8
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
@@@ -105,10 -104,10 +105,7 @@@ import static org.apache.ignite.interna
   * Reduce query executor.
   */
  public class GridReduceQueryExecutor {
-     /** Thread pool to process query messages. */
-     public static final byte QUERY_POOL = GridIoPolicy.SYSTEM_POOL;
- 
      /** */
 -    private static final IgniteProductVersion DISTRIBUTED_JOIN_SINCE = IgniteProductVersion.fromString("1.7.0");
 -
 -    /** */
      private GridKernalContext ctx;
  
      /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQueryIndexDisabledSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
index 15f110f,81c28a3..da2fe2e
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
@@@ -549,8 -614,115 +589,115 @@@ public abstract class IgniteCacheAbstra
       *
       * @throws Exception In case of error.
       */
+     public void testSimpleCustomTableName() throws Exception {
+         final IgniteCache<Integer, Object> cache = ignite().cache(null);
+ 
+         cache.put(10, new Type1(1, "Type1 record #1"));
+         cache.put(20, new Type1(2, "Type1 record #2"));
+ 
+         QueryCursor<Cache.Entry<Integer, Type1>> qry1 =
+             cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type2"));
+ 
+         List<Cache.Entry<Integer, Type1>> all = qry1.getAll();
+ 
+         assertEquals(2, all.size());
+ 
+         QueryCursor<List<?>> qry = cache.query(new SqlFieldsQuery("SELECT name FROM Type2"));
+ 
+         assertEquals(2, qry.getAll().size());
+ 
+         GridTestUtils.assertThrows(log, new GridPlainCallable<Void>() {
+             @Override public Void call() throws Exception {
+                 QueryCursor<Cache.Entry<Integer, Type1>> qry =
+                     cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type1"));
+ 
+                 qry.getAll();
+ 
+                 return null;
+             }
+         }, CacheException.class, null);
+     }
+ 
+     /**
+      * JUnit.
+      *
+      * @throws Exception In case of error.
+      */
+     public void testMixedCustomTableName() throws Exception {
+         final IgniteCache<Integer, Object> cache = ignite().cache(null);
+ 
+         cache.put(10, new Type1(1, "Type1 record #1"));
+         cache.put(20, new Type1(2, "Type1 record #2"));
+         cache.put(30, new Type2(1, "Type2 record #1"));
+         cache.put(40, new Type2(2, "Type2 record #2"));
+         cache.put(50, new Type2(3, "Type2 record #3"));
+ 
+         QueryCursor<Cache.Entry<Integer, Type1>> qry1 =
+             cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type2"));
+ 
+         List<Cache.Entry<Integer, Type1>> all = qry1.getAll();
+ 
+         assertEquals(2, all.size());
+ 
+         QueryCursor<Cache.Entry<Integer, Type2>> qry2 =
+             cache.query(new SqlQuery<Integer, Type2>(Type2.class, "FROM Type1"));
+ 
+         assertEquals(3, qry2.getAll().size());
+ 
+         QueryCursor<List<?>> qry = cache.query(new SqlFieldsQuery("SELECT name FROM Type1"));
+ 
+         assertEquals(3, qry.getAll().size());
+ 
+         qry = cache.query(new SqlFieldsQuery("SELECT name FROM Type2"));
+ 
+         assertEquals(2, qry.getAll().size());
+ 
+         GridTestUtils.assertThrows(log, new GridPlainCallable<Void>() {
+             @Override public Void call() throws Exception {
+                 QueryCursor<Cache.Entry<Integer, Type1>> qry1 =
+                     cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type1"));
+ 
+                 qry1.getAll().size();
+ 
+                 return null;
+             }
+         }, CacheException.class, null);
+     }
+ 
+     /**
+      * JUnit.
+      *
+      * @throws Exception In case of error.
+      */
+     public void testDistributedJoinCustomTableName() throws Exception {
+         IgniteCache<Integer, Object> cache = ignite().cache(null);
+ 
+         cache.put(10, new Type1(1, "Type1 record #1"));
+         cache.put(20, new Type1(2, "Type1 record #2"));
+         cache.put(30, new Type2(1, "Type2 record #1"));
+         cache.put(40, new Type2(2, "Type2 record #2"));
+         cache.put(50, new Type2(3, "Type2 record #3"));
+ 
+         QueryCursor<List<?>> query = cache.query(
+             new SqlFieldsQuery("SELECT t2.name, t1.name FROM Type2 as t2 LEFT JOIN Type1 as t1 ON t1.id = t2.id")
+                 .setDistributedJoins(cacheMode() == PARTITIONED));
+ 
+         assertEquals(2, query.getAll().size());
+ 
+         query = cache.query(
+             new SqlFieldsQuery("SELECT t2.name, t1.name FROM Type2 as t2 RIGHT JOIN Type1 as t1 ON t1.id = t2.id")
+                 .setDistributedJoins(cacheMode() == PARTITIONED));
+ 
+         assertEquals(3, query.getAll().size());
+     }
+ 
+     /**
+      * JUnit.
+      *
+      * @throws Exception In case of error.
+      */
      public void testObjectQuery() throws Exception {
 -        IgniteCache<Integer, ObjectValue> cache = ignite().cache(null);
 +        IgniteCache<Integer, ObjectValue> cache = jcache(Integer.class, ObjectValue.class);
  
          ObjectValue val = new ObjectValue("test", 0);
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheLockPartitionOnAffinityRunTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapEvictQueryTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCachePartitionedQuerySelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSplitterSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index b9152fa,f1d72bf..13cf1cb
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@@ -758,10 -722,5 +768,10 @@@ public abstract class GridIndexingSpiAb
          @Override public byte fieldsCount() {
              throw new UnsupportedOperationException();
          }
 +
 +        /** {@inheritDoc} */
 +        @Override public boolean internal() {
 +            return false;
 +        }
      }
- }
+ }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
index 4eaaab8,07125a6..045d772
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
@@@ -33,7 -33,9 +33,8 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBinaryIterationNearEnabledTest;
  import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBinaryIterationTest;
  import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBinaryIterationStoreEnabledTest;
 -import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBinaryIterationSwapEnabledTest;
 -import org.apache.ignite.internal.processors.cache.query.continuous.ClientReconnectContinuousQueryTest;
  import org.apache.ignite.internal.processors.cache.query.continuous.ContinuousQueryRemoteFilterMissingInClassPathSelfTest;
++import org.apache.ignite.internal.processors.cache.query.continuous.ClientReconnectContinuousQueryTest;
  import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicNearEnabledSelfTest;
  import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicOffheapTieredTest;
  import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicOffheapValuesTest;
@@@ -121,9 -123,9 +122,10 @@@ public class IgniteCacheQuerySelfTestSu
          suite.addTestSuite(CacheKeepBinaryIterationNearEnabledTest.class);
          suite.addTestSuite(IgniteCacheContinuousQueryBackupQueueTest.class);
          suite.addTestSuite(IgniteCacheContinuousQueryNoUnsubscribeTest.class);
+         suite.addTestSuite(ClientReconnectContinuousQueryTest.class);
  
 +        suite.addTest(IgniteDistributedJoinTestSuite.suite());
 +
          return suite;
      }
  }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/kafka/src/test/java/org/apache/ignite/stream/kafka/TestKafkaBroker.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/spark/src/test/java/org/apache/ignite/spark/JavaStandaloneIgniteRDDSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/yardstick/pom.xml
----------------------------------------------------------------------
diff --cc modules/yardstick/pom.xml
index b24f67c,d96fcc6..3eed80e
--- a/modules/yardstick/pom.xml
+++ b/modules/yardstick/pom.xml
@@@ -35,9 -35,8 +35,10 @@@
      <url>http://ignite.apache.org</url>
  
      <properties>
-         <yardstick.version>0.8.0</yardstick.version>
+         <yardstick.version>0.8.2</yardstick.version>
+         <spring.version>4.1.0.RELEASE</spring.version>
 +        <mysql.connector.version>5.1.39</mysql.connector.version>
 +        <postgres.connector.version>9.4.1208.jre7</postgres.connector.version>
      </properties>
  
      <dependencies>


[20/50] [abbrv] ignite git commit: IGNITE-4363: Fix QueryEntity field order for attribute-based config

Posted by sb...@apache.org.
IGNITE-4363: Fix QueryEntity field order for attribute-based config


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 9ce099c05f4b672fd4ce95173342335402f63039
Parents: d01406f
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Thu Feb 9 13:29:40 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Thu Feb 9 13:29:40 2017 +0300

----------------------------------------------------------------------
 .../dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9ce099c0/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
index ff9af37..2cd0295 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
@@ -283,7 +283,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
                 ScanAttributes(valType, fields, indexes, null, new HashSet<Type>(), false);
 
             if (fields.Any())
-                Fields = fields;
+                Fields = fields.OrderBy(x => x.Name).ToList();
 
             if (indexes.Any())
                 Indexes = GetGroupIndexes(indexes).ToArray();


[19/50] [abbrv] ignite git commit: IGNITE-4676 Fixed hang if closure executed nested internal task with continuation. Added test.

Posted by sb...@apache.org.
IGNITE-4676 Fixed hang if closure executed nested internal task with continuation. Added test.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: e7a5307911dff1df93d003b2ef98aeca96a89dac
Parents: db5da76
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Feb 9 16:44:41 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Feb 9 16:44:41 2017 +0700

----------------------------------------------------------------------
 .../internal/processors/job/GridJobWorker.java  |  4 +
 .../internal/GridContinuousTaskSelfTest.java    | 79 ++++++++++++++++++++
 2 files changed, 83 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e7a53079/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
index 6a00d96..acefde7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
@@ -617,6 +617,10 @@ public class GridJobWorker extends GridWorker implements GridTimeoutObject {
                 // Finish here only if not held by this thread.
                 if (!HOLD.get())
                     finishJob(res, ex, sndRes);
+                else
+                    // Make sure flag is not set for current thread.
+                    // This may happen in case of nested internal task call with continuation.
+                    HOLD.set(false);
 
                 ctx.job().currentTaskSession(null);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e7a53079/modules/core/src/test/java/org/apache/ignite/internal/GridContinuousTaskSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridContinuousTaskSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridContinuousTaskSelfTest.java
index 88667d9..d224fc5 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/GridContinuousTaskSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/GridContinuousTaskSelfTest.java
@@ -21,10 +21,12 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.concurrent.Callable;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCompute;
 import org.apache.ignite.IgniteException;
@@ -43,7 +45,9 @@ import org.apache.ignite.compute.ComputeTaskSession;
 import org.apache.ignite.compute.ComputeTaskSessionAttributeListener;
 import org.apache.ignite.compute.ComputeTaskSessionFullSupport;
 import org.apache.ignite.compute.ComputeTaskSplitAdapter;
+import org.apache.ignite.internal.processors.task.GridInternal;
 import org.apache.ignite.lang.IgniteClosure;
+import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.resources.JobContextResource;
 import org.apache.ignite.resources.LoggerResource;
 import org.apache.ignite.resources.TaskContinuousMapperResource;
@@ -51,6 +55,7 @@ import org.apache.ignite.resources.TaskSessionResource;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.common.GridCommonTest;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Continuous task test.
@@ -195,6 +200,80 @@ public class GridContinuousTaskSelfTest extends GridCommonAbstractTest {
         }
     }
 
+    /**
+     * @throws Exception If test failed.
+     */
+    public void testClosureWithNestedInternalTask() throws Exception {
+        try {
+            IgniteEx ignite = startGrid(0);
+
+            ComputeTaskInternalFuture<String> fut = ignite.context().closure().callAsync(GridClosureCallMode.BALANCE, new Callable<String>() {
+                /** */
+                @IgniteInstanceResource
+                private IgniteEx g;
+
+                @Override public String call() throws Exception {
+                    return g.compute(g.cluster()).execute(NestedHoldccTask.class, null);
+                }
+            }, ignite.cluster().nodes());
+
+            assertEquals("DONE", fut.get(3000));
+        }
+        finally {
+            stopGrid(0, true);
+        }
+    }
+
+    /** Test task with continuation. */
+    @GridInternal
+    public static class NestedHoldccTask extends ComputeTaskAdapter<String, String> {
+        /** {@inheritDoc} */
+        @Nullable @Override public Map<? extends ComputeJob, ClusterNode> map(List<ClusterNode> subgrid,
+            @Nullable String arg) throws IgniteException {
+            Map<ComputeJob, ClusterNode> map = new HashMap<>();
+
+            for (ClusterNode node : subgrid)
+                map.put(new NestedHoldccJob(), node);
+
+            return map;
+
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public String reduce(List<ComputeJobResult> results) throws IgniteException {
+            return results.get(0).getData();
+        }
+    }
+
+    /** Test job. */
+    public static class NestedHoldccJob extends ComputeJobAdapter {
+        /** */
+        @JobContextResource
+        private ComputeJobContext jobCtx;
+
+        /** */
+        private int cnt = 0;
+
+        /** {@inheritDoc} */
+        @Override public Object execute() throws IgniteException {
+            if (cnt < 1) {
+                cnt++;
+
+                jobCtx.holdcc();
+
+                new Timer().schedule(new TimerTask() {
+                    @Override public void run() {
+                        jobCtx.callcc();
+                    }
+                }, 500);
+
+                return "NOT DONE";
+            }
+
+            return "DONE";
+        }
+    }
+
     /** */
     @SuppressWarnings({"PublicInnerClass"})
     public static class TestMultipleHoldccCallsClosure implements IgniteClosure<Object, Boolean> {


[30/50] [abbrv] ignite git commit: IGNITE-4425 .NET: Support "ICollection.Contains" in LINQ

Posted by sb...@apache.org.
IGNITE-4425 .NET: Support "ICollection.Contains" in LINQ

This closes #1502


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: d949b739d1fc47a13dcbf8fe107276bc603b6d92
Parents: 2f4bdbb
Author: Sergey Stronchinskiy <gu...@gmail.com>
Authored: Fri Feb 10 15:38:01 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Feb 10 15:38:52 2017 +0300

----------------------------------------------------------------------
 .../Cache/Query/CacheLinqTest.cs                |  96 ++++++++++++++
 .../Impl/CacheQueryExpressionVisitor.cs         | 127 ++++++++++++++++++-
 .../Impl/CacheQueryModelVisitor.cs              |   3 +
 3 files changed, 224 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d949b739/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
index 798e7e8..931fdd4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
@@ -28,6 +28,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
 {
     using System;
     using System.Collections;
+    using System.Collections.Generic;
     using System.Linq;
     using System.Linq.Expressions;
     using System.Text.RegularExpressions;
@@ -106,6 +107,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
 
             orgCache[1000] = new Organization {Id = 1000, Name = "Org_0"};
             orgCache[1001] = new Organization {Id = 1001, Name = "Org_1"};
+            orgCache[1002] = new Organization {Id = 1002, Name = null};
 
             var roleCache = GetRoleCache();
 
@@ -747,6 +749,74 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         }
 
         /// <summary>
+        /// Tests IEnumerable.Contains.
+        /// </summary>
+        [Test]
+        public void TestContains()
+        {
+            var cache = GetPersonCache().AsCacheQueryable();
+            var orgCache = GetOrgCache().AsCacheQueryable();
+
+            var keys = new[] { 1, 2, 3 };
+            var emptyKeys = new int[0];
+
+            var bigNumberOfKeys = 10000;
+            var aLotOfKeys = Enumerable.Range(-bigNumberOfKeys + 10 - PersonCount, bigNumberOfKeys + PersonCount)
+                .ToArray();
+            var hashSetKeys = new HashSet<int>(keys);
+
+            CheckWhereFunc(cache, e => new[] { 1, 2, 3 }.Contains(e.Key));
+            CheckWhereFunc(cache, e => emptyKeys.Contains(e.Key));
+            CheckWhereFunc(cache, e => new int[0].Contains(e.Key));
+            CheckWhereFunc(cache, e => new int[0].Contains(e.Key));
+            CheckWhereFunc(cache, e => new List<int> { 1, 2, 3 }.Contains(e.Key));
+            CheckWhereFunc(cache, e => new List<int>(keys).Contains(e.Key));
+            CheckWhereFunc(cache, e => aLotOfKeys.Contains(e.Key));
+            CheckWhereFunc(cache, e => hashSetKeys.Contains(e.Key));
+            CheckWhereFunc(cache, e => !keys.Contains(e.Key));
+            CheckWhereFunc(orgCache, e => new[] { "Org_1", "NonExistentName", null }.Contains(e.Value.Name));
+            CheckWhereFunc(orgCache, e => !new[] { "Org_1", "NonExistentName", null }.Contains(e.Value.Name));
+            CheckWhereFunc(orgCache, e => new[] { "Org_1", null, null }.Contains(e.Value.Name));
+            CheckWhereFunc(orgCache, e => !new[] { "Org_1", null, null }.Contains(e.Value.Name));
+            CheckWhereFunc(orgCache, e => new string[] { null }.Contains(e.Value.Name));
+            CheckWhereFunc(orgCache, e => !new string[] { null }.Contains(e.Value.Name));
+            CheckWhereFunc(orgCache, e => !new string[] { null, null }.Contains(e.Value.Name));
+            CheckWhereFunc(orgCache, e => new string[] { null, null }.Contains(e.Value.Name));
+
+            //check passing a null object as collection
+            int[] nullKeys = null;
+            var nullKeysEntries = cache
+                .Where(e => nullKeys.Contains(e.Key))
+                .ToArray();
+            Assert.AreEqual(0, nullKeysEntries.Length, "Evaluating 'null.Contains' should return zero results");
+
+
+            Func<int[]> getKeysFunc = () => null;
+            var funcNullKeyEntries = cache
+                .Where(e => getKeysFunc().Contains(e.Key))
+                .ToArray();
+            Assert.AreEqual(0, funcNullKeyEntries.Length, "Evaluating 'null.Contains' should return zero results");
+
+
+            // Check subselect from other cache
+            var subSelectCount = cache
+                .Count(entry => orgCache
+                    .Where(orgEntry => orgEntry.Value.Name == "Org_1")
+                    .Select(orgEntry => orgEntry.Key)
+                    .Contains(entry.Value.OrganizationId));
+            var orgNumberOne = orgCache
+                .Where(orgEntry => orgEntry.Value.Name == "Org_1")
+                .Select(orgEntry => orgEntry.Key)
+                .First();
+            var subSelectCheckCount = cache.Count(entry => entry.Value.OrganizationId == orgNumberOne);
+            Assert.AreEqual(subSelectCheckCount, subSelectCount, "subselecting another CacheQueryable failed");
+
+            var ex = Assert.Throws<NotSupportedException>(() =>
+                CompiledQuery2.Compile((int[] k) => cache.Where(x => k.Contains(x.Key))));
+            Assert.AreEqual("'Contains' clause coming from compiled query parameter is not supported.", ex.Message);
+        }
+
+        /// <summary>
         /// Tests nulls.
         /// </summary>
         [Test]
@@ -1412,6 +1482,32 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             CollectionAssert.AreEqual(expected, actual, new NumericComparer());
         }
 
+        /// <summary>
+        /// Checks that function used in Where Clause maps to SQL function properly
+        /// </summary>
+        private static void CheckWhereFunc<TKey, TEntry>(IQueryable<ICacheEntry<TKey,TEntry>> query, Expression<Func<ICacheEntry<TKey, TEntry>,bool>> whereExpression)
+        {
+            // Calculate result locally, using real method invocation
+            var expected = query
+                .ToArray()
+                .AsQueryable()
+                .Where(whereExpression)
+                .Select(entry => entry.Key)
+                .OrderBy(x => x)
+                .ToArray();
+
+            // Perform SQL query
+            var actual = query
+                .Where(whereExpression)
+                .Select(entry => entry.Key)
+                .ToArray()
+                .OrderBy(x => x)
+                .ToArray();
+
+            // Compare results
+            CollectionAssert.AreEqual(expected, actual, new NumericComparer());
+        }
+
         public interface IPerson
         {
             int Age { get; set; }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d949b739/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
index 1f9da1c..94e59fa 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
@@ -20,6 +20,7 @@ using System.Text;
 
 namespace Apache.Ignite.Linq.Impl
 {
+    using System.Collections;
     using System.Collections.Generic;
     using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
@@ -29,6 +30,7 @@ namespace Apache.Ignite.Linq.Impl
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Impl.Common;
+    using Remotion.Linq;
     using Remotion.Linq.Clauses;
     using Remotion.Linq.Clauses.Expressions;
     using Remotion.Linq.Clauses.ResultOperators;
@@ -470,15 +472,136 @@ namespace Apache.Ignite.Linq.Impl
         }
 
         /** <inheritdoc /> */
+
         [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
         protected override Expression VisitSubQuery(SubQueryExpression expression)
         {
-            // This happens when New expression uses a subquery, in a GroupBy.
-            _modelVisitor.VisitSelectors(expression.QueryModel, false);
+            var subQueryModel = expression.QueryModel;
+
+            var contains = subQueryModel.ResultOperators.FirstOrDefault() as ContainsResultOperator;
+            
+            // Check if IEnumerable.Contains is used.
+            if (subQueryModel.ResultOperators.Count == 1 && contains != null)
+            {
+                VisitContains(subQueryModel, contains);
+            }
+            else
+            {
+                // This happens when New expression uses a subquery, in a GroupBy.
+                _modelVisitor.VisitSelectors(expression.QueryModel, false);
+            }
 
             return expression;
         }
 
+        /// <summary>
+        /// Visits IEnumerable.Contains
+        /// </summary>
+        private void VisitContains(QueryModel subQueryModel, ContainsResultOperator contains)
+        {
+            ResultBuilder.Append("(");
+
+            var fromExpression = subQueryModel.MainFromClause.FromExpression;
+
+            var queryable = ExpressionWalker.GetCacheQueryable(fromExpression, false);
+
+            if (queryable != null)
+            {
+                Visit(contains.Item);
+
+                ResultBuilder.Append(" IN (");
+                _modelVisitor.VisitQueryModel(subQueryModel);
+                ResultBuilder.Append(")");
+            }
+            else
+            {
+                var inValues = GetInValues(fromExpression).ToArray();
+
+                var hasNulls = inValues.Any(o => o == null);
+
+                if (hasNulls)
+                {
+                    ResultBuilder.Append("(");
+                }
+
+                Visit(contains.Item);
+
+                ResultBuilder.Append(" IN (");
+                AppendInParameters(inValues);
+                ResultBuilder.Append(")");
+
+                if (hasNulls)
+                {
+                    ResultBuilder.Append(") OR ");
+                    Visit(contains.Item);
+                    ResultBuilder.Append(" IS NULL");
+                }
+            }
+
+            ResultBuilder.Append(")");
+        }
+
+        /// <summary>
+        /// Gets values for IN expression.
+        /// </summary>
+        private static IEnumerable<object> GetInValues(Expression fromExpression)
+        {
+            IEnumerable result;
+            switch (fromExpression.NodeType)
+            {
+                case ExpressionType.MemberAccess:
+                    var memberExpression = (MemberExpression) fromExpression;
+                    result = ExpressionWalker.EvaluateExpression<IEnumerable>(memberExpression);
+                    break;
+                case ExpressionType.ListInit:
+                    var listInitExpression = (ListInitExpression) fromExpression;
+                    result = listInitExpression.Initializers
+                        .SelectMany(init => init.Arguments)
+                        .Select(ExpressionWalker.EvaluateExpression<object>);
+                    break;
+                case ExpressionType.NewArrayInit:
+                    var newArrayExpression = (NewArrayExpression) fromExpression;
+                    result = newArrayExpression.Expressions
+                        .Select(ExpressionWalker.EvaluateExpression<object>);
+                    break;
+                case ExpressionType.Parameter:
+                    // This should happen only when 'IEnumerable.Contains' is called on parameter of compiled query
+                    throw new NotSupportedException("'Contains' clause coming from compiled query parameter is not supported.");
+                default:
+                    result = Expression.Lambda(fromExpression).Compile().DynamicInvoke() as IEnumerable;
+                    break;
+            }
+
+            result = result ?? Enumerable.Empty<object>();
+
+            return result
+                .Cast<object>()
+                .ToArray();
+        }
+
+        /// <summary>
+        /// Appends not null parameters using ", " as delimeter.
+        /// </summary>
+        private void AppendInParameters(IEnumerable<object> values)
+        {
+            var first = true;
+
+            foreach (var val in values)
+            {
+                if (val == null)
+                    continue;
+
+                if (!first)
+                {
+                    ResultBuilder.Append(", ");
+                }
+
+                first = false;
+
+                AppendParameter(val);
+            }
+        }
+
         /** <inheritdoc /> */
         protected override Exception CreateUnhandledItemException<T>(T unhandledItem, string visitMethod)
         {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d949b739/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
index ae94cfb..7cc9265 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
@@ -184,6 +184,9 @@ namespace Apache.Ignite.Linq.Impl
                          || op is DefaultIfEmptyResultOperator || op is SkipResultOperator || op is TakeResultOperator)
                     // Will be processed later
                     break;
+                else if (op is ContainsResultOperator)
+                    // Should be processed already
+                    break;
                 else
                     throw new NotSupportedException("Operator is not supported: " + op);
             }


[21/50] [abbrv] ignite git commit: Reviewed and merged IGNITE-4374 contributed by daradurvs daradurvs at gmail.com

Posted by sb...@apache.org.
Reviewed and merged IGNITE-4374 contributed by daradurvs daradurvs at gmail.com


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 3459bdd3a35869df13c9b35f616325c0c3e3481e
Parents: e7a5307
Author: daradurvs <da...@gmail.com>
Authored: Thu Feb 9 20:29:02 2017 +0700
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Thu Feb 9 20:29:02 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/GridKernalContext.java      |   1 +
 .../ignite/internal/GridKernalContextImpl.java  |   1 +
 .../internal/GridPerformanceSuggestions.java    |  92 --------------
 .../apache/ignite/internal/IgniteKernal.java    |   9 ++
 .../processors/cache/GridCacheProcessor.java    |   2 +-
 .../suggestions/GridPerformanceSuggestions.java | 104 +++++++++++++++
 .../JvmConfigurationSuggestions.java            | 104 +++++++++++++++
 .../suggestions/OsConfigurationSuggestions.java | 127 +++++++++++++++++++
 .../internal/suggestions/package-info.java      |  21 +++
 .../ignite/internal/util/IgniteUtils.java       |  14 ++
 10 files changed, 382 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
index 927944f..00696c7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
@@ -65,6 +65,7 @@ import org.apache.ignite.internal.processors.service.GridServiceProcessor;
 import org.apache.ignite.internal.processors.session.GridTaskSessionProcessor;
 import org.apache.ignite.internal.processors.task.GridTaskProcessor;
 import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
+import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions;
 import org.apache.ignite.internal.util.IgniteExceptionRegistry;
 import org.apache.ignite.internal.util.StripedExecutor;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
index a2ad1b2..e80ec6b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
@@ -82,6 +82,7 @@ import org.apache.ignite.internal.processors.service.GridServiceProcessor;
 import org.apache.ignite.internal.processors.session.GridTaskSessionProcessor;
 import org.apache.ignite.internal.processors.task.GridTaskProcessor;
 import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
+import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions;
 import org.apache.ignite.internal.util.IgniteExceptionRegistry;
 import org.apache.ignite.internal.util.StripedExecutor;
 import org.apache.ignite.internal.util.spring.IgniteSpringHelper;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/GridPerformanceSuggestions.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridPerformanceSuggestions.java b/modules/core/src/main/java/org/apache/ignite/internal/GridPerformanceSuggestions.java
deleted file mode 100644
index 5e8e520..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridPerformanceSuggestions.java
+++ /dev/null
@@ -1,92 +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.internal;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.jetbrains.annotations.Nullable;
-
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED;
-
-/**
- * Grid performance suggestions.
- */
-public class GridPerformanceSuggestions {
-    /** */
-    private static final boolean disabled = Boolean.getBoolean(IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED);
-
-    /** */
-    private final Collection<String> perfs = !disabled ? new LinkedHashSet<String>() : null;
-
-    /** */
-    private final Collection<String> suppressed = !disabled ? new HashSet<String>() : null;
-
-    /**
-     * @param sug Suggestion to add.
-     */
-    public synchronized void add(String sug) {
-        add(sug, false);
-    }
-
-    /**
-     * @param sug Suggestion to add.
-     * @param suppress {@code True} to suppress this suggestion.
-     */
-    public synchronized void add(String sug, boolean suppress) {
-        if (disabled)
-            return;
-
-        if (!suppress)
-            perfs.add(sug);
-        else
-            suppressed.add(sug);
-    }
-
-    /**
-     * @param log Log.
-     * @param gridName Grid name.
-     */
-    public synchronized void logSuggestions(IgniteLogger log, @Nullable String gridName) {
-        if (disabled)
-            return;
-
-        if (!F.isEmpty(perfs) && !suppressed.containsAll(perfs)) {
-            U.quietAndInfo(log, "Performance suggestions for grid " +
-                (gridName == null ? "" : '\'' + gridName + '\'') + " (fix if possible)");
-            U.quietAndInfo(log, "To disable, set -D" + IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED + "=true");
-
-            for (String s : perfs)
-                if (!suppressed.contains(s))
-                    U.quietAndInfo(log, "  ^-- " + s);
-
-            U.quietAndInfo(log, "");
-
-            perfs.clear();
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return S.toString(GridPerformanceSuggestions.class, this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/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 9f1c746..a3d8c7b 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
@@ -138,6 +138,9 @@ import org.apache.ignite.internal.processors.service.GridServiceProcessor;
 import org.apache.ignite.internal.processors.session.GridTaskSessionProcessor;
 import org.apache.ignite.internal.processors.task.GridTaskProcessor;
 import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
+import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions;
+import org.apache.ignite.internal.suggestions.JvmConfigurationSuggestions;
+import org.apache.ignite.internal.suggestions.OsConfigurationSuggestions;
 import org.apache.ignite.internal.util.StripedExecutor;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
@@ -930,6 +933,12 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
             // Suggest configuration optimizations.
             suggestOptimizations(cfg);
 
+            // Suggest JVM optimizations.
+            ctx.performance().addAll(JvmConfigurationSuggestions.getSuggestions());
+
+            // Suggest Operation System optimizations.
+            ctx.performance().addAll(OsConfigurationSuggestions.getSuggestions());
+
             // Notify discovery manager the first to make sure that topology is discovered.
             ctx.discovery().onKernalStart();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 87f5236..b0a78f4 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -63,7 +63,7 @@ import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.configuration.TransactionConfiguration;
 import org.apache.ignite.events.EventType;
 import org.apache.ignite.internal.GridKernalContext;
-import org.apache.ignite.internal.GridPerformanceSuggestions;
+import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions;
 import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
 import org.apache.ignite.internal.IgniteComponentType;
 import org.apache.ignite.internal.IgniteInternalFuture;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java
new file mode 100644
index 0000000..c51a136
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/GridPerformanceSuggestions.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.suggestions;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED;
+
+/**
+ * Grid performance suggestions.
+ */
+public class GridPerformanceSuggestions {
+    /** Link to article about Ignite performance tuning */
+    private static final String SUGGESTIONS_LINK = "https://apacheignite.readme.io/docs/jvm-and-system-tuning";
+
+    /** */
+    private static final boolean disabled = Boolean.getBoolean(IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED);
+
+    /** */
+    private final Collection<String> perfs = !disabled ? new LinkedHashSet<String>() : null;
+
+    /** */
+    private final Collection<String> suppressed = !disabled ? new HashSet<String>() : null;
+
+    /**
+     * @param suggestions Suggestions to add.
+     */
+    public synchronized void addAll(List<String> suggestions) {
+        for (String suggestion : suggestions)
+            add(suggestion);
+    }
+
+    /**
+     * @param sug Suggestion to add.
+     */
+    public synchronized void add(String sug) {
+        add(sug, false);
+    }
+
+    /**
+     * @param sug Suggestion to add.
+     * @param suppress {@code True} to suppress this suggestion.
+     */
+    public synchronized void add(String sug, boolean suppress) {
+        if (disabled)
+            return;
+
+        if (!suppress)
+            perfs.add(sug);
+        else
+            suppressed.add(sug);
+    }
+
+    /**
+     * @param log Log.
+     * @param gridName Grid name.
+     */
+    public synchronized void logSuggestions(IgniteLogger log, @Nullable String gridName) {
+        if (disabled)
+            return;
+
+        if (!F.isEmpty(perfs) && !suppressed.containsAll(perfs)) {
+            U.quietAndInfo(log, "Performance suggestions for grid " +
+                (gridName == null ? "" : '\'' + gridName + '\'') + " (fix if possible)");
+            U.quietAndInfo(log, "To disable, set -D" + IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED + "=true");
+
+            for (String s : perfs)
+                if (!suppressed.contains(s))
+                    U.quietAndInfo(log, "  ^-- " + s);
+
+            perfs.clear();
+        }
+        U.quietAndInfo(log, "Refer to this page for more performance suggestions: " + SUGGESTIONS_LINK);
+        U.quietAndInfo(log, "");
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(GridPerformanceSuggestions.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/suggestions/JvmConfigurationSuggestions.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/suggestions/JvmConfigurationSuggestions.java b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/JvmConfigurationSuggestions.java
new file mode 100644
index 0000000..4319229
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/JvmConfigurationSuggestions.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.suggestions;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Java Virtual Machine configuration suggestions.
+ */
+public class JvmConfigurationSuggestions {
+    /** */
+    private static final String XMX = "-Xmx";
+
+    /** */
+    private static final String MX = "-mx";
+
+    /** */
+    private static final String MAX_DIRECT_MEMORY_SIZE = "-XX:MaxDirectMemorySize";
+
+    /** */
+    private static final String DISABLE_EXPLICIT_GC = "-XX:+DisableExplicitGC";
+
+    /** */
+    private static final String NOT_USE_TLAB = "-XX:-UseTLAB";
+
+    /** */
+    private static final String SERVER = "-server";
+
+    /** */
+    private static final String USE_G1_GC = "-XX:+UseG1GC";
+
+    /**
+     * Checks JVM configurations and produces tuning suggestions.
+     *
+     * @return List of suggestions of Java Virtual Machine configuration tuning to increase Ignite performance.
+     */
+    public static synchronized List<String> getSuggestions() {
+        List<String> suggestions = new ArrayList<>();
+
+        List<String> args = U.jvmArgs();
+
+        if (!U.jvmName().toLowerCase().contains("server"))
+            suggestions.add("Enable server mode for JVM (add '" + SERVER + "' to JVM options)");
+
+        if (!U.jdkVersion().equals("1.8"))
+            suggestions.add("Switch to the most recent 1.8 JVM version");
+
+        if (U.jdkVersion().equals("1.8") && !args.contains(USE_G1_GC))
+            suggestions.add("Enable G1 Garbage Collector (add '" + USE_G1_GC + "' to JVM options)");
+
+        if (!anyStartWith(args, XMX) && !anyStartWith(args, MX))
+            suggestions.add("Specify JVM heap max size (add '" + XMX + "<size>[g|G|m|M|k|K]' to JVM options)");
+
+        if (!anyStartWith(args, MAX_DIRECT_MEMORY_SIZE))
+            suggestions.add("Set max direct memory size if getting 'OOME: Direct buffer memory' " +
+                "(add '" + MAX_DIRECT_MEMORY_SIZE + "=<size>[g|G|m|M|k|K]' to JVM options)");
+
+        if (args.contains(NOT_USE_TLAB))
+            suggestions.add("Enable thread-local allocation buffer (add '-XX:+UseTLAB' to JVM options)");
+
+        if (!args.contains(DISABLE_EXPLICIT_GC))
+            suggestions.add("Disable processing of calls to System.gc() (add '" + DISABLE_EXPLICIT_GC + "' to JVM options)");
+
+        return suggestions;
+    }
+
+    /**
+     * @param lines Lines to check.
+     * @param prefix Prefix.
+     * @return {@code True} if found.
+     */
+    private static boolean anyStartWith(@NotNull List<String> lines, @NotNull String prefix) {
+        for (String line : lines) {
+            if (line.startsWith(prefix))
+                return true;
+        }
+
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JvmConfigurationSuggestions.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/suggestions/OsConfigurationSuggestions.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/suggestions/OsConfigurationSuggestions.java b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/OsConfigurationSuggestions.java
new file mode 100644
index 0000000..e5b4c12
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/OsConfigurationSuggestions.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.suggestions;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Operation System configuration suggestions.
+ */
+public class OsConfigurationSuggestions {
+    /** */
+    private static final String VM_PARAMS_BASE_PATH = "/proc/sys/vm/";
+
+    /** */
+    private static final String DIRTY_WRITEBACK_CENTISECS = "dirty_writeback_centisecs";
+
+    /** */
+    private static final String DIRTY_EXPIRE_CENTISECS = "dirty_expire_centisecs";
+
+    /** */
+    private static final String SWAPPINESS = "swappiness";
+
+    /** */
+    private static final String ZONE_RECLAIM_MODE = "zone_reclaim_mode";
+
+    /** */
+    private static final String EXTRA_FREE_KBYTES = "extra_free_kbytes";
+
+    /**
+     * Checks OS configurations and produces tuning suggestions.
+     *
+     * @return List of suggestions of Operation system configuration tuning to increase Ignite performance.
+     */
+    public static synchronized List<String> getSuggestions() {
+        List<String> suggestions = new ArrayList<>();
+
+        if (U.isRedHat()) {
+            String value;
+            String expected = "500";
+
+            boolean dwcParamFlag = (value = readVmParam(DIRTY_WRITEBACK_CENTISECS)) != null && !value.equals(expected);
+            boolean decParamFlag = (value = readVmParam(DIRTY_EXPIRE_CENTISECS)) != null && !value.equals(expected);
+
+            if (dwcParamFlag || decParamFlag)
+                suggestions.add(String.format("Speed up flushing of dirty pages by OS " +
+                        "(alter %s%s%s parameter%s by setting to %s)",
+                    (dwcParamFlag ? "vm." + DIRTY_WRITEBACK_CENTISECS : ""),
+                    (dwcParamFlag && decParamFlag ? " and " : ""),
+                    (decParamFlag ? "vm." + DIRTY_EXPIRE_CENTISECS : ""),
+                    (dwcParamFlag && decParamFlag ? "s" : ""),
+                    expected));
+
+            if ((value = readVmParam(SWAPPINESS)) != null && !value.equals(expected = "10"))
+                suggestions.add(String.format("Reduce pages swapping ratio (set vm.%s=%s)", SWAPPINESS, expected));
+
+            if ((value = readVmParam(ZONE_RECLAIM_MODE)) != null && !value.equals(expected = "0"))
+                suggestions.add(String.format("Disable NUMA memory reclaim (set vm.%s=%s)", ZONE_RECLAIM_MODE,
+                    expected));
+
+            if ((value = readVmParam(EXTRA_FREE_KBYTES)) != null && !value.equals(expected = "1240000"))
+                suggestions.add(String.format("Avoid direct reclaim and page allocation failures (set vm.%s=%s)",
+                    EXTRA_FREE_KBYTES, expected));
+        }
+
+        return suggestions;
+    }
+
+    /**
+     * @param name Parameter name.
+     * @return Value (possibly null).
+     */
+    @Nullable private static String readVmParam(@NotNull String name) {
+        try {
+            Path path = Paths.get(VM_PARAMS_BASE_PATH + name);
+
+            if (!Files.exists(path))
+                return null;
+
+            return readLine(path);
+        }
+        catch (Exception ignored) {
+            return null;
+        }
+    }
+
+    /**
+     * @param path Path.
+     * @return Read line.
+     * @throws IOException If failed.
+     */
+    @Nullable private static String readLine(@NotNull Path path) throws IOException {
+        try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
+            return reader.readLine();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(OsConfigurationSuggestions.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/suggestions/package-info.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/suggestions/package-info.java b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/package-info.java
new file mode 100644
index 0000000..baced67
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/suggestions/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Contains classes for configurations suggestions.
+ */
+package org.apache.ignite.internal.suggestions;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3459bdd3/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 653302c..f6c8163 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -73,6 +73,8 @@ import java.nio.channels.FileLock;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.KeyManagementException;
 import java.security.MessageDigest;
@@ -366,6 +368,9 @@ public abstract class IgniteUtils {
     /** Indicates whether current OS is Mac OS. */
     private static boolean mac;
 
+    /** Indicates whether current OS is of RedHat family. */
+    private static boolean redHat;
+
     /** Indicates whether current OS architecture is Sun Sparc. */
     private static boolean sparc;
 
@@ -525,6 +530,8 @@ public abstract class IgniteUtils {
             assertionsEnabled = assertionsEnabled0;
         }
 
+        redHat = Files.exists(Paths.get("/etc/redhat-release")); // RedHat family OS (Fedora, CentOS, RedHat)
+
         String osName = System.getProperty("os.name");
 
         String osLow = osName.toLowerCase();
@@ -6282,6 +6289,13 @@ public abstract class IgniteUtils {
     }
 
     /**
+     * @return {@code True} if current OS is RedHat.
+     */
+    public static boolean isRedHat() {
+        return redHat;
+    }
+
+    /**
      * Indicates whether current OS is Netware.
      *
      * @return {@code true} if current OS is Netware - {@code false} otherwise.


[34/50] [abbrv] ignite git commit: IGNITE-1680: CPP: Implemented API for user entry point lookup. This closes #1430.

Posted by sb...@apache.org.
IGNITE-1680: CPP: Implemented API for user entry point lookup. This closes #1430.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 1410900f2c0e2f8819a1fb945109ca0d88f3a2f9
Parents: 9ce099c
Author: isapego <ig...@gmail.com>
Authored: Fri Feb 10 15:52:02 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Feb 10 15:52:02 2017 +0300

----------------------------------------------------------------------
 .../platform/PlatformProcessorImpl.java         |   9 -
 .../cache/PlatformCacheEntryProcessorImpl.java  |   6 +-
 .../include/ignite/binary/binary_object.h       |  22 +-
 .../binary/include/ignite/binary/binary_type.h  |   8 +-
 .../include/ignite/impl/binary/binary_common.h  |   6 +
 .../ignite/impl/binary/binary_object_header.h   |   9 +-
 .../ignite/impl/binary/binary_object_impl.h     |  61 +-
 .../ignite/impl/binary/binary_reader_impl.h     |  29 +-
 .../ignite/impl/binary/binary_type_updater.h    |   2 +-
 .../binary/binary_array_identity_resolver.cpp   |   2 +-
 .../src/impl/binary/binary_object_header.cpp    |  26 +-
 .../src/impl/binary/binary_object_impl.cpp      |  61 +-
 .../src/impl/binary/binary_type_manager.cpp     |   2 +-
 modules/platforms/cpp/common/Makefile.am        |   1 +
 .../common/include/ignite/common/concurrent.h   |  29 +-
 .../include/ignite/common/platform_utils.h      |   6 +-
 .../cpp/common/include/ignite/ignite_error.h    |   2 +-
 .../include/ignite/common/dynamic_load_os.h     | 131 +++++
 .../os/linux/src/common/dynamic_load_os.cpp     |  90 +++
 .../os/linux/src/common/platform_utils.cpp      |  18 +-
 .../win/include/ignite/common/dynamic_load_os.h | 133 +++++
 .../os/win/src/common/dynamic_load_os.cpp       | 115 ++++
 .../common/os/win/src/common/platform_utils.cpp |  26 +-
 .../cpp/common/project/vs/common.vcxproj        |   2 +
 .../common/project/vs/common.vcxproj.filters    |   6 +
 .../platforms/cpp/common/src/common/utils.cpp   |   3 +-
 .../platforms/cpp/common/src/ignite_error.cpp   |  68 +--
 modules/platforms/cpp/core-test/Makefile.am     |   5 +-
 .../core-test/include/ignite/binary_test_defs.h | 106 ++--
 .../cpp/core-test/project/vs/core-test.vcxproj  |   2 +
 .../project/vs/core-test.vcxproj.filters        |   6 +
 .../cpp/core-test/src/binary_object_test.cpp    |   6 +-
 .../src/binary_reader_writer_raw_test.cpp       |  23 +-
 .../cpp/core-test/src/cache_invoke_test.cpp     | 553 +++++++++++++++++++
 .../platforms/cpp/core-test/src/cache_test.cpp  |   5 +-
 .../cpp/core-test/src/cluster_test.cpp          |  98 ++++
 .../cpp/core-test/src/interop_memory_test.cpp   |   3 +-
 modules/platforms/cpp/core/Makefile.am          |   1 +
 modules/platforms/cpp/core/include/Makefile.am  |   8 +
 .../cpp/core/include/ignite/cache/cache.h       | 217 ++++++--
 .../ignite/cache/cache_entry_processor.h        | 111 ++++
 .../include/ignite/cache/mutable_cache_entry.h  | 176 ++++++
 .../include/ignite/cache/query/query_cursor.h   |   2 +-
 .../platforms/cpp/core/include/ignite/ignite.h  |  18 +
 .../cpp/core/include/ignite/ignite_binding.h    | 119 ++++
 .../include/ignite/ignite_binding_context.h     |  88 +++
 .../core/include/ignite/ignite_configuration.h  |   2 -
 .../impl/binary/binary_type_updater_impl.h      |   2 +-
 .../impl/cache/cache_entry_processor_holder.h   | 282 ++++++++++
 .../core/include/ignite/impl/cache/cache_impl.h |  71 +--
 .../ignite/impl/cluster/cluster_group_impl.h    |  77 +++
 .../include/ignite/impl/ignite_binding_impl.h   | 121 ++++
 .../include/ignite/impl/ignite_environment.h    |  61 +-
 .../cpp/core/include/ignite/impl/ignite_impl.h  |  50 +-
 .../ignite/impl/interop/interop_target.h        |  37 +-
 .../core/include/ignite/impl/module_manager.h   | 131 +++++
 .../cpp/core/include/ignite/impl/operations.h   |  62 +--
 .../platforms/cpp/core/project/vs/core.vcxproj  |   9 +
 .../cpp/core/project/vs/core.vcxproj.filters    |  30 +
 modules/platforms/cpp/core/src/ignite.cpp       |  12 +-
 modules/platforms/cpp/core/src/ignition.cpp     | 343 +++++++-----
 .../impl/binary/binary_type_updater_impl.cpp    |   2 +-
 .../cpp/core/src/impl/cache/cache_impl.cpp      |  66 ++-
 .../continuous/continuous_query_handle_impl.cpp |   2 +-
 .../core/src/impl/cache/query/query_impl.cpp    |   8 +-
 .../src/impl/cluster/cluster_group_impl.cpp     |  64 +++
 .../cpp/core/src/impl/ignite_environment.cpp    |  92 ++-
 .../platforms/cpp/core/src/impl/ignite_impl.cpp |  32 +-
 .../core/src/impl/interop/interop_target.cpp    |  49 +-
 .../src/impl/transactions/transactions_impl.cpp |  14 +-
 .../platforms/cpp/jni/include/ignite/jni/java.h |   2 +-
 .../cpp/jni/include/ignite/jni/utils.h          |  69 ++-
 .../platforms/cpp/jni/os/linux/src/utils.cpp    | 221 ++++----
 modules/platforms/cpp/jni/os/win/src/utils.cpp  | 227 ++++----
 modules/platforms/cpp/jni/src/java.cpp          |  53 +-
 .../Impl/Unmanaged/UnmanagedCallbacks.cs        |   5 +-
 76 files changed, 3821 insertions(+), 795 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
index 63fdc18..a3d01c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
@@ -214,15 +214,6 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
 
     /** {@inheritDoc} */
     @Override public PlatformContext context() {
-        // This method is a single point of entry for all remote closures
-        // CPP platform does not currently support remote code execution
-        // Therefore, all remote execution attempts come from .NET
-        // Throw an error if current platform is not .NET
-        if (!PlatformUtils.PLATFORM_DOTNET.equals(interopCfg.platform())) {
-            throw new IgniteException(".NET platform is not available [nodeId=" + ctx.grid().localNode().id() + "] " +
-                "(Use Apache.Ignite.Core.Ignition.Start() or Apache.Ignite.exe to start Ignite.NET nodes).");
-        }
-
         return platformCtx;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
index 31dd267..9388855 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheEntryProcessorImpl.java
@@ -143,9 +143,6 @@ public class PlatformCacheEntryProcessorImpl implements PlatformCacheEntryProces
      * @param writer Writer.
      */
     private void writeEntryAndProcessor(MutableEntry entry, BinaryRawWriter writer) {
-        writer.writeObject(entry.getKey());
-        writer.writeObject(entry.getValue());
-
         if (ptr != 0) {
             // Execute locally - we have a pointer to native processor.
             writer.writeBoolean(true);
@@ -156,6 +153,9 @@ public class PlatformCacheEntryProcessorImpl implements PlatformCacheEntryProces
             writer.writeBoolean(false);
             writer.writeObject(proc);
         }
+
+        writer.writeObject(entry.getKey());
+        writer.writeObject(entry.getValue());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
index 08b503e..12ac938 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
@@ -39,7 +39,7 @@ namespace ignite
          * This is a thin wrapper over the memory area that contains serialized
          * binary object. Provides method that allows deserialize object.
          */
-        class IGNITE_IMPORT_EXPORT BinaryObject : private impl::binary::BinaryObjectImpl
+        class IGNITE_IMPORT_EXPORT BinaryObject
         {
             friend class BinaryArrayIdentityResolver;
         public:
@@ -47,11 +47,22 @@ namespace ignite
             /**
              * Constructor.
              *
+             * @param impl Implementation.
+             */
+            BinaryObject(const impl::binary::BinaryObjectImpl& impl) :
+                impl(impl)
+            {
+                // No-op.
+            };
+
+            /**
+             * Constructor.
+             *
              * @param mem Binary object memory.
              * @param start Object starting position in memory.
              */
-            BinaryObject(impl::interop::InteropMemory& mem, int32_t start) : 
-                BinaryObjectImpl(mem, start)
+            BinaryObject(impl::interop::InteropMemory& mem, int32_t start) :
+                impl(mem, start)
             {
                 // No-op.
             };
@@ -66,10 +77,13 @@ namespace ignite
             template<typename T>
             T Deserialize() const
             {
-                return impl::binary::BinaryObjectImpl::Deserialize<T>();
+                return impl.Deserialize<T>();
             }
 
         private:
+            /** Implementation. */
+            impl::binary::BinaryObjectImpl impl;
+
             IGNITE_NO_COPY_ASSIGNMENT(BinaryObject)
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
index 1c37f6d..f65c652 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
@@ -172,7 +172,7 @@ namespace ignite
              *
              * @return Type name.
              */
-            std::string GetTypeName() 
+            std::string GetTypeName()
             {
                 IGNITE_ERROR_1(IgniteError::IGNITE_ERR_BINARY, "GetTypeName function is not defined for binary type.");
             }
@@ -244,9 +244,9 @@ namespace ignite
             /**
              * Constructor.
              */
-            BinaryType()
+            BinaryType() : typ()
             {
-                typ = BinaryType<T>();
+                // No-op.
             }
 
             int32_t GetTypeId()
@@ -285,7 +285,7 @@ namespace ignite
 
             T* GetNull()
             {
-                return NULL;
+                return 0;
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
index 462bc5b..aa15cc5 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_common.h
@@ -62,6 +62,12 @@ namespace ignite
             /** Full header length. */
             const int32_t IGNITE_DFLT_HDR_LEN = 24;
 
+            /** Binary header length. */
+            const int32_t IGNITE_BINARY_HDR_LEN = 5;
+
+            /** Common header length. */
+            const int32_t IGNITE_COMMON_HDR_LEN = 1;
+
             /** Type: object. */
             const int8_t IGNITE_TYPE_OBJECT = IGNITE_HDR_FULL;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
index 5ba1960..8e74de6 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
@@ -43,7 +43,7 @@ namespace ignite
             /**
              * Binary object header layout.
              */
-            struct IGNITE_IMPORT_EXPORT BinaryObjectHeaderLayout
+            struct BinaryObjectHeaderLayout
             {
                 int8_t  headerType;
                 int8_t  version;
@@ -239,6 +239,13 @@ namespace ignite
                     return GetFooterOffset() - SIZE;
                 }
 
+                /**
+                 * Get underlying memory.
+                 *
+                 * @return Underlying memory.
+                 */
+                int8_t* GetMem();
+
             private:
                 /** Header layout */
                 BinaryObjectHeaderLayout* header;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
index efe1f49..0eb0dd6 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
@@ -54,6 +54,42 @@ namespace ignite
                 BinaryObjectImpl(interop::InteropMemory& mem, int32_t start);
 
                 /**
+                 * Copy constructor.
+                 *
+                 * @param other Another instance.
+                 */
+                BinaryObjectImpl(const BinaryObjectImpl& other);
+
+                /**
+                 * Assignment operator.
+                 *
+                 * @param other Another instance.
+                 * @return *this.
+                 */
+                BinaryObjectImpl& operator=(const BinaryObjectImpl& other);
+
+                /**
+                 * Create from InteropMemory instance.
+                 * @throw IgniteError if the memory at the specified offset
+                 *    is not a valid BinaryObject.
+                 *
+                 * @param mem Memory.
+                 * @param offset Offset in memory.
+                 * @return BinaryObjectImpl instance.
+                 */
+                static BinaryObjectImpl FromMemory(interop::InteropMemory& mem, int32_t offset);
+
+                /**
+                 * Create from InteropMemory instance.
+                 * @warning Does not check memory for validity.
+                 *
+                 * @param mem Memory.
+                 * @param offset Offset in memory.
+                 * @return BinaryObjectImpl instance.
+                 */
+                static BinaryObjectImpl FromMemoryUnsafe(interop::InteropMemory& mem, int32_t offset);
+
+                /**
                  * Deserialize object.
                  * @throw IgniteError if the object can not be deserialized to specified type.
                  *
@@ -62,7 +98,7 @@ namespace ignite
                 template<typename T>
                 T Deserialize() const
                 {
-                    interop::InteropInputStream stream(&mem);
+                    interop::InteropInputStream stream(mem);
 
                     stream.Position(start);
                     BinaryReaderImpl reader(&stream);
@@ -71,6 +107,17 @@ namespace ignite
                 }
 
                 /**
+                 * Get binary object field.
+                 *
+                 * @warning Works only if all object fields are objects.
+                 *     Otherwise behavior is undefined.
+                 *
+                 * @param idx Field index. Starts from 0.
+                 * @return Binary object field.
+                 */
+                BinaryObjectImpl GetField(int32_t idx);
+
+                /**
                  * Get object data.
                  *
                  * @return Pointer to object data.
@@ -86,6 +133,14 @@ namespace ignite
                 int32_t GetLength() const;
 
                 /**
+                 * Get type ID.
+                 * @throw IgniteError if the object is not in a valid state.
+                 *
+                 * @return Type ID.
+                 */
+                int32_t GetTypeId() const;
+
+                /**
                  * Get object hash code.
                  * @throw IgniteError if the object is not in a valid state.
                  *
@@ -94,10 +149,8 @@ namespace ignite
                 int32_t GetHashCode() const;
 
             private:
-                IGNITE_NO_COPY_ASSIGNMENT(BinaryObjectImpl)
-
                 /** Underlying object memory. */
-                interop::InteropMemory& mem;
+                interop::InteropMemory* mem;
 
                 /** Object starting position in memory. */
                 int32_t start;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
index cd32203..814651d 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
@@ -808,6 +808,28 @@ namespace ignite
                 }
 
                 /**
+                 * Try read object.
+                 * Reads value, stores it to res and returns true if the value is
+                 * not null. Otherwise just returns false.
+                 *
+                 * @param res Read value is placed here if non-null.
+                 * @return True if the non-null value has been read and false
+                 *     otherwise.
+                 */
+                template<typename T>
+                bool TryReadObject(T& res)
+                {
+                    CheckRawMode(true);
+
+                    if (SkipIfNull())
+                        return false;
+
+                    res = ReadObject<T>();
+
+                    return true;
+                }
+
+                /**
                  * Set raw mode.
                  */
                 void SetRawMode();
@@ -896,7 +918,8 @@ namespace ignite
 
                             int32_t footerEnd;
 
-                            if (flags & IGNITE_BINARY_FLAG_HAS_RAW)
+                            if (flags & IGNITE_BINARY_FLAG_HAS_RAW &&
+                                flags & IGNITE_BINARY_FLAG_HAS_SCHEMA)
                             {
                                 // 4 is the size of RawOffset field at the end of the packet.
                                 footerEnd = pos + len - 4;
@@ -910,7 +933,7 @@ namespace ignite
                                 rawOff = schemaOrRawOff;
                             }
 
-                            bool usrType = flags & IGNITE_BINARY_FLAG_USER_TYPE;
+                            bool usrType = (flags & IGNITE_BINARY_FLAG_USER_TYPE) != 0;
 
                             ignite::binary::BinaryType<T> type;
                             TemplatedBinaryIdResolver<T> idRslvr(type);
@@ -929,7 +952,7 @@ namespace ignite
                         default:
                         {
                             IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_BINARY, 
-                                           "Unexpected header during deserialization: ", static_cast<int>(hdr));
+                                           "Unexpected header during deserialization: ", (hdr & 0xFF));
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
index 5bd1d7e..6bded74 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_updater.h
@@ -44,7 +44,7 @@ namespace ignite
                  * @param snapshot Snapshot.
                  * @param err Error.
                  */
-                virtual bool Update(Snap* snapshot, IgniteError* err) = 0;
+                virtual bool Update(Snap* snapshot, IgniteError& err) = 0;
             };
         }
     }    

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp b/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
index 1d4e384..6338842 100644
--- a/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
+++ b/modules/platforms/cpp/binary/src/binary/binary_array_identity_resolver.cpp
@@ -36,7 +36,7 @@ namespace ignite
 
         int32_t BinaryArrayIdentityResolver::GetHashCode(const BinaryObject& obj)
         {
-            return impl::binary::BinaryUtils::GetDataHashCode(obj.GetData(), obj.GetLength());
+            return impl::binary::BinaryUtils::GetDataHashCode(obj.impl.GetData(), obj.impl.GetLength());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
index aef095f..3a9d182 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
@@ -18,6 +18,7 @@
 #include <ignite/ignite_error.h>
 
 #include <ignite/impl/binary/binary_object_header.h>
+#include <ignite/impl/binary/binary_utils.h>
 
 namespace ignite
 {
@@ -31,20 +32,31 @@ namespace ignite
                 {
                     IGNITE_ERROR_FORMATTED_3(ignite::IgniteError::IGNITE_ERR_MEMORY,
                         "Not enough data in the binary object", "memPtr", mem.PointerLong(),
-                        "len", mem.Length(), "headerLen", SIZE);
+                        "len", (mem.Length() - offset), "headerLen", static_cast<int>(SIZE));
                 }
 
-                BinaryObjectHeader hdr(mem.Data() + offset);
+                int8_t type = BinaryUtils::UnsafeReadInt8(mem, offset);
+                if (type == impl::binary::IGNITE_TYPE_BINARY)
+                {
+                    int32_t binLen = BinaryUtils::UnsafeReadInt32(mem, offset + IGNITE_COMMON_HDR_LEN);
+                    int32_t binOff = BinaryUtils::ReadInt32(mem, offset + IGNITE_BINARY_HDR_LEN + binLen);
 
-                int8_t type = hdr.GetType();
-                if (type != impl::binary::IGNITE_TYPE_OBJECT)
+                    return BinaryObjectHeader::FromMemory(mem, offset + IGNITE_BINARY_HDR_LEN + binOff);
+                }
+                else if (type != impl::binary::IGNITE_TYPE_OBJECT)
                 {
                     IGNITE_ERROR_FORMATTED_3(ignite::IgniteError::IGNITE_ERR_MEMORY,
-                        "Not enough data in the binary object", "memPtr", mem.PointerLong(),
-                        "type", type, "expected", impl::binary::IGNITE_TYPE_OBJECT);
+                        "Not expected type header of the binary object", "memPtr", mem.PointerLong(),
+                        "type", (type & 0xFF),
+                        "expected", (impl::binary::IGNITE_TYPE_OBJECT & 0xFF));
                 }
 
-                return hdr;
+                return BinaryObjectHeader(mem.Data() + offset);
+            }
+
+            int8_t* BinaryObjectHeader::GetMem()
+            {
+                return reinterpret_cast<int8_t*>(header);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
index 8167f8b..0b397b1 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
@@ -26,28 +26,79 @@ namespace ignite
     {
         namespace binary
         {
-            BinaryObjectImpl::BinaryObjectImpl(impl::interop::InteropMemory& mem, int32_t start) :
-                mem(mem),
+            BinaryObjectImpl::BinaryObjectImpl(interop::InteropMemory& mem, int32_t start) :
+                mem(&mem),
                 start(start)
             {
                 // No-op.
             }
 
+            BinaryObjectImpl::BinaryObjectImpl(const BinaryObjectImpl& other) :
+                mem(other.mem),
+                start(other.start)
+            {
+                // No-op.
+            }
+
+            BinaryObjectImpl& BinaryObjectImpl::operator=(const BinaryObjectImpl& other)
+            {
+                mem = other.mem;
+
+                return *this;
+            }
+
+            BinaryObjectImpl BinaryObjectImpl::FromMemory(interop::InteropMemory& mem, int32_t offset)
+            {
+                BinaryObjectHeader header = BinaryObjectHeader::FromMemory(mem, offset);
+
+                int32_t adjustedStart = static_cast<int32_t>(header.GetMem() - mem.Data());
+
+                assert(adjustedStart >= 0);
+
+                return BinaryObjectImpl(mem, adjustedStart);
+            }
+
+            BinaryObjectImpl BinaryObjectImpl::FromMemoryUnsafe(interop::InteropMemory& mem, int32_t offset)
+            {
+                return BinaryObjectImpl(mem, offset);
+            }
+
+            BinaryObjectImpl BinaryObjectImpl::GetField(int32_t idx)
+            {
+                int32_t offset = start + BinaryObjectHeader::SIZE;
+
+                for (int32_t i = 0; i < idx; ++i)
+                {
+                    BinaryObjectHeader fieldHeader = BinaryObjectHeader::FromMemory(*mem, offset);
+
+                    offset += fieldHeader.GetLength();
+                }
+
+                return BinaryObjectImpl::FromMemory(*mem, offset);
+            }
+
             const int8_t* BinaryObjectImpl::GetData() const
             {
-                return mem.Data() + start + BinaryObjectHeader::SIZE;
+                return mem->Data() + start + BinaryObjectHeader::SIZE;
             }
 
             int32_t BinaryObjectImpl::GetLength() const
             {
-                BinaryObjectHeader header = BinaryObjectHeader::FromMemory(mem, start);
+                BinaryObjectHeader header(mem->Data() + start);
 
                 return header.GetDataLength();
             }
 
+            int32_t BinaryObjectImpl::GetTypeId() const
+            {
+                BinaryObjectHeader header(mem->Data() + start);
+
+                return header.GetTypeId();
+            }
+
             int32_t BinaryObjectImpl::GetHashCode() const
             {
-                BinaryObjectHeader header = BinaryObjectHeader::FromMemory(mem, start);
+                BinaryObjectHeader header(mem->Data() + start);
 
                 return header.GetHashCode();
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
index a6692d1..2a7b617 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
@@ -113,7 +113,7 @@ namespace ignite
                 {
                     Snap* pendingSnap = it->Get();
 
-                    if (updater->Update(pendingSnap, err))
+                    if (updater->Update(pendingSnap, *err))
                     {
                         // Perform copy-on-write update of snapshot collection.
                         std::map<int32_t, SPSnap>* newSnapshots = new std::map<int32_t, SPSnap>();

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/Makefile.am b/modules/platforms/cpp/common/Makefile.am
index 8c79c3e..c4f4827 100644
--- a/modules/platforms/cpp/common/Makefile.am
+++ b/modules/platforms/cpp/common/Makefile.am
@@ -44,6 +44,7 @@ libignite_common_la_LDFLAGS = \
 libignite_common_la_SOURCES = \
     os/linux/src/common/concurrent_os.cpp \
     os/linux/src/common/platform_utils.cpp \
+    os/linux/src/common/dynamic_load_os.cpp \
     src/common/big_integer.cpp \
     src/common/concurrent.cpp \
     src/common/decimal.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/include/ignite/common/concurrent.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/concurrent.h b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
index ff0e54a..84a1f0e 100644
--- a/modules/platforms/cpp/common/include/ignite/common/concurrent.h
+++ b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
@@ -401,7 +401,7 @@ namespace ignite
                  * @param lock Lockable object.
                  */
                 LockGuard(T& lock) :
-                    lock(lock)
+                    lock(&lock)
                 {
                     lock.Enter();
                 }
@@ -411,11 +411,34 @@ namespace ignite
                  */
                 ~LockGuard()
                 {
-                    lock.Leave();
+                    if (lock)
+                        lock->Leave();
+                }
+
+                /**
+                 * Releases control over lock without unlocking it.
+                 */
+                void Forget()
+                {
+                    lock = 0;
+                }
+
+                /**
+                 * Releases control over lock and unlocks it as if it would
+                 * go out of scope.
+                 */
+                void Reset()
+                {
+                    if (lock)
+                    {
+                        lock->Leave();
+
+                        Forget();
+                    }
                 }
 
             private:
-                T& lock;
+                T* lock;
             };
 
             typedef LockGuard<CriticalSection> CsLockGuard;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
index 273a5e0..8674ce3 100644
--- a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
+++ b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
@@ -61,10 +61,10 @@ namespace ignite
          * Read system environment variable taking thread-safety in count.
          *
          * @param name Environment variable name.
-         * @param found Whether environment variable with such name was found.
-         * @return Environment variable value.
+         * @param val Environment variable value.
+         * @return True if the environment variable with such name was found.
          */
-        IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name, bool& found);
+        IGNITE_IMPORT_EXPORT bool GetEnv(const std::string& name, std::string& val);
 
         /**
          * Ensure that file on the given path exists in the system.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/include/ignite/ignite_error.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/ignite_error.h b/modules/platforms/cpp/common/include/ignite/ignite_error.h
index 4c5c06e..cecaf3f 100644
--- a/modules/platforms/cpp/common/include/ignite/ignite_error.h
+++ b/modules/platforms/cpp/common/include/ignite/ignite_error.h
@@ -277,7 +277,7 @@ namespace ignite
          * @param jniMsg Error message.
          * @param err Error. Can not be NULL.
          */
-        static void SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError* err);
+        static void SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError& err);
     private:
         /** Error code. */
         int32_t code;    

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h b/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h
new file mode 100644
index 0000000..af07e57
--- /dev/null
+++ b/modules/platforms/cpp/common/os/linux/include/ignite/common/dynamic_load_os.h
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_COMMON_DYNAMIC_LOAD
+#define _IGNITE_COMMON_DYNAMIC_LOAD
+
+#include <string>
+
+#include "ignite/common/common.h"
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            /**
+             * Represents dynamically loadable program module such as dymanic
+             * or shared library.
+             */
+            class IGNITE_IMPORT_EXPORT Module
+            {
+            public:
+                /**
+                 * Default constructor.
+                 */
+                Module();
+
+                /**
+                 * Handle constructor.
+                 *
+                 * @param handle Os-specific Module handle.
+                 */
+                Module(void* handle);
+
+                /**
+                 * Destructor.
+                 */
+                ~Module();
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 */
+                Module(const Module& other);
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 * @return This.
+                 */
+                Module& operator=(const Module& other);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const char* name);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const std::string& name)
+                {
+                    return FindSymbol(name.c_str());
+                }
+
+                /**
+                 * Check if the instance is loaded.
+                 *
+                 * @return True if the instance is loaded.
+                 */
+                bool IsLoaded() const;
+
+                /**
+                 * Unload module.
+                 */
+                void Unload();
+
+            private:
+                void* handle;
+            };
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const char* path);
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const std::string& path);
+
+            /**
+             * Returns Module associated with the calling process itself.
+             *
+             * @return Module for the calling process.
+             */
+            IGNITE_IMPORT_EXPORT Module GetCurrent();
+        }
+    }
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp b/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp
new file mode 100644
index 0000000..3ba562e
--- /dev/null
+++ b/modules/platforms/cpp/common/os/linux/src/common/dynamic_load_os.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#include <dlfcn.h>
+
+#include <sstream>
+#include "ignite/common/dynamic_load_os.h"
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            Module::Module() : handle(NULL)
+            {
+                // No-op.
+            }
+
+            Module::Module(void* handle) : handle(handle)
+            {
+                // No-op.
+            }
+
+            Module::~Module()
+            {
+                // No-op.
+            }
+
+            Module::Module(const Module& other) : handle(other.handle)
+            {
+                // No-op.
+            }
+
+            Module& Module::operator=(const Module& other)
+            {
+                handle = other.handle;
+
+                return *this;
+            }
+
+            void* Module::FindSymbol(const char* name)
+            {
+                return dlsym(handle, name);
+            }
+
+            bool Module::IsLoaded() const
+            {
+                return handle != NULL;
+            }
+
+            void Module::Unload()
+            {
+                if (IsLoaded())
+                    dlclose(handle);
+            }
+
+            Module LoadModule(const char* path)
+            {
+                void* handle = dlopen(path, RTLD_NOW);
+
+                return Module(handle);
+            }
+
+            Module LoadModule(const std::string& path)
+            {
+                return LoadModule(path.c_str());
+            }
+
+            Module GetCurrent()
+            {
+                return LoadModule(NULL);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
index a3e1d17..3e8d0c9 100644
--- a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
@@ -51,22 +51,16 @@ namespace ignite
             return localtime_r(&in, &out) == 0;
         }
 
-        std::string GetEnv(const std::string& name, bool& found)
+        bool GetEnv(const std::string& name, std::string& val)
         {
-            char* val = std::getenv(name.c_str());
+            char* val0 = std::getenv(name.c_str());
 
-            if (val)
-            {
-                found = true;
+            if (!val0)
+                return false;
 
-                return std::string(val);
-            }
-            else
-            {
-                found = false;
+            val = val0;
 
-                return std::string();
-            }
+            return true;
         }
 
         bool FileExists(const std::string& path)

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h b/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h
new file mode 100644
index 0000000..1936e21
--- /dev/null
+++ b/modules/platforms/cpp/common/os/win/include/ignite/common/dynamic_load_os.h
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_COMMON_DYNAMIC_LOAD
+#define _IGNITE_COMMON_DYNAMIC_LOAD
+
+#include <Windows.h>
+
+#include <string>
+
+#include "ignite/common/common.h"
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            /**
+             * Represents dynamically loadable program module such as dymanic
+             * or shared library.
+             */
+            class IGNITE_IMPORT_EXPORT Module
+            {
+            public:
+                /**
+                 * Default constructor.
+                 */
+                Module();
+
+                /**
+                 * Handle constructor.
+                 *
+                 * @param handle Os-specific Module handle.
+                 */
+                Module(HMODULE handle);
+
+                /**
+                 * Destructor.
+                 */
+                ~Module();
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 */
+                Module(const Module& other);
+
+                /**
+                 * Copy constructor.
+                 *
+                 * @param other Other instance.
+                 * @return This.
+                 */
+                Module& operator=(const Module& other);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const char* name);
+
+                /**
+                 * Load symbol from Module.
+                 *
+                 * @param name Name of the symbol to load.
+                 * @return Pointer to symbol if found and NULL otherwise.
+                 */
+                void* FindSymbol(const std::string& name)
+                {
+                    return FindSymbol(name.c_str());
+                }
+
+                /**
+                 * Check if the instance is loaded.
+                 *
+                 * @return True if the instance is loaded.
+                 */
+                bool IsLoaded() const;
+
+                /**
+                 * Unload module.
+                 */
+                void Unload();
+
+            private:
+                HMODULE handle;
+            };
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const char* path);
+
+            /**
+             * Load Module by the specified path.
+             *
+             * @param path Path to the Module to load.
+             * @return Module instance.
+             */
+            IGNITE_IMPORT_EXPORT Module LoadModule(const std::string& path);
+
+            /**
+             * Returns Module associated with the calling process itself.
+             *
+             * @return Module for the calling process.
+             */
+            IGNITE_IMPORT_EXPORT Module GetCurrent();
+        }
+    }
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp b/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
new file mode 100644
index 0000000..f7812cd
--- /dev/null
+++ b/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+#include <sstream>
+#include <vector>
+
+#include "ignite/common/dynamic_load_os.h"
+
+namespace
+{
+    std::wstring StringToWstring(const std::string& str)
+    {
+        int wslen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast<int>(str.size()), NULL, 0);
+
+        if (!wslen)
+            return std::wstring();
+
+        std::vector<WCHAR> converted(wslen);
+
+        MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast<int>(str.size()), &converted[0], wslen);
+
+        std::wstring res(converted.begin(), converted.end());
+
+        return res;
+    }
+}
+
+namespace ignite
+{
+    namespace common
+    {
+        namespace dynamic
+        {
+            Module::Module() : handle(NULL)
+            {
+                // No-op.
+            }
+
+            Module::Module(HMODULE handle) : handle(handle)
+            {
+                // No-op.
+            }
+
+            Module::~Module()
+            {
+                // No-op.
+            }
+
+            Module::Module(const Module& other) : handle(other.handle)
+            {
+                // No-op.
+            }
+
+            Module& Module::operator=(const Module& other)
+            {
+                handle = other.handle;
+
+                return *this;
+            }
+
+            void* Module::FindSymbol(const char* name)
+            {
+                return GetProcAddress(handle, name);
+            }
+
+            bool Module::IsLoaded() const
+            {
+                return handle != NULL;
+            }
+
+            void Module::Unload()
+            {
+                if (IsLoaded())
+                    FreeLibrary(handle);
+            }
+
+            Module LoadModule(const char* path)
+            {
+                std::string strPath(path);
+
+                return LoadModule(strPath);
+            }
+
+            Module LoadModule(const std::string& path)
+            {
+                std::wstring convertedPath = StringToWstring(path);
+
+                HMODULE handle = LoadLibrary(convertedPath.c_str());
+
+                return Module(handle);
+            }
+
+            Module GetCurrent()
+            {
+                HMODULE handle = GetModuleHandle(NULL);
+
+                return Module(handle);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
index 16fd6ec..b8a445c 100644
--- a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
@@ -49,24 +49,18 @@ namespace ignite
             return localtime_s(&out, &in) == 0;
         }
 
-        std::string GetEnv(const std::string& name, bool& found)
+        bool GetEnv(const std::string& name, std::string& val)
         {
             char res0[32767];
 
-            DWORD envRes = GetEnvironmentVariableA(name.c_str(), res0, 32767);
+            DWORD envRes = GetEnvironmentVariableA(name.c_str(), res0, sizeof(res0) / sizeof(res0[0]));
 
-            if (envRes != 0)
-            {
-                found = true;
+            if (envRes == 0)
+                return false;
 
-                return std::string(res0);
-            }
-            else
-            {
-                found = false;
+            val.assign(res0);
 
-                return std::string();
-            }
+            return true;
         }
 
         bool FileExists(const std::string& path)
@@ -77,12 +71,10 @@ namespace ignite
 
             if (hnd == INVALID_HANDLE_VALUE)
                 return false;
-            else
-            {
-                FindClose(hnd);
 
-                return true;
-            }
+            FindClose(hnd);
+
+            return true;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/project/vs/common.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/project/vs/common.vcxproj b/modules/platforms/cpp/common/project/vs/common.vcxproj
index 7a57ac0..ab9ce53 100644
--- a/modules/platforms/cpp/common/project/vs/common.vcxproj
+++ b/modules/platforms/cpp/common/project/vs/common.vcxproj
@@ -182,10 +182,12 @@
     <ClInclude Include="..\..\include\ignite\timestamp.h" />
     <ClInclude Include="..\..\os\win\include\ignite\common\common.h" />
     <ClInclude Include="..\..\os\win\include\ignite\common\concurrent_os.h" />
+    <ClInclude Include="..\..\os\win\include\ignite\common\dynamic_load_os.h" />
     <ClInclude Include="targetver.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\os\win\src\common\concurrent_os.cpp" />
+    <ClCompile Include="..\..\os\win\src\common\dynamic_load_os.cpp" />
     <ClCompile Include="..\..\os\win\src\common\platform_utils.cpp" />
     <ClCompile Include="..\..\src\common\big_integer.cpp" />
     <ClCompile Include="..\..\src\common\bits.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/project/vs/common.vcxproj.filters b/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
index f08471e..063edd0 100644
--- a/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
+++ b/modules/platforms/cpp/common/project/vs/common.vcxproj.filters
@@ -64,6 +64,9 @@
     <ClInclude Include="..\..\include\ignite\reference.h">
       <Filter>Code</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\os\win\include\ignite\common\dynamic_load_os.h">
+      <Filter>Code\common</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\include\ignite\common\platform_utils.h">
       <Filter>Code\common</Filter>
     </ClInclude>
@@ -96,6 +99,9 @@
     <ClCompile Include="..\..\src\common\bits.cpp">
       <Filter>Code\common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\os\win\src\common\dynamic_load_os.cpp">
+      <Filter>Code\common</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\os\win\src\common\platform_utils.cpp">
       <Filter>Code\common</Filter>
     </ClCompile>

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/src/common/utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/common/utils.cpp b/modules/platforms/cpp/common/src/common/utils.cpp
index 27d2473..2b425c1 100644
--- a/modules/platforms/cpp/common/src/common/utils.cpp
+++ b/modules/platforms/cpp/common/src/common/utils.cpp
@@ -66,11 +66,12 @@ namespace ignite
                 return dest;
             }
 
-            return NULL;
+            return 0;
         }
 
         void ReleaseChars(char* val)
         {
+            // Its OK to delete null-pointer.
             delete[] val;
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/common/src/ignite_error.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/ignite_error.cpp b/modules/platforms/cpp/common/src/ignite_error.cpp
index 3076d7a..d20eda8 100644
--- a/modules/platforms/cpp/common/src/ignite_error.cpp
+++ b/modules/platforms/cpp/common/src/ignite_error.cpp
@@ -95,10 +95,10 @@ namespace ignite
         return GetText();
     }
 
-    void IgniteError::SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError* err)
+    void IgniteError::SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError& err)
     {
         if (jniCode == IGNITE_JNI_ERR_SUCCESS)
-            *err = IgniteError();
+            err = IgniteError();
         else if (jniCode == IGNITE_JNI_ERR_GENERIC)
         {
             // The most common case when we have Java exception "in hands" and must map it to respective code.
@@ -114,8 +114,8 @@ namespace ignite
 
                     if (jniMsg)
                         stream << ": " << jniMsg;
-                    
-                    *err = IgniteError(IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND, stream.str().c_str());
+
+                    err = IgniteError(IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND, stream.str().c_str());
                 }
                 else if (jniCls0.compare("java.lang.NoSuchMethodError") == 0)
                 {
@@ -126,58 +126,58 @@ namespace ignite
                     if (jniMsg)
                         stream << ": " << jniMsg;
 
-                    *err = IgniteError(IGNITE_ERR_JVM_NO_SUCH_METHOD, stream.str().c_str());
+                    err = IgniteError(IGNITE_ERR_JVM_NO_SUCH_METHOD, stream.str().c_str());
                 }
                 else if (jniCls0.compare("java.lang.IllegalArgumentException") == 0)
-                    *err = IgniteError(IGNITE_ERR_ILLEGAL_ARGUMENT, jniMsg);
+                    err = IgniteError(IGNITE_ERR_ILLEGAL_ARGUMENT, jniMsg);
                 else if (jniCls0.compare("java.lang.IllegalStateException") == 0)
-                    *err = IgniteError(IGNITE_ERR_ILLEGAL_STATE, jniMsg);
+                    err = IgniteError(IGNITE_ERR_ILLEGAL_STATE, jniMsg);
                 else if (jniCls0.compare("java.lang.UnsupportedOperationException") == 0)
-                    *err = IgniteError(IGNITE_ERR_UNSUPPORTED_OPERATION, jniMsg);
+                    err = IgniteError(IGNITE_ERR_UNSUPPORTED_OPERATION, jniMsg);
                 else if (jniCls0.compare("java.lang.InterruptedException") == 0)
-                    *err = IgniteError(IGNITE_ERR_INTERRUPTED, jniMsg);
+                    err = IgniteError(IGNITE_ERR_INTERRUPTED, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.cluster.ClusterGroupEmptyException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CLUSTER_GROUP_EMPTY, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CLUSTER_GROUP_EMPTY, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.cluster.ClusterTopologyException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CLUSTER_TOPOLOGY, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CLUSTER_TOPOLOGY, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.compute.ComputeExecutionRejectedException") == 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_EXECUTION_REJECTED, jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_EXECUTION_REJECTED, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.compute.ComputeJobFailoverException") == 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_JOB_FAILOVER, jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_JOB_FAILOVER, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.compute.ComputeTaskCancelledException") == 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_TASK_CANCELLED, jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_TASK_CANCELLED, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.compute.ComputeTaskTimeoutException") == 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_TASK_TIMEOUT, jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_TASK_TIMEOUT, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.compute.ComputeUserUndeclaredException") == 0)
-                    *err = IgniteError(IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, jniMsg);
+                    err = IgniteError(IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, jniMsg);
                 else if (jniCls0.compare("javax.cache.CacheException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE, jniMsg);
                 else if (jniCls0.compare("javax.cache.integration.CacheLoaderException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_LOADER, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_LOADER, jniMsg);
                 else if (jniCls0.compare("javax.cache.integration.CacheWriterException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_WRITER, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_WRITER, jniMsg);
                 else if (jniCls0.compare("javax.cache.processor.EntryProcessorException") == 0)
-                    *err = IgniteError(IGNITE_ERR_ENTRY_PROCESSOR, jniMsg);
+                    err = IgniteError(IGNITE_ERR_ENTRY_PROCESSOR, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.cache.CacheAtomicUpdateTimeoutException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_ATOMIC_UPDATE_TIMEOUT, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_ATOMIC_UPDATE_TIMEOUT, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.cache.CachePartialUpdateException") == 0)
-                    *err = IgniteError(IGNITE_ERR_CACHE_PARTIAL_UPDATE, jniMsg);
+                    err = IgniteError(IGNITE_ERR_CACHE_PARTIAL_UPDATE, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.transactions.TransactionOptimisticException") == 0)
-                    *err = IgniteError(IGNITE_ERR_TX_OPTIMISTIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_OPTIMISTIC, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.transactions.TransactionTimeoutException") == 0)
-                    *err = IgniteError(IGNITE_ERR_TX_TIMEOUT, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_TIMEOUT, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.transactions.TransactionRollbackException") == 0)
-                    *err = IgniteError(IGNITE_ERR_TX_ROLLBACK, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_ROLLBACK, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.transactions.TransactionHeuristicException") == 0)
-                    *err = IgniteError(IGNITE_ERR_TX_HEURISTIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_TX_HEURISTIC, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.IgniteAuthenticationException") == 0)
-                    *err = IgniteError(IGNITE_ERR_AUTHENTICATION, jniMsg);
+                    err = IgniteError(IGNITE_ERR_AUTHENTICATION, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.plugin.security.GridSecurityException") == 0)
-                    *err = IgniteError(IGNITE_ERR_SECURITY, jniMsg);
+                    err = IgniteError(IGNITE_ERR_SECURITY, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.IgniteException") == 0)
-                    *err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
                 else if (jniCls0.compare("org.apache.ignite.IgniteCheckedException") == 0)
-                    *err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
+                    err = IgniteError(IGNITE_ERR_GENERIC, jniMsg);
                 else
                 {
                     std::stringstream stream;
@@ -189,13 +189,13 @@ namespace ignite
 
                     stream << "]";
 
-                    *err = IgniteError(IGNITE_ERR_UNKNOWN, stream.str().c_str());
+                    err = IgniteError(IGNITE_ERR_UNKNOWN, stream.str().c_str());
                 }                    
             }
             else
             {
                 // JNI class name is not available. Something really weird.
-                *err = IgniteError(IGNITE_ERR_UNKNOWN);
+                err = IgniteError(IGNITE_ERR_UNKNOWN);
             }
         }
         else if (jniCode == IGNITE_JNI_ERR_JVM_INIT)
@@ -218,9 +218,9 @@ namespace ignite
 
             stream << "]";
 
-            *err = IgniteError(IGNITE_ERR_JVM_INIT, stream.str().c_str());
+            err = IgniteError(IGNITE_ERR_JVM_INIT, stream.str().c_str());
         }
         else if (jniCode == IGNITE_JNI_ERR_JVM_ATTACH)
-            *err = IgniteError(IGNITE_ERR_JVM_ATTACH, "Failed to attach to JVM.");
+            err = IgniteError(IGNITE_ERR_JVM_ATTACH, "Failed to attach to JVM.");
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/Makefile.am b/modules/platforms/cpp/core-test/Makefile.am
index 566a827..05b00b7 100644
--- a/modules/platforms/cpp/core-test/Makefile.am
+++ b/modules/platforms/cpp/core-test/Makefile.am
@@ -49,7 +49,8 @@ ignite_tests_LDADD = \
     -lboost_chrono
 
 ignite_tests_LDFLAGS = \
-    -static-libtool-libs
+    -static-libtool-libs \
+    -rdynamic
 
 ignite_tests_SOURCES = \
     src/reference_test.cpp \
@@ -62,6 +63,8 @@ ignite_tests_SOURCES = \
     src/ignition_test.cpp \
     src/interop_memory_test.cpp \
     src/interop_test.cpp \
+    src/cluster_test.cpp \
+    src/cache_invoke_test.cpp \
     src/handle_registry_test.cpp \
     src/ignite_error_test.cpp \
     src/binary_test_defs.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
index 42f4539..2965797 100644
--- a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
+++ b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
@@ -84,6 +84,27 @@ namespace ignite_test
                 }
             };
 
+            struct PureRaw
+            {
+                std::string val1;
+                int32_t val2;
+
+                PureRaw() : val1(), val2()
+                {
+                    // No-op.
+                }
+
+                PureRaw(std::string val1, int32_t val2) : val1(val1), val2(val2)
+                {
+                    // No-op.
+                }
+
+                friend bool operator==(const PureRaw& one, const PureRaw& two)
+                {
+                    return one.val1 == two.val1 && one.val2 == two.val2;
+                }
+            };
+
             class DummyIdResolver : public ignite::impl::binary::BinaryIdResolver
             {
             public:
@@ -115,49 +136,41 @@ namespace ignite
         template<>
         struct BinaryType<gt::BinaryDummy>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryDummy");
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryDummy";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryInner& obj)
             {
                 return obj.GetValue();
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryInner& obj)
             {
                 return obj.GetValue() == 0;
             }
 
-            /** <inheritdoc /> */
             gt::BinaryInner GetNull()
             {
                 return gt::BinaryInner(0);
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryDummy& obj)
             {
                 // No-op.
             }
 
-            /** <inheritdoc /> */
             gt::BinaryDummy Read(BinaryReader& reader)
             {
                 return gt::BinaryDummy();
@@ -167,49 +180,41 @@ namespace ignite
         template<> 
         struct BinaryType<gt::BinaryInner>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId() 
             { 
                 return GetBinaryStringHashCode("BinaryInner"); 
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryInner";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name) 
             { 
                 return GetBinaryStringHashCode(name); 
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryInner& obj)
             {
                 return obj.GetValue();
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryInner& obj)
             {
                 return obj.GetValue() == 0;
             }
 
-            /** <inheritdoc /> */
             gt::BinaryInner GetNull()
             {
                 return gt::BinaryInner(0);
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryInner& obj)
             {
                 writer.WriteInt32("val", obj.GetValue());
             }
 
-            /** <inheritdoc /> */
             gt::BinaryInner Read(BinaryReader& reader)
             {
                 int val = reader.ReadInt32("val");
@@ -221,50 +226,42 @@ namespace ignite
         template<>
         struct BinaryType<gt::BinaryOuter>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryOuter");
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryOuter";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryOuter& obj)
             {
                 return obj.GetValue() + obj.GetInner().GetValue();
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryOuter& obj)
             {
                 return obj.GetValue() == 0 && obj.GetInner().GetValue();
             }
 
-            /** <inheritdoc /> */
             gt::BinaryOuter GetNull()
             {
                 return gt::BinaryOuter(0, 0);
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryOuter& obj)
             {
                 writer.WriteObject("inner", obj.GetInner());
                 writer.WriteInt32("val", obj.GetValue());                
             }
 
-            /** <inheritdoc /> */
             gt::BinaryOuter Read(BinaryReader& reader)
             {
                 gt::BinaryInner inner = reader.ReadObject<gt::BinaryInner>("inner");
@@ -277,43 +274,36 @@ namespace ignite
         template<>
         struct BinaryType<gt::BinaryFields>
         {
-            /** <inheritdoc /> */
             int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryFields");
             }
 
-            /** <inheritdoc /> */
             std::string GetTypeName()
             {
                 return "BinaryFields";
             }
 
-            /** <inheritdoc /> */
             int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            /** <inheritdoc /> */
             int32_t GetHashCode(const gt::BinaryFields& obj)
             {
                 return obj.val1 + obj.val2 + obj.rawVal1 + obj.rawVal2;
             }
 
-            /** <inheritdoc /> */
             bool IsNull(const gt::BinaryFields& obj)
             {
                 return false;
             }
 
-            /** <inheritdoc /> */
             gt::BinaryFields GetNull()
             {
                 throw std::runtime_error("Must not be called.");
             }
 
-            /** <inheritdoc /> */
             void Write(BinaryWriter& writer, const gt::BinaryFields& obj)
             {
                 writer.WriteInt32("val1", obj.val1);
@@ -325,7 +315,6 @@ namespace ignite
                 rawWriter.WriteInt32(obj.rawVal2);
             }
 
-            /** <inheritdoc /> */
             gt::BinaryFields Read(BinaryReader& reader)
             {
                 int32_t val1 = reader.ReadInt32("val1");
@@ -339,6 +328,59 @@ namespace ignite
                 return gt::BinaryFields(val1, val2, rawVal1, rawVal2);
             }
         };
+
+        template<>
+        struct BinaryType<gt::PureRaw>
+        {
+            int32_t GetTypeId()
+            {
+                return GetBinaryStringHashCode("PureRaw");
+            }
+
+            std::string GetTypeName()
+            {
+                return "PureRaw";
+            }
+
+            int32_t GetFieldId(const char* name)
+            {
+                return GetBinaryStringHashCode(name);
+            }
+
+            int32_t GetHashCode(const gt::PureRaw& obj)
+            {
+                return GetBinaryStringHashCode(obj.val1.c_str()) ^ obj.val2;
+            }
+
+            bool IsNull(const gt::PureRaw& obj)
+            {
+                return false;
+            }
+
+            gt::PureRaw GetNull()
+            {
+                throw std::runtime_error("Must not be called.");
+            }
+
+            void Write(BinaryWriter& writer, const gt::PureRaw& obj)
+            {
+                BinaryRawWriter rawWriter = writer.RawWriter();
+
+                rawWriter.WriteString(obj.val1);
+                rawWriter.WriteInt32(obj.val2);
+            }
+
+            gt::PureRaw Read(BinaryReader& reader)
+            {
+                BinaryRawReader rawReader = reader.RawReader();
+
+                gt::PureRaw res;
+                res.val1 = rawReader.ReadString();
+                res.val2 = rawReader.ReadInt32();
+
+                return res;
+            }
+        };
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
index d39746e..607b5a0 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
@@ -42,6 +42,8 @@
     <ClCompile Include="..\..\src\binary_object_test.cpp" />
     <ClCompile Include="..\..\src\binary_identity_resolver_test.cpp" />
     <ClCompile Include="..\..\src\cache_test.cpp" />
+    <ClCompile Include="..\..\src\cluster_test.cpp" />
+    <ClCompile Include="..\..\src\cache_invoke_test.cpp" />
     <ClCompile Include="..\..\src\concurrent_test.cpp" />
     <ClCompile Include="..\..\src\decimal_test.cpp" />
     <ClCompile Include="..\..\src\dynamic_size_array_test.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
index 22048b1..9c333eb 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
@@ -55,9 +55,15 @@
     <ClCompile Include="..\..\src\dynamic_size_array_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\cache_invoke_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\interop_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\cluster_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\continuous_query_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/binary_object_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_object_test.cpp b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
index 0a8f948..fb3725f 100644
--- a/modules/platforms/cpp/core-test/src/binary_object_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
@@ -53,7 +53,7 @@ void CheckSimple(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObject obj(mem, 0);
+    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0));
 
     T actual = obj.Deserialize<T>();
 
@@ -67,7 +67,7 @@ void CheckSimpleNP(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObject obj(mem, 0);
+    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0));
 
     T actual = obj.Deserialize<T>();
 
@@ -100,7 +100,7 @@ void CheckData(const T& obj)
     InteropUnpooledMemory mem(1024);
     FillMem<T>(mem, obj);
 
-    BinaryObjectImpl binObj(mem, 0);
+    BinaryObjectImpl binObj(BinaryObjectImpl::FromMemory(mem, 0));
 
     BOOST_REQUIRE_EQUAL(binObj.GetLength(), objData.GetSize());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp b/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
index b6d9eab..fbd0ce5 100644
--- a/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_reader_writer_raw_test.cpp
@@ -51,7 +51,7 @@ void CheckRawPrimitive(T val)
     BinaryRawReader rawReader(&reader);
 
     T readVal = Read<T>(rawReader);
-    
+
     BOOST_REQUIRE(readVal == val);
 }
 
@@ -1714,4 +1714,25 @@ BOOST_AUTO_TEST_CASE(TestMapTyped)
     CheckRawMap(&typ);
 }
 
+BOOST_AUTO_TEST_CASE(TestUserType)
+{
+    PureRaw expected("Hello Ignite from", 2017);
+
+    InteropUnpooledMemory mem(1024);
+
+    InteropOutputStream out(&mem);
+    BinaryWriterImpl writer(&out, NULL);
+
+    writer.WriteObject<PureRaw>(expected);
+
+    out.Synchronize();
+
+    InteropInputStream in(&mem);
+    BinaryReaderImpl reader(&in);
+
+    PureRaw actual = reader.ReadObject<PureRaw>();
+
+    BOOST_REQUIRE(actual == expected);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file


[04/50] [abbrv] ignite git commit: IGNITE-4105: Added separate thread pool for queries. This closes #1469.

Posted by sb...@apache.org.
IGNITE-4105: Added separate thread pool for queries. This closes #1469.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: aa46bc7c82e7f172bcceed4afa4b010bf4071cda
Parents: 739c606
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Fri Feb 3 12:09:27 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Feb 3 12:09:27 2017 +0300

----------------------------------------------------------------------
 .../configuration/IgniteConfiguration.java      |  31 ++++++
 .../ignite/internal/GridKernalContext.java      |   7 ++
 .../ignite/internal/GridKernalContextImpl.java  |  13 +++
 .../apache/ignite/internal/IgniteKernal.java    |  17 ++-
 .../org/apache/ignite/internal/IgnitionEx.java  |  20 ++++
 .../managers/communication/GridIoManager.java   |   4 +-
 .../managers/communication/GridIoPolicy.java    |   3 +
 .../internal/processors/pool/PoolProcessor.java |   5 +
 .../junits/GridTestKernalContext.java           |   1 +
 .../query/h2/twostep/GridMapQueryExecutor.java  |   8 +-
 .../h2/twostep/GridReduceQueryExecutor.java     |   7 +-
 .../query/IgniteSqlQueryDedicatedPoolTest.java  | 110 +++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite.java          |   2 +
 13 files changed, 215 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/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 512ceee..f35742b 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
@@ -169,6 +169,9 @@ public class IgniteConfiguration {
     @Deprecated
     public static final int DFLT_SYSTEM_MAX_THREAD_CNT = DFLT_PUBLIC_THREAD_CNT;
 
+    /** Default size of query thread pool. */
+    public static final int DFLT_QUERY_THREAD_POOL_SIZE = DFLT_PUBLIC_THREAD_CNT;
+
     /** Default keep alive time for system thread pool. */
     @Deprecated
     public static final long DFLT_SYSTEM_KEEP_ALIVE_TIME = 0;
@@ -266,6 +269,9 @@ public class IgniteConfiguration {
     /** P2P pool size. */
     private int p2pPoolSize = DFLT_P2P_THREAD_CNT;
 
+    /** Query pool size. */
+    private int qryPoolSize = DFLT_QUERY_THREAD_POOL_SIZE;
+
     /** Ignite installation folder. */
     private String igniteHome;
 
@@ -549,6 +555,7 @@ public class IgniteConfiguration {
         platformCfg = cfg.getPlatformConfiguration();
         pluginCfgs = cfg.getPluginConfigurations();
         pubPoolSize = cfg.getPublicThreadPoolSize();
+        qryPoolSize = cfg.getQueryThreadPoolSize();
         rebalanceThreadPoolSize = cfg.getRebalanceThreadPoolSize();
         segChkFreq = cfg.getSegmentCheckFrequency();
         segPlc = cfg.getSegmentationPolicy();
@@ -869,6 +876,17 @@ public class IgniteConfiguration {
     }
 
     /**
+     * Size of thread pool that is in charge of processing query messages.
+     * <p>
+     * If not provided, executor service will have size {@link #DFLT_QUERY_THREAD_POOL_SIZE}.
+     *
+     * @return Thread pool size to be used in grid for query messages.
+     */
+    public int getQueryThreadPoolSize() {
+        return qryPoolSize;
+    }
+
+    /**
      * Sets thread pool size to use within grid.
      *
      * @param poolSize Thread pool size to use within grid.
@@ -975,6 +993,19 @@ public class IgniteConfiguration {
     }
 
     /**
+     * Sets query thread pool size to use within grid.
+     *
+     * @param poolSize Thread pool size to use within grid.
+     * @see IgniteConfiguration#getQueryThreadPoolSize()
+     * @return {@code this} for chaining.
+     */
+    public IgniteConfiguration setQueryThreadPoolSize(int poolSize) {
+        qryPoolSize = poolSize;
+
+        return this;
+    }
+
+    /**
      * Sets keep alive time of thread pool size that will be used to process utility cache messages.
      *
      * @param keepAliveTime Keep alive time of executor service to use for utility cache messages.

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
index 177062d..8e3dbe1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
@@ -573,6 +573,13 @@ public interface GridKernalContext extends Iterable<GridComponent> {
     @Nullable public ExecutorService getIndexingExecutorService();
 
     /**
+     * Executor service that is in charge of processing query messages.
+     *
+     * @return Thread pool implementation to be used in grid for query messages.
+     */
+    public ExecutorService getQueryExecutorService();
+
+    /**
      * Gets exception registry.
      *
      * @return Exception registry.

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
index a45be59..d8075d3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
@@ -343,6 +343,10 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
 
     /** */
     @GridToStringExclude
+    protected ExecutorService qryExecSvc;
+
+    /** */
+    @GridToStringExclude
     private Map<String, Object> attrs = new HashMap<>();
 
     /** */
@@ -400,6 +404,8 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
      * @param restExecSvc REST executor service.
      * @param affExecSvc Affinity executor service.
      * @param idxExecSvc Indexing executor service.
+     * @param callbackExecSvc Callback executor service.
+     * @param qryExecSvc Query executor service.
      * @param plugins Plugin providers.
      * @throws IgniteCheckedException In case of error.
      */
@@ -421,6 +427,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         ExecutorService affExecSvc,
         @Nullable ExecutorService idxExecSvc,
         IgniteStripedThreadPoolExecutor callbackExecSvc,
+        ExecutorService qryExecSvc,
         List<PluginProvider> plugins
     ) {
         assert grid != null;
@@ -442,6 +449,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         this.affExecSvc = affExecSvc;
         this.idxExecSvc = idxExecSvc;
         this.callbackExecSvc = callbackExecSvc;
+        this.qryExecSvc = qryExecSvc;
 
         marshCtx = new MarshallerContextImpl(plugins);
 
@@ -1005,6 +1013,11 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
     }
 
     /** {@inheritDoc} */
+    @Override public ExecutorService getQueryExecutorService() {
+        return qryExecSvc;
+    }
+
+    /** {@inheritDoc} */
     @Override public IgniteExceptionRegistry exceptionRegistry() {
         return IgniteExceptionRegistry.get();
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/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 63041a3..1f7f0d8 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
@@ -295,6 +295,10 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
     @GridToStringExclude
     private ObjectName restExecSvcMBean;
 
+    /** */
+    @GridToStringExclude
+    private ObjectName qryExecSvcMBean;
+
     /** Kernal start timestamp. */
     private long startTime = U.currentTimeMillis();
 
@@ -674,6 +678,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
      * @param restExecSvc Reset executor service.
      * @param affExecSvc Affinity executor service.
      * @param idxExecSvc Indexing executor service.
+     * @param callbackExecSvc Callback executor service.
+     * @param qryExecSvc Query executor service.
      * @param errHnd Error handler to use for notification about startup problems.
      * @throws IgniteCheckedException Thrown in case of any errors.
      */
@@ -692,6 +698,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
         ExecutorService affExecSvc,
         @Nullable ExecutorService idxExecSvc,
         IgniteStripedThreadPoolExecutor callbackExecSvc,
+        ExecutorService qryExecSvc,
         GridAbsClosure errHnd
     )
         throws IgniteCheckedException
@@ -801,6 +808,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                 affExecSvc,
                 idxExecSvc,
                 callbackExecSvc,
+                qryExecSvc,
                 plugins
             );
 
@@ -961,7 +969,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
             // Register MBeans.
             registerKernalMBean();
             registerLocalNodeMBean();
-            registerExecutorMBeans(execSvc, sysExecSvc, p2pExecSvc, mgmtExecSvc, restExecSvc);
+            registerExecutorMBeans(execSvc, sysExecSvc, p2pExecSvc, mgmtExecSvc, restExecSvc, qryExecSvc);
 
             // Lifecycle bean notifications.
             notifyLifecycleBeans(AFTER_NODE_START);
@@ -1545,11 +1553,13 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
         ExecutorService sysExecSvc,
         ExecutorService p2pExecSvc,
         ExecutorService mgmtExecSvc,
-        ExecutorService restExecSvc) throws IgniteCheckedException {
+        ExecutorService restExecSvc,
+        ExecutorService qryExecSvc) throws IgniteCheckedException {
         pubExecSvcMBean = registerExecutorMBean(execSvc, "GridExecutionExecutor");
         sysExecSvcMBean = registerExecutorMBean(sysExecSvc, "GridSystemExecutor");
         mgmtExecSvcMBean = registerExecutorMBean(mgmtExecSvc, "GridManagementExecutor");
         p2PExecSvcMBean = registerExecutorMBean(p2pExecSvc, "GridClassLoadingExecutor");
+        qryExecSvcMBean = registerExecutorMBean(qryExecSvc, "GridQueryExecutor");
 
         ConnectorConfiguration clientCfg = cfg.getConnectorConfiguration();
 
@@ -2043,7 +2053,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                     unregisterMBean(p2PExecSvcMBean) &
                     unregisterMBean(kernalMBean) &
                     unregisterMBean(locNodeMBean) &
-                    unregisterMBean(restExecSvcMBean)
+                    unregisterMBean(restExecSvcMBean) &
+                    unregisterMBean(qryExecSvcMBean)
             ))
                 errOnStop = false;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/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 c55f954..42ff739 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
@@ -1489,6 +1489,9 @@ public class IgnitionEx {
         /** Continuous query executor service. */
         private IgniteStripedThreadPoolExecutor callbackExecSvc;
 
+        /** Query executor service. */
+        private ThreadPoolExecutor qryExecSvc;
+
         /** Grid state. */
         private volatile IgniteState state = STOPPED;
 
@@ -1783,6 +1786,18 @@ public class IgnitionEx {
                 );
             }
 
+            validateThreadPoolSize(cfg.getQueryThreadPoolSize(), "query");
+
+            qryExecSvc = new IgniteThreadPoolExecutor(
+                "query",
+                cfg.getGridName(),
+                cfg.getQueryThreadPoolSize(),
+                cfg.getQueryThreadPoolSize(),
+                DFLT_THREAD_KEEP_ALIVE_TIME,
+                new LinkedBlockingQueue<Runnable>());
+
+            qryExecSvc.allowCoreThreadTimeOut(true);
+
             // Register Ignite MBean for current grid instance.
             registerFactoryMbean(myCfg.getMBeanServer());
 
@@ -1808,6 +1823,7 @@ public class IgnitionEx {
                     affExecSvc,
                     idxExecSvc,
                     callbackExecSvc,
+                    qryExecSvc,
                     new CA() {
                         @Override public void apply() {
                             startLatch.countDown();
@@ -2402,6 +2418,10 @@ public class IgnitionEx {
 
             sysExecSvc = null;
 
+            U.shutdownNow(getClass(), qryExecSvc, log);
+
+            qryExecSvc = null;
+
             U.shutdownNow(getClass(), stripedExecSvc, log);
 
             stripedExecSvc = null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index 16ea972..0228684 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -98,6 +98,7 @@ import static org.apache.ignite.internal.managers.communication.GridIoPolicy.P2P
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.PUBLIC_POOL;
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.UTILITY_CACHE_POOL;
+import static org.apache.ignite.internal.managers.communication.GridIoPolicy.QUERY_POOL;
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.isReservedGridIoPolicy;
 import static org.apache.ignite.internal.util.nio.GridNioBackPressureControl.threadProcessingMessage;
 import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q_OPTIMIZED_RMV;
@@ -686,6 +687,7 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
                 case IDX_POOL:
                 case IGFS_POOL:
                 case DATA_STREAMER_POOL:
+                case QUERY_POOL:
                 {
                     if (msg.isOrdered())
                         processOrderedMessage(nodeId, msg, plc, msgC);
@@ -1206,7 +1208,7 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
     private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Object msg) {
         Byte oldPlc = CUR_PLC.get();
 
-        boolean change = F.eq(oldPlc, plc);
+        boolean change = !F.eq(oldPlc, plc);
 
         if (change)
             CUR_PLC.set(plc);

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoPolicy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoPolicy.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoPolicy.java
index cb673d0..a3fb370 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoPolicy.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoPolicy.java
@@ -49,6 +49,9 @@ public class GridIoPolicy {
     /** Data streamer execution pool. */
     public static final byte DATA_STREAMER_POOL = 9;
 
+    /** Query execution pool. */
+    public static final byte QUERY_POOL = 10;
+
     /**
      * Defines the range of reserved pools that are not available for plugins.
      * @param key The key.

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/core/src/main/java/org/apache/ignite/internal/processors/pool/PoolProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/pool/PoolProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/pool/PoolProcessor.java
index f42815b..f84b741 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/pool/PoolProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/pool/PoolProcessor.java
@@ -128,6 +128,11 @@ public class PoolProcessor extends GridProcessorAdapter {
 
                 return ctx.getDataStreamerExecutorService();
 
+            case GridIoPolicy.QUERY_POOL:
+                assert ctx.getQueryExecutorService() != null : "Query pool is not configured.";
+
+                return ctx.getQueryExecutorService();
+
             default: {
                 if (plc < 0)
                     throw new IgniteCheckedException("Policy cannot be negative: " + plc);

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
index db45e27..40f0e43 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
@@ -64,6 +64,7 @@ public class GridTestKernalContext extends GridKernalContextImpl {
                 null,
                 null,
                 null,
+                null,
                 U.allPluginProviders()
         );
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
index ac1a6a6..2802da5 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
@@ -44,6 +44,7 @@ import org.apache.ignite.events.Event;
 import org.apache.ignite.events.EventType;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.GridTopic;
+import org.apache.ignite.internal.managers.communication.GridIoPolicy;
 import org.apache.ignite.internal.managers.communication.GridMessageListener;
 import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -86,7 +87,6 @@ import static org.apache.ignite.internal.processors.affinity.AffinityTopologyVer
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING;
 import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.MAP;
 import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.REPLICATED;
-import static org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor.QUERY_POOL;
 import static org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessageFactory.toMessages;
 import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q;
 
@@ -655,7 +655,7 @@ public class GridMapQueryExecutor {
                 h2.reduceQueryExecutor().onMessage(ctx.localNodeId(), msg);
             }
             else
-                ctx.io().send(node, GridTopic.TOPIC_QUERY, msg, QUERY_POOL);
+                ctx.io().send(node, GridTopic.TOPIC_QUERY, msg, GridIoPolicy.QUERY_POOL);
         }
         catch (Exception e) {
             e.addSuppressed(err);
@@ -729,7 +729,7 @@ public class GridMapQueryExecutor {
             if (loc)
                 h2.reduceQueryExecutor().onMessage(ctx.localNodeId(), msg);
             else
-                ctx.io().send(node, GridTopic.TOPIC_QUERY, msg, QUERY_POOL);
+                ctx.io().send(node, GridTopic.TOPIC_QUERY, msg, GridIoPolicy.QUERY_POOL);
         }
         catch (IgniteCheckedException e) {
             log.error("Failed to send message.", e);
@@ -756,7 +756,7 @@ public class GridMapQueryExecutor {
             if (loc)
                 h2.reduceQueryExecutor().onMessage(ctx.localNodeId(), msg);
             else
-                ctx.io().send(node, GridTopic.TOPIC_QUERY, msg, QUERY_POOL);
+                ctx.io().send(node, GridTopic.TOPIC_QUERY, msg, GridIoPolicy.QUERY_POOL);
         }
         catch (Exception e) {
             U.warn(log, "Failed to send retry message: " + e.getMessage());

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
index 1f00ed2..7c036ea 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
@@ -104,9 +104,6 @@ import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType
  * Reduce query executor.
  */
 public class GridReduceQueryExecutor {
-    /** Thread pool to process query messages. */
-    public static final byte QUERY_POOL = GridIoPolicy.SYSTEM_POOL;
-
     /** */
     private static final IgniteProductVersion DISTRIBUTED_JOIN_SINCE = IgniteProductVersion.fromString("1.7.0");
 
@@ -327,7 +324,7 @@ public class GridReduceQueryExecutor {
                         if (node.isLocal())
                             h2.mapQueryExecutor().onMessage(ctx.localNodeId(), msg0);
                         else
-                            ctx.io().send(node, GridTopic.TOPIC_QUERY, msg0, QUERY_POOL);
+                            ctx.io().send(node, GridTopic.TOPIC_QUERY, msg0, GridIoPolicy.QUERY_POOL);
                     }
                     catch (IgniteCheckedException e) {
                         throw new CacheException("Failed to fetch data from node: " + node.id(), e);
@@ -1178,7 +1175,7 @@ public class GridReduceQueryExecutor {
             msg,
             specialize,
             locNodeHnd,
-            QUERY_POOL,
+            GridIoPolicy.QUERY_POOL,
             runLocParallel);
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlQueryDedicatedPoolTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlQueryDedicatedPoolTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlQueryDedicatedPoolTest.java
new file mode 100644
index 0000000..bba3642
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlQueryDedicatedPoolTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.communication.GridIoManager;
+import org.apache.ignite.internal.managers.communication.GridIoPolicy;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import java.util.List;
+
+/**
+ * Ensures that SQL queries are executed in a dedicated thread pool.
+ */
+public class IgniteSqlQueryDedicatedPoolTest extends GridCommonAbstractTest {
+    /** IP finder. */
+    private static final TcpDiscoveryVmIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Name of the cache for test */
+    private static final String CACHE_NAME = "query_pool_test";
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        startGrid("server");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi spi = (TcpDiscoverySpi)cfg.getDiscoverySpi();
+
+        spi.setIpFinder(IP_FINDER);
+
+        CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+
+        ccfg.setIndexedTypes(Integer.class, Integer.class);
+        ccfg.setSqlFunctionClasses(IgniteSqlQueryDedicatedPoolTest.class);
+        ccfg.setName(CACHE_NAME);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        if ("client".equals(gridName))
+            cfg.setClientMode(true);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+    }
+
+    /**
+     * Test that SQL queries are executed in dedicated pool
+     */
+    public void testSqlQueryUsesDedicatedThreadPool() throws Exception {
+        try (Ignite client = startGrid("client")) {
+            IgniteCache<Integer, Integer> cache = client.cache(CACHE_NAME);
+
+            QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery("select currentPolicy()"));
+
+            List<List<?>> result = cursor.getAll();
+
+            cursor.close();
+
+            assertEquals(1, result.size());
+
+            Byte plc = (Byte)result.get(0).get(0);
+
+            assert plc != null;
+            assert plc == GridIoPolicy.QUERY_POOL;
+        }
+    }
+
+    /**
+     * Custom SQL function to return current thread name from inside query executor
+     */
+    @SuppressWarnings("unused")
+    @QuerySqlFunction(alias = "currentPolicy")
+    public static Byte currentPolicy() {
+         return GridIoManager.currentPolicy();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa46bc7c/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index b5e4078..49fb269 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -95,6 +95,7 @@ import org.apache.ignite.internal.processors.cache.query.GridCacheSwapScanQueryS
 import org.apache.ignite.internal.processors.cache.query.IgniteCacheQueryCacheDestroySelfTest;
 import org.apache.ignite.internal.processors.cache.query.IndexingSpiQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.query.IndexingSpiQueryTxSelfTest;
+import org.apache.ignite.internal.processors.query.IgniteSqlQueryDedicatedPoolTest;
 import org.apache.ignite.internal.processors.query.IgniteSqlSchemaIndexingTest;
 import org.apache.ignite.internal.processors.query.IgniteSqlSplitterSelfTest;
 import org.apache.ignite.internal.processors.query.h2.GridH2IndexRebuildTest;
@@ -240,6 +241,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         suite.addTestSuite(CacheOffheapBatchIndexingSingleTypeTest.class);
         suite.addTestSuite(CacheSqlQueryValueCopySelfTest.class);
         suite.addTestSuite(IgniteCacheQueryCacheDestroySelfTest.class);
+        suite.addTestSuite(IgniteSqlQueryDedicatedPoolTest.class);
 
         return suite;
     }


[40/50] [abbrv] ignite git commit: IGNITE-4687 Added pool to process REST request in Web Agent.

Posted by sb...@apache.org.
IGNITE-4687 Added pool to process REST request in Web Agent.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 262a3410802de790b75de9b94fea9599b30171bd
Parents: 0ace63c
Author: Andrey Novikov <an...@gridgain.com>
Authored: Mon Feb 13 17:35:29 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Mon Feb 13 17:35:29 2017 +0700

----------------------------------------------------------------------
 .../ignite/console/agent/AgentLauncher.java     | 203 ++++++------
 .../apache/ignite/console/agent/AgentUtils.java |  80 +++++
 .../console/agent/handlers/AbstractHandler.java | 110 -------
 .../agent/handlers/AbstractListener.java        | 104 ++++++
 .../console/agent/handlers/DatabaseHandler.java | 298 -----------------
 .../agent/handlers/DatabaseListener.java        | 316 +++++++++++++++++++
 .../console/agent/handlers/RestHandler.java     | 276 ----------------
 .../console/agent/handlers/RestListener.java    | 280 ++++++++++++++++
 8 files changed, 880 insertions(+), 787 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
index 049791f..a3d609f 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
@@ -41,8 +41,8 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
-import org.apache.ignite.console.agent.handlers.DatabaseHandler;
-import org.apache.ignite.console.agent.handlers.RestHandler;
+import org.apache.ignite.console.agent.handlers.DatabaseListener;
+import org.apache.ignite.console.agent.handlers.RestListener;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.log4j.Logger;
 import org.json.JSONException;
@@ -278,141 +278,138 @@ public class AgentLauncher {
             cfg.tokens(Arrays.asList(tokens.trim().split(",")));
         }
 
-        final RestHandler restHnd = new RestHandler(cfg);
+        URI uri = URI.create(cfg.serverUri());
 
-        try {
-            restHnd.start();
+        // Create proxy authenticator using passed properties.
+        switch (uri.getScheme()) {
+            case "http":
+            case "https":
+                final String username = System.getProperty(uri.getScheme() + ".proxyUsername");
+                final char[] pwd = System.getProperty(uri.getScheme() +  ".proxyPassword", "").toCharArray();
 
-            URI uri = URI.create(cfg.serverUri());
+                Authenticator.setDefault(new Authenticator() {
+                    @Override protected PasswordAuthentication getPasswordAuthentication() {
+                        return new PasswordAuthentication(username, pwd);
+                    }
+                });
 
-            // Create proxy authenticator using passed properties.
-            switch (uri.getScheme()) {
-                case "http":
-                case "https":
-                    final String username = System.getProperty(uri.getScheme() + ".proxyUsername");
-                    final char[] pwd = System.getProperty(uri.getScheme() +  ".proxyPassword", "").toCharArray();
+                break;
 
-                    Authenticator.setDefault(new Authenticator() {
-                        @Override protected PasswordAuthentication getPasswordAuthentication() {
-                            return new PasswordAuthentication(username, pwd);
-                        }
-                    });
-
-                    break;
+            default:
+                // No-op.
+        }
 
-                default:
-                    // No-op.
-            }
+        IO.Options opts = new IO.Options();
 
-            IO.Options opts = new IO.Options();
+        opts.path = "/agents";
 
-            opts.path = "/agents";
+        // Workaround for use self-signed certificate
+        if (Boolean.getBoolean("trust.all")) {
+            SSLContext ctx = SSLContext.getInstance("TLS");
 
-            // Workaround for use self-signed certificate
-            if (Boolean.getBoolean("trust.all")) {
-                SSLContext ctx = SSLContext.getInstance("TLS");
+            // Create an SSLContext that uses our TrustManager
+            ctx.init(null, getTrustManagers(), null);
 
-                // Create an SSLContext that uses our TrustManager
-                ctx.init(null, getTrustManagers(), null);
+            opts.sslContext = ctx;
+        }
 
-                opts.sslContext = ctx;
-            }
+        final Socket client = IO.socket(uri, opts);
 
-            final Socket client = IO.socket(uri, opts);
+        final RestListener restHnd = new RestListener(cfg);
 
-            try {
-                Emitter.Listener onConnecting = new Emitter.Listener() {
-                    @Override public void call(Object... args) {
-                        log.info("Connecting to: " + cfg.serverUri());
-                    }
-                };
+        final DatabaseListener dbHnd = new DatabaseListener(cfg);
 
-                Emitter.Listener onConnect = new Emitter.Listener() {
-                    @Override public void call(Object... args) {
-                        log.info("Connection established.");
+        try {
+            Emitter.Listener onConnecting = new Emitter.Listener() {
+                @Override public void call(Object... args) {
+                    log.info("Connecting to: " + cfg.serverUri());
+                }
+            };
 
-                        JSONObject authMsg = new JSONObject();
+            Emitter.Listener onConnect = new Emitter.Listener() {
+                @Override public void call(Object... args) {
+                    log.info("Connection established.");
 
-                        try {
-                            authMsg.put("tokens", cfg.tokens());
+                    JSONObject authMsg = new JSONObject();
 
-                            String clsName = AgentLauncher.class.getSimpleName() + ".class";
+                    try {
+                        authMsg.put("tokens", cfg.tokens());
 
-                            String clsPath = AgentLauncher.class.getResource(clsName).toString();
+                        String clsName = AgentLauncher.class.getSimpleName() + ".class";
 
-                            if (clsPath.startsWith("jar")) {
-                                String manifestPath = clsPath.substring(0, clsPath.lastIndexOf('!') + 1) +
-                                    "/META-INF/MANIFEST.MF";
+                        String clsPath = AgentLauncher.class.getResource(clsName).toString();
 
-                                Manifest manifest = new Manifest(new URL(manifestPath).openStream());
+                        if (clsPath.startsWith("jar")) {
+                            String manifestPath = clsPath.substring(0, clsPath.lastIndexOf('!') + 1) +
+                                "/META-INF/MANIFEST.MF";
 
-                                Attributes attr = manifest.getMainAttributes();
+                            Manifest manifest = new Manifest(new URL(manifestPath).openStream());
 
-                                authMsg.put("ver", attr.getValue("Implementation-Version"));
-                                authMsg.put("bt", attr.getValue("Build-Time"));
-                            }
+                            Attributes attr = manifest.getMainAttributes();
 
-                            client.emit("agent:auth", authMsg, new Ack() {
-                                @Override public void call(Object... args) {
-                                    // Authentication failed if response contains args.
-                                    if (args != null && args.length > 0) {
-                                        onDisconnect.call(args);
+                            authMsg.put("ver", attr.getValue("Implementation-Version"));
+                            authMsg.put("bt", attr.getValue("Build-Time"));
+                        }
 
-                                        System.exit(1);
-                                    }
+                        client.emit("agent:auth", authMsg, new Ack() {
+                            @Override public void call(Object... args) {
+                                // Authentication failed if response contains args.
+                                if (args != null && args.length > 0) {
+                                    onDisconnect.call(args);
 
-                                    log.info("Authentication success.");
+                                    System.exit(1);
                                 }
-                            });
-                        }
-                        catch (JSONException | IOException e) {
-                            log.error("Failed to construct authentication message", e);
 
-                            client.close();
-                        }
+                                log.info("Authentication success.");
+                            }
+                        });
                     }
-                };
-
-                DatabaseHandler dbHnd = new DatabaseHandler(cfg);
-
-                final CountDownLatch latch = new CountDownLatch(1);
-
-                client
-                    .on(EVENT_CONNECTING, onConnecting)
-                    .on(EVENT_CONNECT, onConnect)
-                    .on(EVENT_CONNECT_ERROR, onError)
-                    .on(EVENT_RECONNECTING, onConnecting)
-                    .on(EVENT_NODE_REST, restHnd)
-                    .on(EVENT_SCHEMA_IMPORT_DRIVERS, dbHnd.availableDriversListener())
-                    .on(EVENT_SCHEMA_IMPORT_SCHEMAS, dbHnd.schemasListener())
-                    .on(EVENT_SCHEMA_IMPORT_METADATA, dbHnd.metadataListener())
-                    .on(EVENT_ERROR, onError)
-                    .on(EVENT_DISCONNECT, onDisconnect)
-                    .on(EVENT_AGENT_WARNING, new Emitter.Listener() {
-                        @Override public void call(Object... args) {
-                            log.warn(args[0]);
-                        }
-                    })
-                    .on(EVENT_AGENT_CLOSE, new Emitter.Listener() {
-                        @Override public void call(Object... args) {
-                            onDisconnect.call(args);
+                    catch (JSONException | IOException e) {
+                        log.error("Failed to construct authentication message", e);
+
+                        client.close();
+                    }
+                }
+            };
+
+            final CountDownLatch latch = new CountDownLatch(1);
+
+            client
+                .on(EVENT_CONNECTING, onConnecting)
+                .on(EVENT_CONNECT, onConnect)
+                .on(EVENT_CONNECT_ERROR, onError)
+                .on(EVENT_RECONNECTING, onConnecting)
+                .on(EVENT_NODE_REST, restHnd)
+                .on(EVENT_SCHEMA_IMPORT_DRIVERS, dbHnd.availableDriversListener())
+                .on(EVENT_SCHEMA_IMPORT_SCHEMAS, dbHnd.schemasListener())
+                .on(EVENT_SCHEMA_IMPORT_METADATA, dbHnd.metadataListener())
+                .on(EVENT_ERROR, onError)
+                .on(EVENT_DISCONNECT, onDisconnect)
+                .on(EVENT_AGENT_WARNING, new Emitter.Listener() {
+                    @Override public void call(Object... args) {
+                        log.warn(args[0]);
+                    }
+                })
+                .on(EVENT_AGENT_CLOSE, new Emitter.Listener() {
+                    @Override public void call(Object... args) {
+                        onDisconnect.call(args);
 
-                            client.off();
+                        client.off();
 
-                            latch.countDown();
-                        }
-                    });
+                        latch.countDown();
+                    }
+                });
 
-                client.connect();
+            client.connect();
 
-                latch.await();
-            }
-            finally {
-                client.close();
-            }
+            latch.await();
         }
         finally {
+            client.close();
+
             restHnd.stop();
+
+            dbHnd.stop();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
index 50a849a..cb22651 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
@@ -17,11 +17,19 @@
 
 package org.apache.ignite.console.agent;
 
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
+import io.socket.client.Ack;
 import java.io.File;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.ProtectionDomain;
+import java.util.Arrays;
 import org.apache.log4j.Logger;
+import org.json.JSONArray;
+import org.json.JSONObject;
 
 /**
  * Utility methods.
@@ -30,6 +38,28 @@ public class AgentUtils {
     /** */
     private static final Logger log = Logger.getLogger(AgentUtils.class.getName());
 
+    /** JSON object mapper. */
+    private static final ObjectMapper mapper = new ObjectMapper();
+
+    /** */
+    private static final Ack NOOP_CB = new Ack() {
+        @Override public void call(Object... args) {
+            if (args != null && args.length > 0 && args[0] instanceof Throwable)
+                log.error("Failed to execute request on agent.", (Throwable) args[0]);
+            else
+                log.info("Request on agent successfully executed " + Arrays.toString(args));
+        }
+    };
+
+    static {
+        JsonOrgModule module = new JsonOrgModule();
+
+        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
+        mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+
+        mapper.registerModule(module);
+    }
+    
     /**
      * Default constructor.
      */
@@ -108,4 +138,54 @@ public class AgentUtils {
 
         return null;
     }
+
+    /**
+     * Get callback from handler arguments.
+     *
+     * @param args Arguments.
+     * @return Callback or noop callback.
+     */
+    public static Ack safeCallback(Object[] args) {
+        boolean hasCb = args != null && args.length > 0 && args[args.length - 1] instanceof Ack;
+
+        return hasCb ? (Ack)args[args.length - 1] : NOOP_CB;
+    }
+
+    /**
+     * Remove callback from handler arguments.
+     * 
+     * @param args Arguments.
+     * @return Arguments without callback.
+     */
+    public static Object[] removeCallback(Object[] args) {
+        boolean hasCb = args != null && args.length > 0 && args[args.length - 1] instanceof Ack;
+
+        return hasCb ? Arrays.copyOf(args, args.length - 1) : args;
+    }
+
+    /**
+     * Map java object to JSON object.
+     * 
+     * @param obj Java object.
+     * @return {@link JSONObject} or {@link JSONArray}.
+     * @throws IllegalArgumentException If conversion fails due to incompatible type.
+     */
+    public static Object toJSON(Object obj) {
+        if (obj instanceof Iterable)
+            return mapper.convertValue(obj, JSONArray.class);
+
+        return mapper.convertValue(obj, JSONObject.class);
+    }
+
+    /**
+     * Map JSON object to java object.
+     *
+     * @param obj {@link JSONObject} or {@link JSONArray}.
+     * @param toValType Expected value type.
+     * @return Mapped object type of {@link T}.
+     * @throws IllegalArgumentException If conversion fails due to incompatible type.
+     */
+    public static <T> T fromJSON(Object obj, Class<T> toValType) throws IllegalArgumentException {
+        return mapper.convertValue(obj, toValType);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
deleted file mode 100644
index 7e4e320..0000000
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
+++ /dev/null
@@ -1,110 +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.console.agent.handlers;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
-import io.socket.client.Ack;
-import io.socket.emitter.Emitter;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Map;
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-/**
- * Base class for web socket handlers.
- */
-abstract class AbstractHandler implements Emitter.Listener {
-    /** JSON object mapper. */
-    private static final ObjectMapper mapper = new ObjectMapper();
-
-    static {
-        JsonOrgModule module = new JsonOrgModule();
-
-        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
-        mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
-
-        mapper.registerModule(module);
-    }
-
-    /**
-     * @param obj Object.
-     * @return {@link JSONObject} or {@link JSONArray}.
-     */
-    private Object toJSON(Object obj) {
-        if (obj instanceof Iterable)
-            return mapper.convertValue(obj, JSONArray.class);
-
-        return mapper.convertValue(obj, JSONObject.class);
-    }
-
-    /** {@inheritDoc} */
-    @SuppressWarnings("unchecked")
-    @Override public final void call(Object... args) {
-        Ack cb = null;
-
-        try {
-            if (args == null || args.length == 0)
-                throw new IllegalArgumentException("Missing arguments.");
-
-            if (args.length > 2)
-                throw new IllegalArgumentException("Wrong arguments count, must be <= 2: " + Arrays.toString(args));
-
-            JSONObject lsnrArgs = null;
-
-            if (args.length == 1) {
-                if (args[0] instanceof JSONObject)
-                    lsnrArgs = (JSONObject)args[0];
-                else if (args[0] instanceof Ack)
-                    cb = (Ack)args[0];
-                else
-                    throw new IllegalArgumentException("Wrong type of argument, must be JSONObject or Ack: " + args[0]);
-            }
-            else {
-                if (args[0] != null && !(args[0] instanceof JSONObject))
-                    throw new IllegalArgumentException("Wrong type of argument, must be JSONObject: " + args[0]);
-
-                if (!(args[1] instanceof Ack))
-                    throw new IllegalArgumentException("Wrong type of argument, must be Ack: " + args[1]);
-
-                lsnrArgs = (JSONObject)args[0];
-
-                cb = (Ack)args[1];
-            }
-
-            Object res = execute(lsnrArgs == null ? Collections.emptyMap() : mapper.convertValue(lsnrArgs, Map.class));
-
-            if (cb != null)
-                cb.call(null, toJSON(res));
-        }
-        catch (Exception e) {
-            if (cb != null)
-                cb.call(e, null);
-        }
-    }
-
-    /**
-     * Execute command with specified arguments.
-     *
-     * @param args Map with method args.
-     */
-    public abstract Object execute(Map<String, Object> args) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractListener.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractListener.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractListener.java
new file mode 100644
index 0000000..987dac9
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractListener.java
@@ -0,0 +1,104 @@
+/*
+ * 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.console.agent.handlers;
+
+import io.socket.client.Ack;
+import io.socket.emitter.Emitter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentUtils.removeCallback;
+import static org.apache.ignite.console.agent.AgentUtils.fromJSON;
+import static org.apache.ignite.console.agent.AgentUtils.safeCallback;
+import static org.apache.ignite.console.agent.AgentUtils.toJSON;
+
+/**
+ * Base class for web socket handlers.
+ */
+abstract class AbstractListener implements Emitter.Listener {
+    /** */
+    private ExecutorService pool;
+
+    /** */
+    final Logger log = Logger.getLogger(this.getClass().getName());
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public final void call(Object... args) {
+        final Ack cb = safeCallback(args);
+
+        args = removeCallback(args);
+
+        try {
+            final Map<String, Object> params;
+
+            if (args == null || args.length == 0)
+                params = Collections.emptyMap();
+            else if (args.length == 1)
+                params = fromJSON(args[0], Map.class);
+            else
+                throw new IllegalArgumentException("Wrong arguments count, must be <= 1: " + Arrays.toString(args));
+
+            if (pool == null)
+                pool = newThreadPool();
+
+            pool.submit(new Runnable() {
+                @Override public void run() {
+                    try {
+                        Object res = execute(params);
+
+                        cb.call(null, toJSON(res));
+                    } catch (Exception e) {
+                        cb.call(e, null);
+                    }
+                }
+            });
+        }
+        catch (Exception e) {
+            cb.call(e, null);
+        }
+    }
+
+    /**
+     * Stop handler.
+     */
+    public void stop() {
+        if (pool != null)
+            pool.shutdownNow();
+    }
+
+    /**
+     * Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
+     *
+     * @return Newly created thread pool.
+     */
+    protected ExecutorService newThreadPool() {
+        return Executors.newSingleThreadExecutor();
+    }
+
+    /**
+     * Execute command with specified arguments.
+     *
+     * @param args Map with method args.
+     */
+    public abstract Object execute(Map<String, Object> args) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
deleted file mode 100644
index 02146d9..0000000
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
+++ /dev/null
@@ -1,298 +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.console.agent.handlers;
-
-import io.socket.emitter.Emitter;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import org.apache.ignite.console.agent.AgentConfiguration;
-import org.apache.ignite.console.demo.AgentMetadataDemo;
-import org.apache.ignite.schema.parser.DbMetadataReader;
-import org.apache.ignite.schema.parser.DbTable;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
-
-/**
- * API to extract database metadata.
- */
-public class DatabaseHandler {
-    /** */
-    private static final Logger log = Logger.getLogger(DatabaseHandler.class.getName());
-
-    /** */
-    private final File driversFolder;
-
-    /**
-     * @param cfg Config.
-     */
-    public DatabaseHandler(AgentConfiguration cfg) {
-        driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @return Connection to database.
-     * @throws SQLException
-     */
-    private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
-        Properties jdbcInfo) throws SQLException {
-        if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
-            return AgentMetadataDemo.testDrive();
-
-        if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
-            jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
-
-        return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @return Collection of schema names.
-     * @throws SQLException
-     */
-    protected Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
-        Properties jdbcInfo) throws SQLException {
-        if (log.isDebugEnabled())
-            log.debug("Start collecting database schemas [drvJar=" + jdbcDriverJarPath +
-                ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
-
-        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
-            Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
-
-            if (log.isDebugEnabled())
-                log.debug("Finished collection of schemas [jdbcUrl=" + jdbcUrl + ", count=" + schemas.size() + "]");
-
-            return schemas;
-        }
-        catch (Throwable e) {
-            log.error("Failed to collect schemas", e);
-
-            throw new SQLException("Failed to collect schemas", e);
-        }
-    }
-
-    /**
-     * Listener for schema names.
-     *
-     * @return Collection of schema names.
-     */
-    public Emitter.Listener schemasListener() {
-        return new AbstractHandler() {
-            @Override public Object execute(Map<String, Object> args) throws Exception {
-                String driverPath = null;
-
-                if (args.containsKey("driverPath"))
-                    driverPath = args.get("driverPath").toString();
-
-                if (!args.containsKey("driverClass"))
-                    throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
-
-                String driverCls = args.get("driverClass").toString();
-
-                if (!args.containsKey("url"))
-                    throw new IllegalArgumentException("Missing url in arguments: " + args);
-
-                String url = args.get("url").toString();
-
-                if (!args.containsKey("info"))
-                    throw new IllegalArgumentException("Missing info in arguments: " + args);
-
-                Properties info = new Properties();
-
-                info.putAll((Map)args.get("info"));
-
-                return schemas(driverPath, driverCls, url, info);
-            }
-        };
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @param schemas List of schema names to process.
-     * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
-     * @return Collection of tables.
-     */
-    protected Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
-        Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
-        if (log.isDebugEnabled())
-            log.debug("Start collecting database metadata [drvJar=" + jdbcDriverJarPath +
-                ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
-
-        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
-            Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
-
-            if (log.isDebugEnabled())
-                log.debug("Finished collection of metadata [jdbcUrl=" + jdbcUrl + ", count=" + metadata.size() + "]");
-
-            return metadata;
-        }
-        catch (Throwable e) {
-            log.error("Failed to collect metadata", e);
-
-            throw new SQLException("Failed to collect metadata", e);
-        }
-    }
-
-    /**
-     * Listener for tables.
-     *
-     * @return Collection of tables.
-     */
-    public Emitter.Listener metadataListener() {
-        return new AbstractHandler() {
-            @SuppressWarnings("unchecked")
-            @Override public Object execute(Map<String, Object> args) throws Exception {
-                String driverPath = null;
-
-                if (args.containsKey("driverPath"))
-                    driverPath = args.get("driverPath").toString();
-
-                if (!args.containsKey("driverClass"))
-                    throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
-
-                String driverCls = args.get("driverClass").toString();
-
-                if (!args.containsKey("url"))
-                    throw new IllegalArgumentException("Missing url in arguments: " + args);
-
-                String url = args.get("url").toString();
-
-                if (!args.containsKey("info"))
-                    throw new IllegalArgumentException("Missing info in arguments: " + args);
-
-                Properties info = new Properties();
-
-                info.putAll((Map)args.get("info"));
-
-                if (!args.containsKey("schemas"))
-                    throw new IllegalArgumentException("Missing schemas in arguments: " + args);
-
-                List<String> schemas = (List<String>)args.get("schemas");
-
-                if (!args.containsKey("tablesOnly"))
-                    throw new IllegalArgumentException("Missing tablesOnly in arguments: " + args);
-
-                boolean tblsOnly = (boolean)args.get("tablesOnly");
-
-                return metadata(driverPath, driverCls, url, info, schemas, tblsOnly);
-            }
-        };
-    }
-
-    /**
-     * Listener for drivers.
-     *
-     * @return Drivers in drivers folder
-     * @see AgentConfiguration#driversFolder
-     */
-    public Emitter.Listener availableDriversListener() {
-        return new AbstractHandler() {
-            @Override public Object execute(Map<String, Object> args) throws Exception {
-                if (driversFolder == null) {
-                    log.info("JDBC drivers folder not specified, returning empty list");
-
-                    return Collections.emptyList();
-                }
-
-                if (log.isDebugEnabled())
-                    log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
-
-                File[] list = driversFolder.listFiles(new FilenameFilter() {
-                    @Override public boolean accept(File dir, String name) {
-                        return name.endsWith(".jar");
-                    }
-                });
-
-                if (list == null) {
-                    log.info("JDBC drivers folder has no files, returning empty list");
-
-                    return Collections.emptyList();
-                }
-
-                List<JdbcDriver> res = new ArrayList<>();
-
-                for (File file : list) {
-                    try {
-                        boolean win = System.getProperty("os.name").contains("win");
-
-                        URL url = new URL("jar", null,
-                            "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
-
-                        try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
-                            String jdbcDriverCls = reader.readLine();
-
-                            res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
-
-                            if (log.isDebugEnabled())
-                                log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
-                        }
-                    }
-                    catch (IOException e) {
-                        res.add(new JdbcDriver(file.getName(), null));
-
-                        log.info("Found: [driver=" + file + "]");
-                        log.info("Failed to detect driver class: " + e.getMessage());
-                    }
-                }
-
-                return res;
-            }
-        };
-    }
-
-    /**
-     * Wrapper class for later to be transformed to JSON and send to Web Console.
-     */
-    private static class JdbcDriver {
-        /** */
-        public final String jdbcDriverJar;
-        /** */
-        public final String jdbcDriverCls;
-
-        /**
-         * @param jdbcDriverJar File name of driver jar file.
-         * @param jdbcDriverCls Optional JDBC driver class.
-         */
-        public JdbcDriver(String jdbcDriverJar, String jdbcDriverCls) {
-            this.jdbcDriverJar = jdbcDriverJar;
-            this.jdbcDriverCls = jdbcDriverCls;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java
new file mode 100644
index 0000000..4577228
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java
@@ -0,0 +1,316 @@
+/*
+ * 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.console.agent.handlers;
+
+import io.socket.emitter.Emitter;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.demo.AgentMetadataDemo;
+import org.apache.ignite.schema.parser.DbMetadataReader;
+import org.apache.ignite.schema.parser.DbTable;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
+
+/**
+ * API to extract database metadata.
+ */
+public class DatabaseListener {
+    /** */
+    private static final Logger log = Logger.getLogger(DatabaseListener.class.getName());
+
+    /** */
+    private final File driversFolder;
+
+    /** */
+    private final AbstractListener schemasLsnr = new AbstractListener() {
+        @Override public Object execute(Map<String, Object> args) throws Exception {
+            String driverPath = null;
+
+            if (args.containsKey("driverPath"))
+                driverPath = args.get("driverPath").toString();
+
+            if (!args.containsKey("driverClass"))
+                throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
+
+            String driverCls = args.get("driverClass").toString();
+
+            if (!args.containsKey("url"))
+                throw new IllegalArgumentException("Missing url in arguments: " + args);
+
+            String url = args.get("url").toString();
+
+            if (!args.containsKey("info"))
+                throw new IllegalArgumentException("Missing info in arguments: " + args);
+
+            Properties info = new Properties();
+
+            info.putAll((Map)args.get("info"));
+
+            return schemas(driverPath, driverCls, url, info);
+        }
+    };
+
+    private final AbstractListener metadataLsnr = new AbstractListener() {
+        @SuppressWarnings("unchecked")
+        @Override public Object execute(Map<String, Object> args) throws Exception {
+            String driverPath = null;
+
+            if (args.containsKey("driverPath"))
+                driverPath = args.get("driverPath").toString();
+
+            if (!args.containsKey("driverClass"))
+                throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
+
+            String driverCls = args.get("driverClass").toString();
+
+            if (!args.containsKey("url"))
+                throw new IllegalArgumentException("Missing url in arguments: " + args);
+
+            String url = args.get("url").toString();
+
+            if (!args.containsKey("info"))
+                throw new IllegalArgumentException("Missing info in arguments: " + args);
+
+            Properties info = new Properties();
+
+            info.putAll((Map)args.get("info"));
+
+            if (!args.containsKey("schemas"))
+                throw new IllegalArgumentException("Missing schemas in arguments: " + args);
+
+            List<String> schemas = (List<String>)args.get("schemas");
+
+            if (!args.containsKey("tablesOnly"))
+                throw new IllegalArgumentException("Missing tablesOnly in arguments: " + args);
+
+            boolean tblsOnly = (boolean)args.get("tablesOnly");
+
+            return metadata(driverPath, driverCls, url, info, schemas, tblsOnly);
+        }
+    };
+
+    private final AbstractListener availableDriversLsnr = new AbstractListener() {
+        @Override public Object execute(Map<String, Object> args) throws Exception {
+            if (driversFolder == null) {
+                log.info("JDBC drivers folder not specified, returning empty list");
+
+                return Collections.emptyList();
+            }
+
+            if (log.isDebugEnabled())
+                log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
+
+            File[] list = driversFolder.listFiles(new FilenameFilter() {
+                @Override public boolean accept(File dir, String name) {
+                    return name.endsWith(".jar");
+                }
+            });
+
+            if (list == null) {
+                log.info("JDBC drivers folder has no files, returning empty list");
+
+                return Collections.emptyList();
+            }
+
+            List<JdbcDriver> res = new ArrayList<>();
+
+            for (File file : list) {
+                try {
+                    boolean win = System.getProperty("os.name").contains("win");
+
+                    URL url = new URL("jar", null,
+                        "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
+
+                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
+                        String jdbcDriverCls = reader.readLine();
+
+                        res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
+
+                        if (log.isDebugEnabled())
+                            log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
+                    }
+                }
+                catch (IOException e) {
+                    res.add(new JdbcDriver(file.getName(), null));
+
+                    log.info("Found: [driver=" + file + "]");
+                    log.info("Failed to detect driver class: " + e.getMessage());
+                }
+            }
+
+            return res;
+        }
+    };
+
+    /**
+     * @param cfg Config.
+     */
+    public DatabaseListener(AgentConfiguration cfg) {
+        driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @return Connection to database.
+     * @throws SQLException
+     */
+    private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo) throws SQLException {
+        if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
+            return AgentMetadataDemo.testDrive();
+
+        if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
+            jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
+
+        return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @return Collection of schema names.
+     * @throws SQLException
+     */
+    protected Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo) throws SQLException {
+        if (log.isDebugEnabled())
+            log.debug("Start collecting database schemas [drvJar=" + jdbcDriverJarPath +
+                ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
+
+        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+            Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
+
+            if (log.isDebugEnabled())
+                log.debug("Finished collection of schemas [jdbcUrl=" + jdbcUrl + ", count=" + schemas.size() + "]");
+
+            return schemas;
+        }
+        catch (Throwable e) {
+            log.error("Failed to collect schemas", e);
+
+            throw new SQLException("Failed to collect schemas", e);
+        }
+    }
+
+    /**
+     * Listener for drivers.
+     *
+     * @return Drivers in drivers folder
+     * @see AgentConfiguration#driversFolder
+     */
+    public Emitter.Listener availableDriversListener() {
+        return availableDriversLsnr;
+    }
+
+    /**
+     * Listener for schema names.
+     *
+     * @return Collection of schema names.
+     */
+    public Emitter.Listener schemasListener() {
+        return schemasLsnr;
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @param schemas List of schema names to process.
+     * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
+     * @return Collection of tables.
+     */
+    protected Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
+        if (log.isDebugEnabled())
+            log.debug("Start collecting database metadata [drvJar=" + jdbcDriverJarPath +
+                ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
+
+        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+            Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
+
+            if (log.isDebugEnabled())
+                log.debug("Finished collection of metadata [jdbcUrl=" + jdbcUrl + ", count=" + metadata.size() + "]");
+
+            return metadata;
+        }
+        catch (Throwable e) {
+            log.error("Failed to collect metadata", e);
+
+            throw new SQLException("Failed to collect metadata", e);
+        }
+    }
+
+    /**
+     * Listener for tables.
+     *
+     * @return Collection of tables.
+     */
+    public Emitter.Listener metadataListener() {
+        return metadataLsnr;
+    }
+
+    /**
+     * Stop handler.
+     */
+    public void stop() {
+        availableDriversLsnr.stop();
+
+        schemasLsnr.stop();
+
+        metadataLsnr.stop();
+    }
+
+    /**
+     * Wrapper class for later to be transformed to JSON and send to Web Console.
+     */
+    private static class JdbcDriver {
+        /** */
+        public final String jdbcDriverJar;
+        /** */
+        public final String jdbcDriverCls;
+
+        /**
+         * @param jdbcDriverJar File name of driver jar file.
+         * @param jdbcDriverCls Optional JDBC driver class.
+         */
+        public JdbcDriver(String jdbcDriverJar, String jdbcDriverCls) {
+            this.jdbcDriverJar = jdbcDriverJar;
+            this.jdbcDriverCls = jdbcDriverCls;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
deleted file mode 100644
index 1b4b565..0000000
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
+++ /dev/null
@@ -1,276 +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.console.agent.handlers;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.URISyntaxException;
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.codec.Charsets;
-import org.apache.http.Header;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.ignite.console.agent.AgentConfiguration;
-import org.apache.ignite.console.demo.AgentClusterDemo;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_NODE_PORT;
-
-/**
- * API to translate REST requests to Ignite cluster.
- */
-public class RestHandler extends AbstractHandler {
-    /** */
-    private static final Logger log = Logger.getLogger(RestHandler.class.getName());
-
-    /** */
-    private final AgentConfiguration cfg;
-
-    /** */
-    private CloseableHttpClient httpClient;
-
-    /**
-     * @param cfg Config.
-     */
-    public RestHandler(AgentConfiguration cfg) {
-        this.cfg = cfg;
-    }
-
-    /**
-     * Start HTTP client for communication with node via REST.
-     */
-    public void start() {
-        httpClient = HttpClientBuilder.create().build();
-    }
-
-    /**
-     * Stop HTTP client.
-     */
-    public void stop() {
-        if (httpClient != null) {
-            try {
-                httpClient.close();
-            }
-            catch (IOException ignore) {
-                // No-op.
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @SuppressWarnings("unchecked")
-    @Override public Object execute(Map<String, Object> args) throws Exception {
-        if (log.isDebugEnabled())
-            log.debug("Start parse REST command args: " + args);
-
-        String uri = null;
-
-        if (args.containsKey("uri"))
-            uri = args.get("uri").toString();
-
-        Map<String, Object> params = null;
-
-        if (args.containsKey("params"))
-            params = (Map<String, Object>)args.get("params");
-
-        if (!args.containsKey("demo"))
-            throw new IllegalArgumentException("Missing demo flag in arguments: " + args);
-
-        boolean demo = (boolean)args.get("demo");
-
-        if (!args.containsKey("method"))
-            throw new IllegalArgumentException("Missing method in arguments: " + args);
-
-        String mtd = args.get("method").toString();
-
-        Map<String, Object> headers = null;
-
-        if (args.containsKey("headers"))
-            headers = (Map<String, Object>)args.get("headers");
-
-        String body = null;
-
-        if (args.containsKey("body"))
-            body = args.get("body").toString();
-
-        return executeRest(uri, params, demo, mtd, headers, body);
-    }
-
-    /**
-     * @param uri Url.
-     * @param params Params.
-     * @param demo Use demo node.
-     * @param mtd Method.
-     * @param headers Headers.
-     * @param body Body.
-     */
-    protected RestResult executeRest(String uri, Map<String, Object> params, boolean demo,
-        String mtd, Map<String, Object> headers, String body) throws IOException, URISyntaxException {
-        if (log.isDebugEnabled())
-            log.debug("Start execute REST command [method=" + mtd + ", uri=/" + (uri == null ? "" : uri) +
-                ", parameters=" + params + "]");
-
-        final URIBuilder builder;
-
-        if (demo) {
-            // try start demo if needed.
-            AgentClusterDemo.testDrive(cfg);
-
-            // null if demo node not started yet.
-            if (cfg.demoNodeUri() == null)
-                return RestResult.fail("Demo node is not started yet.", 404);
-
-            builder = new URIBuilder(cfg.demoNodeUri());
-        }
-        else
-            builder = new URIBuilder(cfg.nodeUri());
-
-        if (builder.getPort() == -1)
-            builder.setPort(DFLT_NODE_PORT);
-
-        if (uri != null) {
-            if (!uri.startsWith("/") && !cfg.nodeUri().endsWith("/"))
-                uri = '/' + uri;
-
-            builder.setPath(uri);
-        }
-
-        if (params != null) {
-            for (Map.Entry<String, Object> entry : params.entrySet()) {
-                if (entry.getValue() != null)
-                    builder.addParameter(entry.getKey(), entry.getValue().toString());
-            }
-        }
-
-        HttpRequestBase httpReq = null;
-
-        try {
-            if ("GET".equalsIgnoreCase(mtd))
-                httpReq = new HttpGet(builder.build());
-            else if ("POST".equalsIgnoreCase(mtd)) {
-                HttpPost post;
-
-                if (body == null) {
-                    List<NameValuePair> nvps = builder.getQueryParams();
-
-                    builder.clearParameters();
-
-                    post = new HttpPost(builder.build());
-
-                    if (!nvps.isEmpty())
-                        post.setEntity(new UrlEncodedFormEntity(nvps));
-                }
-                else {
-                    post = new HttpPost(builder.build());
-
-                    post.setEntity(new StringEntity(body));
-                }
-
-                httpReq = post;
-            }
-            else
-                throw new IOException("Unknown HTTP-method: " + mtd);
-
-            if (headers != null) {
-                for (Map.Entry<String, Object> entry : headers.entrySet())
-                    httpReq.addHeader(entry.getKey(), entry.getValue() == null ? null : entry.getValue().toString());
-            }
-
-            try (CloseableHttpResponse resp = httpClient.execute(httpReq)) {
-                ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-                resp.getEntity().writeTo(out);
-
-                Charset charset = Charsets.UTF_8;
-
-                Header encodingHdr = resp.getEntity().getContentEncoding();
-
-                if (encodingHdr != null) {
-                    String encoding = encodingHdr.getValue();
-
-                    charset = Charsets.toCharset(encoding);
-                }
-
-                return RestResult.success(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
-            }
-            catch (ConnectException e) {
-                log.info("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
-
-                return RestResult.fail("Failed connect to node and execute REST command.", 404);
-            }
-        }
-        finally {
-            if (httpReq != null)
-                httpReq.reset();
-        }
-    }
-
-    /**
-     * Request result.
-     */
-    public static class RestResult {
-        /** The field contains description of error if server could not handle the request. */
-        public final String error;
-
-        /** REST http code. */
-        public final int code;
-
-        /** The field contains result of command. */
-        public final String data;
-
-        /**
-         * @param error The field contains description of error if server could not handle the request.
-         * @param resCode REST http code.
-         * @param res The field contains result of command.
-         */
-        private RestResult(String error, int resCode, String res) {
-            this.error = error;
-            this.code = resCode;
-            this.data = res;
-        }
-
-        /**
-         * @param error The field contains description of error if server could not handle the request.
-         * @param restCode REST http code.
-         * @return Request result.
-         */
-        public static RestResult fail(String error, int restCode) {
-            return new RestResult(error, restCode, null);
-        }
-
-        /**
-         * @param code REST http code.
-         * @param data The field contains result of command.
-         * @return Request result.
-         */
-        public static RestResult success(int code, String data) {
-            return new RestResult(null, code, data);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/262a3410/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestListener.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestListener.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestListener.java
new file mode 100644
index 0000000..1e86549
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestListener.java
@@ -0,0 +1,280 @@
+/*
+ * 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.console.agent.handlers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.apache.commons.codec.Charsets;
+import org.apache.http.Header;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.demo.AgentClusterDemo;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_NODE_PORT;
+
+/**
+ * API to translate REST requests to Ignite cluster.
+ */
+public class RestListener extends AbstractListener {
+    /** */
+    private static final Logger log = Logger.getLogger(RestListener.class.getName());
+
+    /** */
+    private final AgentConfiguration cfg;
+
+    /** */
+    private CloseableHttpClient httpClient;
+
+    /**
+     * @param cfg Config.
+     */
+    public RestListener(AgentConfiguration cfg) {
+        super();
+
+        this.cfg = cfg;
+
+        httpClient = HttpClientBuilder.create().build();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void stop() {
+        super.stop();
+
+        if (httpClient != null) {
+            try {
+                httpClient.close();
+            }
+            catch (IOException ignore) {
+                // No-op.
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected ExecutorService newThreadPool() {
+        return Executors.newCachedThreadPool();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public Object execute(Map<String, Object> args) throws Exception {
+        if (log.isDebugEnabled())
+            log.debug("Start parse REST command args: " + args);
+
+        String uri = null;
+
+        if (args.containsKey("uri"))
+            uri = args.get("uri").toString();
+
+        Map<String, Object> params = null;
+
+        if (args.containsKey("params"))
+            params = (Map<String, Object>)args.get("params");
+
+        if (!args.containsKey("demo"))
+            throw new IllegalArgumentException("Missing demo flag in arguments: " + args);
+
+        boolean demo = (boolean)args.get("demo");
+
+        if (!args.containsKey("method"))
+            throw new IllegalArgumentException("Missing method in arguments: " + args);
+
+        String mtd = args.get("method").toString();
+
+        Map<String, Object> headers = null;
+
+        if (args.containsKey("headers"))
+            headers = (Map<String, Object>)args.get("headers");
+
+        String body = null;
+
+        if (args.containsKey("body"))
+            body = args.get("body").toString();
+
+        return executeRest(uri, params, demo, mtd, headers, body);
+    }
+
+    /**
+     * @param uri Url.
+     * @param params Params.
+     * @param demo Use demo node.
+     * @param mtd Method.
+     * @param headers Headers.
+     * @param body Body.
+     */
+    protected RestResult executeRest(String uri, Map<String, Object> params, boolean demo,
+        String mtd, Map<String, Object> headers, String body) throws IOException, URISyntaxException {
+        if (log.isDebugEnabled())
+            log.debug("Start execute REST command [method=" + mtd + ", uri=/" + (uri == null ? "" : uri) +
+                ", parameters=" + params + "]");
+
+        final URIBuilder builder;
+
+        if (demo) {
+            // try start demo if needed.
+            AgentClusterDemo.testDrive(cfg);
+
+            // null if demo node not started yet.
+            if (cfg.demoNodeUri() == null)
+                return RestResult.fail("Demo node is not started yet.", 404);
+
+            builder = new URIBuilder(cfg.demoNodeUri());
+        }
+        else
+            builder = new URIBuilder(cfg.nodeUri());
+
+        if (builder.getPort() == -1)
+            builder.setPort(DFLT_NODE_PORT);
+
+        if (uri != null) {
+            if (!uri.startsWith("/") && !cfg.nodeUri().endsWith("/"))
+                uri = '/' + uri;
+
+            builder.setPath(uri);
+        }
+
+        if (params != null) {
+            for (Map.Entry<String, Object> entry : params.entrySet()) {
+                if (entry.getValue() != null)
+                    builder.addParameter(entry.getKey(), entry.getValue().toString());
+            }
+        }
+
+        HttpRequestBase httpReq = null;
+
+        try {
+            if ("GET".equalsIgnoreCase(mtd))
+                httpReq = new HttpGet(builder.build());
+            else if ("POST".equalsIgnoreCase(mtd)) {
+                HttpPost post;
+
+                if (body == null) {
+                    List<NameValuePair> nvps = builder.getQueryParams();
+
+                    builder.clearParameters();
+
+                    post = new HttpPost(builder.build());
+
+                    if (!nvps.isEmpty())
+                        post.setEntity(new UrlEncodedFormEntity(nvps));
+                }
+                else {
+                    post = new HttpPost(builder.build());
+
+                    post.setEntity(new StringEntity(body));
+                }
+
+                httpReq = post;
+            }
+            else
+                throw new IOException("Unknown HTTP-method: " + mtd);
+
+            if (headers != null) {
+                for (Map.Entry<String, Object> entry : headers.entrySet())
+                    httpReq.addHeader(entry.getKey(), entry.getValue() == null ? null : entry.getValue().toString());
+            }
+
+            try (CloseableHttpResponse resp = httpClient.execute(httpReq)) {
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+                resp.getEntity().writeTo(out);
+
+                Charset charset = Charsets.UTF_8;
+
+                Header encodingHdr = resp.getEntity().getContentEncoding();
+
+                if (encodingHdr != null) {
+                    String encoding = encodingHdr.getValue();
+
+                    charset = Charsets.toCharset(encoding);
+                }
+
+                return RestResult.success(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
+            }
+            catch (ConnectException e) {
+                log.info("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
+
+                return RestResult.fail("Failed connect to node and execute REST command.", 404);
+            }
+        }
+        finally {
+            if (httpReq != null)
+                httpReq.reset();
+        }
+    }
+
+    /**
+     * Request result.
+     */
+    public static class RestResult {
+        /** The field contains description of error if server could not handle the request. */
+        public final String error;
+
+        /** REST http code. */
+        public final int code;
+
+        /** The field contains result of command. */
+        public final String data;
+
+        /**
+         * @param error The field contains description of error if server could not handle the request.
+         * @param resCode REST http code.
+         * @param res The field contains result of command.
+         */
+        private RestResult(String error, int resCode, String res) {
+            this.error = error;
+            this.code = resCode;
+            this.data = res;
+        }
+
+        /**
+         * @param error The field contains description of error if server could not handle the request.
+         * @param restCode REST http code.
+         * @return Request result.
+         */
+        public static RestResult fail(String error, int restCode) {
+            return new RestResult(error, restCode, null);
+        }
+
+        /**
+         * @param code REST http code.
+         * @param data The field contains result of command.
+         * @return Request result.
+         */
+        public static RestResult success(int code, String data) {
+            return new RestResult(null, code, data);
+        }
+    }
+}


[43/50] [abbrv] ignite git commit: IGNITE-4692 .NET: Add ClassName and Message to JavaException

Posted by sb...@apache.org.
IGNITE-4692 .NET: Add ClassName and Message to JavaException


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: d8ad967c85fb56810ee7fab76494b176f443d773
Parents: 00dd3d8
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Mon Feb 13 19:34:34 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Mon Feb 13 19:34:34 2017 +0300

----------------------------------------------------------------------
 .../Apache.Ignite.Core.Tests/ExceptionsTest.cs  | 28 +++++++++
 .../Apache.Ignite.Core/Common/JavaException.cs  | 62 +++++++++++++++++++-
 .../Apache.Ignite.Core/Impl/ExceptionUtils.cs   |  4 +-
 3 files changed, 91 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d8ad967c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs
index 8c23ab7..7afb10f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ExceptionsTest.cs
@@ -111,6 +111,34 @@ namespace Apache.Ignite.Core.Tests
 
             Assert.IsNotNull(javaEx);
             Assert.IsTrue(javaEx.Message.Contains("at " + ExceptionTask));
+            Assert.AreEqual(name, javaEx.JavaMessage);
+            Assert.IsTrue(javaEx.JavaClassName.EndsWith("." + name));
+
+            // Check serialization.
+            var formatter = new BinaryFormatter();
+            using (var ms = new MemoryStream())
+            {
+                formatter.Serialize(ms, ex);
+
+                ms.Seek(0, SeekOrigin.Begin);
+
+                var res = (T) formatter.Deserialize(ms);
+
+                Assert.AreEqual(ex.Message, res.Message);
+                Assert.AreEqual(ex.Source, res.Source);
+                Assert.AreEqual(ex.StackTrace, res.StackTrace);
+                Assert.AreEqual(ex.HelpLink, res.HelpLink);
+
+                var resJavaEx = res.InnerException as JavaException;
+
+                Assert.IsNotNull(resJavaEx);
+                Assert.AreEqual(javaEx.Message, resJavaEx.Message);
+                Assert.AreEqual(javaEx.JavaClassName, resJavaEx.JavaClassName);
+                Assert.AreEqual(javaEx.JavaMessage, resJavaEx.JavaMessage);
+                Assert.AreEqual(javaEx.StackTrace, resJavaEx.StackTrace);
+                Assert.AreEqual(javaEx.Source, resJavaEx.Source);
+                Assert.AreEqual(javaEx.HelpLink, resJavaEx.HelpLink);
+            }
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/d8ad967c/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs
index 5f7ba66..1988335 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs
@@ -26,6 +26,18 @@ namespace Apache.Ignite.Core.Common
     [Serializable]
     public class JavaException : IgniteException
     {
+        /** JavaClassName field. */
+        private const string JavaClassNameField = "JavaClassName";
+
+        /** JavaMessage field. */
+        private const string JavaMessageField = "JavaMessage";
+
+        /** Java exception class name. */
+        private readonly string _javaClassName;
+        
+        /** Java exception message. */
+        private readonly string _javaMessage;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="JavaException"/> class.
         /// </summary>
@@ -44,6 +56,21 @@ namespace Apache.Ignite.Core.Common
         }
 
         /// <summary>
+        /// Initializes a new instance of the <see cref="JavaException" /> class.
+        /// </summary>
+        /// <param name="javaClassName">Java exception class name.</param>
+        /// <param name="javaMessage">Java exception message.</param>
+        /// <param name="stackTrace">Java stack trace.</param>
+        public JavaException(string javaClassName, string javaMessage, string stackTrace)
+            : base(stackTrace ?? javaMessage)
+        {
+            // Send stackTrace to base ctor because it has all information, including class names and messages.
+            // Store ClassName and Message separately for mapping purposes.
+            _javaClassName = javaClassName;
+            _javaMessage = javaMessage;
+        }
+
+        /// <summary>
         /// Initializes a new instance of the <see cref="JavaException"/> class.
         /// </summary>
         /// <param name="message">The message.</param>
@@ -60,7 +87,40 @@ namespace Apache.Ignite.Core.Common
         /// <param name="ctx">Streaming context.</param>
         protected JavaException(SerializationInfo info, StreamingContext ctx) : base(info, ctx)
         {
-            // No-op.
+            _javaClassName = info.GetString(JavaClassNameField);
+            _javaMessage = info.GetString(JavaMessageField);
+        }
+
+        /// <summary>
+        /// When overridden in a derived class, sets the <see cref="SerializationInfo" /> 
+        /// with information about the exception.
+        /// </summary>
+        /// <param name="info">The <see cref="SerializationInfo" /> that holds the serialized object data
+        /// about the exception being thrown.</param>
+        /// <param name="context">The <see cref="StreamingContext" /> that contains contextual information
+        /// about the source or destination.</param>
+        public override void GetObjectData(SerializationInfo info, StreamingContext context)
+        {
+            base.GetObjectData(info, context);
+
+            info.AddValue(JavaClassNameField, _javaClassName);
+            info.AddValue(JavaMessageField, _javaMessage);
+        }
+
+        /// <summary>
+        /// Gets the Java exception class name.
+        /// </summary>
+        public string JavaClassName
+        {
+            get { return _javaClassName; }
+        }
+
+        /// <summary>
+        /// Gets the Java exception message.
+        /// </summary>
+        public string JavaMessage
+        {
+            get { return _javaMessage; }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d8ad967c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
index 64f3ccc..4534e91 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
@@ -124,8 +124,8 @@ namespace Apache.Ignite.Core.Impl
             BinaryReader reader = null, Exception innerException = null)
         {
             // Set JavaException as inner only if there is no InnerException.
-            if (innerException == null && !string.IsNullOrEmpty(stackTrace))
-                innerException = new JavaException(stackTrace);
+            if (innerException == null)
+                innerException = new JavaException(clsName, msg, stackTrace);
 
             ExceptionFactoryDelegate ctor;
 


[13/50] [abbrv] ignite git commit: IGNITE-4619 .NET: TransactionScope example

Posted by sb...@apache.org.
IGNITE-4619 .NET: TransactionScope example

This closes #1492


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: e6cc8cdab85c96d7a2088d3a5267f3f42039601b
Parents: 26ee9c2
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Wed Feb 8 13:15:08 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Wed Feb 8 13:15:08 2017 +0300

----------------------------------------------------------------------
 .../Apache.Ignite.Examples.csproj               |  1 +
 .../Datagrid/TransactionExample.cs              | 75 +++++++++++++++-----
 2 files changed, 59 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e6cc8cda/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Apache.Ignite.Examples.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Apache.Ignite.Examples.csproj b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Apache.Ignite.Examples.csproj
index ebf9e92..c3ea378 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Apache.Ignite.Examples.csproj
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Apache.Ignite.Examples.csproj
@@ -49,6 +49,7 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Transactions" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Compute\ClosureExample.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6cc8cda/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/TransactionExample.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/TransactionExample.cs b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/TransactionExample.cs
index f90cf96..83d08ff 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/TransactionExample.cs
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.Examples/Datagrid/TransactionExample.cs
@@ -18,7 +18,9 @@
 namespace Apache.Ignite.Examples.Datagrid
 {
     using System;
+    using System.Transactions;
     using Apache.Ignite.Core;
+    using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Transactions;
     using Apache.Ignite.ExamplesDll.Binary;
@@ -59,18 +61,9 @@ namespace Apache.Ignite.Examples.Datagrid
                     AtomicityMode = CacheAtomicityMode.Transactional
                 });
 
-                // Clean up caches on all nodes before run.
-                cache.Clear();
+                InitAccounts(cache);
 
-                // Initialize.
-                cache.Put(1, new Account(1, 100));
-                cache.Put(2, new Account(2, 200));
-
-                Console.WriteLine();
-                Console.WriteLine(">>> Accounts before transfer: ");
-                Console.WriteLine(">>>     " + cache.Get(1));
-                Console.WriteLine(">>>     " + cache.Get(2));
-                Console.WriteLine();
+                Console.WriteLine("\n>>> Transferring with Ignite transaction API...");
 
                 // Transfer money between accounts in a single transaction.
                 using (var tx = cache.Ignite.GetTransactions().TxStart(TransactionConcurrency.Pessimistic,
@@ -88,18 +81,66 @@ namespace Apache.Ignite.Examples.Datagrid
                     tx.Commit();
                 }
 
-                Console.WriteLine(">>> Transfer finished.");
+                DisplayAccounts(cache);
 
-                Console.WriteLine();
-                Console.WriteLine(">>> Accounts after transfer: ");
-                Console.WriteLine(">>>     " + cache.Get(1));
-                Console.WriteLine(">>>     " + cache.Get(2));
-                Console.WriteLine();
+                InitAccounts(cache);
+
+                Console.WriteLine("\n>>> Transferring with TransactionScope API...");
+
+                // Do the same transaction with TransactionScope API.
+                using (var ts = new TransactionScope())
+                {
+                    Account acc1 = cache.Get(1);
+                    Account acc2 = cache.Get(2);
+
+                    acc1.Balance += 100;
+                    acc2.Balance -= 100;
+
+                    cache.Put(1, acc1);
+                    cache.Put(2, acc2);
+
+                    ts.Complete();
+                }
+
+                DisplayAccounts(cache);
             }
 
             Console.WriteLine();
             Console.WriteLine(">>> Example finished, press any key to exit ...");
             Console.ReadKey();
         }
+
+        /// <summary>
+        /// Displays accounts.
+        /// </summary>
+        private static void DisplayAccounts(ICache<int, Account> cache)
+        {
+            Console.WriteLine(">>> Transfer finished.");
+
+            Console.WriteLine();
+            Console.WriteLine(">>> Accounts after transfer: ");
+            Console.WriteLine(">>>     " + cache.Get(1));
+            Console.WriteLine(">>>     " + cache.Get(2));
+            Console.WriteLine();
+        }
+
+        /// <summary>
+        /// Initializes account balance.
+        /// </summary>
+        private static void InitAccounts(ICache<int, Account> cache)
+        {
+            // Clean up caches on all nodes before run.
+            cache.Clear();
+
+            // Initialize.
+            cache.Put(1, new Account(1, 100));
+            cache.Put(2, new Account(2, 200));
+
+            Console.WriteLine();
+            Console.WriteLine(">>> Accounts before transfer: ");
+            Console.WriteLine(">>>     " + cache.Get(1));
+            Console.WriteLine(">>>     " + cache.Get(2));
+            Console.WriteLine();
+        }
     }
 }


[25/50] [abbrv] ignite git commit: Merge branch 'ignite-1.7.6'

Posted by sb...@apache.org.
Merge branch 'ignite-1.7.6'


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: aaeda7214f738dff2fbd865e83250413a9b7cc0f
Parents: e1c3dda f350578
Author: agura <ag...@apache.org>
Authored: Thu Feb 9 20:29:48 2017 +0300
Committer: agura <ag...@apache.org>
Committed: Thu Feb 9 20:29:48 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/IgniteSystemProperties.java   |   3 +
 .../org/apache/ignite/cache/QueryEntity.java    |  21 +
 .../org/apache/ignite/cache/query/SqlQuery.java |  25 +
 .../processors/cache/EntryGetResult.java        |  65 +++
 .../processors/cache/GridCacheAdapter.java      | 125 +++--
 .../processors/cache/GridCacheContext.java      |   4 +-
 .../processors/cache/GridCacheEntryEx.java      |  42 +-
 .../processors/cache/GridCacheMapEntry.java     | 140 +++++-
 .../processors/cache/GridCacheUtils.java        |   3 +
 .../processors/cache/IgniteCacheProxy.java      |   3 +
 .../processors/cache/ReaderArguments.java       |  74 +++
 .../distributed/dht/GridDhtCacheAdapter.java    |   9 +-
 .../cache/distributed/dht/GridDhtGetFuture.java |  83 ++--
 .../distributed/dht/GridDhtGetSingleFuture.java |  75 ++-
 .../dht/GridPartitionedGetFuture.java           |  10 +-
 .../dht/GridPartitionedSingleGetFuture.java     |  10 +-
 .../dht/atomic/GridDhtAtomicCache.java          |  12 +-
 .../dht/colocated/GridDhtColocatedCache.java    |  10 +-
 .../distributed/near/GridNearGetFuture.java     |  19 +-
 .../local/atomic/GridLocalAtomicCache.java      |  11 +-
 .../cache/query/GridCacheQueryManager.java      |  83 +++-
 .../continuous/CacheContinuousQueryHandler.java |  81 +++-
 .../cache/transactions/IgniteTxHandler.java     |   2 +-
 .../transactions/IgniteTxLocalAdapter.java      |  65 +--
 .../processors/query/GridQueryIndexing.java     |   4 +-
 .../processors/query/GridQueryProcessor.java    |  79 ++--
 .../query/GridQueryTypeDescriptor.java          |   7 +
 .../communication/tcp/TcpCommunicationSpi.java  |  16 +
 .../ignite/spi/discovery/tcp/ClientImpl.java    |  90 +++-
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  63 ++-
 .../messages/TcpDiscoveryAbstractMessage.java   |  21 +
 modules/core/src/test/config/log4j-test.xml     |   6 +
 .../cache/CacheConcurrentReadThroughTest.java   | 184 ++++++++
 .../processors/cache/GridCacheTestEntryEx.java  |  30 +-
 .../near/GridNearCacheStoreUpdateTest.java      | 466 +++++++++++++++++++
 .../GridNearOffheapCacheStoreUpdateTest.java    |  35 ++
 .../cache/query/IndexingSpiQuerySelfTest.java   |  69 ++-
 .../IndexingSpiQueryWithH2IndexingSelfTest.java |  36 ++
 .../tcp/TcpCommunicationSpiDropNodesTest.java   | 322 +++++++++++++
 .../TcpCommunicationSpiFaultyClientTest.java    | 265 +++++++++++
 .../ignite/testframework/GridTestNode.java      |   1 +
 .../testframework/junits/GridAbstractTest.java  |   2 +
 .../testsuites/IgniteCacheTestSuite2.java       |   7 +
 .../IgniteSpiCommunicationSelfTestSuite.java    |   5 +
 .../IgniteSpiDiscoverySelfTestSuite.java        |   2 +-
 .../processors/query/h2/IgniteH2Indexing.java   |  30 +-
 ...CacheScanPartitionQueryFallbackSelfTest.java |   2 +-
 .../cache/IgniteCacheAbstractQuerySelfTest.java | 294 ++++++++++++
 .../IgniteCachePartitionedQuerySelfTest.java    |  85 ++++
 .../h2/GridIndexingSpiAbstractSelfTest.java     |  29 +-
 50 files changed, 2719 insertions(+), 406 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 8d0a962,59665bb..264fa14
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@@ -1995,12 -2023,11 +2016,12 @@@ public abstract class GridCacheAdapter<
                                              GridCacheEntryEx entry = entryEx(key);
  
                                              try {
-                                                 GridCacheVersion verSet = entry.versionedValue(cacheVal,
-                                                     ver,
+                                                 T2<CacheObject, GridCacheVersion> verVal = entry.versionedValue(
+                                                     cacheVal,
+                                                     res.version(),
                                                      null,
-                                                     expiry);
- 
-                                                 boolean set = verSet != null;
++                                                    expiry,
+                                                     readerArgs);
  
                                                  if (log.isDebugEnabled())
                                                      log.debug("Set value loaded from store into entry [" +

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
index 9e9b496,51f423a..f26288f
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
@@@ -725,15 -755,15 +755,17 @@@ public interface GridCacheEntryEx 
       * @param val New value.
       * @param curVer Version to match or {@code null} if match is not required.
       * @param newVer Version to set.
 +     * @param loadExpiryPlc Expiry policy if entry is loaded from store.
-      * @return Non null version if value was set.
+      * @param readerArgs Reader will be added if not null.
+      * @return Current version and value.
       * @throws IgniteCheckedException If index could not be updated.
       * @throws GridCacheEntryRemovedException If entry was removed.
       */
-     public GridCacheVersion versionedValue(CacheObject val,
+     public T2<CacheObject, GridCacheVersion> versionedValue(CacheObject val,
          @Nullable GridCacheVersion curVer,
          @Nullable GridCacheVersion newVer,
-         @Nullable IgniteCacheExpiryPolicy loadExpiryPlc)
++        @Nullable IgniteCacheExpiryPolicy loadExpiryPlc,
+         @Nullable ReaderArguments readerArgs)
          throws IgniteCheckedException, GridCacheEntryRemovedException;
  
      /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 52b779d,59e4181..942ae21
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@@ -3549,14 -3609,28 +3609,29 @@@ public abstract class GridCacheMapEntr
      }
  
      /** {@inheritDoc} */
-     @Override public synchronized GridCacheVersion versionedValue(CacheObject val,
+     @Override public synchronized void clearReserveForLoad(GridCacheVersion ver) throws IgniteCheckedException {
+         if (obsoleteVersionExtras() != null)
+             return;
+ 
+         if (ver.equals(this.ver)) {
+             assert evictionDisabled() : this;
+ 
+             flags &= ~IS_EVICT_DISABLED;
+         }
+     }
+ 
+     /** {@inheritDoc} */
+     @Override public synchronized T2<CacheObject, GridCacheVersion> versionedValue(CacheObject val,
          GridCacheVersion curVer,
          GridCacheVersion newVer,
-         @Nullable IgniteCacheExpiryPolicy loadExpiryPlc)
++        @Nullable IgniteCacheExpiryPolicy loadExpiryPlc,
+         @Nullable ReaderArguments readerArgs)
 -        throws IgniteCheckedException, GridCacheEntryRemovedException
 -    {
 +        throws IgniteCheckedException, GridCacheEntryRemovedException {
 +
          checkObsolete();
  
+         addReaderIfNeed(readerArgs);
+ 
          if (curVer == null || curVer.equals(ver)) {
              if (val != this.val) {
                  GridCacheMvcc mvcc = mvccExtras();

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetSingleFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index e657f32,f601e0a..1b6179e
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@@ -2381,7 -2293,7 +2383,7 @@@ public class GridDhtAtomicCache<K, V> e
                          try {
                              GridCacheVersion ver = entry.version();
  
--                            entry.versionedValue(ctx.toCacheObject(v), null, ver, null);
++                            entry.versionedValue(ctx.toCacheObject(v), null, ver, null, null);
                          }
                          catch (GridCacheEntryRemovedException e) {
                              assert false : "Entry should not get obsolete while holding lock [entry=" + entry +

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
index 63b0717,83edab4..a9a7d7c
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
@@@ -1253,8 -1312,8 +1312,8 @@@ public class CacheContinuousQueryHandle
                                  try {
                                      cctx.io().send(node, msg, GridIoPolicy.SYSTEM_POOL);
                                  }
 -                                catch (ClusterTopologyCheckedException e) {
 +                                catch (ClusterTopologyCheckedException ignored) {
-                                     IgniteLogger log = ctx.log(getClass());
+                                     IgniteLogger log = ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY);
  
                                      if (log.isDebugEnabled())
                                          log.debug("Failed to send acknowledge message, node left " +

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index 7ceb701,f05d90d..cd4c55c
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@@ -439,8 -437,9 +440,9 @@@ public abstract class IgniteTxLocalAdap
                              CU.subjectId(this, cctx),
                              null,
                              resolveTaskName(),
 -                            expiryPlc,
 +                            expiryPlc0,
-                             txEntry == null ? keepBinary : txEntry.keepBinary());
+                             txEntry == null ? keepBinary : txEntry.keepBinary(),
+                             null);
  
                          if (res == null) {
                              if (misses == null)
@@@ -476,20 -475,22 +478,23 @@@
                              CacheObject cacheVal = cacheCtx.toCacheObject(val);
  
                              while (true) {
 -                                GridCacheEntryEx entry = cacheCtx.cache().entryEx(key);
 +                                GridCacheEntryEx entry = cacheCtx.cache().entryEx(key, topVer);
  
                                  try {
-                                     GridCacheVersion setVer = entry.versionedValue(cacheVal, ver, null, null);
- 
-                                     boolean set = setVer != null;
+                                     T2<CacheObject, GridCacheVersion> verVal = entry.versionedValue(cacheVal,
+                                         ver,
+                                         null,
++                                        null,
+                                         null);
  
-                                     if (set)
-                                         ver = setVer;
+                                     if (log.isDebugEnabled()) {
+                                         log.debug("Set value loaded from store into entry [" +
+                                             "oldVer=" + ver +
+                                             ", newVer=" + verVal.get2() +
+                                             ", entry=" + entry + ']');
+                                     }
  
-                                     if (log.isDebugEnabled())
-                                         log.debug("Set value loaded from store into entry [set=" + set +
-                                             ", curVer=" + ver + ", newVer=" + setVer + ", " +
-                                             "entry=" + entry + ']');
+                                     ver = verVal.get2();
  
                                      break;
                                  }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
index 9fdadf3,8db68b4..e76ab40
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
@@@ -664,10 -686,10 +685,11 @@@ public class GridCacheTestEntryEx exten
      }
  
      /** @inheritDoc */
-     @Override public GridCacheVersion versionedValue(CacheObject val,
+     @Override public T2<CacheObject, GridCacheVersion> versionedValue(CacheObject val,
          GridCacheVersion curVer,
          GridCacheVersion newVer,
-         IgniteCacheExpiryPolicy loadExpiryPlc) {
++        @Nullable IgniteCacheExpiryPolicy loadExpiryPlc,
+         @Nullable ReaderArguments readerArgs) {
          assert false;
  
          return null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiDropNodesTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiDropNodesTest.java
index 0000000,d29231e..b530e36
mode 000000,100644..100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiDropNodesTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiDropNodesTest.java
@@@ -1,0 -1,322 +1,322 @@@
+ /*
+  * 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.communication.tcp;
+ 
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.concurrent.Callable;
+ import java.util.concurrent.CountDownLatch;
+ import java.util.concurrent.CyclicBarrier;
+ import java.util.concurrent.TimeUnit;
+ import org.apache.ignite.IgniteCheckedException;
+ import org.apache.ignite.cluster.ClusterNode;
+ import org.apache.ignite.configuration.IgniteConfiguration;
+ import org.apache.ignite.events.Event;
+ import org.apache.ignite.internal.IgniteEx;
+ import org.apache.ignite.internal.IgniteInternalFuture;
+ import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+ import org.apache.ignite.internal.util.nio.GridCommunicationClient;
+ import org.apache.ignite.internal.util.typedef.internal.U;
+ import org.apache.ignite.lang.IgniteBiPredicate;
+ import org.apache.ignite.lang.IgnitePredicate;
+ import org.apache.ignite.lang.IgniteRunnable;
+ import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+ import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+ import org.apache.ignite.testframework.GridTestUtils;
+ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+ 
+ import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
+ 
+ /**
+  *
+  */
+ public class TcpCommunicationSpiDropNodesTest extends GridCommonAbstractTest {
+     /** IP finder. */
+     private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+ 
+     /** Nodes count. */
+     private static final int NODES_CNT = 4;
+ 
+     /** Block. */
+     private static volatile boolean block;
+ 
+     /** Predicate. */
+     private static IgniteBiPredicate<ClusterNode, ClusterNode> pred;
+ 
+     /** {@inheritDoc} */
+     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+         IgniteConfiguration cfg = super.getConfiguration(gridName);
+ 
+         cfg.setClockSyncFrequency(300000);
+         cfg.setFailureDetectionTimeout(1000);
+ 
+         TestCommunicationSpi spi = new TestCommunicationSpi();
+ 
+         spi.setIdleConnectionTimeout(100);
+         spi.setSharedMemoryPort(-1);
+ 
+         TcpDiscoverySpi discoSpi = (TcpDiscoverySpi) cfg.getDiscoverySpi();
+         discoSpi.setIpFinder(IP_FINDER);
+ 
+         cfg.setCommunicationSpi(spi);
+         cfg.setDiscoverySpi(discoSpi);
+ 
+         return cfg;
+     }
+ 
+     /** {@inheritDoc} */
+     @Override protected void beforeTest() throws Exception {
+         super.beforeTest();
+ 
+         block = false;
+     }
+ 
+     /** {@inheritDoc} */
+     @Override protected void afterTest() throws Exception {
+         super.afterTest();
+ 
+         stopAllGrids();
+     }
+ 
+     /**
+      * @throws Exception If failed.
+      */
+     public void testOneNode() throws Exception {
+         pred = new IgniteBiPredicate<ClusterNode, ClusterNode>() {
+             @Override public boolean apply(ClusterNode locNode, ClusterNode rmtNode) {
+                 return block && rmtNode.order() == 3;
+             }
+         };
+ 
+         startGrids(NODES_CNT);
+ 
+         final CountDownLatch latch = new CountDownLatch(1);
+ 
+         grid(0).events().localListen(new IgnitePredicate<Event>() {
+             @Override
+             public boolean apply(Event event) {
+                 latch.countDown();
+ 
+                 return true;
+             }
+         }, EVT_NODE_FAILED);
+ 
+         U.sleep(1000); // Wait for write timeout and closing idle connections.
+ 
+         block = true;
+ 
+         grid(0).compute().broadcast(new IgniteRunnable() {
+             @Override public void run() {
+                 // No-op.
+             }
+         });
+ 
+         assertTrue(latch.await(15, TimeUnit.SECONDS));
+ 
+         assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
+             @Override public boolean apply() {
+                 return grid(3).cluster().topologyVersion() == NODES_CNT + 1;
+             }
+         }, 5000));
+ 
+         for (int i = 0; i < 10; i++) {
+             U.sleep(1000);
+ 
+             assertEquals(NODES_CNT - 1, grid(0).cluster().nodes().size());
+ 
+             int liveNodesCnt = 0;
+ 
+             for (int j = 0; j < NODES_CNT; j++) {
+                 IgniteEx ignite;
+ 
+                 try {
+                     ignite = grid(j);
+ 
+                     log.info("Checking topology for grid(" + j + "): " + ignite.cluster().nodes());
+ 
+                     ClusterNode locNode = ignite.localNode();
+ 
+                     if (locNode.order() != 3) {
+                         assertEquals(NODES_CNT - 1, ignite.cluster().nodes().size());
+ 
+                         for (ClusterNode node : ignite.cluster().nodes())
+                             assertTrue(node.order() != 3);
+ 
+                         liveNodesCnt++;
+                     }
+                 }
+                 catch (Exception e) {
+                     log.info("Checking topology for grid(" + j + "): no grid in topology.");
+                 }
+             }
+ 
+             assertEquals(NODES_CNT - 1, liveNodesCnt);
+         }
+     }
+ 
+     /**
+      * @throws Exception If failed.
+      */
+     public void testTwoNodesEachOther() throws Exception {
+         pred = new IgniteBiPredicate<ClusterNode, ClusterNode>() {
+             @Override public boolean apply(ClusterNode locNode, ClusterNode rmtNode) {
+                 return block && (locNode.order() == 2 || locNode.order() == 4) &&
+                     (rmtNode.order() == 2 || rmtNode.order() == 4);
+             }
+         };
+ 
+         startGrids(NODES_CNT);
+ 
+         final CountDownLatch latch = new CountDownLatch(1);
+ 
+         grid(0).events().localListen(new IgnitePredicate<Event>() {
+             @Override
+             public boolean apply(Event event) {
+                 latch.countDown();
+ 
+                 return true;
+             }
+         }, EVT_NODE_FAILED);
+ 
+         U.sleep(1000); // Wait for write timeout and closing idle connections.
+ 
+         block = true;
+ 
+         final CyclicBarrier barrier = new CyclicBarrier(2);
+ 
+         IgniteInternalFuture<Void> fut1 = GridTestUtils.runAsync(new Callable<Void>() {
+             @Override public Void call() throws Exception {
+                 barrier.await();
+ 
+                 grid(1).compute().withNoFailover().broadcast(new IgniteRunnable() {
+                     @Override public void run() {
+                         // No-op.
+                     }
+                 });
+ 
+                 return null;
+             }
+         });
+ 
+         IgniteInternalFuture<Void> fut2 = GridTestUtils.runAsync(new Callable<Void>() {
+             @Override public Void call() throws Exception {
+                 barrier.await();
+ 
+                 grid(3).compute().withNoFailover().broadcast(new IgniteRunnable() {
+                     @Override public void run() {
+                         // No-op.
+                     }
+                 });
+ 
+                 return null;
+             }
+         });
+ 
+         assertTrue(latch.await(5, TimeUnit.SECONDS));
+ 
+         GridTestUtils.waitForCondition(new GridAbsPredicate() {
+             @Override public boolean apply() {
+                 return grid(2).cluster().nodes().size() == NODES_CNT - 1;
+             }
+         }, 5000);
+ 
+         try {
+             fut1.get();
+         }
+         catch (IgniteCheckedException e) {
+             // No-op.
+         }
+ 
+         try {
+             fut2.get();
+         }
+         catch (IgniteCheckedException e) {
+             // No-op.
+         }
+ 
+         long failedNodeOrder = 1 + 2 + 3 + 4;
+ 
+         for (ClusterNode node : grid(0).cluster().nodes())
+             failedNodeOrder -= node.order();
+ 
+         for (int i = 0; i < 10; i++) {
+             U.sleep(1000);
+ 
+             assertEquals(NODES_CNT - 1, grid(0).cluster().nodes().size());
+ 
+             int liveNodesCnt = 0;
+ 
+             for (int j = 0; j < NODES_CNT; j++) {
+                 IgniteEx ignite;
+ 
+                 try {
+                     ignite = grid(j);
+ 
+                     log.info("Checking topology for grid(" + j + "): " + ignite.cluster().nodes());
+ 
+                     ClusterNode locNode = ignite.localNode();
+ 
+                     if (locNode.order() != failedNodeOrder) {
+                         assertEquals(NODES_CNT - 1, ignite.cluster().nodes().size());
+ 
+                         for (ClusterNode node : ignite.cluster().nodes())
+                             assertTrue(node.order() != failedNodeOrder);
+ 
+                         liveNodesCnt++;
+                     }
+                 }
+                 catch (Exception e) {
+                     log.info("Checking topology for grid(" + j + "): no grid in topology.");
+                 }
+             }
+ 
+             assertEquals(NODES_CNT - 1, liveNodesCnt);
+         }
+     }
+ 
+     /**
+      *
+      */
+     private static class TestCommunicationSpi extends TcpCommunicationSpi {
+         /** {@inheritDoc} */
 -        @Override protected GridCommunicationClient createTcpClient(ClusterNode node) throws IgniteCheckedException {
++        @Override protected GridCommunicationClient createTcpClient(ClusterNode node, int connIdx) throws IgniteCheckedException {
+             if (pred.apply(getLocalNode(), node)) {
+                 Map<String, Object> attrs = new HashMap<>(node.attributes());
+ 
+                 attrs.put(createAttributeName(ATTR_ADDRS), Collections.singleton("127.0.0.1"));
+                 attrs.put(createAttributeName(ATTR_PORT), 47200);
+                 attrs.put(createAttributeName(ATTR_EXT_ADDRS), Collections.emptyList());
+                 attrs.put(createAttributeName(ATTR_HOST_NAMES), Collections.emptyList());
+ 
+                 ((TcpDiscoveryNode)node).setAttributes(attrs);
+             }
+ 
 -            return super.createTcpClient(node);
++            return super.createTcpClient(node, connIdx);
+         }
+ 
+         /**
+          * @param name Name.
+          */
+         private String createAttributeName(String name) {
+             return getClass().getSimpleName() + '.' + name;
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiFaultyClientTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiFaultyClientTest.java
index 0000000,6e99487..c21e6ce
mode 000000,100644..100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiFaultyClientTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiFaultyClientTest.java
@@@ -1,0 -1,270 +1,265 @@@
+ /*
+  * 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.communication.tcp;
+ 
+ import java.io.IOException;
 -import java.io.OutputStream;
+ import java.net.InetAddress;
+ import java.net.ServerSocket;
 -import java.net.Socket;
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.concurrent.CountDownLatch;
+ import java.util.concurrent.TimeUnit;
 -import org.apache.ignite.Ignite;
+ import org.apache.ignite.IgniteCheckedException;
+ import org.apache.ignite.IgniteException;
+ import org.apache.ignite.cluster.ClusterNode;
+ import org.apache.ignite.configuration.IgniteConfiguration;
+ import org.apache.ignite.events.Event;
+ import org.apache.ignite.internal.IgniteInternalFuture;
+ import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+ import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+ import org.apache.ignite.internal.util.nio.GridCommunicationClient;
+ import org.apache.ignite.internal.util.typedef.internal.U;
+ import org.apache.ignite.lang.IgnitePredicate;
+ import org.apache.ignite.lang.IgniteRunnable;
+ import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+ import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage;
 -import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage;
+ import org.apache.ignite.testframework.GridTestUtils;
+ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+ 
+ import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
+ 
+ /**
+  * Tests that faulty client will be failed if connection can't be established.
+  */
+ public class TcpCommunicationSpiFaultyClientTest extends GridCommonAbstractTest {
+     /** */
+     private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+ 
+     /** Predicate. */
+     private static final IgnitePredicate<ClusterNode> PRED = new IgnitePredicate<ClusterNode>() {
+         @Override public boolean apply(ClusterNode node) {
+             return block && node.order() == 3;
+         }
+     };
+ 
+     /** Client mode. */
+     private static boolean clientMode;
+ 
+     /** Block. */
+     private static volatile boolean block;
+ 
+     /** {@inheritDoc} */
+     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+         IgniteConfiguration cfg = super.getConfiguration(gridName);
+ 
+         cfg.setClockSyncFrequency(300000);
+         cfg.setFailureDetectionTimeout(1000);
+         cfg.setClientMode(clientMode);
+ 
+         TestCommunicationSpi spi = new TestCommunicationSpi();
+ 
+         spi.setIdleConnectionTimeout(100);
+         spi.setSharedMemoryPort(-1);
+ 
+         TcpDiscoverySpi discoSpi = (TcpDiscoverySpi) cfg.getDiscoverySpi();
+ 
+         discoSpi.setIpFinder(IP_FINDER);
+         discoSpi.setClientReconnectDisabled(true);
+ 
+         cfg.setCommunicationSpi(spi);
+         cfg.setDiscoverySpi(discoSpi);
+ 
+         return cfg;
+     }
+ 
+     /** {@inheritDoc} */
+     @Override protected void beforeTest() throws Exception {
+         super.beforeTest();
+ 
+         block = false;
+     }
+ 
+     /** {@inheritDoc} */
+     @Override protected void afterTest() throws Exception {
+         super.afterTest();
+ 
+         stopAllGrids();
+     }
+ 
+     /**
+      * @throws Exception If failed.
+      */
+     public void testNoServerOnHost() throws Exception {
+         testFailClient(null);
+     }
+ 
+     /**
+      * @throws Exception If failed.
+      */
+     public void testNotAcceptedConnection() throws Exception {
+         testFailClient(new FakeServer());
+     }
+ 
+     /**
+      * @param srv Server.
+      * @throws Exception If failed.
+      */
+     private void testFailClient(FakeServer srv) throws Exception {
+         IgniteInternalFuture<Long> fut = null;
+ 
+         try {
+             if (srv != null)
+                 fut = GridTestUtils.runMultiThreadedAsync(srv, 1, "fake-server");
+ 
+             clientMode = false;
+ 
+             startGrids(2);
+ 
+             clientMode = true;
+ 
+             startGrid(2);
+             startGrid(3);
+ 
+             U.sleep(1000); // Wait for write timeout and closing idle connections.
+ 
+             final CountDownLatch latch = new CountDownLatch(1);
+ 
+             grid(0).events().localListen(new IgnitePredicate<Event>() {
+                 @Override
+                 public boolean apply(Event event) {
+                     latch.countDown();
+ 
+                     return true;
+                 }
+             }, EVT_NODE_FAILED);
+ 
+             block = true;
+ 
+             try {
+                 grid(0).compute(grid(0).cluster().forClients()).withNoFailover().broadcast(new IgniteRunnable() {
+                     @Override public void run() {
+                         // No-op.
+                     }
+                 });
+             }
+             catch (IgniteException e) {
+                 // No-op.
+             }
+ 
+             assertTrue(latch.await(3, TimeUnit.SECONDS));
+ 
+             assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
+                 @Override public boolean apply() {
+                     return grid(0).cluster().forClients().nodes().size() == 1;
+                 }
+             }, 5000));
+ 
+             for (int i = 0; i < 5; i++) {
+                 U.sleep(1000);
+ 
+                 log.info("Check topology (" + (i + 1) + "): " + grid(0).cluster().nodes());
+ 
+                 assertEquals(1, grid(0).cluster().forClients().nodes().size());
+             }
+         }
+         finally {
+             if (srv != null) {
+                 srv.stop();
+ 
+                 assert fut != null;
+ 
+                 fut.get();
+             }
+ 
+             stopAllGrids();
+         }
+     }
+ 
+     /**
+      * Server that emulates connection troubles.
+      */
+     private static class FakeServer implements Runnable {
+         /** Server. */
+         private final ServerSocket srv;
+ 
+         /** Stop. */
+         private volatile boolean stop;
+ 
+         /**
+          * Default constructor.
+          */
+         FakeServer() throws IOException {
+             this.srv = new ServerSocket(47200, 50, InetAddress.getByName("127.0.0.1"));
+         }
+ 
+         /**
+          *
+          */
+         public void stop() {
+             stop = true;
+         }
+ 
+         /** {@inheritDoc} */
+         @Override public void run() {
+             try {
+                 while (!stop) {
+                     try {
+                         U.sleep(10);
+                     }
+                     catch (IgniteInterruptedCheckedException e) {
+                         // No-op.
+                     }
+                 }
+             }
+             finally {
+                 U.closeQuiet(srv);
+             }
+         }
+     }
+ 
+     /**
+      *
+      */
+     private static class TestCommunicationSpi extends TcpCommunicationSpi {
+         /** {@inheritDoc} */
 -        @Override protected GridCommunicationClient createTcpClient(ClusterNode node) throws IgniteCheckedException {
++        @Override protected GridCommunicationClient createTcpClient(ClusterNode node, int connIdx) throws IgniteCheckedException {
+             if (PRED.apply(node)) {
+                 Map<String, Object> attrs = new HashMap<>(node.attributes());
+ 
+                 attrs.put(createAttributeName(ATTR_ADDRS), Collections.singleton("127.0.0.1"));
+                 attrs.put(createAttributeName(ATTR_PORT), 47200);
+                 attrs.put(createAttributeName(ATTR_EXT_ADDRS), Collections.emptyList());
+                 attrs.put(createAttributeName(ATTR_HOST_NAMES), Collections.emptyList());
+ 
+                 ((TcpDiscoveryNode)node).setAttributes(attrs);
+             }
+ 
 -            return super.createTcpClient(node);
++            return super.createTcpClient(node, connIdx);
+         }
+ 
+         /**
+          * @param name Name.
+          */
+         private String createAttributeName(String name) {
+             return getClass().getSimpleName() + '.' + name;
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiCommunicationSelfTestSuite.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 69a65fe,cbf2ebd..9416621
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@@ -1077,10 -1051,9 +1077,10 @@@ public class IgniteH2Indexing implement
          final TableDescriptor tbl = tableDescriptor(spaceName, type);
  
          if (tbl == null)
 -            throw new CacheException("Failed to find SQL table for type: " + type.name());
 +            throw new IgniteSQLException("Failed to find SQL table for type: " + type.name(),
 +                IgniteQueryErrorCode.TABLE_NOT_FOUND);
  
-         String sql = generateQuery(qry, tbl);
+         String sql = generateQuery(qry, alias, tbl);
  
          Connection conn = connectionForThread(tbl.schemaName());
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/aaeda721/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------


[03/50] [abbrv] ignite git commit: IGNITE-4252: Fixed exception with local cache query started on partitioned cache. This closes #1489.

Posted by sb...@apache.org.
IGNITE-4252: Fixed exception with local cache query started on partitioned cache. This closes #1489.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 26562d3575c54a359df06c72202ec91e078fde05
Parents: b246260
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Fri Feb 3 11:58:35 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Feb 3 11:58:35 2017 +0300

----------------------------------------------------------------------
 .../h2/twostep/GridReduceQueryExecutor.java     |   2 +-
 .../IgniteSqlEntryCacheModeAgnosticTest.java    | 140 +++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite.java          |   2 +
 3 files changed, 143 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/26562d35/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
index 1f00ed2..cbe1599 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
@@ -384,7 +384,7 @@ public class GridReduceQueryExecutor {
      * @return {@code True} If cache has partitions in {@link GridDhtPartitionState#MOVING} state.
      */
     private boolean hasMovingPartitions(GridCacheContext<?, ?> cctx) {
-        return cctx.topology().hasMovingPartitions();
+        return !cctx.isLocal() && cctx.topology().hasMovingPartitions();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/26562d35/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlEntryCacheModeAgnosticTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlEntryCacheModeAgnosticTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlEntryCacheModeAgnosticTest.java
new file mode 100644
index 0000000..db7ca39
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlEntryCacheModeAgnosticTest.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.query;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import java.util.List;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.LOCAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheMode.REPLICATED;
+
+/**
+ * Test different cache modes for query entry
+ */
+public class IgniteSqlEntryCacheModeAgnosticTest extends GridCommonAbstractTest {
+    /** IP finder. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Host. */
+    public static final String HOST = "127.0.0.1";
+
+    /** Partitioned cache name. */
+    private static final String PARTITIONED_CACHE_NAME = "PART_CACHE";
+
+    /** Replicated cache name. */
+    private static final String REPLICATED_CACHE_NAME = "REPL_CACHE";
+
+    /** Local cache name. */
+    private static final String LOCAL_CACHE_NAME = "LOCAL_CACHE";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration c = super.getConfiguration(gridName);
+
+        c.setLocalHost(HOST);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        c.setDiscoverySpi(disco);
+
+        c.setCacheConfiguration(cacheConfiguration(LOCAL_CACHE_NAME),
+            cacheConfiguration(REPLICATED_CACHE_NAME), cacheConfiguration(PARTITIONED_CACHE_NAME));
+
+        return c;
+    }
+
+    /**
+     * Provides configuration for cache given its name
+     * @param cacheName Cache name.
+     * @return Cache configuration.
+     * @throws Exception In case of error.
+     */
+    @SuppressWarnings("unchecked")
+    private CacheConfiguration cacheConfiguration(String cacheName) throws Exception {
+        CacheConfiguration cfg = defaultCacheConfiguration();
+
+        cfg.setAffinity(new RendezvousAffinityFunction());
+
+        cfg.setAtomicityMode(TRANSACTIONAL);
+
+        switch (cacheName) {
+            case LOCAL_CACHE_NAME:
+                cfg.setCacheMode(LOCAL);
+                break;
+            case REPLICATED_CACHE_NAME:
+                cfg.setCacheMode(REPLICATED);
+                break;
+            case PARTITIONED_CACHE_NAME:
+                cfg.setCacheMode(PARTITIONED);
+                cfg.setBackups(0);
+                break;
+            default:
+                throw new Exception("Invalid cache name " + cacheName);
+        }
+
+        cfg.setName(cacheName);
+
+        cfg.setIndexedTypes(Integer.class, String.class);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * It should not matter what cache mode does entry cache use, if there is no join
+     */
+    public void testCrossCacheModeQuery() throws Exception {
+        Ignite ignite = startGrid();
+
+        ignite.cache(LOCAL_CACHE_NAME).put(1, LOCAL_CACHE_NAME);
+        ignite.cache(REPLICATED_CACHE_NAME).put(1, REPLICATED_CACHE_NAME);
+        ignite.cache(PARTITIONED_CACHE_NAME).put(1, PARTITIONED_CACHE_NAME);
+
+        final List<String> cacheNamesList = F.asList(LOCAL_CACHE_NAME, REPLICATED_CACHE_NAME, PARTITIONED_CACHE_NAME);
+
+        for(String entryCacheName: cacheNamesList) {
+            for(String qryCacheName: cacheNamesList) {
+                if (entryCacheName.equals(qryCacheName))
+                    continue;
+
+                QueryCursor<List<?>> cursor = ignite.cache(entryCacheName).query(
+                    new SqlFieldsQuery("SELECT _VAL FROM \"" + qryCacheName + "\".String"));
+
+                assertEquals(qryCacheName, (String)cursor.getAll().get(0).get(0));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26562d35/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index b5e4078..d85e111 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -95,6 +95,7 @@ import org.apache.ignite.internal.processors.cache.query.GridCacheSwapScanQueryS
 import org.apache.ignite.internal.processors.cache.query.IgniteCacheQueryCacheDestroySelfTest;
 import org.apache.ignite.internal.processors.cache.query.IndexingSpiQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.query.IndexingSpiQueryTxSelfTest;
+import org.apache.ignite.internal.processors.query.IgniteSqlEntryCacheModeAgnosticTest;
 import org.apache.ignite.internal.processors.query.IgniteSqlSchemaIndexingTest;
 import org.apache.ignite.internal.processors.query.IgniteSqlSplitterSelfTest;
 import org.apache.ignite.internal.processors.query.h2.GridH2IndexRebuildTest;
@@ -240,6 +241,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         suite.addTestSuite(CacheOffheapBatchIndexingSingleTypeTest.class);
         suite.addTestSuite(CacheSqlQueryValueCopySelfTest.class);
         suite.addTestSuite(IgniteCacheQueryCacheDestroySelfTest.class);
+        suite.addTestSuite(IgniteSqlEntryCacheModeAgnosticTest.class);
 
         return suite;
     }


[27/50] [abbrv] ignite git commit: IGNITE-4678 Web Console: Implemented demo load as service.

Posted by sb...@apache.org.
IGNITE-4678 Web Console: Implemented demo load as service.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: a600cafd1eec7581e8edde5a10b7d171997551f7
Parents: 3bf880c
Author: Andrey Novikov <an...@gridgain.com>
Authored: Fri Feb 10 15:55:05 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Fri Feb 10 15:55:05 2017 +0700

----------------------------------------------------------------------
 modules/web-console/backend/app/agent.js        |  34 ++
 modules/web-console/backend/app/browser.js      |  26 +
 modules/web-console/frontend/package.json       |   2 +-
 .../ignite/console/demo/AgentClusterDemo.java   | 475 +------------------
 .../ignite/console/demo/AgentDemoUtils.java     |  79 +++
 .../demo/service/DemoCachesLoadService.java     | 456 ++++++++++++++++++
 .../service/DemoRandomCacheLoadService.java     | 120 +++++
 .../service/DemoServiceClusterSingleton.java    |  41 ++
 .../demo/service/DemoServiceKeyAffinity.java    |  41 ++
 .../service/DemoServiceMultipleInstances.java   |  41 ++
 .../demo/service/DemoServiceNodeSingleton.java  |  41 ++
 11 files changed, 897 insertions(+), 459 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/backend/app/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/agent.js b/modules/web-console/backend/app/agent.js
index 8170280..4cae8ee 100644
--- a/modules/web-console/backend/app/agent.js
+++ b/modules/web-console/backend/app/agent.js
@@ -581,6 +581,40 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo,
 
             return this.executeRest(cmd);
         }
+
+        /**
+         * Collect service information.
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {String} nid Node ID.
+         * @returns {Promise}
+         */
+        services(demo, nid) {
+            const cmd = new Command(demo, 'exe')
+                .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask')
+                .addParam('p1', nid)
+                .addParam('p2', 'org.apache.ignite.internal.visor.service.VisorServiceTask')
+                .addParam('p3', 'java.lang.Void');
+
+            return this.executeRest(cmd);
+        }
+
+        /**
+         * Cancel service with specified name.
+         * @param {Boolean} demo Is need run command on demo node.
+         * @param {String} nid Node ID.
+         * @param {String} name Name of service to cancel.
+         * @returns {Promise}
+         */
+        serviceCancel(demo, nid, name) {
+            const cmd = new Command(demo, 'exe')
+                .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask')
+                .addParam('p1', nid)
+                .addParam('p2', 'org.apache.ignite.internal.visor.service.VisorCancelServiceTask')
+                .addParam('p3', 'java.lang.String')
+                .addParam('p4', name);
+
+            return this.executeRest(cmd);
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/backend/app/browser.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/browser.js b/modules/web-console/backend/app/browser.js
index 499d84d..2b1285e 100644
--- a/modules/web-console/backend/app/browser.js
+++ b/modules/web-console/backend/app/browser.js
@@ -455,6 +455,32 @@ module.exports.factory = (_, socketio, agentMgr, configure) => {
                         .catch((err) => cb(_errorToJson(err)));
                 });
 
+                // Collect service information from grid.
+                socket.on('service:collect', (nid, cb) => {
+                    agentMgr.findAgent(accountId())
+                        .then((agent) => agent.services(demo, nid))
+                        .then((data) => {
+                            if (data.finished)
+                                return cb(null, data.result);
+
+                            cb(_errorToJson(data.error));
+                        })
+                        .catch((err) => cb(_errorToJson(err)));
+                });
+
+                // Collect service information from grid.
+                socket.on('service:cancel', (nid, name, cb) => {
+                    agentMgr.findAgent(accountId())
+                        .then((agent) => agent.serviceCancel(demo, nid, name))
+                        .then((data) => {
+                            if (data.finished)
+                                return cb(null, data.result);
+
+                            cb(_errorToJson(data.error));
+                        })
+                        .catch((err) => cb(_errorToJson(err)));
+                });
+
                 const count = agentMgr.addAgentListener(user._id, socket);
 
                 socket.emit('agent:count', {count});

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/frontend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json
index ff52ba4..651f496 100644
--- a/modules/web-console/frontend/package.json
+++ b/modules/web-console/frontend/package.json
@@ -46,7 +46,7 @@
     "angular-touch": "~1.5.9",
     "angular-translate": "~2.13.1",
     "angular-tree-control": "~0.2.26",
-    "angular-ui-grid": "~3.2.9",
+    "angular-ui-grid": "~4.0.0",
     "angular-ui-router": "~0.3.1",
     "bootstrap-sass": "~3.3.6",
     "brace": "~0.8.0",

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
index 489e762..252692e 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
@@ -17,37 +17,24 @@
 
 package org.apache.ignite.console.demo;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Random;
-import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteServices;
 import org.apache.ignite.Ignition;
-import org.apache.ignite.cache.CacheAtomicityMode;
-import org.apache.ignite.cache.QueryEntity;
-import org.apache.ignite.cache.QueryIndex;
-import org.apache.ignite.cache.QueryIndexType;
-import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
-import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.console.agent.AgentConfiguration;
-import org.apache.ignite.console.demo.model.Car;
-import org.apache.ignite.console.demo.model.Country;
-import org.apache.ignite.console.demo.model.Department;
-import org.apache.ignite.console.demo.model.Employee;
-import org.apache.ignite.console.demo.model.Parking;
+import org.apache.ignite.console.demo.service.DemoCachesLoadService;
+import org.apache.ignite.console.demo.service.DemoRandomCacheLoadService;
+import org.apache.ignite.console.demo.service.DemoServiceMultipleInstances;
+import org.apache.ignite.console.demo.service.DemoServiceClusterSingleton;
+import org.apache.ignite.console.demo.service.DemoServiceKeyAffinity;
+import org.apache.ignite.console.demo.service.DemoServiceNodeSingleton;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.logger.log4j.Log4JLogger;
@@ -55,7 +42,6 @@ import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi;
-import org.apache.ignite.transactions.Transaction;
 import org.apache.log4j.Logger;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE;
@@ -66,8 +52,6 @@ import static org.apache.ignite.IgniteSystemProperties.IGNITE_NO_ASCII;
 import static org.apache.ignite.events.EventType.EVTS_DISCOVERY;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_ADDRS;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_PORT;
-import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
-import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
 
 /**
  * Demo for cluster features like SQL and Monitoring.
@@ -84,247 +68,6 @@ public class AgentClusterDemo {
     /** */
     private static final int NODE_CNT = 3;
 
-    /** */
-    private static final String COUNTRY_CACHE_NAME = "CountryCache";
-
-    /** */
-    private static final String DEPARTMENT_CACHE_NAME = "DepartmentCache";
-
-    /** */
-    private static final String EMPLOYEE_CACHE_NAME = "EmployeeCache";
-
-    /** */
-    private static final String PARKING_CACHE_NAME = "ParkingCache";
-
-    /** */
-    private static final String CAR_CACHE_NAME = "CarCache";
-
-    /** */
-    private static final Set<String> DEMO_CACHES = new HashSet<>(Arrays.asList(COUNTRY_CACHE_NAME,
-        DEPARTMENT_CACHE_NAME, EMPLOYEE_CACHE_NAME, PARKING_CACHE_NAME, CAR_CACHE_NAME));
-
-    /** */
-    private static final Random rnd = new Random();
-
-    /** Countries count. */
-    private static final int CNTR_CNT = 10;
-
-    /** Departments count */
-    private static final int DEP_CNT = 100;
-
-    /** Employees count. */
-    private static final int EMPL_CNT = 1000;
-
-    /** Countries count. */
-    private static final int CAR_CNT = 100;
-
-    /** Departments count */
-    private static final int PARK_CNT = 10;
-
-    /** Counter for threads in pool. */
-    private static final AtomicInteger THREAD_CNT = new AtomicInteger(0);
-
-    /**
-     * Create base cache configuration.
-     *
-     * @param name cache name.
-     * @return Cache configuration with basic properties set.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheConfiguration(String name) {
-        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name);
-
-        ccfg.setAffinity(new RendezvousAffinityFunction(false, 32));
-        ccfg.setQueryDetailMetricsSize(10);
-        ccfg.setStartSize(100);
-        ccfg.setStatisticsEnabled(true);
-
-        return ccfg;
-    }
-
-    /**
-     * Configure cacheCountry.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheCountry() {
-        CacheConfiguration<K, V> ccfg = cacheConfiguration(COUNTRY_CACHE_NAME);
-
-        // Configure cacheCountry types.
-        Collection<QueryEntity> qryEntities = new ArrayList<>();
-
-        // COUNTRY.
-        QueryEntity type = new QueryEntity();
-
-        qryEntities.add(type);
-
-        type.setKeyType(Integer.class.getName());
-        type.setValueType(Country.class.getName());
-
-        // Query fields for COUNTRY.
-        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("id", "java.lang.Integer");
-        qryFlds.put("name", "java.lang.String");
-        qryFlds.put("population", "java.lang.Integer");
-
-        type.setFields(qryFlds);
-
-        ccfg.setQueryEntities(qryEntities);
-
-        return ccfg;
-    }
-
-    /**
-     * Configure cacheEmployee.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheDepartment() {
-        CacheConfiguration<K, V> ccfg = cacheConfiguration(DEPARTMENT_CACHE_NAME);
-
-        // Configure cacheDepartment types.
-        Collection<QueryEntity> qryEntities = new ArrayList<>();
-
-        // DEPARTMENT.
-        QueryEntity type = new QueryEntity();
-
-        qryEntities.add(type);
-
-        type.setKeyType(Integer.class.getName());
-        type.setValueType(Department.class.getName());
-
-        // Query fields for DEPARTMENT.
-        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("id", "java.lang.Integer");
-        qryFlds.put("countryId", "java.lang.Integer");
-        qryFlds.put("name", "java.lang.String");
-
-        type.setFields(qryFlds);
-
-        ccfg.setQueryEntities(qryEntities);
-
-        return ccfg;
-    }
-
-    /**
-     * Configure cacheEmployee.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheEmployee() {
-        CacheConfiguration<K, V> ccfg = cacheConfiguration(EMPLOYEE_CACHE_NAME);
-
-        ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-        ccfg.setBackups(1);
-
-        // Configure cacheEmployee types.
-        Collection<QueryEntity> qryEntities = new ArrayList<>();
-
-        // EMPLOYEE.
-        QueryEntity type = new QueryEntity();
-
-        qryEntities.add(type);
-
-        type.setKeyType(Integer.class.getName());
-        type.setValueType(Employee.class.getName());
-
-        // Query fields for EMPLOYEE.
-        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("id", "java.lang.Integer");
-        qryFlds.put("departmentId", "java.lang.Integer");
-        qryFlds.put("managerId", "java.lang.Integer");
-        qryFlds.put("firstName", "java.lang.String");
-        qryFlds.put("lastName", "java.lang.String");
-        qryFlds.put("email", "java.lang.String");
-        qryFlds.put("phoneNumber", "java.lang.String");
-        qryFlds.put("hireDate", "java.sql.Date");
-        qryFlds.put("job", "java.lang.String");
-        qryFlds.put("salary", "java.lang.Double");
-
-        type.setFields(qryFlds);
-
-        // Indexes for EMPLOYEE.
-        Collection<QueryIndex> indexes = new ArrayList<>();
-
-        QueryIndex idx = new QueryIndex();
-
-        idx.setName("EMP_NAMES");
-        idx.setIndexType(QueryIndexType.SORTED);
-        LinkedHashMap<String, Boolean> indFlds = new LinkedHashMap<>();
-
-        indFlds.put("firstName", Boolean.FALSE);
-        indFlds.put("lastName", Boolean.FALSE);
-
-        idx.setFields(indFlds);
-
-        indexes.add(idx);
-        indexes.add(new QueryIndex("salary", QueryIndexType.SORTED, false, "EMP_SALARY"));
-
-        type.setIndexes(indexes);
-
-        ccfg.setQueryEntities(qryEntities);
-
-        return ccfg;
-    }
-
-    /**
-     * Configure cacheEmployee.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheParking() {
-        CacheConfiguration<K, V> ccfg = cacheConfiguration(PARKING_CACHE_NAME);
-
-        // Configure cacheParking types.
-        Collection<QueryEntity> qryEntities = new ArrayList<>();
-
-        // PARKING.
-        QueryEntity type = new QueryEntity();
-
-        qryEntities.add(type);
-
-        type.setKeyType(Integer.class.getName());
-        type.setValueType(Parking.class.getName());
-
-        // Query fields for PARKING.
-        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("id", "java.lang.Integer");
-        qryFlds.put("name", "java.lang.String");
-        qryFlds.put("capacity", "java.lang.Integer");
-
-        type.setFields(qryFlds);
-
-        ccfg.setQueryEntities(qryEntities);
-
-        return ccfg;
-    }
-
-    /**
-     * Configure cacheEmployee.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheCar() {
-        CacheConfiguration<K, V> ccfg = cacheConfiguration(CAR_CACHE_NAME);
-
-        // Configure cacheCar types.
-        Collection<QueryEntity> qryEntities = new ArrayList<>();
-
-        // CAR.
-        QueryEntity type = new QueryEntity();
-
-        qryEntities.add(type);
-
-        type.setKeyType(Integer.class.getName());
-        type.setValueType(Car.class.getName());
-
-        // Query fields for CAR.
-        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("id", "java.lang.Integer");
-        qryFlds.put("parkingId", "java.lang.Integer");
-        qryFlds.put("name", "java.lang.String");
-
-        type.setFields(qryFlds);
-
-        ccfg.setQueryEntities(qryEntities);
-
-        return ccfg;
-    }
-
     /**
      * Configure node.
      * @param gridIdx Grid name index.
@@ -363,212 +106,20 @@ public class AgentClusterDemo {
         if (client)
             cfg.setClientMode(true);
 
-        cfg.setCacheConfiguration(cacheCountry(), cacheDepartment(), cacheEmployee(), cacheParking(), cacheCar());
-
         cfg.setSwapSpaceSpi(new FileSwapSpaceSpi());
 
         return cfg;
     }
 
     /**
-     * @param val Value to round.
-     * @param places Numbers after point.
-     * @return Rounded value;
-     */
-    private static double round(double val, int places) {
-        if (places < 0)
-            throw new IllegalArgumentException();
-
-        long factor = (long)Math.pow(10, places);
-
-        val *= factor;
-
-        long tmp = Math.round(val);
-
-        return (double)tmp / factor;
-    }
-
-    /**
-     * @param ignite Ignite.
-     * @param range Time range in milliseconds.
-     */
-    private static void populateCacheEmployee(Ignite ignite, long range) {
-        if (log.isDebugEnabled())
-            log.debug("DEMO: Start employees population with data...");
-
-        IgniteCache<Integer, Country> cacheCountry = ignite.cache(COUNTRY_CACHE_NAME);
-
-        for (int i = 0, n = 1; i < CNTR_CNT; i++, n++)
-            cacheCountry.put(i, new Country(i, "Country #" + n, n * 10000000));
-
-        IgniteCache<Integer, Department> cacheDepartment = ignite.cache(DEPARTMENT_CACHE_NAME);
-
-        IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
-
-        for (int i = 0, n = 1; i < DEP_CNT; i++, n++) {
-            cacheDepartment.put(i, new Department(n, rnd.nextInt(CNTR_CNT), "Department #" + n));
-
-            double r = rnd.nextDouble();
-
-            cacheEmployee.put(i, new Employee(i, rnd.nextInt(DEP_CNT), null, "First name manager #" + n,
-                "Last name manager #" + n, "Email manager #" + n, "Phone number manager #" + n,
-                new java.sql.Date((long)(r * range)), "Job manager #" + n, 1000 + round(r * 4000, 2)));
-        }
-
-        for (int i = 0, n = 1; i < EMPL_CNT; i++, n++) {
-            Integer depId = rnd.nextInt(DEP_CNT);
-
-            double r = rnd.nextDouble();
-
-            cacheEmployee.put(i, new Employee(i, depId, depId, "First name employee #" + n,
-                "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
-                new java.sql.Date((long)(r * range)), "Job employee #" + n, 500 + round(r * 2000, 2)));
-        }
-
-        if (log.isDebugEnabled())
-            log.debug("DEMO: Finished employees population.");
-    }
-
-    /**
-     * @param ignite Ignite.
-     */
-    private static void populateCacheCar(Ignite ignite) {
-        if (log.isDebugEnabled())
-            log.debug("DEMO: Start cars population...");
-
-        IgniteCache<Integer, Parking> cacheParking = ignite.cache(PARKING_CACHE_NAME);
-
-        for (int i = 0, n = 1; i < PARK_CNT; i++, n++)
-            cacheParking.put(i, new Parking(i, "Parking #" + n, n * 10));
-
-        IgniteCache<Integer, Car> cacheCar = ignite.cache(CAR_CACHE_NAME);
-
-        for (int i = 0, n = 1; i < CAR_CNT; i++, n++)
-            cacheCar.put(i, new Car(i, rnd.nextInt(PARK_CNT), "Car #" + n));
-
-        if (log.isDebugEnabled())
-            log.debug("DEMO: Finished cars population.");
-    }
-
-    /**
-     * Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
-     *
-     * @param corePoolSize Number of threads to keep in the pool, even if they are idle.
-     * @param threadName Part of thread name that would be used by thread factory.
-     * @return Newly created scheduled thread pool.
-     */
-    private static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, final String threadName) {
-        ScheduledExecutorService srvc = Executors.newScheduledThreadPool(corePoolSize, new ThreadFactory() {
-            @Override public Thread newThread(Runnable r) {
-                Thread thread = new Thread(r, String.format("%s-%d", threadName, THREAD_CNT.getAndIncrement()));
-
-                thread.setDaemon(true);
-
-                return thread;
-            }
-        });
-
-        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)srvc;
-
-        // Setting up shutdown policy.
-        executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-        executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
-
-        return srvc;
-    }
-
-    /**
      * Starts read and write from cache in background.
      *
      * @param ignite Ignite.
      * @param cnt - maximum count read/write key
      */
     private static void startLoad(final Ignite ignite, final int cnt) {
-        final long diff = new java.util.Date().getTime();
-
-        populateCacheEmployee(ignite, diff);
-        populateCacheCar(ignite);
-
-        ScheduledExecutorService cachePool = newScheduledThreadPool(2, "demo-sql-load-cache-tasks");
-
-        cachePool.scheduleWithFixedDelay(new Runnable() {
-            @Override public void run() {
-                try {
-                    for (String cacheName : ignite.cacheNames()) {
-                        if (!DEMO_CACHES.contains(cacheName)) {
-                            IgniteCache<Integer, String> otherCache = ignite.cache(cacheName);
-
-                            if (otherCache != null) {
-                                for (int i = 0, n = 1; i < cnt; i++, n++) {
-                                    Integer key = rnd.nextInt(1000);
-
-                                    String val = otherCache.get(key);
-
-                                    if (val == null)
-                                        otherCache.put(key, "other-" + key);
-                                    else if (rnd.nextInt(100) < 30)
-                                        otherCache.remove(key);
-                                }
-                            }
-                        }
-                    }
-
-                    IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
-
-                    if (cacheEmployee != null)
-                        try(Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
-                            for (int i = 0, n = 1; i < cnt; i++, n++) {
-                                Integer id = rnd.nextInt(EMPL_CNT);
-
-                                Integer depId = rnd.nextInt(DEP_CNT);
-
-                                double r = rnd.nextDouble();
-
-                                cacheEmployee.put(id, new Employee(id, depId, depId, "First name employee #" + n,
-                                    "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
-                                    new java.sql.Date((long)(r * diff)), "Job employee #" + n, 500 + round(r * 2000, 2)));
-
-                                if (rnd.nextBoolean())
-                                    cacheEmployee.remove(rnd.nextInt(EMPL_CNT));
-
-                                cacheEmployee.get(rnd.nextInt(EMPL_CNT));
-                            }
-
-                            if (rnd.nextInt(100) > 20)
-                                tx.commit();
-                        }
-                }
-                catch (Throwable e) {
-                    if (!e.getMessage().contains("cache is stopped"))
-                        ignite.log().error("Cache write task execution error", e);
-                }
-            }
-        }, 10, 3, TimeUnit.SECONDS);
-
-        cachePool.scheduleWithFixedDelay(new Runnable() {
-            @Override public void run() {
-                try {
-                    IgniteCache<Integer, Car> cache = ignite.cache(CAR_CACHE_NAME);
-
-                    if (cache != null)
-                        for (int i = 0; i < cnt; i++) {
-                            Integer carId = rnd.nextInt(CAR_CNT);
-
-                            cache.put(carId, new Car(carId, rnd.nextInt(PARK_CNT), "Car #" + (i + 1)));
-
-                            if (rnd.nextBoolean())
-                                cache.remove(rnd.nextInt(CAR_CNT));
-                        }
-                }
-                catch (IllegalStateException ignored) {
-                    // No-op.
-                }
-                catch (Throwable e) {
-                    if (!e.getMessage().contains("cache is stopped"))
-                        ignite.log().error("Cache write task execution error", e);
-                }
-            }
-        }, 10, 3, TimeUnit.SECONDS);
+        ignite.services().deployClusterSingleton("Demo caches load service", new DemoCachesLoadService(cnt));
+        ignite.services().deployNodeSingleton("RandomCache load service", new DemoRandomCacheLoadService(cnt));
     }
 
     /**
@@ -609,6 +160,14 @@ public class AgentClusterDemo {
                     }
                 }, 10, 10, TimeUnit.SECONDS);
 
+                IgniteServices services = ignite.services();
+
+                services.deployMultiple("Demo service: Multiple instances", new DemoServiceMultipleInstances(), 7, 3);
+                services.deployNodeSingleton("Demo service: Node singleton", new DemoServiceNodeSingleton());
+                services.deployClusterSingleton("Demo service: Cluster singleton", new DemoServiceClusterSingleton());
+                services.deployKeyAffinitySingleton("Demo service: Key affinity singleton",
+                    new DemoServiceKeyAffinity(), DemoCachesLoadService.CAR_CACHE_NAME, "id");
+
                 if (log.isDebugEnabled())
                     log.debug("DEMO: Started embedded nodes with indexed enabled caches...");
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentDemoUtils.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentDemoUtils.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentDemoUtils.java
new file mode 100644
index 0000000..fb34de7
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentDemoUtils.java
@@ -0,0 +1,79 @@
+/*
+ * 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.console.demo;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Utilites for Agent demo mode.
+ */
+public class AgentDemoUtils {
+    /** Counter for threads in pool. */
+    private static final AtomicInteger THREAD_CNT = new AtomicInteger(0);
+
+    /**
+     * Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
+     *
+     * @param corePoolSize Number of threads to keep in the pool, even if they are idle.
+     * @param threadName Part of thread name that would be used by thread factory.
+     * @return Newly created scheduled thread pool.
+     */
+    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, final String threadName) {
+        ScheduledExecutorService srvc = Executors.newScheduledThreadPool(corePoolSize, new ThreadFactory() {
+            @Override public Thread newThread(Runnable r) {
+                Thread thread = new Thread(r, String.format("%s-%d", threadName, THREAD_CNT.getAndIncrement()));
+
+                thread.setDaemon(true);
+
+                return thread;
+            }
+        });
+
+        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)srvc;
+
+        // Setting up shutdown policy.
+        executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+        executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+
+        return srvc;
+    }
+
+    /**
+     * Round value.
+     *
+     * @param val Value to round.
+     * @param places Numbers after point.
+     * @return Rounded value;
+     */
+    public static double round(double val, int places) {
+        if (places < 0)
+            throw new IllegalArgumentException();
+
+        long factor = (long)Math.pow(10, places);
+
+        val *= factor;
+
+        long tmp = Math.round(val);
+
+        return (double)tmp / factor;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoCachesLoadService.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoCachesLoadService.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoCachesLoadService.java
new file mode 100644
index 0000000..9117646
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoCachesLoadService.java
@@ -0,0 +1,456 @@
+/*
+ * 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.console.demo.service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.console.demo.AgentDemoUtils;
+import org.apache.ignite.console.demo.model.Car;
+import org.apache.ignite.console.demo.model.Country;
+import org.apache.ignite.console.demo.model.Department;
+import org.apache.ignite.console.demo.model.Employee;
+import org.apache.ignite.console.demo.model.Parking;
+import org.apache.ignite.resources.IgniteInstanceResource;
+import org.apache.ignite.services.Service;
+import org.apache.ignite.services.ServiceContext;
+import org.apache.ignite.transactions.Transaction;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+
+/**
+ * Demo service. Create and populate caches. Run demo load on caches.
+ */
+public class DemoCachesLoadService implements Service {
+    /** Ignite instance. */
+    @IgniteInstanceResource
+    private Ignite ignite;
+
+    /** Thread pool to execute cache load operations. */
+    private ScheduledExecutorService cachePool;
+
+    /** */
+    private static final String COUNTRY_CACHE_NAME = "CountryCache";
+
+    /** */
+    private static final String DEPARTMENT_CACHE_NAME = "DepartmentCache";
+
+    /** */
+    private static final String EMPLOYEE_CACHE_NAME = "EmployeeCache";
+
+    /** */
+    private static final String PARKING_CACHE_NAME = "ParkingCache";
+
+    /** */
+    public static final String CAR_CACHE_NAME = "CarCache";
+
+    /** */
+    static final Set<String> DEMO_CACHES = new HashSet<>(Arrays.asList(COUNTRY_CACHE_NAME,
+        DEPARTMENT_CACHE_NAME, EMPLOYEE_CACHE_NAME, PARKING_CACHE_NAME, CAR_CACHE_NAME));
+
+    /** Countries count. */
+    private static final int CNTR_CNT = 10;
+
+    /** Departments count */
+    private static final int DEP_CNT = 100;
+
+    /** Employees count. */
+    private static final int EMPL_CNT = 1000;
+
+    /** Countries count. */
+    private static final int CAR_CNT = 100;
+
+    /** Departments count */
+    private static final int PARK_CNT = 10;
+
+    /** */
+    private static final Random rnd = new Random();
+
+    /** Maximum count read/write key. */
+    private final int cnt;
+
+    /** Time range in milliseconds. */
+    private final long range;
+
+    /**
+     * @param cnt Maximum count read/write key.
+     */
+    public DemoCachesLoadService(int cnt) {
+        this.cnt = cnt;
+
+        range = new java.util.Date().getTime();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void cancel(ServiceContext ctx) {
+        if (cachePool != null)
+            cachePool.shutdown();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void init(ServiceContext ctx) throws Exception {
+        ignite.createCache(cacheCountry());
+        ignite.createCache(cacheDepartment());
+        ignite.createCache(cacheEmployee());
+        ignite.createCache(cacheCar());
+        ignite.createCache(cacheParking());
+
+        populateCacheEmployee();
+        populateCacheCar();
+
+        cachePool = AgentDemoUtils.newScheduledThreadPool(2, "demo-sql-load-cache-tasks");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void execute(ServiceContext ctx) throws Exception {
+        cachePool.scheduleWithFixedDelay(new Runnable() {
+            @Override public void run() {
+                try {
+                    IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
+
+                    if (cacheEmployee != null)
+                        try(Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
+                            for (int i = 0, n = 1; i < cnt; i++, n++) {
+                                Integer id = rnd.nextInt(EMPL_CNT);
+
+                                Integer depId = rnd.nextInt(DEP_CNT);
+
+                                double r = rnd.nextDouble();
+
+                                cacheEmployee.put(id, new Employee(id, depId, depId, "First name employee #" + n,
+                                    "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
+                                    new java.sql.Date((long)(r * range)), "Job employee #" + n,
+                                    500 + AgentDemoUtils.round(r * 2000, 2)));
+
+                                if (rnd.nextBoolean())
+                                    cacheEmployee.remove(rnd.nextInt(EMPL_CNT));
+
+                                cacheEmployee.get(rnd.nextInt(EMPL_CNT));
+                            }
+
+                            if (rnd.nextInt(100) > 20)
+                                tx.commit();
+                        }
+                }
+                catch (Throwable e) {
+                    if (!e.getMessage().contains("cache is stopped"))
+                        ignite.log().error("Cache write task execution error", e);
+                }
+            }
+        }, 10, 3, TimeUnit.SECONDS);
+
+        cachePool.scheduleWithFixedDelay(new Runnable() {
+            @Override public void run() {
+                try {
+                    IgniteCache<Integer, Car> cache = ignite.cache(CAR_CACHE_NAME);
+
+                    if (cache != null)
+                        for (int i = 0; i < cnt; i++) {
+                            Integer carId = rnd.nextInt(CAR_CNT);
+
+                            cache.put(carId, new Car(carId, rnd.nextInt(PARK_CNT), "Car #" + (i + 1)));
+
+                            if (rnd.nextBoolean())
+                                cache.remove(rnd.nextInt(CAR_CNT));
+                        }
+                }
+                catch (IllegalStateException ignored) {
+                    // No-op.
+                }
+                catch (Throwable e) {
+                    if (!e.getMessage().contains("cache is stopped"))
+                        ignite.log().error("Cache write task execution error", e);
+                }
+            }
+        }, 10, 3, TimeUnit.SECONDS);
+    }
+
+
+    /**
+     * Create base cache configuration.
+     *
+     * @param name cache name.
+     * @return Cache configuration with basic properties set.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheConfiguration(String name) {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name);
+
+        ccfg.setAffinity(new RendezvousAffinityFunction(false, 32));
+        ccfg.setQueryDetailMetricsSize(10);
+        ccfg.setStartSize(100);
+        ccfg.setStatisticsEnabled(true);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheCountry.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheCountry() {
+        CacheConfiguration<K, V> ccfg = cacheConfiguration(COUNTRY_CACHE_NAME);
+
+        // Configure cacheCountry types.
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
+
+        // COUNTRY.
+        QueryEntity type = new QueryEntity();
+
+        qryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Country.class.getName());
+
+        // Query fields for COUNTRY.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+        qryFlds.put("population", "java.lang.Integer");
+
+        type.setFields(qryFlds);
+
+        ccfg.setQueryEntities(qryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheDepartment() {
+        CacheConfiguration<K, V> ccfg = cacheConfiguration(DEPARTMENT_CACHE_NAME);
+
+        // Configure cacheDepartment types.
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
+
+        // DEPARTMENT.
+        QueryEntity type = new QueryEntity();
+
+        qryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Department.class.getName());
+
+        // Query fields for DEPARTMENT.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("countryId", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+
+        type.setFields(qryFlds);
+
+        ccfg.setQueryEntities(qryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheEmployee() {
+        CacheConfiguration<K, V> ccfg = cacheConfiguration(EMPLOYEE_CACHE_NAME);
+
+        ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+        ccfg.setBackups(1);
+
+        // Configure cacheEmployee types.
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
+
+        // EMPLOYEE.
+        QueryEntity type = new QueryEntity();
+
+        qryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Employee.class.getName());
+
+        // Query fields for EMPLOYEE.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("departmentId", "java.lang.Integer");
+        qryFlds.put("managerId", "java.lang.Integer");
+        qryFlds.put("firstName", "java.lang.String");
+        qryFlds.put("lastName", "java.lang.String");
+        qryFlds.put("email", "java.lang.String");
+        qryFlds.put("phoneNumber", "java.lang.String");
+        qryFlds.put("hireDate", "java.sql.Date");
+        qryFlds.put("job", "java.lang.String");
+        qryFlds.put("salary", "java.lang.Double");
+
+        type.setFields(qryFlds);
+
+        // Indexes for EMPLOYEE.
+        Collection<QueryIndex> indexes = new ArrayList<>();
+
+        QueryIndex idx = new QueryIndex();
+
+        idx.setName("EMP_NAMES");
+        idx.setIndexType(QueryIndexType.SORTED);
+        LinkedHashMap<String, Boolean> indFlds = new LinkedHashMap<>();
+
+        indFlds.put("firstName", Boolean.FALSE);
+        indFlds.put("lastName", Boolean.FALSE);
+
+        idx.setFields(indFlds);
+
+        indexes.add(idx);
+        indexes.add(new QueryIndex("salary", QueryIndexType.SORTED, false, "EMP_SALARY"));
+
+        type.setIndexes(indexes);
+
+        ccfg.setQueryEntities(qryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheParking() {
+        CacheConfiguration<K, V> ccfg = cacheConfiguration(PARKING_CACHE_NAME);
+
+        // Configure cacheParking types.
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
+
+        // PARKING.
+        QueryEntity type = new QueryEntity();
+
+        qryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Parking.class.getName());
+
+        // Query fields for PARKING.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+        qryFlds.put("capacity", "java.lang.Integer");
+
+        type.setFields(qryFlds);
+
+        ccfg.setQueryEntities(qryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheCar() {
+        CacheConfiguration<K, V> ccfg = cacheConfiguration(CAR_CACHE_NAME);
+
+        // Configure cacheCar types.
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
+
+        // CAR.
+        QueryEntity type = new QueryEntity();
+
+        qryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Car.class.getName());
+
+        // Query fields for CAR.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("parkingId", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+
+        type.setFields(qryFlds);
+
+        ccfg.setQueryEntities(qryEntities);
+
+        return ccfg;
+    }
+
+    /** */
+    private void populateCacheEmployee() {
+        if (ignite.log().isDebugEnabled())
+            ignite.log().debug("DEMO: Start employees population with data...");
+
+        IgniteCache<Integer, Country> cacheCountry = ignite.cache(COUNTRY_CACHE_NAME);
+
+        for (int i = 0, n = 1; i < CNTR_CNT; i++, n++)
+            cacheCountry.put(i, new Country(i, "Country #" + n, n * 10000000));
+
+        IgniteCache<Integer, Department> cacheDepartment = ignite.cache(DEPARTMENT_CACHE_NAME);
+
+        IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
+
+        for (int i = 0, n = 1; i < DEP_CNT; i++, n++) {
+            cacheDepartment.put(i, new Department(n, rnd.nextInt(CNTR_CNT), "Department #" + n));
+
+            double r = rnd.nextDouble();
+
+            cacheEmployee.put(i, new Employee(i, rnd.nextInt(DEP_CNT), null, "First name manager #" + n,
+                "Last name manager #" + n, "Email manager #" + n, "Phone number manager #" + n,
+                new java.sql.Date((long)(r * range)), "Job manager #" + n, 1000 + AgentDemoUtils.round(r * 4000, 2)));
+        }
+
+        for (int i = 0, n = 1; i < EMPL_CNT; i++, n++) {
+            Integer depId = rnd.nextInt(DEP_CNT);
+
+            double r = rnd.nextDouble();
+
+            cacheEmployee.put(i, new Employee(i, depId, depId, "First name employee #" + n,
+                "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
+                new java.sql.Date((long)(r * range)), "Job employee #" + n, 500 + AgentDemoUtils.round(r * 2000, 2)));
+        }
+
+        if (ignite.log().isDebugEnabled())
+            ignite.log().debug("DEMO: Finished employees population.");
+    }
+
+    /** */
+    private void populateCacheCar() {
+        if (ignite.log().isDebugEnabled())
+            ignite.log().debug("DEMO: Start cars population...");
+
+        IgniteCache<Integer, Parking> cacheParking = ignite.cache(PARKING_CACHE_NAME);
+
+        for (int i = 0, n = 1; i < PARK_CNT; i++, n++)
+            cacheParking.put(i, new Parking(i, "Parking #" + n, n * 10));
+
+        IgniteCache<Integer, Car> cacheCar = ignite.cache(CAR_CACHE_NAME);
+
+        for (int i = 0, n = 1; i < CAR_CNT; i++, n++)
+            cacheCar.put(i, new Car(i, rnd.nextInt(PARK_CNT), "Car #" + n));
+
+        if (ignite.log().isDebugEnabled())
+            ignite.log().debug("DEMO: Finished cars population.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoRandomCacheLoadService.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoRandomCacheLoadService.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoRandomCacheLoadService.java
new file mode 100644
index 0000000..57b26a2
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoRandomCacheLoadService.java
@@ -0,0 +1,120 @@
+/*
+ * 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.console.demo.service;
+
+import java.util.Random;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.console.demo.AgentDemoUtils;
+import org.apache.ignite.resources.IgniteInstanceResource;
+import org.apache.ignite.services.Service;
+import org.apache.ignite.services.ServiceContext;
+
+/**
+ * Demo service. Create cache and populate it by random int pairs.
+ */
+public class DemoRandomCacheLoadService implements Service {
+    /** Ignite instance. */
+    @IgniteInstanceResource
+    private Ignite ignite;
+
+    /** Thread pool to execute cache load operations. */
+    private ScheduledExecutorService cachePool;
+
+    /** */
+    public static final String RANDOM_CACHE_NAME = "RandomCache";
+
+    /** Employees count. */
+    private static final int RND_CNT = 1024;
+
+    /** */
+    private static final Random rnd = new Random();
+
+    /** Maximum count read/write key. */
+    private final int cnt;
+
+    /**
+     * @param cnt Maximum count read/write key.
+     */
+    public DemoRandomCacheLoadService(int cnt) {
+        this.cnt = cnt;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void cancel(ServiceContext ctx) {
+        if (cachePool != null)
+            cachePool.shutdown();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void init(ServiceContext ctx) throws Exception {
+        ignite.getOrCreateCache(cacheRandom());
+
+        cachePool = AgentDemoUtils.newScheduledThreadPool(2, "demo-sql-random-load-cache-tasks");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void execute(ServiceContext ctx) throws Exception {
+        cachePool.scheduleWithFixedDelay(new Runnable() {
+            @Override public void run() {
+                try {
+                    for (String cacheName : ignite.cacheNames()) {
+                        if (!DemoCachesLoadService.DEMO_CACHES.contains(cacheName)) {
+                            IgniteCache<Integer, Integer> cache = ignite.cache(cacheName);
+
+                            if (cache != null) {
+                                for (int i = 0, n = 1; i < cnt; i++, n++) {
+                                    Integer key = rnd.nextInt(RND_CNT);
+                                    Integer val = rnd.nextInt(RND_CNT);
+
+                                    cache.put(key, val);
+
+                                    if (rnd.nextInt(100) < 30)
+                                        cache.remove(key);
+                                }
+                            }
+                        }
+                    }
+                }
+                catch (Throwable e) {
+                    if (!e.getMessage().contains("cache is stopped"))
+                        ignite.log().error("Cache write task execution error", e);
+                }
+            }
+        }, 10, 3, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Configure cacheCountry.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheRandom() {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(RANDOM_CACHE_NAME);
+
+        ccfg.setAffinity(new RendezvousAffinityFunction(false, 32));
+        ccfg.setQueryDetailMetricsSize(10);
+        ccfg.setStartSize(100);
+        ccfg.setStatisticsEnabled(true);
+        ccfg.setIndexedTypes(Integer.class, Integer.class);
+
+        return ccfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceClusterSingleton.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceClusterSingleton.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceClusterSingleton.java
new file mode 100644
index 0000000..8c0623a
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceClusterSingleton.java
@@ -0,0 +1,41 @@
+/*
+ * 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.console.demo.service;
+
+import org.apache.ignite.services.Service;
+import org.apache.ignite.services.ServiceContext;
+
+/**
+ * Demo service to provide on one node in cluster.
+ */
+public class DemoServiceClusterSingleton implements Service {
+    /** {@inheritDoc} */
+    @Override public void cancel(ServiceContext ctx) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void init(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void execute(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceKeyAffinity.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceKeyAffinity.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceKeyAffinity.java
new file mode 100644
index 0000000..081ae27
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceKeyAffinity.java
@@ -0,0 +1,41 @@
+/*
+ * 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.console.demo.service;
+
+import org.apache.ignite.services.Service;
+import org.apache.ignite.services.ServiceContext;
+
+/**
+ * Demo service to provide for cache.
+ */
+public class DemoServiceKeyAffinity implements Service {
+    /** {@inheritDoc} */
+    @Override public void cancel(ServiceContext ctx) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void init(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void execute(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceMultipleInstances.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceMultipleInstances.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceMultipleInstances.java
new file mode 100644
index 0000000..0d10753
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceMultipleInstances.java
@@ -0,0 +1,41 @@
+/*
+ * 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.console.demo.service;
+
+import org.apache.ignite.services.Service;
+import org.apache.ignite.services.ServiceContext;
+
+/**
+ * Demo service to provide on all nodes.
+ */
+public class DemoServiceMultipleInstances implements Service {
+    /** {@inheritDoc} */
+    @Override public void cancel(ServiceContext ctx) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void init(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void execute(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/a600cafd/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceNodeSingleton.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceNodeSingleton.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceNodeSingleton.java
new file mode 100644
index 0000000..4d491da
--- /dev/null
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/service/DemoServiceNodeSingleton.java
@@ -0,0 +1,41 @@
+/*
+ * 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.console.demo.service;
+
+import org.apache.ignite.services.Service;
+import org.apache.ignite.services.ServiceContext;
+
+/**
+ * Demo service to provide on all nodes by one.
+ */
+public class DemoServiceNodeSingleton implements Service {
+    /** {@inheritDoc} */
+    @Override public void cancel(ServiceContext ctx) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void init(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void execute(ServiceContext ctx) throws Exception {
+        // No-op.
+    }
+}


[36/50] [abbrv] ignite git commit: IGNITE-4157 Mapping update notification hook - Fixes #1447.

Posted by sb...@apache.org.
IGNITE-4157 Mapping update notification hook - Fixes #1447.

Signed-off-by: Alexey Goncharuk <al...@gmail.com>


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 2e421c2a847caec7a2666a9d6cdf1035093c10fa
Parents: 19739a0
Author: Sergey Chugunov <se...@gmail.com>
Authored: Fri Feb 10 17:42:45 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Fri Feb 10 17:42:45 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/MappingStoreTask.java       |  3 +-
 .../ignite/internal/MarshallerContextImpl.java  | 50 ++++++++++++++++----
 .../communication/GridIoMessageFactory.java     | 20 ++++----
 .../GridMarshallerMappingProcessor.java         | 39 ++++++++++-----
 .../marshaller/MappingUpdatedListener.java      | 29 ++++++++++++
 .../MissingMappingRequestMessage.java           |  2 +-
 .../MissingMappingResponseMessage.java          |  2 +-
 .../MarshallerContextLockingSelfTest.java       |  6 +++
 ...lerCacheClientRequestsMappingOnMissTest.java | 24 ++++------
 .../marshaller/MarshallerContextSelfTest.java   |  8 ++++
 .../marshaller/MarshallerContextTestImpl.java   |  1 +
 11 files changed, 136 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/main/java/org/apache/ignite/internal/MappingStoreTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/MappingStoreTask.java b/modules/core/src/main/java/org/apache/ignite/internal/MappingStoreTask.java
index 102347a..96ef1b9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/MappingStoreTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/MappingStoreTask.java
@@ -18,12 +18,13 @@
 package org.apache.ignite.internal;
 
 import org.apache.ignite.internal.processors.marshaller.MarshallerMappingItem;
+import org.apache.ignite.internal.util.lang.GridPlainRunnable;
 
 /**
  * Task is used in {@link MarshallerContextImpl#onMappingAccepted(MarshallerMappingItem)}
  * to offload storing mapping data into file system from discovery thread.
  */
-class MappingStoreTask implements Runnable {
+class MappingStoreTask implements GridPlainRunnable {
     /** Store to put item to. */
     private final MarshallerMappingFileStore fileStore;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
index b137e99..5416ff0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
@@ -28,6 +28,7 @@ import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -39,10 +40,12 @@ import org.apache.ignite.IgniteException;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap2;
+import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.processors.marshaller.MappedName;
 import org.apache.ignite.internal.processors.marshaller.MappingExchangeResult;
 import org.apache.ignite.internal.processors.marshaller.MarshallerMappingItem;
 import org.apache.ignite.internal.processors.marshaller.MarshallerMappingTransport;
+import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.MarshallerContext;
@@ -76,13 +79,13 @@ public class MarshallerContextImpl implements MarshallerContext {
     private MarshallerMappingFileStore fileStore;
 
     /** */
-    private ExecutorService execSrvc;
+    private GridClosureProcessor closProc;
 
     /** */
     private MarshallerMappingTransport transport;
 
     /** */
-    private boolean isClientNode;
+    private boolean clientNode;
 
     /**
      * Initializes context.
@@ -319,7 +322,7 @@ public class MarshallerContextImpl implements MarshallerContext {
 
         cache.replace(item.typeId(), new MappedName(item.className(), true));
 
-        execSrvc.submit(new MappingStoreTask(fileStore, item.platformId(), item.typeId(), item.className()));
+        closProc.runLocalSafe(new MappingStoreTask(fileStore, item.platformId(), item.typeId(), item.className()));
     }
 
     /** {@inheritDoc} */
@@ -351,7 +354,7 @@ public class MarshallerContextImpl implements MarshallerContext {
             if (clsName != null)
                 cache.putIfAbsent(typeId, new MappedName(clsName, true));
             else
-                if (isClientNode) {
+                if (clientNode) {
                     mappedName = cache.get(typeId);
 
                     if (mappedName == null) {
@@ -375,7 +378,7 @@ public class MarshallerContextImpl implements MarshallerContext {
                 }
                 else
                     throw new ClassNotFoundException(
-                            "Unknown pair [platformId= "
+                            "Unknown pair [platformId="
                                     + platformId
                                     + ", typeId="
                                     + typeId + "]");
@@ -406,7 +409,7 @@ public class MarshallerContextImpl implements MarshallerContext {
      * @param item Item.
      * @param resolvedClsName Resolved class name.
      */
-    public void onMissedMappingResolved(MarshallerMappingItem item, String resolvedClsName) {
+    public void onMissedMappingResolved(final MarshallerMappingItem item, String resolvedClsName) {
         ConcurrentMap<Integer, MappedName> cache = getCacheFor(item.platformId());
 
         int typeId = item.typeId();
@@ -422,7 +425,7 @@ public class MarshallerContextImpl implements MarshallerContext {
             mappedName = new MappedName(resolvedClsName, true);
             cache.putIfAbsent(typeId, mappedName);
 
-            execSrvc.submit(new MappingStoreTask(fileStore, item.platformId(), item.typeId(), resolvedClsName));
+            closProc.runLocalSafe(new MappingStoreTask(fileStore, item.platformId(), item.typeId(), resolvedClsName));
         }
     }
 
@@ -502,8 +505,8 @@ public class MarshallerContextImpl implements MarshallerContext {
 
         fileStore = new MarshallerMappingFileStore(workDir, ctx.log(MarshallerMappingFileStore.class));
         this.transport = transport;
-        execSrvc = ctx.getSystemExecutorService();
-        isClientNode = ctx.clientNode();
+        closProc = ctx.closure();
+        clientNode = ctx.clientNode();
     }
 
     /**
@@ -514,6 +517,35 @@ public class MarshallerContextImpl implements MarshallerContext {
     }
 
     /**
+     * Method collects current mappings for all platforms.
+     *
+     * @return current mappings.
+     */
+    public Iterator<Map.Entry<Byte, Map<Integer, String>>> currentMappings() {
+        int size = allCaches.size();
+
+        Map<Byte, Map<Integer, String>> res = IgniteUtils.newHashMap(size);
+
+        for (byte i = 0; i < size; i++) {
+            Map<Integer, MappedName> platformMappings = allCaches.get(i);
+
+            if (platformMappings != null) {
+                if (i == JAVA_ID)
+                    platformMappings = ((CombinedMap)platformMappings).userMap;
+
+                Map<Integer, String> nameMappings = IgniteUtils.newHashMap(platformMappings.size());
+
+                for (Map.Entry<Integer, MappedName> e : platformMappings.entrySet())
+                    nameMappings.put(e.getKey(), e.getValue().className());
+
+                res.put(i, nameMappings);
+            }
+        }
+
+        return res.entrySet().iterator();
+    }
+
+    /**
      *
      */
     static final class CombinedMap extends AbstractMap<Integer, MappedName>

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
index e283bdc..6f95400 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
@@ -618,6 +618,16 @@ public class GridIoMessageFactory implements MessageFactory {
 
                 break;
 
+            case 78:
+                msg = new MissingMappingRequestMessage();
+
+                break;
+
+            case 79:
+                msg = new MissingMappingResponseMessage();
+
+                break;
+
             case 82:
                 msg = new JobStealingRequest();
 
@@ -808,16 +818,6 @@ public class GridIoMessageFactory implements MessageFactory {
 
                 break;
 
-            case 120:
-                msg = new MissingMappingRequestMessage();
-
-                break;
-
-            case 121:
-                msg = new MissingMappingResponseMessage();
-
-                break;
-
             case 124:
                 msg = new GridMessageCollection<>();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
index f5193ab..fdea869 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/GridMarshallerMappingProcessor.java
@@ -17,12 +17,13 @@
 
 package org.apache.ignite.internal.processors.marshaller;
 
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
@@ -38,10 +39,9 @@ import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
 import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteBiInClosure;
-import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.spi.discovery.DiscoveryDataBag;
 import org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData;
@@ -77,6 +77,12 @@ public class GridMarshallerMappingProcessor extends GridProcessorAdapter {
     private final MarshallerContextImpl marshallerCtx;
 
     /** */
+    private final GridClosureProcessor closProc;
+
+    /** */
+    private final List<MappingUpdatedListener> mappingUpdatedLsnrs = new CopyOnWriteArrayList<>();
+
+    /** */
     private final ConcurrentMap<MarshallerMappingItem, GridFutureAdapter<MappingExchangeResult>> mappingExchangeSyncMap
             = new ConcurrentHashMap8<>();
 
@@ -90,6 +96,8 @@ public class GridMarshallerMappingProcessor extends GridProcessorAdapter {
         super(ctx);
 
         marshallerCtx = ctx.marshallerContext();
+
+        closProc = ctx.closure();
     }
 
     /** {@inheritDoc} */
@@ -108,10 +116,10 @@ public class GridMarshallerMappingProcessor extends GridProcessorAdapter {
 
         discoMgr.setCustomEventListener(MappingAcceptedMessage.class, new MappingAcceptedListener());
 
-        if (!ctx.clientNode())
-            ioMgr.addMessageListener(TOPIC_MAPPING_MARSH, new MissingMappingRequestListener(ioMgr));
-        else
+        if (ctx.clientNode())
             ioMgr.addMessageListener(TOPIC_MAPPING_MARSH, new MissingMappingResponseListener());
+        else
+            ioMgr.addMessageListener(TOPIC_MAPPING_MARSH, new MissingMappingRequestListener(ioMgr));
 
         if (ctx.clientNode())
             ctx.event().addLocalEventListener(new GridLocalEventListener() {
@@ -129,10 +137,10 @@ public class GridMarshallerMappingProcessor extends GridProcessorAdapter {
     /**
      * Adds a listener to be notified when mapping changes.
      *
-     * @param mappingUpdatedListener Mapping updated listener.
+     * @param mappingUpdatedListener listener for mapping updated events.
      */
-    public void addMappingUpdatedListener(IgniteBiInClosure<Integer, String> mappingUpdatedListener) {
-
+    public void addMappingUpdatedListener(MappingUpdatedListener mappingUpdatedListener) {
+        mappingUpdatedLsnrs.add(mappingUpdatedListener);
     }
 
     /**
@@ -140,8 +148,8 @@ public class GridMarshallerMappingProcessor extends GridProcessorAdapter {
      *
      * @return Iterator over current mappings.
      */
-    public Iterator<IgniteBiTuple<Integer, String>> currentMappings() {
-        return Collections.emptyListIterator();
+    public Iterator<Map.Entry<Byte, Map<Integer, String>>> currentMappings() {
+        return marshallerCtx.currentMappings();
     }
 
     /**
@@ -286,9 +294,16 @@ public class GridMarshallerMappingProcessor extends GridProcessorAdapter {
                 ClusterNode snd,
                 MappingAcceptedMessage msg
         ) {
-            MarshallerMappingItem item = msg.getMappingItem();
+            final MarshallerMappingItem item = msg.getMappingItem();
             marshallerCtx.onMappingAccepted(item);
 
+            closProc.runLocalSafe(new Runnable() {
+                @Override public void run() {
+                    for (MappingUpdatedListener lsnr : mappingUpdatedLsnrs)
+                        lsnr.mappingUpdated(item.platformId(), item.typeId(), item.className());
+                }
+            });
+
             GridFutureAdapter<MappingExchangeResult> fut = mappingExchangeSyncMap.get(item);
 
             if (fut != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MappingUpdatedListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MappingUpdatedListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MappingUpdatedListener.java
new file mode 100644
index 0000000..8a9d3d8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MappingUpdatedListener.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.marshaller;
+
+/**
+ *  Interface allows any component to register for events of newly added mappings.
+ */
+public interface MappingUpdatedListener {
+    /**
+     * @param platformId Id of platform new mapping was added for.
+     * @param typeId Id of type new mapping was added for.
+     * @param className Name of mapped class.
+     */
+    public void mappingUpdated(byte platformId, int typeId, String className);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingRequestMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingRequestMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingRequestMessage.java
index ba2afce..a42072a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingRequestMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingRequestMessage.java
@@ -116,7 +116,7 @@ public class MissingMappingRequestMessage implements Message {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return 120;
+        return 78;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingResponseMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingResponseMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingResponseMessage.java
index d468302..33f892b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingResponseMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/marshaller/MissingMappingResponseMessage.java
@@ -128,7 +128,7 @@ public class MissingMappingResponseMessage implements Message {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return 121;
+        return 79;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
index cc2bc39..0e278f3 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
@@ -24,8 +24,10 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.processors.marshaller.MarshallerMappingItem;
 import org.apache.ignite.internal.processors.marshaller.MarshallerMappingTransport;
+import org.apache.ignite.internal.processors.pool.PoolProcessor;
 import org.apache.ignite.testframework.GridTestClassLoader;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -40,6 +42,7 @@ public class MarshallerContextLockingSelfTest extends GridCommonAbstractTest {
     /** Inner logger. */
     private InnerLogger innerLog;
 
+    /** */
     private GridTestKernalContext ctx;
 
     /** {@inheritDoc} */
@@ -56,6 +59,9 @@ public class MarshallerContextLockingSelfTest extends GridCommonAbstractTest {
         };
 
         ctx.setSystemExecutorService(Executors.newFixedThreadPool(12));
+
+        ctx.add(new PoolProcessor(ctx));
+        ctx.add(new GridClosureProcessor(ctx));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingOnMissTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingOnMissTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingOnMissTest.java
index 27c01c5..d0e863e 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingOnMissTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingOnMissTest.java
@@ -24,8 +24,6 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Map;
 import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -131,22 +129,20 @@ public class IgniteMarshallerCacheClientRequestsMappingOnMissTest extends GridCo
 
         stopGrid(1);
 
-        if (!getMarshCtxFileStoreExecutorSrvc((GridKernalContext) U.field(cl1, "ctx"))
-                .awaitTermination(5000, TimeUnit.MILLISECONDS))
-            fail("Failed to wait for executor service used by MarshallerContext to shutdown");
-
         File[] files = Paths.get(TMP_DIR, "marshaller").toFile().listFiles();
 
         assertNotNull(TMP_DIR + "/marshaller directory should contain at least one file", files);
-        assertEquals(TMP_DIR + "/marshaller directory should contain exactly one file", 1, files.length);
-        assertEquals(clsName, new String(Files.readAllBytes(files[0].toPath())));
-    }
 
-    /**
-     * @param ctx Context.
-     */
-    private ExecutorService getMarshCtxFileStoreExecutorSrvc(GridKernalContext ctx) {
-        return U.field((Object)U.field(ctx, "marshCtx"), "execSrvc");
+        boolean orgClsMarshalled = false;
+
+        for (File f : files) {
+            if (clsName.equals(new String(Files.readAllBytes(f.toPath())))) {
+                orgClsMarshalled = true;
+                break;
+            }
+        }
+
+        assertTrue(clsName + " should be marshalled and stored to disk", orgClsMarshalled);
     }
 
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
index 7ce6ece..5883898 100644
--- a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
@@ -28,7 +28,9 @@ import java.util.concurrent.TimeUnit;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.MarshallerContextImpl;
+import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.processors.marshaller.MarshallerMappingItem;
+import org.apache.ignite.internal.processors.pool.PoolProcessor;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -52,6 +54,10 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
         execSvc = Executors.newSingleThreadExecutor();
 
         ctx.setSystemExecutorService(execSvc);
+
+        ctx.add(new PoolProcessor(ctx));
+
+        ctx.add(new GridClosureProcessor(ctx));
     }
 
     /**
@@ -64,6 +70,8 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
 
         MarshallerMappingItem item = new MarshallerMappingItem(JAVA_ID, 1, String.class.getName());
 
+        ctx.onMappingProposed(item);
+
         ctx.onMappingAccepted(item);
 
         try (Ignite g1 = startGrid(1)) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/2e421c2a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
index 6085332..0a59bba 100644
--- a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
+++ b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
@@ -91,6 +91,7 @@ public class MarshallerContextTestImpl extends MarshallerContextImpl {
             int typeId
     ) throws ClassNotFoundException, IgniteCheckedException {
         String clsName = map.get(typeId);
+
         return (clsName == null) ? super.getClassName(platformId, typeId) : clsName;
     }
 }


[09/50] [abbrv] ignite git commit: IGNITE-4363: SQL: fixed inner property updates for DML operations.

Posted by sb...@apache.org.
IGNITE-4363: SQL: fixed inner property updates for DML operations.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 70cd8e452b94b806a2fe6fe00b4b67ce80eb4373
Parents: 0726d32
Author: Alexander Paschenko <al...@gmail.com>
Authored: Tue Feb 7 11:41:08 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Feb 7 11:41:08 2017 +0300

----------------------------------------------------------------------
 .../configuration/CacheConfiguration.java       |  16 ++-
 .../processors/query/GridQueryProcessor.java    |  81 ++++++++++----
 .../processors/query/GridQueryProperty.java     |  21 ++--
 .../query/h2/DmlStatementsProcessor.java        |  69 ++++++------
 .../query/h2/dml/UpdatePlanBuilder.java         | 105 +++++++++++++------
 ...niteCacheAbstractInsertSqlQuerySelfTest.java |   4 +
 .../IgniteCacheAbstractSqlDmlQuerySelfTest.java |   2 +-
 .../IgniteCacheInsertSqlQuerySelfTest.java      |  22 ++++
 .../cache/IgniteCacheMergeSqlQuerySelfTest.java |  24 +++++
 .../IgniteCacheUpdateSqlQuerySelfTest.java      |  63 +++++++++--
 .../h2/GridIndexingSpiAbstractSelfTest.java     |   5 +
 11 files changed, 301 insertions(+), 111 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 0656dda..f0179ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -2358,9 +2358,13 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    processAnnotation(key, sqlAnn, txtAnn, field.getType(), prop, type);
-
+                    // Add parent property before its possible nested properties so that
+                    // resulting parent column comes before columns corresponding to those
+                    // nested properties in the resulting table - that way nested
+                    // properties override will happen properly (first parent, then children).
                     type.addProperty(prop, key, true);
+
+                    processAnnotation(key, sqlAnn, txtAnn, field.getType(), prop, type);
                 }
             }
 
@@ -2380,9 +2384,13 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    processAnnotation(key, sqlAnn, txtAnn, mtd.getReturnType(), prop, type);
-
+                    // Add parent property before its possible nested properties so that
+                    // resulting parent column comes before columns corresponding to those
+                    // nested properties in the resulting table - that way nested
+                    // properties override will happen properly (first parent, then children).
                     type.addProperty(prop, key, true);
+
+                    processAnnotation(key, sqlAnn, txtAnn, mtd.getReturnType(), prop, type);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index a239ee2..5bfdde8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.binary.BinaryObjectEx;
+import org.apache.ignite.internal.binary.BinaryObjectExImpl;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
@@ -1948,7 +1949,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     /**
      * Description of type property.
      */
-    private static class ClassProperty extends GridQueryProperty {
+    private static class ClassProperty implements GridQueryProperty {
         /** */
         private final PropertyAccessor accessor;
 
@@ -2041,12 +2042,17 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public String toString() {
             return S.toString(ClassProperty.class, this);
         }
+
+        /** {@inheritDoc} */
+        @Override public GridQueryProperty parent() {
+            return parent;
+        }
     }
 
     /**
      *
      */
-    private class BinaryProperty extends GridQueryProperty {
+    private class BinaryProperty implements GridQueryProperty {
         /** Property name. */
         private String propName;
 
@@ -2130,11 +2136,17 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                 obj = isKeyProp0 == 1 ? key : val;
             }
 
-            assert obj instanceof BinaryObject;
-
-            BinaryObject obj0 = (BinaryObject)obj;
+            if (obj instanceof BinaryObject) {
+                BinaryObject obj0 = (BinaryObject) obj;
+                return fieldValue(obj0);
+            }
+            else if (obj instanceof BinaryObjectBuilder) {
+                BinaryObjectBuilder obj0 = (BinaryObjectBuilder)obj;
 
-            return fieldValue(obj0);
+                return obj0.getField(name());
+            }
+            else
+                throw new IgniteCheckedException("Unexpected binary object class [type=" + obj.getClass() + ']');
         }
 
         /** {@inheritDoc} */
@@ -2144,10 +2156,38 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             if (obj == null)
                 return;
 
+            Object srcObj = obj;
+
+            if (!(srcObj instanceof BinaryObjectBuilder))
+                throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
+
+            if (parent != null)
+                obj = parent.value(key, val);
+
+            boolean needsBuild = false;
+
+            if (obj instanceof BinaryObjectExImpl) {
+                if (parent == null)
+                    throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
+
+                needsBuild = true;
+
+                obj = ((BinaryObjectExImpl)obj).toBuilder();
+            }
+
             if (!(obj instanceof BinaryObjectBuilder))
                 throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
 
             setValue0((BinaryObjectBuilder) obj, propName, propVal, type());
+
+            if (needsBuild) {
+                obj = ((BinaryObjectBuilder) obj).build();
+
+                assert parent != null;
+
+                // And now let's set this newly constructed object to parent
+                setValue0((BinaryObjectBuilder) srcObj, parent.propName, obj, obj.getClass());
+            }
         }
 
         /**
@@ -2224,6 +2264,11 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
             return isKeyProp0 == 1;
         }
+
+        /** {@inheritDoc} */
+        @Override public GridQueryProperty parent() {
+            return parent;
+        }
     }
 
     /**
@@ -2307,7 +2352,12 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
         /** {@inheritDoc} */
         @Override public GridQueryProperty property(String name) {
-            return getProperty(name);
+            GridQueryProperty res = props.get(name);
+
+            if (res == null)
+                res = uppercaseProps.get(name.toUpperCase());
+
+            return res;
         }
 
         /** {@inheritDoc} */
@@ -2315,7 +2365,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public <T> T value(String field, Object key, Object val) throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = getProperty(field);
+            GridQueryProperty prop = property(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2329,7 +2379,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = getProperty(field);
+            GridQueryProperty prop = property(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2469,19 +2519,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             fields.put(name, prop.type());
         }
 
-        /**
-         * @param field Property name.
-         * @return Property with given field name.
-         */
-        private GridQueryProperty getProperty(String field) {
-            GridQueryProperty res = props.get(field);
-
-            if (res == null)
-                res = uppercaseProps.get(field.toUpperCase());
-
-            return res;
-        }
-
         /** {@inheritDoc} */
         @Override public boolean valueTextIndex() {
             return valTextIdx;

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
index 5d74a2e..fb4c037 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
@@ -22,11 +22,7 @@ import org.apache.ignite.IgniteCheckedException;
 /**
  * Description and access method for query entity field.
  */
-public abstract class GridQueryProperty {
-    /** */
-    public GridQueryProperty() {
-    }
-
+public interface GridQueryProperty {
     /**
      * Gets this property value from the given object.
      *
@@ -35,7 +31,7 @@ public abstract class GridQueryProperty {
      * @return Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public abstract Object value(Object key, Object val) throws IgniteCheckedException;
+    public Object value(Object key, Object val) throws IgniteCheckedException;
 
     /**
      * Sets this property value for the given object.
@@ -45,21 +41,26 @@ public abstract class GridQueryProperty {
      * @param propVal Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public abstract void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
+    public void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
 
     /**
      * @return Property name.
      */
-    public abstract String name();
+    public String name();
 
     /**
      * @return Class member type.
      */
-    public abstract Class<?> type();
+    public Class<?> type();
 
     /**
      * Property ownership flag.
      * @return {@code true} if this property belongs to key, {@code false} if it belongs to value.
      */
-    public abstract boolean key();
+    public boolean key();
+
+    /**
+     * @return Parent property or {@code null} if this property is not nested.
+     */
+    public GridQueryProperty parent();
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
index 4030758..7995083 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
@@ -59,7 +59,6 @@ import org.apache.ignite.internal.processors.query.GridQueryProperty;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.h2.dml.FastUpdateArguments;
-import org.apache.ignite.internal.processors.query.h2.dml.KeyValueSupplier;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlanBuilder;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor;
@@ -481,7 +480,6 @@ public class DmlStatementsProcessor {
         while (it.hasNext()) {
             List<?> e = it.next();
             Object key = e.get(0);
-            Object val = (hasNewVal ? e.get(valColIdx) : e.get(1));
 
             Object newVal;
 
@@ -500,9 +498,6 @@ public class DmlStatementsProcessor {
             if (newVal == null)
                 throw new IgniteSQLException("New value for UPDATE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
-            if (bin && !(val instanceof BinaryObject))
-                val = cctx.grid().binary().toBinary(val);
-
             // Skip key and value - that's why we start off with 2nd column
             for (int i = 0; i < plan.tbl.getColumns().length - 2; i++) {
                 Column c = plan.tbl.getColumn(i + 2);
@@ -514,13 +509,10 @@ public class DmlStatementsProcessor {
 
                 boolean hasNewColVal = newColVals.containsKey(c.getName());
 
-                // Binary objects get old field values from the Builder, so we can skip what we're not updating
-                if (bin && !hasNewColVal)
+                if (!hasNewColVal)
                     continue;
 
-                // Column values that have been explicitly specified have priority over field values in old or new _val
-                // If no value given for the column, then we expect to find it in value, and not in key - hence null arg.
-                Object colVal = hasNewColVal ? newColVals.get(c.getName()) : prop.value(null, val);
+                Object colVal = newColVals.get(c.getName());
 
                 // UPDATE currently does not allow to modify key or its fields, so we must be safe to pass null as key.
                 desc.setColumnValue(null, newVal, colVal, i);
@@ -696,8 +688,8 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
-                plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(),
+                plan);
 
             cctx.cache().put(t.getKey(), t.getValue());
             return 1;
@@ -709,8 +701,7 @@ public class DmlStatementsProcessor {
             for (Iterator<List<?>> it = cursor.iterator(); it.hasNext();) {
                 List<?> row = it.next();
 
-                IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier, plan.valSupplier,
-                    plan.keyColIdx, plan.valColIdx, desc);
+                IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
 
                 rows.put(t.getKey(), t.getValue());
 
@@ -742,8 +733,7 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes,
-                plan.keySupplier, plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(), plan);
 
             if (cctx.cache().putIfAbsent(t.getKey(), t.getValue()))
                 return 1;
@@ -768,8 +758,7 @@ public class DmlStatementsProcessor {
             while (it.hasNext()) {
                 List<?> row = it.next();
 
-                final IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
-                    plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
+                final IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
 
                 rows.put(t.getKey(), new InsertEntryProcessor(t.getValue()));
 
@@ -837,21 +826,14 @@ public class DmlStatementsProcessor {
      * Convert row presented as an array of Objects into key-value pair to be inserted to cache.
      * @param cctx Cache context.
      * @param row Row to process.
-     * @param cols Query cols.
-     * @param colTypes Column types to convert data from {@code row} to.
-     * @param keySupplier Key instantiation method.
-     * @param valSupplier Key instantiation method.
-     * @param keyColIdx Key column index, or {@code -1} if no key column is mentioned in {@code cols}.
-     * @param valColIdx Value column index, or {@code -1} if no value column is mentioned in {@code cols}.
-     * @param rowDesc Row descriptor.
+     * @param plan Update plan.
      * @throws IgniteCheckedException if failed.
      */
     @SuppressWarnings({"unchecked", "ConstantConditions", "ResultOfMethodCallIgnored"})
-    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, Object[] row, String[] cols,
-        int[] colTypes, KeyValueSupplier keySupplier, KeyValueSupplier valSupplier, int keyColIdx, int valColIdx,
-        GridH2RowDescriptor rowDesc) throws IgniteCheckedException {
-        Object key = keySupplier.apply(F.asList(row));
-        Object val = valSupplier.apply(F.asList(row));
+    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, List<?> row, UpdatePlan plan)
+        throws IgniteCheckedException {
+        Object key = plan.keySupplier.apply(row);
+        Object val = plan.valSupplier.apply(row);
 
         if (key == null)
             throw new IgniteSQLException("Key for INSERT or MERGE must not be null",  IgniteQueryErrorCode.NULL_KEY);
@@ -859,13 +841,32 @@ public class DmlStatementsProcessor {
         if (val == null)
             throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
-        GridQueryTypeDescriptor desc = rowDesc.type();
+        GridQueryTypeDescriptor desc = plan.tbl.rowDescriptor().type();
+
+        Map<String, Object> newColVals = new HashMap<>();
+
+        for (int i = 0; i < plan.colNames.length; i++) {
+            if (i == plan.keyColIdx || i == plan.valColIdx)
+                continue;
+
+            newColVals.put(plan.colNames[i], convert(row.get(i), plan.colNames[i],
+                plan.tbl.rowDescriptor(), plan.colTypes[i]));
+        }
+
+        // We update columns in the order specified by the table for a reason - table's
+        // column order preserves their precedence for correct update of nested properties.
+        Column[] cols = plan.tbl.getColumns();
 
-        for (int i = 0; i < cols.length; i++) {
-            if (i == keyColIdx || i == valColIdx)
+        // First 2 columns are _key and _val, skip 'em.
+        for (int i = 2; i < cols.length; i++) {
+            String colName = cols[i].getName();
+
+            if (!newColVals.containsKey(colName))
                 continue;
 
-            desc.setValue(cols[i], key, val, convert(row[i], cols[i], rowDesc, colTypes[i]));
+            Object colVal = newColVals.get(colName);
+
+            desc.setValue(colName, key, val, colVal);
         }
 
         if (cctx.binaryMarshaller()) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
index fdcd164..ce2971a 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
@@ -48,6 +48,7 @@ import org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate;
 import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.h2.command.Prepared;
 import org.h2.table.Column;
@@ -192,8 +193,8 @@ public final class UpdatePlanBuilder {
                 hasValProps = true;
         }
 
-        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true);
-        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false);
+        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true, false);
+        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false, false);
 
         if (stmt instanceof GridSqlMerge)
             return UpdatePlan.forMerge(tbl.dataTable(), colNames, colTypes, keySupplier, valSupplier, keyColIdx,
@@ -253,8 +254,6 @@ public final class UpdatePlanBuilder {
             GridSqlSelect sel;
 
             if (stmt instanceof GridSqlUpdate) {
-                boolean bin = desc.context().binaryMarshaller();
-
                 List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
 
                 int valColIdx = -1;
@@ -282,20 +281,10 @@ public final class UpdatePlanBuilder {
                 if (hasNewVal)
                     valColIdx += 2;
 
-                int newValColIdx;
-
-                if (!hasProps) // No distinct properties, only whole new value - let's take it
-                    newValColIdx = valColIdx;
-                else if (bin) // We update distinct columns in binary mode - let's choose correct index for the builder
-                    newValColIdx = (hasNewVal ? valColIdx : 1);
-                else // Distinct properties, non binary mode - let's instantiate.
-                    newValColIdx = -1;
+                int newValColIdx = (hasNewVal ? valColIdx : 1);
 
-                // We want supplier to take present value only in case of binary mode as it will create
-                // whole new object as a result anyway, so we don't need to copy previous property values explicitly.
-                // Otherwise we always want it to instantiate new object whose properties we will later
-                // set to current values.
-                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false);
+                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps,
+                    false, true);
 
                 sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
 
@@ -319,11 +308,11 @@ public final class UpdatePlanBuilder {
      * @param hasProps Whether column list affects individual properties of key or value.
      * @param key Whether supplier should be created for key or for value.
      * @return Closure returning key or value.
-     * @throws IgniteCheckedException
+     * @throws IgniteCheckedException If failed.
      */
     @SuppressWarnings({"ConstantConditions", "unchecked"})
     private static KeyValueSupplier createSupplier(final GridCacheContext<?, ?> cctx, GridQueryTypeDescriptor desc,
-                                                   final int colIdx, boolean hasProps, final boolean key) throws IgniteCheckedException {
+        final int colIdx, boolean hasProps, final boolean key, boolean forUpdate) throws IgniteCheckedException {
         final String typeName = key ? desc.keyTypeName() : desc.valueTypeName();
 
         //Try to find class for the key locally.
@@ -332,15 +321,10 @@ public final class UpdatePlanBuilder {
 
         boolean isSqlType = GridQueryProcessor.isSqlType(cls);
 
-        // If we don't need to construct anything from scratch, just return value from array.
-        if (isSqlType || !hasProps || !cctx.binaryMarshaller()) {
+        // If we don't need to construct anything from scratch, just return value from given list.
+        if (isSqlType || !hasProps) {
             if (colIdx != -1)
-                return new KeyValueSupplier() {
-                    /** {@inheritDoc} */
-                    @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                        return arg.get(colIdx);
-                    }
-                };
+                return new PlainValueSupplier(colIdx);
             else if (isSqlType)
                 // Non constructable keys and values (SQL types) must be present in the query explicitly.
                 throw new IgniteCheckedException((key ? "Key" : "Value") + " is missing from query");
@@ -352,7 +336,12 @@ public final class UpdatePlanBuilder {
                 return new KeyValueSupplier() {
                     /** {@inheritDoc} */
                     @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                        BinaryObject bin = cctx.grid().binary().toBinary(arg.get(colIdx));
+                        Object obj = arg.get(colIdx);
+
+                        if (obj == null)
+                            return null;
+
+                        BinaryObject bin = cctx.grid().binary().toBinary(obj);
 
                         return cctx.grid().binary().builder(bin);
                     }
@@ -369,6 +358,26 @@ public final class UpdatePlanBuilder {
             }
         }
         else {
+            if (colIdx != -1) {
+                if (forUpdate && colIdx == 1) {
+                    // It's the case when the old value has to be taken as the basis for the new one on UPDATE,
+                    // so we have to clone it. And on UPDATE we don't expect any key supplier.
+                    assert !key;
+
+                    return new KeyValueSupplier() {
+                        /** {@inheritDoc} */
+                        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
+                            byte[] oldPropBytes = cctx.marshaller().marshal(arg.get(1));
+
+                            // colVal is another object now, we can mutate it
+                            return cctx.marshaller().unmarshal(oldPropBytes, U.resolveClassLoader(cctx.gridConfig()));
+                        }
+                    };
+                }
+                else // We either are not updating, or the new value is given explicitly, no cloning needed.
+                    return new PlainValueSupplier(colIdx);
+            }
+
             Constructor<?> ctor;
 
             try {
@@ -390,8 +399,12 @@ public final class UpdatePlanBuilder {
                             return ctor0.newInstance();
                         }
                         catch (Exception e) {
-                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
-                                (key ? "key" : "value"), e);
+                            if (S.INCLUDE_SENSITIVE)
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
+                            else
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + '.', e);
                         }
                     }
                 };
@@ -405,8 +418,12 @@ public final class UpdatePlanBuilder {
                             return GridUnsafe.allocateInstance(cls);
                         }
                         catch (InstantiationException e) {
-                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
-                                (key ? "key" : "value"), e);
+                            if (S.INCLUDE_SENSITIVE)
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
+                            else
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + '.', e);
                         }
                     }
                 };
@@ -414,8 +431,6 @@ public final class UpdatePlanBuilder {
         }
     }
 
-
-
     /**
      * @param target Expression to extract the table from.
      * @return Back end table for this element.
@@ -483,4 +498,26 @@ public final class UpdatePlanBuilder {
 
         return false;
     }
+
+    /**
+     * Simple supplier that just takes specified element of a given row.
+     */
+    private final static class PlainValueSupplier implements KeyValueSupplier {
+        /** Index of column to use. */
+        private final int colIdx;
+
+        /**
+         * Constructor.
+         *
+         * @param colIdx Column index.
+         */
+        private PlainValueSupplier(int colIdx) {
+            this.colIdx = colIdx;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
+            return arg.get(colIdx);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
index 86d01c7..626846b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
@@ -46,6 +46,8 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.junits.IgniteTestResources;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
+import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
+
 /**
  *
  */
@@ -126,6 +128,8 @@ public abstract class IgniteCacheAbstractInsertSqlQuerySelfTest extends GridComm
             createCaches();
         else
             createBinaryCaches();
+
+        ignite(0).createCache(cacheConfig("I2AT", true, false, Integer.class, AllTypes.class));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
index 649012f..3c92fdf 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
@@ -65,7 +65,7 @@ public abstract class IgniteCacheAbstractSqlDmlQuerySelfTest extends GridCommonA
     /**
      * @return whether {@link #marsh} is an instance of {@link BinaryMarshaller} or not.
      */
-    private boolean isBinaryMarshaller() {
+    protected boolean isBinaryMarshaller() {
         return marsh instanceof BinaryMarshaller;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
index e9c21dc..f91f405 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.concurrent.Callable;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCache;
@@ -202,4 +204,24 @@ public class IgniteCacheInsertSqlQuerySelfTest extends IgniteCacheAbstractInsert
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
+
+    /**
+     *
+     */
+    public void testNestedFieldsHandling() {
+        IgniteCache<Integer, IgniteCacheUpdateSqlQuerySelfTest.AllTypes> p = ignite(0).cache("I2AT");
+
+        p.query(new SqlFieldsQuery("insert into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
+            "values (1, ?, ?, ?, 'sss')") .setArgs(new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L),
+            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L)));
+
+        IgniteCacheUpdateSqlQuerySelfTest.AllTypes res = p.get(1);
+
+        IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType resInner = new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L);
+
+        resInner.innerStrCol = "sss";
+        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
+
+        assertEquals(resInner, res.innerTypeCol);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
index 32b7a12..d9a2d9e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
@@ -17,9 +17,13 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 
+import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
+
 /**
  *
  */
@@ -149,4 +153,24 @@ public class IgniteCacheMergeSqlQuerySelfTest extends IgniteCacheAbstractInsertS
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
+
+    /**
+     *
+     */
+    public void testNestedFieldsHandling() {
+        IgniteCache<Integer, AllTypes> p = ignite(0).cache("I2AT");
+
+        p.query(new SqlFieldsQuery("merge into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
+            "values (1, ?, ?, ?, 'sss')") .setArgs(new AllTypes.InnerType(50L),
+            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new AllTypes(1L)));
+
+        AllTypes res = p.get(1);
+
+        AllTypes.InnerType resInner = new AllTypes.InnerType(50L);
+
+        resInner.innerStrCol = "sss";
+        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
+
+        assertEquals(resInner, res.innerTypeCol);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
index 575f617..c3d9d8e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
@@ -44,6 +44,12 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         ignite(0).createCache(createAllTypesCacheConfig());
     }
 
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+        ignite(0).cache("L2AT").clear();
+    }
+
     /**
      *
      */
@@ -182,17 +188,19 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\"," +
             "\"tsCol\") values(2, ?, '2016-11-30 12:00:00', false, DATE '2016-12-01')").setArgs(new AllTypes(2L)));
 
-        cache.query(new SqlFieldsQuery("select \"primitiveIntsCol\" from \"AllTypes\"")).getAll();
-
-        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"doubleCol\" = CAST('50' as INT)," +
+        // Look ma, no hands: first we set value of inner object column (innerTypeCol), then update only one of its
+        // fields (innerLongCol), while leaving another inner property (innerStrCol) as specified by innerTypeCol.
+        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = ?, \"doubleCol\" = CAST('50' as INT)," +
             " \"booleanCol\" = 80, \"innerTypeCol\" = ?, \"strCol\" = PI(), \"shortCol\" = " +
             "CAST(WEEK(PARSEDATETIME('2016-11-30', 'yyyy-MM-dd')) as VARCHAR), " +
             "\"sqlDateCol\"=TIMESTAMP '2016-12-02 13:47:00', \"tsCol\"=TIMESTAMPADD('MI', 2, " +
             "DATEADD('DAY', 2, \"tsCol\")), \"primitiveIntsCol\" = ?, \"bytesCol\" = ?")
-            .setArgs(new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
+            .setArgs(5, new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
 
         AllTypes res = (AllTypes) cache.get(2L);
 
+        assertNotNull(res);
+
         assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
         assertEquals(50.0, res.doubleCol);
         assertEquals(2L, (long) res.longCol);
@@ -202,7 +210,11 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertTrue(Arrays.equals(new Byte[] {4, 5, 6}, res.bytesCol));
         assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
         assertTrue(Arrays.equals(new int[] {2, 3}, res.primitiveIntsCol));
-        assertEquals(new AllTypes.InnerType(80L), res.innerTypeCol);
+
+        AllTypes.InnerType expInnerType = new AllTypes.InnerType(80L);
+        expInnerType.innerLongCol = 5L;
+
+        assertEquals(expInnerType, res.innerTypeCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-12-03 00:02:00"), res.tsCol);
         assertEquals(2, res.intCol);
@@ -213,6 +225,45 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertEquals(49, res.shortCol);
     }
 
+    /** */
+    public void testSingleInnerFieldUpdate() throws ParseException {
+        IgniteCache cache = ignite(0).cache("L2AT");
+
+        cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\") values(2, ?," +
+            "'2016-11-30 12:00:00', false)").setArgs(new AllTypes(2L)));
+
+        assertFalse(cache.query(new SqlFieldsQuery("select * from \"AllTypes\"")).getAll().isEmpty());
+
+        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = 5"));
+
+        AllTypes res = (AllTypes) cache.get(2L);
+
+        assertNotNull(res);
+
+        assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
+        assertEquals(3.01, res.doubleCol);
+        assertEquals(2L, (long) res.longCol);
+        assertFalse(res.booleanCol);
+
+        assertEquals("2", res.strCol);
+        assertTrue(Arrays.equals(new byte[] {0, 1}, res.primitiveBytesCol));
+        assertTrue(Arrays.deepEquals(new Byte[] {0, 1}, res.bytesCol));
+        assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
+        assertTrue(Arrays.equals(new int[] {0, 1}, res.primitiveIntsCol));
+
+        AllTypes.InnerType expInnerType = new AllTypes.InnerType(2L);
+        expInnerType.innerLongCol = 5L;
+
+        assertEquals(expInnerType, res.innerTypeCol);
+        assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
+        assertNull(res.tsCol);
+        assertEquals(2, res.intCol);
+        assertEquals(AllTypes.EnumType.ENUMTRUE, res.enumCol);
+        assertNull(res.sqlDateCol);
+
+        assertEquals(-23000, res.shortCol);
+    }
+
     /**
      *
      */
@@ -308,7 +359,7 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         InnerType innerTypeCol;
 
         /** */
-        static final class InnerType implements Serializable {
+        static class InnerType implements Serializable {
             /** */
             @QuerySqlField
             Long innerLongCol;

http://git-wip-us.apache.org/repos/asf/ignite/blob/70cd8e45/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index e412828..69285f1 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -578,6 +578,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
                 @Override public boolean key() {
                     return false;
                 }
+
+                /** */
+                @Override public GridQueryProperty parent() {
+                    return null;
+                }
             };
         }
 


[31/50] [abbrv] ignite git commit: IGNITE-1680: CPP: Implemented API for user entry point lookup. This closes #1430.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/jni/include/ignite/jni/utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/include/ignite/jni/utils.h b/modules/platforms/cpp/jni/include/ignite/jni/utils.h
index 2b22cf9..bbd461d 100644
--- a/modules/platforms/cpp/jni/include/ignite/jni/utils.h
+++ b/modules/platforms/cpp/jni/include/ignite/jni/utils.h
@@ -44,14 +44,14 @@ namespace ignite
         };
 
         /**
-        * Represents global reference to Java object.
-        */
+         * Represents global reference to Java object.
+         */
         class IGNITE_IMPORT_EXPORT JavaGlobalRef
         {
         public:
             /**
-            * Default constructor
-            */
+             * Default constructor
+             */
             JavaGlobalRef() :
                 ctx(0),
                 obj(0)
@@ -60,11 +60,11 @@ namespace ignite
             }
 
             /**
-            * Constructor
-            *
-            * @param ctx JNI context.
-            * @param obj Java object.
-            */
+             * Constructor
+             *
+             * @param ctx JNI context.
+             * @param obj Java object.
+             */
             JavaGlobalRef(java::JniContext& ctx, jobject obj) :
                 ctx(&ctx),
                 obj(ctx.Acquire(obj))
@@ -73,10 +73,10 @@ namespace ignite
             }
 
             /**
-            * Copy constructor
-            *
-            * @param other Other instance.
-            */
+             * Copy constructor
+             *
+             * @param other Other instance.
+             */
             JavaGlobalRef(const JavaGlobalRef& other) :
                 ctx(other.ctx),
                 obj(ctx->Acquire(other.obj))
@@ -85,11 +85,11 @@ namespace ignite
             }
 
             /**
-            * Assignment operator.
-            *
-            * @param other Other instance.
-            * @return *this.
-            */
+             * Assignment operator.
+             *
+             * @param other Other instance.
+             * @return *this.
+             */
             JavaGlobalRef& operator=(const JavaGlobalRef& other)
             {
                 if (this != &other)
@@ -105,8 +105,8 @@ namespace ignite
             }
 
             /**
-            * Destructor.
-            */
+             * Destructor.
+             */
             ~JavaGlobalRef()
             {
                 if (ctx)
@@ -114,10 +114,10 @@ namespace ignite
             }
 
             /**
-            * Get object.
-            *
-            * @return Object.
-            */
+             * Get object.
+             *
+             * @return Object.
+             */
             jobject Get()
             {
                 return obj;
@@ -136,11 +136,10 @@ namespace ignite
          * First search is performed using the passed path argument (is not NULL).
          * Then JRE_HOME is evaluated. Last, JAVA_HOME is evaluated.
          *
-         * @param Explicitly defined path (optional).
-         * @param found Whether library was found.
-         * @return Path to the file.
+         * @param path Explicitly defined path (optional).
+         * @return Path to the file. Empty string if the library was not found.
          */
-        IGNITE_IMPORT_EXPORT std::string FindJvmLibrary(const std::string* path, bool* found);
+        IGNITE_IMPORT_EXPORT std::string FindJvmLibrary(const std::string& path);
 
         /**
          * Load JVM library into the process.
@@ -151,23 +150,21 @@ namespace ignite
         IGNITE_IMPORT_EXPORT bool LoadJvmLibrary(const std::string& path);
 
         /**
-         * Create Ignite classpath based on user input and home directory.
+         * Create Ignite classpath based on user input directory.
          *
          * @param usrCp User's classpath.
-         * @param home Ignite home directory.
          * @return Classpath.
          */
-        IGNITE_IMPORT_EXPORT std::string CreateIgniteClasspath(const std::string* usrCp, const std::string* home);
+        IGNITE_IMPORT_EXPORT std::string CreateIgniteClasspath(const std::string& usrCp);
 
         /**
          * Create Ignite classpath based on user input and home directory.
          *
          * @param usrCp User's classpath.
          * @param home Ignite home directory.
-         * @param test Whether test classpath must be used.
          * @return Classpath.
          */
-        IGNITE_IMPORT_EXPORT std::string CreateIgniteClasspath(const std::string* usrCp, const std::string* home, bool test);
+        IGNITE_IMPORT_EXPORT std::string CreateIgniteClasspath(const std::string& usrCp, const std::string& home);
 
         /**
          * Resolve IGNITE_HOME directory. Resolution is performed in several
@@ -180,10 +177,10 @@ namespace ignite
          * IGNITE_HOME is considered resolved.
          *
          * @param path Optional path to evaluate.
-         * @param found Whether IGNITE_HOME home was found.
-         * @return Resolved GG home.
+         * @param home Resolved GG home.
+         * @return True if IGNITE_HOME home was found.
          */
-        IGNITE_IMPORT_EXPORT std::string ResolveIgniteHome(const std::string* path, bool* found);
+        IGNITE_IMPORT_EXPORT bool ResolveIgniteHome(const std::string& path, std::string& home);
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/jni/os/linux/src/utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/os/linux/src/utils.cpp b/modules/platforms/cpp/jni/os/linux/src/utils.cpp
index a0f74ef..924779c 100644
--- a/modules/platforms/cpp/jni/os/linux/src/utils.cpp
+++ b/modules/platforms/cpp/jni/os/linux/src/utils.cpp
@@ -21,8 +21,10 @@
 #include <sys/stat.h>
 #include <dirent.h>
 #include <dlfcn.h>
+#include <unistd.h>
 
 #include "ignite/common/utils.h"
+#include "ignite/common/fixed_size_array.h"
 #include "ignite/jni/utils.h"
 #include "ignite/jni/java.h"
 
@@ -73,81 +75,57 @@ namespace ignite
             if (!val)
                 pthread_setspecific(attachKey, new AttachHelper());
         }
-		
-        /**
-         * Helper method to set boolean result to reference with proper NULL-check.
-         *
-         * @param res Result.
-         * @param outRes Where to set the result.
-         */
-        inline void SetBoolResult(bool res, bool* outRes)
-        {
-            if (outRes)
-                *outRes = res;
-        }
-		
+
         /**
          * Helper function for GG home resolution. Checks whether certain folders
          * exist in the path. Optionally goes upwards in directory hierarchy.
          *
          * @param path Path to evaluate.
          * @param up Whether to go upwards.
-         * @res Resolution result.
-         * @return Resolved directory.
+         * @param res Resolved directory.
+         * @return Resolution result.
          */
-        std::string ResolveIgniteHome0(const std::string& path, bool up, bool* res)
+        bool ResolveIgniteHome0(const std::string& path, bool up, std::string& res)
         {
             struct stat pathStat;
-            
-            if (stat(path.c_str(), &pathStat) != -1 && S_ISDIR(pathStat.st_mode)) 
-            {
-                // Remove trailing slashes, otherwise we will have an infinite loop.
-                std::string path0 = path;
 
-                while (true) {
-                    char lastChar = *path0.rbegin();
+            if (stat(path.c_str(), &pathStat) == -1 || !S_ISDIR(pathStat.st_mode))
+                return false;
+            
+            // Remove trailing slashes, otherwise we will have an infinite loop.
+            std::string path0;
 
-                    if (lastChar == '/' || lastChar == ' ') {
-                        size_t off = path0.find_last_of(lastChar);
+            size_t last = path.find_last_not_of("/\\ ");
 
-                        path0.erase(off, 1);
-                    }
-                    else
-                        break;
-                }
+            if (last != std::string::npos)
+                path0.assign(path, 0, last + 1);
 
-                std::string binStr = path0 + PROBE_BIN;
-                struct stat binStat;
+            std::string binStr = path0 + PROBE_BIN;
+            struct stat binStat;
 
-                std::string examplesStr = path0 + PROBE_EXAMPLES;
-                struct stat examplesStat;
+            std::string examplesStr = path0 + PROBE_EXAMPLES;
+            struct stat examplesStat;
 
-                if (stat(binStr.c_str(), &binStat) != -1 && S_ISDIR(binStat.st_mode) &&
-                    stat(examplesStr.c_str(), &examplesStat) != -1 && S_ISDIR(examplesStat.st_mode))
-                {
-                    SetBoolResult(true, res);
-
-                    return std::string(path0);
-                }
+            if (stat(binStr.c_str(), &binStat) != -1 && S_ISDIR(binStat.st_mode) &&
+                stat(examplesStr.c_str(), &examplesStat) != -1 && S_ISDIR(examplesStat.st_mode))
+            {
+                res = path0;
 
-                if (up)
-                {
-                    // Evaluate parent directory.
-                    size_t slashPos = path0.find_last_of("/");
+                return true;
+            }
 
-                    if (slashPos != std::string::npos)
-                    {
-                        std::string parent = path0.substr(0, slashPos);
+            if (!up)
+                return false;
 
-                        return ResolveIgniteHome0(parent, true, res);
-                    }
-                }
+            // Evaluate parent directory.
+            size_t slashPos = path0.find_last_of("/");
 
-            }
+            if (slashPos == std::string::npos)
+                return false;
 
-            SetBoolResult(false, res);
+            std::string parent(path0, 0, slashPos);
 
-            return std::string();
+            return ResolveIgniteHome0(parent, true, res);
         }
 
         /**
@@ -158,7 +136,7 @@ namespace ignite
          */
         std::string ClasspathJars(const std::string& path)
         {
-            std::string res = std::string();
+            std::string res;
 
             DIR* dir = opendir(path.c_str());
 
@@ -168,7 +146,8 @@ namespace ignite
 
                 while ((entry = readdir(dir)) != NULL)
                 {
-                    if (strstr(entry->d_name, ".jar"))
+                    char *dot = strrchr(entry->d_name, '.');
+                    if (dot && !strcmp(dot, ".jar"))
                     {
                         res.append(path);
                         res.append("/");
@@ -319,31 +298,22 @@ namespace ignite
             return res;
         }
 
-        std::string FindJvmLibrary(const std::string* path, bool* found)
+        std::string FindJvmLibrary(const std::string& path)
         {
-            SetBoolResult(true, found); // Optimistically assume that we will find it.
+            // If path is provided explicitly, then check only it.
+            if (!path.empty() && FileExists(path))
+                return path;
 
-            if (path) {
-                // If path is provided explicitly, then check only it.
-                if (FileExists(*path))                            
-                    return std::string(path->data());
-            }
-            else
-            {
-                bool javaEnvFound;
-                std::string javaEnv = GetEnv(JAVA_HOME, javaEnvFound);
+            std::string javaEnv;
 
-                if (javaEnvFound)
-                {
-                    std::string javaDll = javaEnv + JAVA_DLL;
+            if (GetEnv(JAVA_HOME, javaEnv))
+            {
+                std::string javaDll = javaEnv + JAVA_DLL;
 
-                    if (FileExists(javaDll))
-                        return std::string(javaDll);
-                }
+                if (FileExists(javaDll))
+                    return javaDll;
             }
 
-            SetBoolResult(false, found);
-
             return std::string();
         }
 
@@ -352,66 +322,91 @@ namespace ignite
             void* hnd = dlopen(path.c_str(), RTLD_LAZY);
             
             return hnd != NULL;
-        }                
+        }
 
-        std::string ResolveIgniteHome(const std::string* path, bool* found)
+        /**
+         * Create Ignite classpath based on user input and home directory.
+         *
+         * @param usrCp User's classpath.
+         * @param home Ignite home directory.
+         * @param forceTest Whether test classpath must be used.
+         * @return Classpath.
+         */
+        std::string CreateIgniteClasspath(const std::string& usrCp, const std::string* home, bool forceTest)
         {
-            if (path)
-                // 1. Check passed argument.
-                return ResolveIgniteHome0(*path, false, found);
-            else
+            // 1. Append user classpath if it exists.
+            std::string cp;
+
+            if (!usrCp.empty())
             {
-                // 2. Check environment variable.
-                bool envFound;
-                std::string env = GetEnv(IGNITE_HOME, envFound);
+                cp.append(usrCp);
 
-                if (envFound)
-                    return ResolveIgniteHome0(env, false, found);
+                if (*cp.rbegin() != ';')
+                    cp.push_back(';');
             }
 
-            SetBoolResult(false, found);
-                    
-            return std::string();
-        }
-
-        std::string CreateIgniteClasspath(const std::string* usrCp, const std::string* home)
-        {
-            bool forceTest = false;
-
+            // 2. Append home classpath if home is defined.
             if (home)
             {
-                bool envFound;
-                std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, envFound);
+                std::string homeCp = CreateIgniteHomeClasspath(*home, forceTest);
 
-                forceTest = envFound && env.compare("true") == 0;
+                cp.append(homeCp);
             }
 
-            return CreateIgniteClasspath(usrCp, home, forceTest);
+            // 3. Return.
+            return cp;
         }
 
-        std::string CreateIgniteClasspath(const std::string* usrCp, const std::string* home, bool forceTest)
+        std::string CreateIgniteClasspath(const std::string& usrCp)
+        {
+            if (usrCp.empty() || *usrCp.rbegin() == ';')
+                return usrCp;
+
+            return usrCp + ';';
+        }
+
+        std::string CreateIgniteClasspath(const std::string& usrCp, const std::string& home)
         {
             // 1. Append user classpath if it exists.
-            std::string cp = std::string();
+            std::string cp = CreateIgniteClasspath(usrCp);
 
-            if (usrCp)
-            {
-                cp.append(*usrCp);
+            // 2. Append home classpath
+            std::string env;
+            bool envFound = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, env);
 
-                if (*cp.rbegin() != ':')
-                    cp.append(":");
-            }
+            bool forceTest = envFound && env.compare("true") == 0;
 
-            // 2. Append home classpath if home is defined.
-            if (home)
-            {
-                std::string homeCp = CreateIgniteHomeClasspath(*home, forceTest);
+            std::string homeCp = CreateIgniteHomeClasspath(home, forceTest);
 
-                cp.append(homeCp);
-            }
+            cp.append(homeCp);
 
             // 3. Return.
             return cp;
         }
+
+        bool ResolveIgniteHome(const std::string& path, std::string& home)
+        {
+            if (!path.empty())
+                // 1. Check passed argument.
+                return ResolveIgniteHome0(path, false, home);
+
+            // 2. Check environment variable.
+            std::string env;
+
+            if (GetEnv(IGNITE_HOME, env))
+                return ResolveIgniteHome0(env, false, home);
+
+            // 3. Check current work dir.
+            FixedSizeArray<char> curDir(1024 * 16);
+
+            char* res = getcwd(curDir.GetData(), curDir.GetSize());
+
+            if (!res)
+                return false;
+
+            std::string curDirStr(curDir.GetData());
+
+            return ResolveIgniteHome0(curDirStr, true, home);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/jni/os/win/src/utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/os/win/src/utils.cpp b/modules/platforms/cpp/jni/os/win/src/utils.cpp
index 0647aa3..3b2033b 100644
--- a/modules/platforms/cpp/jni/os/win/src/utils.cpp
+++ b/modules/platforms/cpp/jni/os/win/src/utils.cpp
@@ -19,6 +19,7 @@
 
 #include "ignite/common/concurrent.h"
 #include "ignite/common/utils.h"
+#include "ignite/common/fixed_size_array.h"
 
 #include "ignite/jni/utils.h"
 #include "ignite/jni/java.h"
@@ -53,77 +54,55 @@ namespace ignite
         const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH";
 
         /**
-         * Helper method to set boolean result to pointer with proper NULL-check.
-         *
-         * @param res Result.
-         * @param outRes Where to set the result.
-         */
-        inline void SetBoolResult(bool res, bool* outRes)
-        {
-            if (outRes)
-                *outRes = res;
-        }
-
-        /**
          * Helper function for GG home resolution. Checks whether certain folders
          * exist in the path. Optionally goes upwards in directory hierarchy.
          *
          * @param path Path to evaluate.
          * @param up Whether to go upwards.
-         * @res Resolution result.
-         * @return Resolved directory.
+         * @param res Resolved directory.
+         * @return Resolution result.
          */
-        std::string ResolveIgniteHome0(const std::string& path, bool up, bool* res)
+        bool ResolveIgniteHome0(const std::string& path, bool up, std::string& res)
         {
             DWORD attrs = GetFileAttributesA(path.c_str());
 
-            if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
-            {
-                // Remove trailing slashes, otherwise we will have an infinite loop.
-                std::string path0 = path;
+            if (attrs == INVALID_FILE_ATTRIBUTES || !(attrs & FILE_ATTRIBUTE_DIRECTORY))
+                return false;
 
-                while (true) {
-                    char lastChar = *path0.rbegin();
+            // Remove trailing slashes, otherwise we will have an infinite loop.
+            std::string path0;
 
-                    if (lastChar == '/' || lastChar == '\\' || lastChar == ' ') {
-                        size_t off = path0.find_last_of(lastChar);
+            size_t last = path.find_last_not_of("/\\ ");
 
-                        path0.erase(off, 1);
-                    }
-                    else
-                        break;
-                }
+            if (last != std::string::npos)
+                path0.assign(path, 0, last + 1);
 
-                std::string binStr = path0 + PROBE_BIN;
-                DWORD binAttrs = GetFileAttributesA(binStr.c_str());
+            std::string binStr = path0 + PROBE_BIN;
+            DWORD binAttrs = GetFileAttributesA(binStr.c_str());
 
-                std::string examplesStr = path0 + PROBE_EXAMPLES;
-                DWORD examplesAttrs = GetFileAttributesA(examplesStr.c_str());
+            std::string examplesStr = path0 + PROBE_EXAMPLES;
+            DWORD examplesAttrs = GetFileAttributesA(examplesStr.c_str());
 
-                if (binAttrs != INVALID_FILE_ATTRIBUTES && (binAttrs & FILE_ATTRIBUTE_DIRECTORY) &&
-                    examplesAttrs != INVALID_FILE_ATTRIBUTES && (examplesAttrs & FILE_ATTRIBUTE_DIRECTORY))
-                {
-                    SetBoolResult(true, res);
-                    return std::string(path0);
-                }
+            if (binAttrs != INVALID_FILE_ATTRIBUTES && (binAttrs & FILE_ATTRIBUTE_DIRECTORY) &&
+                examplesAttrs != INVALID_FILE_ATTRIBUTES && (examplesAttrs & FILE_ATTRIBUTE_DIRECTORY))
+            {
+                res = path0;
 
-                if (up)
-                {
-                    // Evaluate parent directory.
-                    size_t slashPos = path0.find_last_of("/\\");
+                return true;
+            }
 
-                    if (slashPos != std::string::npos)
-                    {
-                        std::string parent = path0.substr(0, slashPos);
+            if (!up)
+                return false;
 
-                        return ResolveIgniteHome0(parent, true, res);
-                    }
-                }
-            }
+            // Evaluate parent directory.
+            size_t slashPos = path0.find_last_of("/\\");
 
-            SetBoolResult(false, res);
+            if (slashPos == std::string::npos)
+                return false;
 
-            return std::string();
+            std::string parent(path0, 0, slashPos);
+
+            return ResolveIgniteHome0(parent, true, res);
         }
 
         /**
@@ -136,24 +115,24 @@ namespace ignite
         {
             std::string searchPath = path + "\\*.jar";
 
-            std::string res = std::string();
-
             WIN32_FIND_DATAA findData;
 
             HANDLE hnd = FindFirstFileA(searchPath.c_str(), &findData);
 
-            if (hnd != INVALID_HANDLE_VALUE)
+            if (hnd == INVALID_HANDLE_VALUE)
+                return std::string();
+
+            std::string res;
+
+            do
             {
-                do
-                {
-                    res.append(path);
-                    res.append("\\");
-                    res.append(findData.cFileName);
-                    res.append(";");
-                } while (FindNextFileA(hnd, &findData) != 0);
+                res.append(path);
+                res.append("\\");
+                res.append(findData.cFileName);
+                res.append(";");
+            } while (FindNextFileA(hnd, &findData) != 0);
 
-                FindClose(hnd);
-            }
+            FindClose(hnd);
 
             return res;
         }
@@ -238,7 +217,7 @@ namespace ignite
          */
         std::string CreateIgniteHomeClasspath(const std::string& home, bool forceTest)
         {
-            std::string res = std::string();
+            std::string res;
 
             // 1. Add exploded test directories.
             if (forceTest)
@@ -292,31 +271,22 @@ namespace ignite
             return res;
         }
 
-        std::string FindJvmLibrary(const std::string* path, bool* found)
+        std::string FindJvmLibrary(const std::string& path)
         {
-            SetBoolResult(true, found); // Optimistically assume that we will find it.
+            // If path is provided explicitly, then check only it.
+            if (!path.empty() && FileExists(path))
+                return path;
 
-            if (path) {
-                // If path is provided explicitly, then check only it.
-                if (FileExists(*path))
-                    return std::string(path->data());
-            }
-            else
-            {
-                bool javaEnvFound;
-                std::string javaEnv = GetEnv(JAVA_HOME, javaEnvFound);
+            std::string javaEnv;
 
-                if (javaEnvFound)
-                {
-                    std::string javaDll = javaEnv + JAVA_DLL;
+            if (GetEnv(JAVA_HOME, javaEnv))
+            {
+                std::string javaDll = javaEnv + JAVA_DLL;
 
-                    if (FileExists(javaDll))
-                        return std::string(javaDll);
-                }
+                if (FileExists(javaDll))
+                    return javaDll;
             }
 
-            *found = false;
-
             return std::string();
         }
 
@@ -327,32 +297,25 @@ namespace ignite
             return mod != NULL;
         }
 
-        std::string CreateIgniteClasspath(const std::string* usrCp, const std::string* home)
-        {
-            bool forceTest = false;
-
-            if (home)
-            {
-                bool envFound;
-                std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, envFound);
-
-                forceTest = envFound && env.compare("true") == 0;
-            }
-
-            return CreateIgniteClasspath(usrCp, home, forceTest);
-        }
-
-        std::string CreateIgniteClasspath(const std::string* usrCp, const std::string* home, bool forceTest)
+        /**
+         * Create Ignite classpath based on user input and home directory.
+         *
+         * @param usrCp User's classpath.
+         * @param home Ignite home directory.
+         * @param forceTest Whether test classpath must be used.
+         * @return Classpath.
+         */
+        std::string CreateIgniteClasspath(const std::string& usrCp, const std::string* home, bool forceTest)
         {
             // 1. Append user classpath if it exists.
-            std::string cp = std::string();
+            std::string cp;
 
-            if (usrCp)
+            if (!usrCp.empty())
             {
-                cp.append(*usrCp);
+                cp.append(usrCp);
 
                 if (*cp.rbegin() != ';')
-                    cp.append(";");
+                    cp.push_back(';');
             }
 
             // 2. Append home classpath if home is defined.
@@ -367,33 +330,55 @@ namespace ignite
             return cp;
         }
 
-        std::string ResolveIgniteHome(const std::string* path, bool* found)
+        std::string CreateIgniteClasspath(const std::string& usrCp)
         {
-            if (path)
+            if (usrCp.empty() || *usrCp.rbegin() == ';')
+                return usrCp;
+
+            return usrCp + ';';
+        }
+
+        std::string CreateIgniteClasspath(const std::string& usrCp, const std::string& home)
+        {
+            // 1. Append user classpath if it exists.
+            std::string cp = CreateIgniteClasspath(usrCp);
+
+            // 2. Append home classpath
+            std::string env;
+            bool envFound = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, env);
+
+            bool forceTest = envFound && env.compare("true") == 0;
+
+            std::string homeCp = CreateIgniteHomeClasspath(home, forceTest);
+
+            cp.append(homeCp);
+
+            // 3. Return.
+            return cp;
+        }
+
+        bool ResolveIgniteHome(const std::string& path, std::string& home)
+        {
+            if (!path.empty())
                 // 1. Check passed argument.
-                return ResolveIgniteHome0(*path, false, found);
-            else
-            {
-                // 2. Check environment variable.
-                bool envFound;
-                std::string env = GetEnv(IGNITE_HOME, envFound);
+                return ResolveIgniteHome0(path, false, home);
 
-                if (envFound)
-                    return ResolveIgniteHome0(env, false, found);
+            // 2. Check environment variable.
+            std::string env;
 
-                // 3. Check current work dir.
-                const DWORD curDirLen = GetCurrentDirectory(0, NULL);
+            if (GetEnv(IGNITE_HOME, env))
+                return ResolveIgniteHome0(env, false, home);
 
-                char* curDir = new char[curDirLen];
+            // 3. Check current work dir.
+            const DWORD curDirLen = GetCurrentDirectory(0, NULL);
 
-                GetCurrentDirectoryA(curDirLen, curDir);
+            FixedSizeArray<char> curDir(curDirLen);
 
-                std::string curDirStr = curDir;
+            GetCurrentDirectoryA(curDir.GetSize(), curDir.GetData());
 
-                delete[] curDir;
+            std::string curDirStr(curDir.GetData());
 
-                return ResolveIgniteHome0(curDirStr, true, found);
-            }
+            return ResolveIgniteHome0(curDirStr, true, home);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/cpp/jni/src/java.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/src/java.cpp b/modules/platforms/cpp/jni/src/java.cpp
index 0c2e460..1988a86 100644
--- a/modules/platforms/cpp/jni/src/java.cpp
+++ b/modules/platforms/cpp/jni/src/java.cpp
@@ -32,7 +32,16 @@
     JniHandlers* hnds = reinterpret_cast<JniHandlers*>(envPtr); \
     type hnd = hnds->field; \
     if (hnd) \
-        hnd(hnds->target); \
+    { \
+        try \
+        { \
+            hnd(hnds->target); \
+        } \
+        catch (std::exception& err) \
+        { \
+            ThrowToJava(jniEnv, err.what()); \
+        } \
+    } \
     else \
         ThrowOnMissingHandler(jniEnv); \
 }
@@ -41,7 +50,16 @@
     JniHandlers* hnds = reinterpret_cast<JniHandlers*>(envPtr); \
     type hnd = hnds->field; \
     if (hnd) \
-        hnd(hnds->target, __VA_ARGS__); \
+    { \
+        try \
+        { \
+            hnd(hnds->target, __VA_ARGS__); \
+        } \
+        catch (std::exception& err) \
+        { \
+            ThrowToJava(jniEnv, err.what()); \
+        } \
+    } \
     else \
         ThrowOnMissingHandler(jniEnv); \
 }
@@ -50,7 +68,17 @@
     JniHandlers* hnds = reinterpret_cast<JniHandlers*>(envPtr); \
     type hnd = hnds->field; \
     if (hnd) \
-        return hnd(hnds->target, __VA_ARGS__); \
+    { \
+        try \
+        { \
+            return hnd(hnds->target, __VA_ARGS__); \
+        } \
+        catch (std::exception& err) \
+        { \
+            ThrowToJava(jniEnv, err.what()); \
+            return 0; \
+        } \
+    } \
     else \
     { \
         ThrowOnMissingHandler(jniEnv); \
@@ -358,6 +386,21 @@ namespace ignite
                 return 0;
             }
 
+            /**
+             * Throw generic exception to Java in case of native exception. As JniContext is not available at
+             * this point, we have to obtain exception details from scratch. This is not critical from performance
+             * perspective because such exception is usually denotes fatal condition.
+             *
+             * @param env JNI environment.
+             * @param msg Message.
+             */
+            void ThrowToJava(JNIEnv* env, const char* msg)
+            {
+                jclass cls = env->FindClass(C_IGNITE_EXCEPTION);
+
+                env->ThrowNew(cls, msg);
+            }
+
             char* StringToChars(JNIEnv* env, jstring str, int* len) {
                 if (!str) {
                     *len = 0;
@@ -937,12 +980,12 @@ namespace ignite
                 ExceptionCheck(env);
             }
 
-            jobject JniContext::ProcessorProjection(jobject obj) {
+            jobject JniContext::ProcessorProjection(jobject obj, JniErrorInfo* errInfo) {
                 JNIEnv* env = Attach();
 
                 jobject prj = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformProcessor_projection);
 
-                ExceptionCheck(env);
+                ExceptionCheck(env, errInfo);
 
                 return LocalToGlobal(env, prj);
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1410900f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
index 53dd47a..1d88f76 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
@@ -443,14 +443,15 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
         {
             var marsh = grid.Marshaller;
 
-            var key = marsh.Unmarshal<object>(inOutStream);
-            var val = marsh.Unmarshal<object>(inOutStream);
             var isLocal = inOutStream.ReadBool();
 
             var holder = isLocal
                 ? _handleRegistry.Get<CacheEntryProcessorHolder>(inOutStream.ReadLong(), true)
                 : marsh.Unmarshal<CacheEntryProcessorHolder>(inOutStream);
 
+            var key = marsh.Unmarshal<object>(inOutStream);
+            var val = marsh.Unmarshal<object>(inOutStream);
+
             return holder.Process(key, val, val != null, grid);
         }
 


[07/50] [abbrv] ignite git commit: Added put/remove benchmarks.

Posted by sb...@apache.org.
Added put/remove benchmarks.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 0726d3200a411817dae8c00cc183c49b25bb1f6f
Parents: d20b7f1
Author: sboikov <sb...@gridgain.com>
Authored: Mon Feb 6 14:11:06 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Mon Feb 6 14:11:06 2017 +0300

----------------------------------------------------------------------
 .../cache/IgnitePutRemoveBenchmark.java         | 42 ++++++++++++++++++++
 .../cache/IgnitePutRemoveTxBenchmark.java       | 30 ++++++++++++++
 2 files changed, 72 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0726d320/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveBenchmark.java
new file mode 100644
index 0000000..7ea3d91
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveBenchmark.java
@@ -0,0 +1,42 @@
+/*
+ * 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.yardstick.cache;
+
+import java.util.Map;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.yardstick.cache.model.SampleValue;
+
+/**
+ * Ignite benchmark that performs put and immediate remove operations.
+ */
+public class IgnitePutRemoveBenchmark extends IgniteCacheAbstractBenchmark<Integer, Object> {
+    /** {@inheritDoc} */
+    @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+        int key = nextRandom(args.range());
+
+        cache.put(key, new SampleValue(key));
+        cache.remove(key);
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Integer, Object> cache() {
+        return ignite().cache("atomic");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0726d320/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveTxBenchmark.java
new file mode 100644
index 0000000..ec88083
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutRemoveTxBenchmark.java
@@ -0,0 +1,30 @@
+/*
+ * 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.yardstick.cache;
+
+import org.apache.ignite.IgniteCache;
+
+/**
+ *
+ */
+public class IgnitePutRemoveTxBenchmark extends IgnitePutRemoveBenchmark {
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Integer, Object> cache() {
+        return ignite().cache("tx");
+    }
+}


[35/50] [abbrv] ignite git commit: IGNITE-3196 Add support for BigDecimals with negative scale in BinaryMarshaller

Posted by sb...@apache.org.
IGNITE-3196 Add support for BigDecimals with negative scale in BinaryMarshaller

This closes #1473


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 19739a080d389658878cd8eea5f28ce7dc5a229e
Parents: 1410900
Author: Vyacheslav Daradur <da...@gmail.com>
Authored: Fri Feb 10 16:51:37 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Feb 10 16:51:37 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/binary/BinaryUtils.java     | 12 +++---
 .../internal/binary/BinaryWriterExImpl.java     | 14 ++++---
 .../binary/BinaryMarshallerSelfTest.java        | 30 +++++++++++++
 modules/platforms/cpp/odbc/src/utility.cpp      | 17 +++++---
 .../Compute/ComputeApiTest.cs                   | 18 ++++----
 .../Impl/Binary/BinaryUtils.cs                  | 44 ++++++++++++--------
 6 files changed, 92 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/19739a08/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index 1153d15..6831ef9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -65,8 +65,8 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2;
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2;
 
 /**
  * Binary utils.
@@ -1193,13 +1193,15 @@ public class BinaryUtils {
         int scale = in.readInt();
         byte[] mag = doReadByteArray(in);
 
-        BigInteger intVal = new BigInteger(mag);
+        boolean negative = mag[0] < 0;
 
-        if (scale < 0) {
-            scale &= 0x7FFFFFFF;
+        if (negative)
+            mag[0] &= 0x7F;
 
+        BigInteger intVal = new BigInteger(mag);
+
+        if (negative)
             intVal = intVal.negate();
-        }
 
         return new BigDecimal(intVal, scale);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/19739a08/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
index adaacdd..3289780 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
@@ -403,18 +403,20 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
 
             out.unsafeWriteByte(GridBinaryMarshaller.DECIMAL);
 
+            out.unsafeWriteInt(val.scale());
+
             BigInteger intVal = val.unscaledValue();
 
-            if (intVal.signum() == -1) {
-                intVal = intVal.negate();
+            boolean negative = intVal.signum() == -1;
 
-                out.unsafeWriteInt(val.scale() | 0x80000000);
-            }
-            else
-                out.unsafeWriteInt(val.scale());
+            if (negative)
+                intVal = intVal.negate();
 
             byte[] vals = intVal.toByteArray();
 
+            if (negative)
+                vals[0] |= -0x80;
+
             out.unsafeWriteInt(vals.length);
             out.writeByteArray(vals);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/19739a08/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
index 003a330..2d43559 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
@@ -29,6 +29,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.net.InetSocketAddress;
 import java.sql.Timestamp;
 import java.util.AbstractQueue;
@@ -183,6 +184,35 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         assertEquals((val = new BigDecimal(new BigInteger("-79228162514264337593543950336"))), marshalUnmarshal(val));
     }
 
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNegativeScaleDecimal() throws Exception {
+        BigDecimal val;
+
+        assertEquals((val = BigDecimal.valueOf(Long.MAX_VALUE, -1)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Long.MIN_VALUE, -2)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Long.MAX_VALUE, -3)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Long.MIN_VALUE, -4)), marshalUnmarshal(val));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNegativeScaleRoundingModeDecimal() throws Exception {
+        BigDecimal val;
+
+        assertEquals((val = BigDecimal.ZERO.setScale(-1, RoundingMode.HALF_UP)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Long.MAX_VALUE).setScale(-3, RoundingMode.HALF_DOWN)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Long.MIN_VALUE).setScale(-5, RoundingMode.HALF_EVEN)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Integer.MAX_VALUE).setScale(-8, RoundingMode.UP)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Integer.MIN_VALUE).setScale(-10, RoundingMode.DOWN)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Double.MAX_VALUE).setScale(-12, RoundingMode.CEILING)), marshalUnmarshal(val));
+        assertEquals((val = BigDecimal.valueOf(Double.MIN_VALUE).setScale(-15, RoundingMode.FLOOR)), marshalUnmarshal(val));
+    }
+
+
     /**
      * @throws Exception If failed.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/19739a08/modules/platforms/cpp/odbc/src/utility.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/utility.cpp b/modules/platforms/cpp/odbc/src/utility.cpp
index 63454dc..3222a38 100644
--- a/modules/platforms/cpp/odbc/src/utility.cpp
+++ b/modules/platforms/cpp/odbc/src/utility.cpp
@@ -83,8 +83,14 @@ namespace ignite
 
             impl::binary::BinaryUtils::ReadInt8Array(reader.GetStream(), mag.data(), static_cast<int32_t>(mag.size()));
 
-            int32_t sign = (scale & 0x80000000) ? -1 : 1;
-            scale = scale & 0x7FFFFFFF;
+            int32_t sign = 1;
+            
+            if (mag[0] < 0)
+            {
+                mag[0] &= 0x7F;
+
+                sign = -1;
+            }
 
             common::Decimal res(mag.data(), static_cast<int32_t>(mag.size()), scale, sign);
 
@@ -97,14 +103,15 @@ namespace ignite
 
             const common::BigInteger &unscaled = decimal.GetUnscaledValue();
 
-            int32_t signFlag = unscaled.GetSign() == -1 ? 0x80000000 : 0;
-
-            writer.WriteInt32(decimal.GetScale() | signFlag);
+            writer.WriteInt32(decimal.GetScale());
 
             common::FixedSizeArray<int8_t> magnitude;
 
             unscaled.MagnitudeToBytes(magnitude);
 
+            if (unscaled.GetSign() == -1)
+                magnitude[0] |= -0x80;
+
             writer.WriteInt32(magnitude.GetSize());
 
             impl::binary::BinaryUtils::WriteInt8Array(writer.GetStream(), magnitude.GetData(), magnitude.GetSize());

http://git-wip-us.apache.org/repos/asf/ignite/blob/19739a08/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
index e2d3f61..da3ef1a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
@@ -823,16 +823,16 @@ namespace Apache.Ignite.Core.Tests.Compute
             Assert.AreEqual(val = decimal.Parse("-11,12"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
 
             // Test echo with overflow.
-            try
-            {
-                _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { null, decimal.MaxValue.ToString() + 1 });
+            var ex = Assert.Throws<BinaryObjectException>(() => _grid1.GetCompute()
+                .ExecuteJavaTask<object>(DecimalTask, new object[] {null, decimal.MaxValue.ToString() + 1}));
 
-                Assert.Fail();
-            }
-            catch (IgniteException)
-            {
-                // No-op.
-            }
+            Assert.AreEqual("Decimal magnitude overflow (must be less than 96 bits): 104", ex.Message);
+
+            // Negative scale. 1E+1 parses to "1 scale -1" on Java side.
+            ex = Assert.Throws<BinaryObjectException>(() => _grid1.GetCompute()
+                .ExecuteJavaTask<object>(DecimalTask, new object[] {null, "1E+1"}));
+
+            Assert.AreEqual("Decimal value scale overflow (must be between 0 and 28): -1", ex.Message);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/19739a08/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
index e6a3716..09c3ad4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -893,7 +893,9 @@ namespace Apache.Ignite.Core.Impl.Binary
             // Write scale and negative flag.
             int scale = (vals[3] & 0x00FF0000) >> 16; 
 
-            stream.WriteInt(((vals[3] & 0x80000000) == 0x80000000) ? (int)((uint)scale | 0x80000000) : scale);
+            stream.WriteInt(scale);
+
+            Boolean neg = vals[3] < 0;
 
             if (idx == -1)
             {
@@ -923,13 +925,15 @@ namespace Apache.Ignite.Core.Impl.Binary
                             if ((part24 & 0x80) == 0x80)
                             {
                                 stream.WriteInt(len + 1);
+                                
+                                stream.WriteByte((byte)(neg ? -0x80 : ByteZero));
 
-                                stream.WriteByte(ByteZero);
+                                neg = false;
                             }
                             else
                                 stream.WriteInt(len);
 
-                            stream.WriteByte((byte)part24);
+                            stream.WriteByte((byte)(neg ? ((sbyte)part24 | -0x80) : part24));
                             stream.WriteByte((byte)part16);
                             stream.WriteByte((byte)part8);
                             stream.WriteByte((byte)part0);
@@ -940,12 +944,14 @@ namespace Apache.Ignite.Core.Impl.Binary
                             {
                                 stream.WriteInt(len);
 
-                                stream.WriteByte(ByteZero);
+                                stream.WriteByte((byte)(neg ? -0x80 : ByteZero));
+
+                                neg = false;
                             }
                             else
                                 stream.WriteInt(len - 1);
-
-                            stream.WriteByte((byte)part16);
+                            
+                            stream.WriteByte((byte)(neg ? ((sbyte)part16 | -0x80) : part16));
                             stream.WriteByte((byte)part8);
                             stream.WriteByte((byte)part0);
                         }
@@ -955,12 +961,14 @@ namespace Apache.Ignite.Core.Impl.Binary
                             {
                                 stream.WriteInt(len - 1);
 
-                                stream.WriteByte(ByteZero);
+                                stream.WriteByte((byte)(neg ? -0x80 : ByteZero));
+
+                                neg = false;
                             }
                             else
                                 stream.WriteInt(len - 2);
-
-                            stream.WriteByte((byte)part8);
+                            
+                            stream.WriteByte((byte)(neg ? ((sbyte)part8 | -0x80) : part8));
                             stream.WriteByte((byte)part0);
                         }
                         else
@@ -969,12 +977,14 @@ namespace Apache.Ignite.Core.Impl.Binary
                             {
                                 stream.WriteInt(len - 2);
 
-                                stream.WriteByte(ByteZero);
+                                stream.WriteByte((byte)(neg ? -0x80 : ByteZero));
+
+                                neg = false;
                             }
                             else
                                 stream.WriteInt(len - 3);
 
-                            stream.WriteByte((byte)part0);
+                            stream.WriteByte((byte)(neg ? ((sbyte)part0 | -0x80) : part0));
                         }
                     }
                     else
@@ -997,18 +1007,16 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             int scale = stream.ReadInt();
 
-            bool neg;
+            bool neg = false;
+
+            byte[] mag = ReadByteArray(stream);
 
-            if (scale < 0)
+            if ((sbyte)mag[0] < 0)
             {
-                scale = scale & 0x7FFFFFFF;
+                mag[0] &= 0x7F;
 
                 neg = true;
             }
-            else
-                neg = false;
-
-            byte[] mag = ReadByteArray(stream);
 
             if (scale < 0 || scale > 28)
                 throw new BinaryObjectException("Decimal value scale overflow (must be between 0 and 28): " + scale);


[29/50] [abbrv] ignite git commit: ignite-3994 GridContinuousHandler cleanup on client disconnect. This closes #1496.

Posted by sb...@apache.org.
ignite-3994 GridContinuousHandler cleanup on client disconnect.
This closes #1496.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 2f4bdbb674e5634ce4c1a3432dede4c865977fde
Parents: 543a65f
Author: vdpyatkov <vp...@gridgain.com>
Authored: Fri Feb 10 15:08:45 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Fri Feb 10 15:09:53 2017 +0300

----------------------------------------------------------------------
 .../internal/GridEventConsumeHandler.java       |   5 +
 .../internal/GridMessageListenHandler.java      |   5 +
 .../continuous/CacheContinuousQueryHandler.java |  16 ++
 .../continuous/GridContinuousHandler.java       |   5 +
 .../continuous/GridContinuousProcessor.java     |   3 +
 .../ClientReconnectContinuousQueryTest.java     | 201 +++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite3.java         |   2 +
 7 files changed, 237 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2f4bdbb6/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
index 68d34ce..0395434 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
@@ -392,6 +392,11 @@ class GridEventConsumeHandler implements GridContinuousHandler {
     }
 
     /** {@inheritDoc} */
+    @Override public void onClientDisconnected() {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
     @Override public void onBatchAcknowledged(UUID routineId, GridContinuousBatch batch, GridKernalContext ctx) {
         // No-op.
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f4bdbb6/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
index 0eeaa8a..88d4450 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
@@ -199,6 +199,11 @@ public class GridMessageListenHandler implements GridContinuousHandler {
     }
 
     /** {@inheritDoc} */
+    @Override public void onClientDisconnected() {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
     @Override public void onBatchAcknowledged(UUID routineId, GridContinuousBatch batch, GridKernalContext ctx) {
         // No-op.
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f4bdbb6/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
index a9a7d7c..b3f0684 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
@@ -854,6 +854,15 @@ public class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler
         return ctx.security().enabled() ? ctx.task().resolveTaskName(taskHash) : null;
     }
 
+    /** {@inheritDoc} */
+    @Override public void onClientDisconnected() {
+        if (internal)
+            return;
+
+        for (PartitionRecovery rec : rcvs.values())
+            rec.resetTopologyCache();
+    }
+
     /**
      * @param ctx Context.
      * @param partId Partition id.
@@ -972,6 +981,13 @@ public class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler
         }
 
         /**
+         * Resets cached topology.
+         */
+        void resetTopologyCache() {
+            curTop = AffinityTopologyVersion.NONE;
+        }
+
+        /**
          * Add continuous entry.
          *
          * @param cctx Cache context.

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f4bdbb6/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
index f14b450..2a3a052 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
@@ -99,6 +99,11 @@ public interface GridContinuousHandler extends Externalizable, Cloneable {
     public GridContinuousBatch createBatch();
 
     /**
+     * Client node disconnected callback.
+     */
+    public void onClientDisconnected();
+
+    /**
      * Called when ack for a batch is received from client.
      *
      * @param routineId Routine ID.

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f4bdbb6/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
index 9fd9b6d..b9f42e1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
@@ -912,6 +912,9 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
                 unregisterRemote(e.getKey());
         }
 
+        for (LocalRoutineInfo routine : locInfos.values())
+            routine.hnd.onClientDisconnected();
+
         rmtInfos.clear();
 
         clientInfos.clear();

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f4bdbb6/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ClientReconnectContinuousQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ClientReconnectContinuousQueryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ClientReconnectContinuousQueryTest.java
new file mode 100644
index 0000000..feded14
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ClientReconnectContinuousQueryTest.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.query.continuous;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.CacheEntryUpdatedListener;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.ContinuousQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.events.Event;
+import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.managers.communication.GridIoManager;
+import org.apache.ignite.internal.util.nio.GridNioServer;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ *
+ */
+public class ClientReconnectContinuousQueryTest extends GridCommonAbstractTest {
+    /** Client index. */
+    private static final int CLIENT_IDX = 1;
+
+    /** Puts before reconnect. */
+    private static final int PUTS_BEFORE_RECONNECT = 50;
+
+    /** Puts after reconnect. */
+    private static final int PUTS_AFTER_RECONNECT = 50;
+
+    /** Recon latch. */
+    private static final CountDownLatch reconLatch = new CountDownLatch(1);
+
+    /** Discon latch. */
+    private static final CountDownLatch disconLatch = new CountDownLatch(1);
+
+    /** Updater received. */
+    private static final CountDownLatch updaterReceived = new CountDownLatch(PUTS_BEFORE_RECONNECT);
+
+    /** Receiver after reconnect. */
+    private static final CountDownLatch receiverAfterReconnect = new CountDownLatch(PUTS_AFTER_RECONNECT);
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        TcpCommunicationSpi commSpi = (TcpCommunicationSpi)cfg.getCommunicationSpi();
+
+        commSpi.setSlowClientQueueLimit(50);
+        commSpi.setIdleConnectionTimeout(300_000);
+
+        if (getTestGridName(CLIENT_IDX).equals(gridName))
+            cfg.setClientMode(true);
+        else {
+            CacheConfiguration ccfg = defaultCacheConfiguration();
+
+            cfg.setCacheConfiguration(ccfg);
+        }
+
+        return cfg;
+    }
+
+    /**
+     * Test client reconnect to alive grid.
+     *
+     * @throws Exception If failed.
+     */
+    public void testClientReconnect() throws Exception {
+        try {
+            startGrids(2);
+
+            IgniteEx client = grid(CLIENT_IDX);
+
+            client.events().localListen(new DisconnectListener(), EventType.EVT_CLIENT_NODE_DISCONNECTED);
+
+            client.events().localListen(new ReconnectListener(), EventType.EVT_CLIENT_NODE_RECONNECTED);
+
+            IgniteCache cache = client.cache(null);
+
+            ContinuousQuery qry = new ContinuousQuery();
+
+            qry.setLocalListener(new CQListener());
+
+            cache.query(qry);
+
+            putSomeKeys(PUTS_BEFORE_RECONNECT);
+
+            info("updaterReceived Count: " + updaterReceived.getCount());
+
+            assertTrue(updaterReceived.await(10_000, TimeUnit.MILLISECONDS));
+
+            skipRead(client, true);
+
+            putSomeKeys(1_000);
+
+            assertTrue(disconLatch.await(10_000, TimeUnit.MILLISECONDS));
+
+            skipRead(client, false);
+
+            assertTrue(reconLatch.await(10_000, TimeUnit.MILLISECONDS));
+
+            putSomeKeys(PUTS_AFTER_RECONNECT);
+
+            info("receiverAfterReconnect Count: " + receiverAfterReconnect.getCount());
+
+            assertTrue(receiverAfterReconnect.await(10_000, TimeUnit.MILLISECONDS));
+        }
+        finally {
+            stopAllGrids();
+        }
+
+    }
+
+    /**
+     *
+     */
+    private static class ReconnectListener implements IgnitePredicate<Event> {
+        /** {@inheritDoc} */
+        @Override public boolean apply(Event evt) {
+            reconLatch.countDown();
+
+            return false;
+        }
+    }
+
+    /**
+     *
+     */
+    private static class DisconnectListener implements IgnitePredicate<Event> {
+        /** {@inheritDoc} */
+        @Override public boolean apply(Event evt) {
+            disconLatch.countDown();
+
+            return false;
+        }
+    }
+
+    /**
+     *
+     */
+    private static class CQListener implements CacheEntryUpdatedListener {
+        /** {@inheritDoc} */
+        @Override public void onUpdated(Iterable iterable) throws CacheEntryListenerException {
+            if (reconLatch.getCount() != 0) {
+                for (Object o : iterable)
+                    updaterReceived.countDown();
+            }
+            else {
+                for (Object o : iterable)
+                    receiverAfterReconnect.countDown();
+            }
+        }
+    }
+
+    /**
+     * @param cnt Number of keys.
+     */
+    private void putSomeKeys(int cnt) {
+        IgniteEx ignite = grid(0);
+
+        IgniteCache<Object, Object> srvCache = ignite.cache(null);
+
+        for (int i = 0; i < cnt; i++)
+            srvCache.put(0, i);
+    }
+
+    /**
+     * @param igniteClient Ignite client.
+     * @param skip Skip.
+     */
+    private void skipRead(IgniteEx igniteClient, boolean skip) {
+        GridIoManager ioMgr = igniteClient.context().io();
+
+        TcpCommunicationSpi commSpi = (TcpCommunicationSpi)((Object[])U.field(ioMgr, "spis"))[0];
+
+        GridNioServer nioSrvr = U.field(commSpi, "nioSrvr");
+
+        GridTestUtils.setFieldValue(nioSrvr, "skipRead", skip);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/2f4bdbb6/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
index a865788..07125a6 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite3.java
@@ -34,6 +34,7 @@ import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBin
 import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBinaryIterationTest;
 import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBinaryIterationStoreEnabledTest;
 import org.apache.ignite.internal.processors.cache.query.continuous.CacheKeepBinaryIterationSwapEnabledTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.ClientReconnectContinuousQueryTest;
 import org.apache.ignite.internal.processors.cache.query.continuous.ContinuousQueryRemoteFilterMissingInClassPathSelfTest;
 import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicNearEnabledSelfTest;
 import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicOffheapTieredTest;
@@ -123,6 +124,7 @@ public class IgniteCacheQuerySelfTestSuite3 extends TestSuite {
         suite.addTestSuite(CacheKeepBinaryIterationNearEnabledTest.class);
         suite.addTestSuite(IgniteCacheContinuousQueryBackupQueueTest.class);
         suite.addTestSuite(IgniteCacheContinuousQueryNoUnsubscribeTest.class);
+        suite.addTestSuite(ClientReconnectContinuousQueryTest.class);
 
         return suite;
     }


[16/50] [abbrv] ignite git commit: IGNITE-4363: SQL: fixed inner properties update in DML.

Posted by sb...@apache.org.
IGNITE-4363: SQL: fixed inner properties update in DML.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: d01406f26061f9a994bbc399ee3033a86d7e307d
Parents: 68ef211
Author: Alexander Paschenko <al...@gmail.com>
Authored: Wed Feb 8 13:45:28 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Feb 8 13:45:28 2017 +0300

----------------------------------------------------------------------
 .../configuration/CacheConfiguration.java       |  16 ++-
 .../processors/query/GridQueryProcessor.java    |  81 ++++++++++----
 .../processors/query/GridQueryProperty.java     |  21 ++--
 .../query/h2/DmlStatementsProcessor.java        |  69 ++++++------
 .../query/h2/dml/UpdatePlanBuilder.java         | 105 +++++++++++++------
 ...niteCacheAbstractInsertSqlQuerySelfTest.java |   4 +
 .../IgniteCacheAbstractSqlDmlQuerySelfTest.java |   2 +-
 .../IgniteCacheInsertSqlQuerySelfTest.java      |  22 ++++
 .../cache/IgniteCacheMergeSqlQuerySelfTest.java |  24 +++++
 .../IgniteCacheUpdateSqlQuerySelfTest.java      |  63 +++++++++--
 .../h2/GridIndexingSpiAbstractSelfTest.java     |   5 +
 11 files changed, 301 insertions(+), 111 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 0656dda..f0179ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -2358,9 +2358,13 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    processAnnotation(key, sqlAnn, txtAnn, field.getType(), prop, type);
-
+                    // Add parent property before its possible nested properties so that
+                    // resulting parent column comes before columns corresponding to those
+                    // nested properties in the resulting table - that way nested
+                    // properties override will happen properly (first parent, then children).
                     type.addProperty(prop, key, true);
+
+                    processAnnotation(key, sqlAnn, txtAnn, field.getType(), prop, type);
                 }
             }
 
@@ -2380,9 +2384,13 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    processAnnotation(key, sqlAnn, txtAnn, mtd.getReturnType(), prop, type);
-
+                    // Add parent property before its possible nested properties so that
+                    // resulting parent column comes before columns corresponding to those
+                    // nested properties in the resulting table - that way nested
+                    // properties override will happen properly (first parent, then children).
                     type.addProperty(prop, key, true);
+
+                    processAnnotation(key, sqlAnn, txtAnn, mtd.getReturnType(), prop, type);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index a239ee2..5bfdde8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.binary.BinaryObjectEx;
+import org.apache.ignite.internal.binary.BinaryObjectExImpl;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
@@ -1948,7 +1949,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     /**
      * Description of type property.
      */
-    private static class ClassProperty extends GridQueryProperty {
+    private static class ClassProperty implements GridQueryProperty {
         /** */
         private final PropertyAccessor accessor;
 
@@ -2041,12 +2042,17 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public String toString() {
             return S.toString(ClassProperty.class, this);
         }
+
+        /** {@inheritDoc} */
+        @Override public GridQueryProperty parent() {
+            return parent;
+        }
     }
 
     /**
      *
      */
-    private class BinaryProperty extends GridQueryProperty {
+    private class BinaryProperty implements GridQueryProperty {
         /** Property name. */
         private String propName;
 
@@ -2130,11 +2136,17 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                 obj = isKeyProp0 == 1 ? key : val;
             }
 
-            assert obj instanceof BinaryObject;
-
-            BinaryObject obj0 = (BinaryObject)obj;
+            if (obj instanceof BinaryObject) {
+                BinaryObject obj0 = (BinaryObject) obj;
+                return fieldValue(obj0);
+            }
+            else if (obj instanceof BinaryObjectBuilder) {
+                BinaryObjectBuilder obj0 = (BinaryObjectBuilder)obj;
 
-            return fieldValue(obj0);
+                return obj0.getField(name());
+            }
+            else
+                throw new IgniteCheckedException("Unexpected binary object class [type=" + obj.getClass() + ']');
         }
 
         /** {@inheritDoc} */
@@ -2144,10 +2156,38 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             if (obj == null)
                 return;
 
+            Object srcObj = obj;
+
+            if (!(srcObj instanceof BinaryObjectBuilder))
+                throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
+
+            if (parent != null)
+                obj = parent.value(key, val);
+
+            boolean needsBuild = false;
+
+            if (obj instanceof BinaryObjectExImpl) {
+                if (parent == null)
+                    throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
+
+                needsBuild = true;
+
+                obj = ((BinaryObjectExImpl)obj).toBuilder();
+            }
+
             if (!(obj instanceof BinaryObjectBuilder))
                 throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
 
             setValue0((BinaryObjectBuilder) obj, propName, propVal, type());
+
+            if (needsBuild) {
+                obj = ((BinaryObjectBuilder) obj).build();
+
+                assert parent != null;
+
+                // And now let's set this newly constructed object to parent
+                setValue0((BinaryObjectBuilder) srcObj, parent.propName, obj, obj.getClass());
+            }
         }
 
         /**
@@ -2224,6 +2264,11 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
             return isKeyProp0 == 1;
         }
+
+        /** {@inheritDoc} */
+        @Override public GridQueryProperty parent() {
+            return parent;
+        }
     }
 
     /**
@@ -2307,7 +2352,12 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
         /** {@inheritDoc} */
         @Override public GridQueryProperty property(String name) {
-            return getProperty(name);
+            GridQueryProperty res = props.get(name);
+
+            if (res == null)
+                res = uppercaseProps.get(name.toUpperCase());
+
+            return res;
         }
 
         /** {@inheritDoc} */
@@ -2315,7 +2365,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public <T> T value(String field, Object key, Object val) throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = getProperty(field);
+            GridQueryProperty prop = property(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2329,7 +2379,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = getProperty(field);
+            GridQueryProperty prop = property(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2469,19 +2519,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             fields.put(name, prop.type());
         }
 
-        /**
-         * @param field Property name.
-         * @return Property with given field name.
-         */
-        private GridQueryProperty getProperty(String field) {
-            GridQueryProperty res = props.get(field);
-
-            if (res == null)
-                res = uppercaseProps.get(field.toUpperCase());
-
-            return res;
-        }
-
         /** {@inheritDoc} */
         @Override public boolean valueTextIndex() {
             return valTextIdx;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
index 5d74a2e..fb4c037 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
@@ -22,11 +22,7 @@ import org.apache.ignite.IgniteCheckedException;
 /**
  * Description and access method for query entity field.
  */
-public abstract class GridQueryProperty {
-    /** */
-    public GridQueryProperty() {
-    }
-
+public interface GridQueryProperty {
     /**
      * Gets this property value from the given object.
      *
@@ -35,7 +31,7 @@ public abstract class GridQueryProperty {
      * @return Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public abstract Object value(Object key, Object val) throws IgniteCheckedException;
+    public Object value(Object key, Object val) throws IgniteCheckedException;
 
     /**
      * Sets this property value for the given object.
@@ -45,21 +41,26 @@ public abstract class GridQueryProperty {
      * @param propVal Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public abstract void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
+    public void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
 
     /**
      * @return Property name.
      */
-    public abstract String name();
+    public String name();
 
     /**
      * @return Class member type.
      */
-    public abstract Class<?> type();
+    public Class<?> type();
 
     /**
      * Property ownership flag.
      * @return {@code true} if this property belongs to key, {@code false} if it belongs to value.
      */
-    public abstract boolean key();
+    public boolean key();
+
+    /**
+     * @return Parent property or {@code null} if this property is not nested.
+     */
+    public GridQueryProperty parent();
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
index 4030758..7995083 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
@@ -59,7 +59,6 @@ import org.apache.ignite.internal.processors.query.GridQueryProperty;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.h2.dml.FastUpdateArguments;
-import org.apache.ignite.internal.processors.query.h2.dml.KeyValueSupplier;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlanBuilder;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor;
@@ -481,7 +480,6 @@ public class DmlStatementsProcessor {
         while (it.hasNext()) {
             List<?> e = it.next();
             Object key = e.get(0);
-            Object val = (hasNewVal ? e.get(valColIdx) : e.get(1));
 
             Object newVal;
 
@@ -500,9 +498,6 @@ public class DmlStatementsProcessor {
             if (newVal == null)
                 throw new IgniteSQLException("New value for UPDATE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
-            if (bin && !(val instanceof BinaryObject))
-                val = cctx.grid().binary().toBinary(val);
-
             // Skip key and value - that's why we start off with 2nd column
             for (int i = 0; i < plan.tbl.getColumns().length - 2; i++) {
                 Column c = plan.tbl.getColumn(i + 2);
@@ -514,13 +509,10 @@ public class DmlStatementsProcessor {
 
                 boolean hasNewColVal = newColVals.containsKey(c.getName());
 
-                // Binary objects get old field values from the Builder, so we can skip what we're not updating
-                if (bin && !hasNewColVal)
+                if (!hasNewColVal)
                     continue;
 
-                // Column values that have been explicitly specified have priority over field values in old or new _val
-                // If no value given for the column, then we expect to find it in value, and not in key - hence null arg.
-                Object colVal = hasNewColVal ? newColVals.get(c.getName()) : prop.value(null, val);
+                Object colVal = newColVals.get(c.getName());
 
                 // UPDATE currently does not allow to modify key or its fields, so we must be safe to pass null as key.
                 desc.setColumnValue(null, newVal, colVal, i);
@@ -696,8 +688,8 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
-                plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(),
+                plan);
 
             cctx.cache().put(t.getKey(), t.getValue());
             return 1;
@@ -709,8 +701,7 @@ public class DmlStatementsProcessor {
             for (Iterator<List<?>> it = cursor.iterator(); it.hasNext();) {
                 List<?> row = it.next();
 
-                IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier, plan.valSupplier,
-                    plan.keyColIdx, plan.valColIdx, desc);
+                IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
 
                 rows.put(t.getKey(), t.getValue());
 
@@ -742,8 +733,7 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes,
-                plan.keySupplier, plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(), plan);
 
             if (cctx.cache().putIfAbsent(t.getKey(), t.getValue()))
                 return 1;
@@ -768,8 +758,7 @@ public class DmlStatementsProcessor {
             while (it.hasNext()) {
                 List<?> row = it.next();
 
-                final IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
-                    plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
+                final IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
 
                 rows.put(t.getKey(), new InsertEntryProcessor(t.getValue()));
 
@@ -837,21 +826,14 @@ public class DmlStatementsProcessor {
      * Convert row presented as an array of Objects into key-value pair to be inserted to cache.
      * @param cctx Cache context.
      * @param row Row to process.
-     * @param cols Query cols.
-     * @param colTypes Column types to convert data from {@code row} to.
-     * @param keySupplier Key instantiation method.
-     * @param valSupplier Key instantiation method.
-     * @param keyColIdx Key column index, or {@code -1} if no key column is mentioned in {@code cols}.
-     * @param valColIdx Value column index, or {@code -1} if no value column is mentioned in {@code cols}.
-     * @param rowDesc Row descriptor.
+     * @param plan Update plan.
      * @throws IgniteCheckedException if failed.
      */
     @SuppressWarnings({"unchecked", "ConstantConditions", "ResultOfMethodCallIgnored"})
-    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, Object[] row, String[] cols,
-        int[] colTypes, KeyValueSupplier keySupplier, KeyValueSupplier valSupplier, int keyColIdx, int valColIdx,
-        GridH2RowDescriptor rowDesc) throws IgniteCheckedException {
-        Object key = keySupplier.apply(F.asList(row));
-        Object val = valSupplier.apply(F.asList(row));
+    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, List<?> row, UpdatePlan plan)
+        throws IgniteCheckedException {
+        Object key = plan.keySupplier.apply(row);
+        Object val = plan.valSupplier.apply(row);
 
         if (key == null)
             throw new IgniteSQLException("Key for INSERT or MERGE must not be null",  IgniteQueryErrorCode.NULL_KEY);
@@ -859,13 +841,32 @@ public class DmlStatementsProcessor {
         if (val == null)
             throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
-        GridQueryTypeDescriptor desc = rowDesc.type();
+        GridQueryTypeDescriptor desc = plan.tbl.rowDescriptor().type();
+
+        Map<String, Object> newColVals = new HashMap<>();
+
+        for (int i = 0; i < plan.colNames.length; i++) {
+            if (i == plan.keyColIdx || i == plan.valColIdx)
+                continue;
+
+            newColVals.put(plan.colNames[i], convert(row.get(i), plan.colNames[i],
+                plan.tbl.rowDescriptor(), plan.colTypes[i]));
+        }
+
+        // We update columns in the order specified by the table for a reason - table's
+        // column order preserves their precedence for correct update of nested properties.
+        Column[] cols = plan.tbl.getColumns();
 
-        for (int i = 0; i < cols.length; i++) {
-            if (i == keyColIdx || i == valColIdx)
+        // First 2 columns are _key and _val, skip 'em.
+        for (int i = 2; i < cols.length; i++) {
+            String colName = cols[i].getName();
+
+            if (!newColVals.containsKey(colName))
                 continue;
 
-            desc.setValue(cols[i], key, val, convert(row[i], cols[i], rowDesc, colTypes[i]));
+            Object colVal = newColVals.get(colName);
+
+            desc.setValue(colName, key, val, colVal);
         }
 
         if (cctx.binaryMarshaller()) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
index fdcd164..ce2971a 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
@@ -48,6 +48,7 @@ import org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate;
 import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.h2.command.Prepared;
 import org.h2.table.Column;
@@ -192,8 +193,8 @@ public final class UpdatePlanBuilder {
                 hasValProps = true;
         }
 
-        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true);
-        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false);
+        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true, false);
+        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false, false);
 
         if (stmt instanceof GridSqlMerge)
             return UpdatePlan.forMerge(tbl.dataTable(), colNames, colTypes, keySupplier, valSupplier, keyColIdx,
@@ -253,8 +254,6 @@ public final class UpdatePlanBuilder {
             GridSqlSelect sel;
 
             if (stmt instanceof GridSqlUpdate) {
-                boolean bin = desc.context().binaryMarshaller();
-
                 List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
 
                 int valColIdx = -1;
@@ -282,20 +281,10 @@ public final class UpdatePlanBuilder {
                 if (hasNewVal)
                     valColIdx += 2;
 
-                int newValColIdx;
-
-                if (!hasProps) // No distinct properties, only whole new value - let's take it
-                    newValColIdx = valColIdx;
-                else if (bin) // We update distinct columns in binary mode - let's choose correct index for the builder
-                    newValColIdx = (hasNewVal ? valColIdx : 1);
-                else // Distinct properties, non binary mode - let's instantiate.
-                    newValColIdx = -1;
+                int newValColIdx = (hasNewVal ? valColIdx : 1);
 
-                // We want supplier to take present value only in case of binary mode as it will create
-                // whole new object as a result anyway, so we don't need to copy previous property values explicitly.
-                // Otherwise we always want it to instantiate new object whose properties we will later
-                // set to current values.
-                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false);
+                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps,
+                    false, true);
 
                 sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
 
@@ -319,11 +308,11 @@ public final class UpdatePlanBuilder {
      * @param hasProps Whether column list affects individual properties of key or value.
      * @param key Whether supplier should be created for key or for value.
      * @return Closure returning key or value.
-     * @throws IgniteCheckedException
+     * @throws IgniteCheckedException If failed.
      */
     @SuppressWarnings({"ConstantConditions", "unchecked"})
     private static KeyValueSupplier createSupplier(final GridCacheContext<?, ?> cctx, GridQueryTypeDescriptor desc,
-                                                   final int colIdx, boolean hasProps, final boolean key) throws IgniteCheckedException {
+        final int colIdx, boolean hasProps, final boolean key, boolean forUpdate) throws IgniteCheckedException {
         final String typeName = key ? desc.keyTypeName() : desc.valueTypeName();
 
         //Try to find class for the key locally.
@@ -332,15 +321,10 @@ public final class UpdatePlanBuilder {
 
         boolean isSqlType = GridQueryProcessor.isSqlType(cls);
 
-        // If we don't need to construct anything from scratch, just return value from array.
-        if (isSqlType || !hasProps || !cctx.binaryMarshaller()) {
+        // If we don't need to construct anything from scratch, just return value from given list.
+        if (isSqlType || !hasProps) {
             if (colIdx != -1)
-                return new KeyValueSupplier() {
-                    /** {@inheritDoc} */
-                    @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                        return arg.get(colIdx);
-                    }
-                };
+                return new PlainValueSupplier(colIdx);
             else if (isSqlType)
                 // Non constructable keys and values (SQL types) must be present in the query explicitly.
                 throw new IgniteCheckedException((key ? "Key" : "Value") + " is missing from query");
@@ -352,7 +336,12 @@ public final class UpdatePlanBuilder {
                 return new KeyValueSupplier() {
                     /** {@inheritDoc} */
                     @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                        BinaryObject bin = cctx.grid().binary().toBinary(arg.get(colIdx));
+                        Object obj = arg.get(colIdx);
+
+                        if (obj == null)
+                            return null;
+
+                        BinaryObject bin = cctx.grid().binary().toBinary(obj);
 
                         return cctx.grid().binary().builder(bin);
                     }
@@ -369,6 +358,26 @@ public final class UpdatePlanBuilder {
             }
         }
         else {
+            if (colIdx != -1) {
+                if (forUpdate && colIdx == 1) {
+                    // It's the case when the old value has to be taken as the basis for the new one on UPDATE,
+                    // so we have to clone it. And on UPDATE we don't expect any key supplier.
+                    assert !key;
+
+                    return new KeyValueSupplier() {
+                        /** {@inheritDoc} */
+                        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
+                            byte[] oldPropBytes = cctx.marshaller().marshal(arg.get(1));
+
+                            // colVal is another object now, we can mutate it
+                            return cctx.marshaller().unmarshal(oldPropBytes, U.resolveClassLoader(cctx.gridConfig()));
+                        }
+                    };
+                }
+                else // We either are not updating, or the new value is given explicitly, no cloning needed.
+                    return new PlainValueSupplier(colIdx);
+            }
+
             Constructor<?> ctor;
 
             try {
@@ -390,8 +399,12 @@ public final class UpdatePlanBuilder {
                             return ctor0.newInstance();
                         }
                         catch (Exception e) {
-                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
-                                (key ? "key" : "value"), e);
+                            if (S.INCLUDE_SENSITIVE)
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
+                            else
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + '.', e);
                         }
                     }
                 };
@@ -405,8 +418,12 @@ public final class UpdatePlanBuilder {
                             return GridUnsafe.allocateInstance(cls);
                         }
                         catch (InstantiationException e) {
-                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
-                                (key ? "key" : "value"), e);
+                            if (S.INCLUDE_SENSITIVE)
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
+                            else
+                                throw new IgniteCheckedException("Failed to instantiate " +
+                                    (key ? "key" : "value") + '.', e);
                         }
                     }
                 };
@@ -414,8 +431,6 @@ public final class UpdatePlanBuilder {
         }
     }
 
-
-
     /**
      * @param target Expression to extract the table from.
      * @return Back end table for this element.
@@ -483,4 +498,26 @@ public final class UpdatePlanBuilder {
 
         return false;
     }
+
+    /**
+     * Simple supplier that just takes specified element of a given row.
+     */
+    private final static class PlainValueSupplier implements KeyValueSupplier {
+        /** Index of column to use. */
+        private final int colIdx;
+
+        /**
+         * Constructor.
+         *
+         * @param colIdx Column index.
+         */
+        private PlainValueSupplier(int colIdx) {
+            this.colIdx = colIdx;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
+            return arg.get(colIdx);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
index 86d01c7..626846b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
@@ -46,6 +46,8 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.junits.IgniteTestResources;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
+import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
+
 /**
  *
  */
@@ -126,6 +128,8 @@ public abstract class IgniteCacheAbstractInsertSqlQuerySelfTest extends GridComm
             createCaches();
         else
             createBinaryCaches();
+
+        ignite(0).createCache(cacheConfig("I2AT", true, false, Integer.class, AllTypes.class));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
index 649012f..3c92fdf 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
@@ -65,7 +65,7 @@ public abstract class IgniteCacheAbstractSqlDmlQuerySelfTest extends GridCommonA
     /**
      * @return whether {@link #marsh} is an instance of {@link BinaryMarshaller} or not.
      */
-    private boolean isBinaryMarshaller() {
+    protected boolean isBinaryMarshaller() {
         return marsh instanceof BinaryMarshaller;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
index e9c21dc..f91f405 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.concurrent.Callable;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCache;
@@ -202,4 +204,24 @@ public class IgniteCacheInsertSqlQuerySelfTest extends IgniteCacheAbstractInsert
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
+
+    /**
+     *
+     */
+    public void testNestedFieldsHandling() {
+        IgniteCache<Integer, IgniteCacheUpdateSqlQuerySelfTest.AllTypes> p = ignite(0).cache("I2AT");
+
+        p.query(new SqlFieldsQuery("insert into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
+            "values (1, ?, ?, ?, 'sss')") .setArgs(new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L),
+            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L)));
+
+        IgniteCacheUpdateSqlQuerySelfTest.AllTypes res = p.get(1);
+
+        IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType resInner = new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L);
+
+        resInner.innerStrCol = "sss";
+        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
+
+        assertEquals(resInner, res.innerTypeCol);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
index 32b7a12..d9a2d9e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
@@ -17,9 +17,13 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 
+import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
+
 /**
  *
  */
@@ -149,4 +153,24 @@ public class IgniteCacheMergeSqlQuerySelfTest extends IgniteCacheAbstractInsertS
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
+
+    /**
+     *
+     */
+    public void testNestedFieldsHandling() {
+        IgniteCache<Integer, AllTypes> p = ignite(0).cache("I2AT");
+
+        p.query(new SqlFieldsQuery("merge into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
+            "values (1, ?, ?, ?, 'sss')") .setArgs(new AllTypes.InnerType(50L),
+            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new AllTypes(1L)));
+
+        AllTypes res = p.get(1);
+
+        AllTypes.InnerType resInner = new AllTypes.InnerType(50L);
+
+        resInner.innerStrCol = "sss";
+        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
+
+        assertEquals(resInner, res.innerTypeCol);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
index 575f617..c3d9d8e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
@@ -44,6 +44,12 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         ignite(0).createCache(createAllTypesCacheConfig());
     }
 
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+        ignite(0).cache("L2AT").clear();
+    }
+
     /**
      *
      */
@@ -182,17 +188,19 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\"," +
             "\"tsCol\") values(2, ?, '2016-11-30 12:00:00', false, DATE '2016-12-01')").setArgs(new AllTypes(2L)));
 
-        cache.query(new SqlFieldsQuery("select \"primitiveIntsCol\" from \"AllTypes\"")).getAll();
-
-        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"doubleCol\" = CAST('50' as INT)," +
+        // Look ma, no hands: first we set value of inner object column (innerTypeCol), then update only one of its
+        // fields (innerLongCol), while leaving another inner property (innerStrCol) as specified by innerTypeCol.
+        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = ?, \"doubleCol\" = CAST('50' as INT)," +
             " \"booleanCol\" = 80, \"innerTypeCol\" = ?, \"strCol\" = PI(), \"shortCol\" = " +
             "CAST(WEEK(PARSEDATETIME('2016-11-30', 'yyyy-MM-dd')) as VARCHAR), " +
             "\"sqlDateCol\"=TIMESTAMP '2016-12-02 13:47:00', \"tsCol\"=TIMESTAMPADD('MI', 2, " +
             "DATEADD('DAY', 2, \"tsCol\")), \"primitiveIntsCol\" = ?, \"bytesCol\" = ?")
-            .setArgs(new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
+            .setArgs(5, new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
 
         AllTypes res = (AllTypes) cache.get(2L);
 
+        assertNotNull(res);
+
         assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
         assertEquals(50.0, res.doubleCol);
         assertEquals(2L, (long) res.longCol);
@@ -202,7 +210,11 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertTrue(Arrays.equals(new Byte[] {4, 5, 6}, res.bytesCol));
         assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
         assertTrue(Arrays.equals(new int[] {2, 3}, res.primitiveIntsCol));
-        assertEquals(new AllTypes.InnerType(80L), res.innerTypeCol);
+
+        AllTypes.InnerType expInnerType = new AllTypes.InnerType(80L);
+        expInnerType.innerLongCol = 5L;
+
+        assertEquals(expInnerType, res.innerTypeCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-12-03 00:02:00"), res.tsCol);
         assertEquals(2, res.intCol);
@@ -213,6 +225,45 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertEquals(49, res.shortCol);
     }
 
+    /** */
+    public void testSingleInnerFieldUpdate() throws ParseException {
+        IgniteCache cache = ignite(0).cache("L2AT");
+
+        cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\") values(2, ?," +
+            "'2016-11-30 12:00:00', false)").setArgs(new AllTypes(2L)));
+
+        assertFalse(cache.query(new SqlFieldsQuery("select * from \"AllTypes\"")).getAll().isEmpty());
+
+        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = 5"));
+
+        AllTypes res = (AllTypes) cache.get(2L);
+
+        assertNotNull(res);
+
+        assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
+        assertEquals(3.01, res.doubleCol);
+        assertEquals(2L, (long) res.longCol);
+        assertFalse(res.booleanCol);
+
+        assertEquals("2", res.strCol);
+        assertTrue(Arrays.equals(new byte[] {0, 1}, res.primitiveBytesCol));
+        assertTrue(Arrays.deepEquals(new Byte[] {0, 1}, res.bytesCol));
+        assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
+        assertTrue(Arrays.equals(new int[] {0, 1}, res.primitiveIntsCol));
+
+        AllTypes.InnerType expInnerType = new AllTypes.InnerType(2L);
+        expInnerType.innerLongCol = 5L;
+
+        assertEquals(expInnerType, res.innerTypeCol);
+        assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
+        assertNull(res.tsCol);
+        assertEquals(2, res.intCol);
+        assertEquals(AllTypes.EnumType.ENUMTRUE, res.enumCol);
+        assertNull(res.sqlDateCol);
+
+        assertEquals(-23000, res.shortCol);
+    }
+
     /**
      *
      */
@@ -308,7 +359,7 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         InnerType innerTypeCol;
 
         /** */
-        static final class InnerType implements Serializable {
+        static class InnerType implements Serializable {
             /** */
             @QuerySqlField
             Long innerLongCol;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d01406f2/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index e412828..69285f1 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -578,6 +578,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
                 @Override public boolean key() {
                     return false;
                 }
+
+                /** */
+                @Override public GridQueryProperty parent() {
+                    return null;
+                }
             };
         }
 


[12/50] [abbrv] ignite git commit: IGNITE-4472 Added user activities in Web Console.

Posted by sb...@apache.org.
IGNITE-4472 Added user activities in Web Console.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 26ee9c2865648118da97ee8ef84df990359edb96
Parents: e6ea938
Author: Andrey Novikov <an...@gridgain.com>
Authored: Wed Feb 8 11:43:22 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Wed Feb 8 11:43:22 2017 +0700

----------------------------------------------------------------------
 modules/web-console/backend/app/agent.js        |  10 +-
 modules/web-console/backend/app/mongo.js        |  49 ++--
 modules/web-console/backend/app/routes.js       |   5 +-
 .../web-console/backend/routes/activities.js    |  52 +++++
 modules/web-console/backend/routes/admin.js     |   2 +-
 modules/web-console/backend/routes/agent.js     |  10 +-
 modules/web-console/backend/routes/public.js    |   1 -
 .../web-console/backend/services/activities.js  | 136 +++++++++++
 modules/web-console/backend/services/users.js   |  13 +-
 modules/web-console/frontend/app/app.config.js  |   9 +
 modules/web-console/frontend/app/app.js         |  29 ++-
 .../activities-user-dialog.controller.js        |  60 +++++
 .../activities-user-dialog.jade                 |  36 +++
 .../components/activities-user-dialog/index.js  |  36 +++
 .../form-field-datepicker.jade                  |  55 +++++
 .../form-field-datepicker.scss                  |  20 ++
 .../list-of-registered-users/index.js           |  28 +++
 .../list-of-registered-users.categories.js      |  30 +++
 .../list-of-registered-users.column-defs.js     |  80 +++++++
 .../list-of-registered-users.controller.js      | 207 ++++++++++++++++
 .../list-of-registered-users.jade               |  54 +++++
 .../ui-grid-header/ui-grid-header.jade          |  27 +++
 .../ui-grid-header/ui-grid-header.scss          |  84 +++++++
 .../ui-grid-settings/ui-grid-settings.jade      |  33 +++
 .../ui-grid-settings/ui-grid-settings.scss      |  70 ++++++
 .../app/core/activities/Activities.data.js      |  39 ++++
 .../frontend/app/core/admin/Admin.data.js       |  77 ++++++
 modules/web-console/frontend/app/core/index.js  |  25 ++
 modules/web-console/frontend/app/data/i18n.js   |  38 +++
 .../ui-grid-settings/ui-grid-settings.jade      |  33 ---
 .../ui-grid-settings/ui-grid-settings.scss      |  38 ---
 .../app/filters/uiGridSubcategories.filter.js   |  24 ++
 .../frontend/app/modules/Demo/Demo.module.js    | 166 -------------
 .../frontend/app/modules/demo/Demo.module.js    | 172 ++++++++++++++
 .../frontend/app/modules/sql/sql.controller.js  |  14 +-
 .../frontend/app/modules/sql/sql.module.js      |   2 +-
 .../frontend/app/modules/states/admin.state.js  |   2 +-
 .../configuration/summary/summary.controller.js |   6 +-
 .../app/modules/user/AclRoute.provider.js       |  31 +--
 .../frontend/app/modules/user/Auth.service.js   |   2 +-
 .../frontend/app/modules/user/permissions.js    |   2 +-
 .../frontend/app/modules/user/user.module.js    |   6 +-
 modules/web-console/frontend/app/vendor.js      |   1 +
 .../frontend/controllers/admin-controller.js    | 234 -------------------
 .../frontend/controllers/domains-controller.js  |  12 +-
 modules/web-console/frontend/package.json       |   1 +
 .../stylesheets/_font-awesome-custom.scss       |  28 +++
 .../frontend/public/stylesheets/style.scss      |  39 +++-
 .../frontend/public/stylesheets/variables.scss  |   1 +
 .../frontend/views/settings/admin.jade          |  32 +--
 modules/web-console/frontend/views/sql/sql.jade |   4 +-
 51 files changed, 1603 insertions(+), 562 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/app/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/agent.js b/modules/web-console/backend/app/agent.js
index 961253f..8170280 100644
--- a/modules/web-console/backend/app/agent.js
+++ b/modules/web-console/backend/app/agent.js
@@ -24,7 +24,7 @@
  */
 module.exports = {
     implements: 'agent-manager',
-    inject: ['require(lodash)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'settings', 'mongo']
+    inject: ['require(lodash)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'settings', 'mongo', 'services/activities']
 };
 
 /**
@@ -35,9 +35,10 @@ module.exports = {
  * @param socketio
  * @param settings
  * @param mongo
+ * @param {ActivitiesService} activitiesService
  * @returns {AgentManager}
  */
-module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo) {
+module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo, activitiesService) {
     /**
      *
      */
@@ -823,6 +824,11 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo)
                 const sockets = this._browsers[accountId];
 
                 _.forEach(sockets, (socket) => socket.emit('agent:count', {count: agents.length}));
+
+                activitiesService.merge(accountId, {
+                    group: 'agent',
+                    action: '/agent/start'
+                });
             });
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/app/mongo.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/mongo.js b/modules/web-console/backend/app/mongo.js
index dd71f3a..2d252b9 100644
--- a/modules/web-console/backend/app/mongo.js
+++ b/modules/web-console/backend/app/mongo.js
@@ -48,6 +48,7 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
         company: String,
         country: String,
         lastLogin: Date,
+        lastActivity: Date,
         admin: Boolean,
         token: String,
         resetPasswordToken: String
@@ -59,22 +60,26 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
         usernameLowerCase: true
     });
 
+    const transform = (doc, ret) => {
+        return {
+            _id: ret._id,
+            email: ret.email,
+            firstName: ret.firstName,
+            lastName: ret.lastName,
+            company: ret.company,
+            country: ret.country,
+            admin: ret.admin,
+            token: ret.token,
+            lastLogin: ret.lastLogin,
+            lastActivity: ret.lastActivity
+        };
+    };
+
     // Configure transformation to JSON.
-    AccountSchema.set('toJSON', {
-        transform: (doc, ret) => {
-            return {
-                _id: ret._id,
-                email: ret.email,
-                firstName: ret.firstName,
-                lastName: ret.lastName,
-                company: ret.company,
-                country: ret.country,
-                admin: ret.admin,
-                token: ret.token,
-                lastLogin: ret.lastLogin
-            };
-        }
-    });
+    AccountSchema.set('toJSON', { transform });
+
+    // Configure transformation to JSON.
+    AccountSchema.set('toObject', { transform });
 
     result.errCodes = {
         DUPLICATE_KEY_ERROR: 11000,
@@ -902,6 +907,20 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
         res.status(err.code || 500).send(err.message);
     };
 
+    // Define Activities schema.
+    const ActivitiesSchema = new Schema({
+        owner: {type: ObjectId, ref: 'Account'},
+        date: Date,
+        group: String,
+        action: String,
+        amount: { type: Number, default: 1 }
+    });
+
+    ActivitiesSchema.index({ owner: 1, group: 1, action: 1, date: 1}, { unique: true });
+
+    // Define Activities model.
+    result.Activities = mongoose.model('Activities', ActivitiesSchema);
+
     // Registering the routes of all plugin modules
     for (const name in pluginMongo) {
         if (pluginMongo.hasOwnProperty(name))

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/app/routes.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/routes.js b/modules/web-console/backend/app/routes.js
index 6961173..6b5d052 100644
--- a/modules/web-console/backend/app/routes.js
+++ b/modules/web-console/backend/app/routes.js
@@ -22,11 +22,11 @@
 module.exports = {
     implements: 'routes',
     inject: ['routes/public', 'routes/admin', 'routes/profiles', 'routes/demo', 'routes/clusters', 'routes/domains',
-        'routes/caches', 'routes/igfss', 'routes/notebooks', 'routes/agents', 'routes/configurations']
+        'routes/caches', 'routes/igfss', 'routes/notebooks', 'routes/agents', 'routes/configurations', 'routes/activities']
 };
 
 module.exports.factory = function(publicRoute, adminRoute, profilesRoute, demoRoute,
-    clustersRoute, domainsRoute, cachesRoute, igfssRoute, notebooksRoute, agentsRoute, configurationsRoute) {
+    clustersRoute, domainsRoute, cachesRoute, igfssRoute, notebooksRoute, agentsRoute, configurationsRoute, activitiesRoute) {
     return {
         register: (app) => {
             const _mustAuthenticated = (req, res, next) => {
@@ -59,6 +59,7 @@ module.exports.factory = function(publicRoute, adminRoute, profilesRoute, demoRo
 
             app.use('/notebooks', _mustAuthenticated, notebooksRoute);
             app.use('/agent', _mustAuthenticated, agentsRoute);
+            app.use('/activities', _mustAuthenticated, activitiesRoute);
         }
     };
 };

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/activities.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/activities.js b/modules/web-console/backend/routes/activities.js
new file mode 100644
index 0000000..08c27cf
--- /dev/null
+++ b/modules/web-console/backend/routes/activities.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+'use strict';
+
+// Fire me up!
+
+module.exports = {
+    implements: 'routes/activities',
+    inject: ['require(express)', 'services/activities']
+};
+
+/**
+ * @param express
+ * @param {ActivitiesService} activitiesService
+ * @returns {Promise}
+ */
+module.exports.factory = function(express, activitiesService) {
+    return new Promise((factoryResolve) => {
+        const router = new express.Router();
+
+        // Get user activities.
+        router.get('/user/:userId', (req, res) => {
+            activitiesService.listByUser(req.params.userId, req.query)
+                .then(res.api.ok)
+                .catch(res.api.error);
+        });
+
+        // Post user activities to page.
+        router.post('/page', (req, res) => {
+            activitiesService.merge(req.user._id, req.body)
+                .then(res.api.ok)
+                .catch(res.api.error);
+        });
+
+        factoryResolve(router);
+    });
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/admin.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/admin.js b/modules/web-console/backend/routes/admin.js
index 70736d0..5b0896a 100644
--- a/modules/web-console/backend/routes/admin.js
+++ b/modules/web-console/backend/routes/admin.js
@@ -43,7 +43,7 @@ module.exports.factory = function(_, express, settings, mongo, spacesService, ma
          * Get list of user accounts.
          */
         router.post('/list', (req, res) => {
-            usersService.list()
+            usersService.list(req.body)
                 .then(res.api.ok)
                 .catch(res.api.error);
         });

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/agent.js b/modules/web-console/backend/routes/agent.js
index 477363f..5ae807b 100644
--- a/modules/web-console/backend/routes/agent.js
+++ b/modules/web-console/backend/routes/agent.js
@@ -21,21 +21,27 @@
 
 module.exports = {
     implements: 'routes/agents',
-    inject: ['require(lodash)', 'require(express)', 'services/agents']
+    inject: ['require(lodash)', 'require(express)', 'services/agents', 'services/activities']
 };
 
 /**
  * @param _
  * @param express
  * @param {AgentsService} agentsService
+ * @param {ActivitiesService} activitiesService
  * @returns {Promise}
  */
-module.exports.factory = function(_, express, agentsService) {
+module.exports.factory = function(_, express, agentsService, activitiesService) {
     return new Promise((resolveFactory) => {
         const router = new express.Router();
 
         /* Get grid topology. */
         router.get('/download/zip', (req, res) => {
+            activitiesService.merge(req.user._id, {
+                group: 'agent',
+                action: '/agent/download'
+            });
+
             agentsService.getArchive(req.origin(), req.user.token)
                 .then(({fileName, buffer}) => {
                     // Set the archive name.

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/public.js b/modules/web-console/backend/routes/public.js
index 590d395..860e267 100644
--- a/modules/web-console/backend/routes/public.js
+++ b/modules/web-console/backend/routes/public.js
@@ -25,7 +25,6 @@ module.exports = {
 };
 
 /**
- *
  * @param express
  * @param passport
  * @param mongo

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/services/activities.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/activities.js b/modules/web-console/backend/services/activities.js
new file mode 100644
index 0000000..7f3a777
--- /dev/null
+++ b/modules/web-console/backend/services/activities.js
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+'use strict';
+
+// Fire me up!
+
+module.exports = {
+    implements: 'services/activities',
+    inject: ['require(lodash)', 'mongo']
+};
+
+/**
+ * @param _
+ * @param mongo
+ * @returns {ActivitiesService}
+ */
+module.exports.factory = (_, mongo) => {
+    class ActivitiesService {
+        /**
+         * Update page activities.
+         *
+         * @param {String} owner - User ID
+         * @param {Object} page - The page
+         * @returns {Promise.<mongo.ObjectId>} that resolve activity
+         */
+        static merge(owner, {action, group}) {
+            mongo.Account.findById(owner)
+                .then((user) => {
+                    user.lastActivity = new Date();
+
+                    return user.save();
+                });
+
+            const date = new Date();
+
+            date.setDate(1);
+            date.setHours(0, 0, 0, 0);
+
+            return mongo.Activities.findOne({owner, action, date}).exec()
+                .then((activity) => {
+                    if (activity) {
+                        activity.amount++;
+
+                        return activity.save();
+                    }
+
+                    return mongo.Activities.create({owner, action, group, date});
+                });
+        }
+
+        /**
+         * Get user activities
+         * @param {String} owner - User ID
+         * @returns {Promise.<mongo.ObjectId>} that resolve activities
+         */
+        static listByUser(owner, {startDate, endDate}) {
+            const $match = {owner};
+
+            if (startDate)
+                $match.date = {$gte: new Date(startDate)};
+
+            if (endDate) {
+                $match.date = $match.date || {};
+                $match.date.$lt = new Date(endDate);
+            }
+
+            return mongo.Activities.find($match);
+        }
+
+        static total({startDate, endDate}) {
+            const $match = {};
+
+            if (startDate)
+                $match.date = {$gte: new Date(startDate)};
+
+            if (endDate) {
+                $match.date = $match.date || {};
+                $match.date.$lt = new Date(endDate);
+            }
+
+            return mongo.Activities.aggregate([
+                {$match},
+                {$group: {
+                    _id: {owner: '$owner', group: '$group'},
+                    amount: {$sum: '$amount'}
+                }}
+            ]).exec().then((data) => {
+                return _.reduce(data, (acc, { _id, amount }) => {
+                    const {owner, group} = _id;
+                    acc[owner] = _.merge(acc[owner] || {}, { [group]: amount });
+                    return acc;
+                }, {});
+            });
+        }
+
+        static detail({startDate, endDate}) {
+            const $match = { };
+
+            if (startDate)
+                $match.date = {$gte: new Date(startDate)};
+
+            if (endDate) {
+                $match.date = $match.date || {};
+                $match.date.$lt = new Date(endDate);
+            }
+
+            return mongo.Activities.aggregate([
+                {$match},
+                {$group: {_id: {owner: '$owner', action: '$action'}, total: {$sum: '$amount'}}}
+            ]).exec().then((data) => {
+                return _.reduce(data, (acc, { _id, total }) => {
+                    const {owner, action} = _id;
+                    acc[owner] = _.merge(acc[owner] || {}, { [action]: total });
+                    return acc;
+                }, {});
+            });
+        }
+    }
+
+    return ActivitiesService;
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/services/users.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/users.js b/modules/web-console/backend/services/users.js
index 8058b25..2dd603f 100644
--- a/modules/web-console/backend/services/users.js
+++ b/modules/web-console/backend/services/users.js
@@ -21,7 +21,7 @@
 
 module.exports = {
     implements: 'services/users',
-    inject: ['require(lodash)', 'mongo', 'settings', 'services/spaces', 'services/mails', 'agent-manager', 'errors']
+    inject: ['require(lodash)', 'mongo', 'settings', 'services/spaces', 'services/mails', 'services/activities', 'agent-manager', 'errors']
 };
 
 /**
@@ -30,11 +30,12 @@ module.exports = {
  * @param settings
  * @param {SpacesService} spacesService
  * @param {MailsService} mailsService
+ * @param {ActivitiesService} activitiesService
  * @param agentMgr
  * @param errors
  * @returns {UsersService}
  */
-module.exports.factory = (_, mongo, settings, spacesService, mailsService, agentMgr, errors) => {
+module.exports.factory = (_, mongo, settings, spacesService, mailsService, activitiesService, agentMgr, errors) => {
     const _randomString = () => {
         const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
         const possibleLen = possible.length;
@@ -143,7 +144,7 @@ module.exports.factory = (_, mongo, settings, spacesService, mailsService, agent
          * Get list of user accounts and summary information.
          * @returns {mongo.Account[]} - returns all accounts with counters object
          */
-        static list() {
+        static list(params) {
             return Promise.all([
                 mongo.Space.aggregate([
                     {$match: {demo: false}},
@@ -161,13 +162,17 @@ module.exports.factory = (_, mongo, settings, spacesService, mailsService, agent
                         }
                     }
                 ]).exec(),
+                activitiesService.total(params),
+                activitiesService.detail(params),
                 mongo.Account.find({}).sort('firstName lastName').lean().exec()
             ])
-                .then(([counters, users]) => {
+                .then(([counters, activitiesTotal, activitiesDetail, users]) => {
                     const countersMap = _.keyBy(counters, 'owner');
 
                     _.forEach(users, (user) => {
                         user.counters = _.omit(countersMap[user._id], '_id', 'owner');
+                        user.activitiesTotal = activitiesTotal[user._id];
+                        user.activitiesDetail = activitiesDetail[user._id];
                     });
 
                     return users;

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/app.config.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.config.js b/modules/web-console/frontend/app/app.config.js
index 7416ce9..0e85711 100644
--- a/modules/web-console/frontend/app/app.config.js
+++ b/modules/web-console/frontend/app/app.config.js
@@ -94,3 +94,12 @@ igniteConsoleCfg.config(['$dropdownProvider', ($dropdownProvider) => {
         templateUrl: 'templates/dropdown.html'
     });
 }]);
+
+// AngularStrap dropdowns () configuration.
+igniteConsoleCfg.config(['$datepickerProvider', ($datepickerProvider) => {
+    angular.extend($datepickerProvider.defaults, {
+        autoclose: true,
+        iconLeft: 'icon-datepicker-left',
+        iconRight: 'icon-datepicker-right'
+    });
+}]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/app.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.js b/modules/web-console/frontend/app/app.js
index 4ecd9b5..9958cb5 100644
--- a/modules/web-console/frontend/app/app.js
+++ b/modules/web-console/frontend/app/app.js
@@ -16,7 +16,9 @@
  */
 
 import '../public/stylesheets/style.scss';
-import '../app/directives/ui-grid-settings/ui-grid-settings.scss';
+import '../app/components/ui-grid-header/ui-grid-header.scss';
+import '../app/components/ui-grid-settings/ui-grid-settings.scss';
+import '../app/components/form-field-datepicker/form-field-datepicker.scss';
 import './helpers/jade/mixins.jade';
 
 import './app.config';
@@ -25,10 +27,10 @@ import './decorator/select';
 import './decorator/tooltip';
 
 import './modules/form/form.module';
-import './modules/agent/agent.module.js';
+import './modules/agent/agent.module';
 import './modules/sql/sql.module';
 import './modules/nodes/nodes.module';
-import './modules/Demo/Demo.module.js';
+import './modules/demo/Demo.module';
 
 import './modules/states/signin.state';
 import './modules/states/logout.state';
@@ -39,6 +41,7 @@ import './modules/states/admin.state';
 import './modules/states/errors.state';
 
 // ignite:modules
+import './core';
 import './modules/user/user.module';
 import './modules/branding/branding.module';
 import './modules/navbar/navbar.module';
@@ -50,6 +53,9 @@ import './modules/socket.module';
 import './modules/loading/loading.module';
 // endignite
 
+// Data
+import i18n from './data/i18n';
+
 // Directives.
 import igniteAutoFocus from './directives/auto-focus.directive.js';
 import igniteBsAffixUpdate from './directives/bs-affix-update.directive';
@@ -98,9 +104,9 @@ import defaultName from './filters/default-name.filter';
 import domainsValidation from './filters/domainsValidation.filter';
 import duration from './filters/duration.filter';
 import hasPojo from './filters/hasPojo.filter';
+import uiGridSubcategories from './filters/uiGridSubcategories.filter';
 
 // Controllers
-import admin from 'controllers/admin-controller';
 import caches from 'controllers/caches-controller';
 import clusters from 'controllers/clusters-controller';
 import domains from 'controllers/domains-controller';
@@ -109,6 +115,10 @@ import profile from 'controllers/profile-controller';
 import auth from './controllers/auth.controller';
 import resetPassword from './controllers/reset-password.controller';
 
+// Components
+import igniteListOfRegisteredUsers from './components/list-of-registered-users';
+import IgniteActivitiesUserDialog from './components/activities-user-dialog';
+
 // Inject external modules.
 import 'ignite_modules_temp/index';
 
@@ -129,6 +139,7 @@ angular
     'nvd3',
     'smart-table',
     'treeControl',
+    'pascalprecht.translate',
     'ui.grid',
     'ui.grid.saveState',
     'ui.grid.selection',
@@ -136,6 +147,7 @@ angular
     'ui.grid.autoResize',
     'ui.grid.exporter',
     // Base modules.
+    'ignite-console.core',
     'ignite-console.ace',
     'ignite-console.Form',
     'ignite-console.user',
@@ -186,6 +198,7 @@ angular
 .directive(...igniteRetainSelection)
 .directive('igniteOnFocusOut', igniteOnFocusOut)
 .directive('igniteRestoreInputFocus', igniteRestoreInputFocus)
+.directive('igniteListOfRegisteredUsers', igniteListOfRegisteredUsers)
 // Services.
 .service('IgniteErrorPopover', ErrorPopover)
 .service('JavaTypes', JavaTypes)
@@ -204,8 +217,8 @@ angular
 .service(...FormUtils)
 .service(...LegacyUtils)
 .service(...UnsavedChangesGuard)
+.service('IgniteActivitiesUserDialog', IgniteActivitiesUserDialog)
 // Controllers.
-.controller(...admin)
 .controller(...auth)
 .controller(...resetPassword)
 .controller(...caches)
@@ -219,7 +232,11 @@ angular
 .filter(...domainsValidation)
 .filter(...duration)
 .filter(...hasPojo)
-.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', ($stateProvider, $locationProvider, $urlRouterProvider) => {
+.filter('uiGridSubcategories', uiGridSubcategories)
+.config(['$translateProvider', '$stateProvider', '$locationProvider', '$urlRouterProvider', ($translateProvider, $stateProvider, $locationProvider, $urlRouterProvider) => {
+    $translateProvider.translations('en', i18n);
+    $translateProvider.preferredLanguage('en');
+
     // Set up the states.
     $stateProvider
         .state('base', {

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js
new file mode 100644
index 0000000..46853b2
--- /dev/null
+++ b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+const COLUMNS_DEFS = [
+    {displayName: 'Action', field: 'action', minWidth: 65 },
+    {displayName: 'Description', field: 'title', minWidth: 65 },
+    {displayName: 'Visited', field: 'amount', minWidth: 65 }
+];
+
+export default class ActivitiesCtrl {
+    static $inject = ['$state', 'user', 'params', 'IgniteActivitiesData'];
+
+    constructor($state, user, params, ActivitiesData) {
+        const $ctrl = this;
+        const userId = user._id;
+
+        $ctrl.user = user;
+
+        $ctrl.gridOptions = {
+            data: [],
+            columnVirtualizationThreshold: 30,
+            columnDefs: COLUMNS_DEFS,
+            categories: [
+                {name: 'Action', visible: true, selectable: true},
+                {name: 'Description', visible: true, selectable: true},
+                {name: 'Visited', visible: true, selectable: true}
+            ],
+            enableRowSelection: false,
+            enableRowHeaderSelection: false,
+            enableColumnMenus: false,
+            multiSelect: false,
+            modifierKeysToMultiSelect: true,
+            noUnselect: true,
+            flatEntityAccess: true,
+            fastWatch: true,
+            onRegisterApi: (api) => {
+                $ctrl.gridApi = api;
+            }
+        };
+
+        ActivitiesData.listByUser(userId, params)
+            .then((data) => {
+                $ctrl.data = data;
+            });
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade
new file mode 100644
index 0000000..2c55ebd
--- /dev/null
+++ b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade
@@ -0,0 +1,36 @@
+//-
+    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.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                h4.modal-title 
+                    i.fa.fa-info-circle
+                    | Activities: {{ ctrl.user.userName }}
+            .modal-body.modal-body-with-scroll(id='activities-user-dialog')
+                table.table.table-striped.table-bordered.table-hover(scrollable-container='#activities-user-dialog' st-table='displayedRows' st-safe-src='ctrl.data')
+                    thead
+                        th.text-center(st-sort='title') Description
+                        th.text-center(st-sort='action') Action
+                        th.text-center(st-sort='amount') Visited
+                    tbody
+                        tr(ng-repeat='row in displayedRows')
+                            td.text-left {{ row.action | translate }}
+                            td.text-left {{ row.action }}
+                            td.text-left {{ row.amount }}
+            .modal-footer
+                button.btn.btn-primary(id='confirm-btn-confirm' ng-click='$hide()') Close

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/activities-user-dialog/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/activities-user-dialog/index.js b/modules/web-console/frontend/app/components/activities-user-dialog/index.js
new file mode 100644
index 0000000..03d3585
--- /dev/null
+++ b/modules/web-console/frontend/app/components/activities-user-dialog/index.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+ import controller from './activities-user-dialog.controller';
+ import templateUrl from './activities-user-dialog.jade';
+
+ export default ['$modal', ($modal) => ({ show = true, user, params }) => {
+     const ActivitiesUserDialog = $modal({
+         templateUrl,
+         show,
+         resolve: {
+             user: () => user,
+             params: () => params
+         },
+         placement: 'center',
+         controller,
+         controllerAs: 'ctrl'
+     });
+
+     return ActivitiesUserDialog.$promise
+         .then(() => ActivitiesUserDialog);
+ }];

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade
new file mode 100644
index 0000000..6792977
--- /dev/null
+++ b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade
@@ -0,0 +1,55 @@
+//-
+    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.
+
+mixin ignite-form-field-datepicker(label, model, name, disabled, required, placeholder, tip)
+    mixin form-field-input()
+        input.form-control(
+            id='{{ #{name} }}Input'
+            name='{{ #{name} }}'
+
+            placeholder=placeholder
+            
+            data-ng-model=model
+
+            data-ng-required=required && '#{required}'
+            data-ng-disabled=disabled && '#{disabled}'
+
+            bs-datepicker
+            data-date-format='MMM yyyy' 
+            data-start-view='1' 
+            data-min-view='1' 
+            data-max-date='today'
+
+            data-container='body > .wrapper'
+
+            tabindex='0'
+
+            onkeydown="return false"
+
+            data-ignite-form-panel-field=''
+        )&attributes(attributes.attributes)
+
+    .ignite-form-field
+        +ignite-form-field__label(label, name, required)
+        .ignite-form-field__control
+            if tip
+                i.tipField.icon-help(bs-tooltip='' data-title=tip)
+
+            if block
+                block
+
+            .input-tip
+                +form-field-input(attributes=attributes)

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss
new file mode 100644
index 0000000..0f6fe6e
--- /dev/null
+++ b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+.datepicker.dropdown-menu tbody button {
+    height: 100%;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/index.js b/modules/web-console/frontend/app/components/list-of-registered-users/index.js
new file mode 100644
index 0000000..32a34f4
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/index.js
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+import templateUrl from './list-of-registered-users.jade';
+import controller from './list-of-registered-users.controller';
+
+export default [() => {
+    return {
+        scope: true,
+        templateUrl,
+        controller,
+        controllerAs: '$ctrl'
+    };
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js
new file mode 100644
index 0000000..95edf8b
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+export default [
+    {name: 'Actions', visible: true, selectable: true},
+    {name: 'User', visible: true, selectable: true},
+    {name: 'Email', visible: true, selectable: true},
+    {name: 'Company', visible: true, selectable: true},
+    {name: 'Country', visible: true, selectable: true},
+    {name: 'Last login', visible: false, selectable: true},
+    {name: 'Last activity', visible: true, selectable: true},
+    {name: 'Configurations', visible: false, selectable: true},
+    {name: 'Total activities', visible: true, selectable: true},
+    {name: 'Configuration\'s activities', visible: false, selectable: true},
+    {name: 'Queries\' activities', visible: false, selectable: true}
+];

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js
new file mode 100644
index 0000000..61e1bd8
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+const ICON_SORT = '<span ui-grid-one-bind-id-grid="col.uid + \'-sortdir-text\'" ui-grid-visible="col.sort.direction" aria-label="Sort Descending"><i ng-class="{ \'ui-grid-icon-up-dir\': col.sort.direction == asc, \'ui-grid-icon-down-dir\': col.sort.direction == desc, \'ui-grid-icon-blank\': !col.sort.direction }" title="" aria-hidden="true"></i></span>';
+
+const USER_TEMPLATE = '<div class="ui-grid-cell-contents"><i class="pull-left" ng-class="row.entity.admin ? \'icon-admin\' : \'icon-user\'"></i>{{ COL_FIELD }}</div>';
+
+const CLUSTER_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-sitemap'></i>${ICON_SORT}</div>`;
+const MODEL_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-object-group'></i>${ICON_SORT}</div>`;
+const CACHE_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-database'></i>${ICON_SORT}</div>`;
+const IGFS_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-folder-o'></i>${ICON_SORT}</div>`;
+
+const ACTIONS_TEMPLATE = `
+<div class='text-center ui-grid-cell-actions'>
+    <a class='btn btn-default dropdown-toggle' bs-dropdown='' data-placement='bottom-right' data-container='.panel'>
+        <i class='fa fa-gear'></i>&nbsp;
+        <span class='caret'></span>
+    </a>
+    <ul class='dropdown-menu' role='menu'>
+        <li ng-show='row.entity._id != $root.user._id'>
+            <a ng-click='grid.api.becomeUser(row.entity)'>Become this user</a>
+        </li>
+        <li ng-show='row.entity._id != $root.user._id'>
+            <a ng-click='grid.api.toggleAdmin(row.entity)' ng-if='row.entity.admin && row.entity._id !== $root.user._id'>Revoke admin</a>
+            <a ng-click='grid.api.toggleAdmin(row.entity)' ng-if='!row.entity.admin && row.entity._id !== $root.user._id'>Grant admin</a>
+        </li>
+        <li ng-show='row.entity._id != $root.user._id'>
+            <a ng-click='grid.api.removeUser(row.entity)'>Remove user</a>
+        </li>
+        <li>
+            <a ng-click='grid.api.showActivities(row.entity)'>Activity detail</a>
+        </li>
+</div>`;
+
+const EMAIL_TEMPLATE = '<div class="ui-grid-cell-contents"><a ng-href="mailto:{{ COL_FIELD }}">{{ COL_FIELD }}</a></div>';
+
+export default [
+    {displayName: 'Actions', categoryDisplayName: 'Actions', cellTemplate: ACTIONS_TEMPLATE, field: 'test', minWidth: 70, width: 70, enableFiltering: false, enableSorting: false, pinnedLeft: true},
+    {displayName: 'User', categoryDisplayName: 'User', field: 'userName', cellTemplate: USER_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by name...' }, pinnedLeft: true},
+    {displayName: 'Email', categoryDisplayName: 'Email', field: 'email', cellTemplate: EMAIL_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by email...' }},
+    {displayName: 'Company', categoryDisplayName: 'Company', field: 'company', minWidth: 160, enableFiltering: true},
+    {displayName: 'Country', categoryDisplayName: 'Country', field: 'countryCode', minWidth: 80, enableFiltering: true},
+    {displayName: 'Last login', categoryDisplayName: 'Last login', field: 'lastLogin', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 105, width: 105, enableFiltering: false, visible: false},
+    {displayName: 'Last activity', categoryDisplayName: 'Last activity', field: 'lastActivity', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 105, width: 105, enableFiltering: false, visible: true, sort: { direction: 'desc', priority: 0 }},
+    // Configurations
+    {displayName: 'Clusters count', categoryDisplayName: 'Configurations', headerCellTemplate: CLUSTER_HEADER_TEMPLATE, field: 'counters.clusters', type: 'number', headerTooltip: 'Clusters count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+    {displayName: 'Models count', categoryDisplayName: 'Configurations', headerCellTemplate: MODEL_HEADER_TEMPLATE, field: 'counters.models', type: 'number', headerTooltip: 'Models count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+    {displayName: 'Caches count', categoryDisplayName: 'Configurations', headerCellTemplate: CACHE_HEADER_TEMPLATE, field: 'counters.caches', type: 'number', headerTooltip: 'Caches count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+    {displayName: 'IGFS count', categoryDisplayName: 'Configurations', headerCellTemplate: IGFS_HEADER_TEMPLATE, field: 'counters.igfs', type: 'number', headerTooltip: 'IGFS count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+    // Activities Total
+    {displayName: 'Cfg', categoryDisplayName: 'Total activities', field: 'activitiesTotal["configuration"] || 0', type: 'number', headerTooltip: 'Configuration', minWidth: 50, width: 50, enableFiltering: false},
+    {displayName: 'Qry', categoryDisplayName: 'Total activities', field: 'activitiesTotal["queries"] || 0', type: 'number', headerTooltip: 'Queries', minWidth: 50, width: 50, enableFiltering: false},
+    {displayName: 'Demo', categoryDisplayName: 'Total activities', field: 'activitiesTotal["demo"] || 0', type: 'number', headerTooltip: 'Demo', minWidth: 50, width: 50, enableFiltering: false},
+    {displayName: 'AD', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/download"] || 0', type: 'number', headerTooltip: 'Agent Download', minWidth: 50, width: 50, enableFiltering: false},
+    {displayName: 'AS', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/start"] || 0', type: 'number', headerTooltip: 'Agent Start', minWidth: 50, width: 50, enableFiltering: false},
+    // Activities Configuration
+    {displayName: 'Clusters', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/clusters"] || 0', type: 'number', headerTooltip: 'Configuration Clusters', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+    {displayName: 'Model', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/domains"] || 0', type: 'number', headerTooltip: 'Configuration Model', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+    {displayName: 'Caches', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/caches"] || 0', type: 'number', headerTooltip: 'Configuration Caches', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+    {displayName: 'IGFS', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/igfs"] || 0', type: 'number', headerTooltip: 'Configuration IGFS', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+    {displayName: 'Summary', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/summary"] || 0', type: 'number', headerTooltip: 'Configuration Summary', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+    // Activities Queries
+    {displayName: 'Execute', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/execute"] || 0', type: 'number', headerTooltip: 'Query execute', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+    {displayName: 'Explain', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/explain"] || 0', type: 'number', headerTooltip: 'Query explain', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+    {displayName: 'Scan', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/scan"] || 0', type: 'number', headerTooltip: 'Scan', minWidth: 50, width: 80, enableFiltering: false, visible: false}
+];

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js
new file mode 100644
index 0000000..19f7921
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ */
+
+import headerTemplate from 'app/components/ui-grid-header/ui-grid-header.jade';
+
+import columnDefs from './list-of-registered-users.column-defs';
+import categories from './list-of-registered-users.categories';
+
+export default class IgniteListOfRegisteredUsersCtrl {
+    static $inject = ['$scope', '$state', '$templateCache', 'User', 'uiGridConstants', 'IgniteAdminData', 'IgniteNotebookData', 'IgniteConfirm', 'IgniteActivitiesUserDialog'];
+
+    constructor($scope, $state, $templateCache, User, uiGridConstants, AdminData, NotebookData, Confirm, ActivitiesUserDialog) {
+        const $ctrl = this;
+
+        const companySelectOptions = [];
+        const countrySelectOptions = [];
+
+        $ctrl.params = {
+            startDate: new Date()
+        };
+
+        $ctrl.params.startDate.setDate(1);
+        $ctrl.params.startDate.setHours(0, 0, 0, 0);
+
+        const columnCompany = _.find(columnDefs, { displayName: 'Company' });
+        const columnCountry = _.find(columnDefs, { displayName: 'Country' });
+
+        columnCompany.filter = {
+            selectOptions: companySelectOptions,
+            type: uiGridConstants.filter.SELECT,
+            condition: uiGridConstants.filter.EXACT
+        };
+
+        columnCountry.filter = {
+            selectOptions: countrySelectOptions,
+            type: uiGridConstants.filter.SELECT,
+            condition: uiGridConstants.filter.EXACT
+        };
+
+        const becomeUser = (user) => {
+            AdminData.becomeUser(user._id)
+                .then(() => User.load())
+                .then(() => $state.go('base.configuration.clusters'))
+                .then(() => NotebookData.load());
+        };
+
+        const removeUser = (user) => {
+            Confirm.confirm(`Are you sure you want to remove user: "${user.userName}"?`)
+                .then(() => AdminData.removeUser(user))
+                .then(() => {
+                    const i = _.findIndex($ctrl.gridOptions.data, (u) => u._id === user._id);
+
+                    if (i >= 0)
+                        $ctrl.gridOptions.data.splice(i, 1);
+                })
+                .then(() => $ctrl.adjustHeight($ctrl.gridOptions.data.length));
+        };
+
+        const toggleAdmin = (user) => {
+            if (user.adminChanging)
+                return;
+
+            user.adminChanging = true;
+
+            AdminData.toggleAdmin(user)
+                .then(() => user.admin = !user.admin)
+                .finally(() => user.adminChanging = false);
+        };
+
+        const showActivities = (user) => {
+            return new ActivitiesUserDialog({ user, params: $ctrl.params });
+        };
+
+        $ctrl.gridOptions = {
+            data: [],
+            columnVirtualizationThreshold: 30,
+            columnDefs,
+            categories,
+            headerTemplate: $templateCache.get(headerTemplate),
+            enableFiltering: true,
+            enableRowSelection: false,
+            enableRowHeaderSelection: false,
+            enableColumnMenus: false,
+            multiSelect: false,
+            modifierKeysToMultiSelect: true,
+            noUnselect: true,
+            fastWatch: true,
+            onRegisterApi: (api) => {
+                $ctrl.gridApi = api;
+
+                api.becomeUser = becomeUser;
+                api.removeUser = removeUser;
+                api.toggleAdmin = toggleAdmin;
+                api.showActivities = showActivities;
+            }
+        };
+
+        const usersToFilterOptions = (column) => {
+            return _.sortBy(
+                _.map(
+                    _.groupBy($ctrl.gridOptions.data, (usr) => {
+                        const fld = usr[column];
+
+                        return _.isNil(fld) ? fld : fld.toUpperCase();
+                    }),
+                    (arr, value) => ({label: `${_.head(arr)[column] || 'Not set'} (${arr.length})`, value})
+                ),
+                'value');
+        };
+
+        /**
+         * @param {{startDate: Date, endDate: Date}} params
+         */
+        const reloadUsers = (params) => {
+            AdminData.loadUsers(params)
+                .then((data) => $ctrl.gridOptions.data = data)
+                .then((data) => {
+                    companySelectOptions.push(...usersToFilterOptions('company'));
+                    countrySelectOptions.push(...usersToFilterOptions('countryCode'));
+
+                    this.gridApi.grid.refresh();
+
+                    return data;
+                })
+                .then((data) => $ctrl.adjustHeight(data.length));
+        };
+
+        $scope.$watch(() => $ctrl.params.startDate, () => {
+            const endDate = new Date($ctrl.params.startDate);
+
+            endDate.setMonth(endDate.getMonth() + 1);
+
+            $ctrl.params.endDate = endDate;
+
+            reloadUsers($ctrl.params);
+        });
+    }
+
+    adjustHeight(rows) {
+        const height = Math.min(rows, 20) * 30 + 75;
+
+        // Remove header height.
+        this.gridApi.grid.element.css('height', height + 'px');
+
+        this.gridApi.core.handleWindowResize();
+    }
+
+    _enableColumns(_categories, visible) {
+        _.forEach(_categories, (cat) => {
+            cat.visible = visible;
+
+            _.forEach(this.gridOptions.columnDefs, (col) => {
+                if (col.categoryDisplayName === cat.name)
+                    col.visible = visible;
+            });
+        });
+
+        // Workaround for this.gridApi.grid.refresh() didn't return promise.
+        this.gridApi.grid.processColumnsProcessors(this.gridApi.grid.columns)
+            .then((renderableColumns) => this.gridApi.grid.setVisibleColumns(renderableColumns))
+            .then(() => this.gridApi.grid.redrawInPlace())
+            .then(() => this.gridApi.grid.refreshCanvas(true))
+            .then(() => {
+                if (visible) {
+                    const categoryDisplayName = _.last(_categories).name;
+
+                    const col = _.findLast(this.gridOptions.columnDefs, {categoryDisplayName});
+
+                    this.gridApi.grid.scrollTo(null, col);
+                }
+            });
+    }
+
+    _selectableColumns() {
+        return _.filter(this.gridOptions.categories, (cat) => cat.selectable);
+    }
+
+    toggleColumns(category, visible) {
+        this._enableColumns([category], visible);
+    }
+
+    selectAllColumns() {
+        this._enableColumns(this._selectableColumns(), true);
+    }
+
+    clearAllColumns() {
+        this._enableColumns(this._selectableColumns(), false);
+    }
+
+    exportCsv() {
+        this.gridApi.exporter.csvExport('all', 'visible');
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade
new file mode 100644
index 0000000..efed9c0
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade
@@ -0,0 +1,54 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins.jade
+include /app/components/form-field-datepicker/form-field-datepicker.jade
+
+mixin grid-settings()
+    i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
+    ul.select.dropdown-menu(role='menu')
+        li(ng-repeat='item in $ctrl.gridOptions.categories|filter:{selectable:true}')
+            a(ng-click='$ctrl.toggleColumns(item, !item.visible)')
+                i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
+                i.fa.fa-square-o.pull-left(ng-if='!item.visible')
+                span {{::item.name}}
+        li.divider
+        li
+            a(ng-click='$ctrl.selectAllColumns()') Select all
+        li
+            a(ng-click='$ctrl.clearAllColumns()') Clear all
+        li.divider
+        li
+            a(ng-click='$hide()') Close
+
+.panel.panel-default
+    .panel-heading.ui-grid-settings
+        +grid-settings
+        label Total users: 
+            strong {{ $ctrl.gridOptions.data.length }}&nbsp;&nbsp;&nbsp;
+        label Showing users: 
+            strong {{ $ctrl.gridApi.grid.getVisibleRows().length }}
+            sub(ng-show='users.length === $ctrl.gridApi.grid.getVisibleRows().length') all
+        div.ui-grid-settings-dateperiod
+            form(ng-form=form novalidate)
+                -var form = 'admin'
+
+                +ignite-form-field-datepicker('Period:', '$ctrl.params.startDate', '"period"')
+                
+                button.btn.btn-primary(ng-click='$ctrl.exportCsv()' bs-tooltip data-title='Export table to csv') Export
+
+    .panel-collapse
+        .grid.ui-grid--ignite(ui-grid='$ctrl.gridOptions' ui-grid-resize-columns ui-grid-selection ui-grid-exporter ui-grid-pinning)

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.jade b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.jade
new file mode 100644
index 0000000..7e44d94
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.jade
@@ -0,0 +1,27 @@
+//-
+    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.
+
+.ui-grid-header.ui-grid-header--subcategories(role='rowgroup')
+    .ui-grid-top-panel
+        .ui-grid-header-viewport
+            .ui-grid-header-canvas
+                .ui-grid-header-cell-wrapper(ng-style='colContainer.headerCellWrapperStyle()')
+                    .ui-grid-header-cell-row(role='row')
+                        .ui-grid-header-span.ui-grid-header-cell.ui-grid-clearfix(ng-repeat='cat in grid.options.categories')
+                            div(ng-show='(colContainer.renderedColumns|uiGridSubcategories:cat.name).length > 1')
+                                .ui-grid-cell-contents {{ cat.name }}
+                            .ui-grid-header-cell-row
+                                .ui-grid-header-cell.ui-grid-clearfix(ng-repeat='col in (colContainer.renderedColumns|uiGridSubcategories:cat.name) track by col.uid' ui-grid-header-cell='' col='col' render-index='$index')

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss
new file mode 100644
index 0000000..c390504
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+.ui-grid-header--subcategories {
+    .ui-grid-row:nth-child(even) .ui-grid-cell.cell-total {
+        background-color: rgba(102,175,233,.6);
+    }
+
+    .ui-grid-row:nth-child(odd) .ui-grid-cell.cell-total {
+        background-color: rgba(102,175,233,.3);
+    }
+
+    .ui-grid-header-cell-row {
+        height: 30px;
+    }
+
+    .ui-grid-header-cell [role="columnheader"] {
+        display: flex;
+        
+        flex-wrap: wrap;
+        align-items: center;
+        justify-content: center;
+
+        height: 100%;
+
+        & > div {
+            flex: 1 100%;
+            height: auto;
+        }
+
+        & > div[ui-grid-filter] {
+            flex: auto;
+        }
+    }
+
+    .ui-grid-header-span {
+        position: relative;
+        border-right: 0;
+
+        .ng-hide + .ui-grid-header-cell-row .ui-grid-header-cell {
+            height: 58px;
+        }
+
+        .ng-hide + .ui-grid-header-cell-row .ui-grid-cell-contents {
+            padding: 5px 5px;
+        }
+
+        .ui-grid-column-resizer.right {
+            top: -100px;
+        }
+        .ng-hide + .ui-grid-header-cell-row .ui-grid-column-resizer.right {
+            bottom: -100px;
+        }
+
+        &.ui-grid-header-cell .ui-grid-header-cell .ui-grid-column-resizer.right {
+            border-right-width: 0;
+        }
+        &.ui-grid-header-cell .ui-grid-header-cell:last-child .ui-grid-column-resizer.right {
+            border-right-width: 1px;
+        }
+
+        & > div > .ui-grid-cell-contents {
+            border-bottom: 1px solid #d4d4d4;
+        }
+    }
+
+    input {
+        line-height: 21px;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade
new file mode 100644
index 0000000..8f1487e
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade
@@ -0,0 +1,33 @@
+//-
+    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.
+
+mixin ui-grid-settings()
+    .ui-grid-settings
+        i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
+        ul.select.dropdown-menu(role='menu')
+            li(ng-repeat='item in paragraph.gridOptions.categories|filter:{selectable:true}')
+                a(ng-click='paragraph.toggleColumns(item, !item.visible)')
+                    i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
+                    i.fa.fa-square-o.pull-left(ng-if='!item.visible')
+                    span {{::item.name}}
+            li.divider
+            li
+                a(ng-click='paragraph.selectAllColumns()') Select all
+            li
+                a(ng-click='paragraph.clearAllColumns()') Clear all
+            li.divider
+            li
+                a(ng-click='$hide()') Close

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss
new file mode 100644
index 0000000..3016488
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+.ui-grid-settings {
+    ul.select.dropdown-menu > li > a {
+        padding-top: 0;
+        padding-bottom: 0;
+    }
+
+    ul.select.dropdown-menu > li > a > i {
+        position: relative;
+        line-height: 26px;
+        width: 14px;
+        margin-left: 0;
+        color: inherit;
+    }
+
+    ul.select.dropdown-menu > li > a > span {
+        line-height: 26px;
+        padding-left: 5px;
+        padding-right: 8px;
+        cursor: pointer;
+    }
+
+    &-dateperiod {
+        float: right;
+
+        .ignite-form-field {
+            width: 160px;
+            margin-right: 10px;
+
+            &__label {
+            }
+
+            &__control {
+            }
+
+            &:nth-child(1) {
+                float: left;
+
+                .ignite-form-field__label {
+                    width: 40%;
+                }
+
+                .ignite-form-field__control {
+                    width: 60%;
+                }
+            }
+        }
+
+        .btn {
+            line-height: 20px;
+            margin-right: 0;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/core/activities/Activities.data.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/core/activities/Activities.data.js b/modules/web-console/frontend/app/core/activities/Activities.data.js
new file mode 100644
index 0000000..8a67a97
--- /dev/null
+++ b/modules/web-console/frontend/app/core/activities/Activities.data.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+export default class ActivitiesData {
+    static $inject = ['$http', '$state'];
+
+    constructor($http, $state) {
+        this.$http = $http;
+        this.$state = $state;
+    }
+
+    post(options = {}) {
+        let { group, action } = options;
+
+        action = action || this.$state.$current.url.source;
+        group = group || action.match(/^\/([^/]+)/)[1];
+
+        return this.$http.post('/api/v1/activities/page', { group, action });
+    }
+
+    listByUser(userId, params) {
+        return this.$http.get(`/api/v1/activities/user/${userId}`, { params })
+            .then(({ data }) => data);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/core/admin/Admin.data.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/core/admin/Admin.data.js b/modules/web-console/frontend/app/core/admin/Admin.data.js
new file mode 100644
index 0000000..66d82f0
--- /dev/null
+++ b/modules/web-console/frontend/app/core/admin/Admin.data.js
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+export default class IgniteAdminData {
+    static $inject = ['$http', 'IgniteMessages', 'IgniteCountries'];
+
+    constructor($http, Messages, Countries) {
+        this.$http = $http;
+        this.Messages = Messages;
+        this.Countries = Countries;
+    }
+
+    becomeUser(viewedUserId) {
+        return this.$http.get('/api/v1/admin/become', {
+            params: {viewedUserId}
+        })
+        .catch(this.Messages.showError);
+    }
+
+    removeUser(user) {
+        return this.$http.post('/api/v1/admin/remove', {
+            userId: user._id
+        })
+        .then(() => {
+            this.Messages.showInfo(`User has been removed: "${user.userName}"`);
+        })
+        .catch(({data, status}) => {
+            if (status === 503)
+                this.Messages.showInfo(data);
+            else
+                this.Messages.showError('Failed to remove user: ', data);
+        });
+    }
+
+    toggleAdmin(user) {
+        return this.$http.post('/api/v1/admin/save', {
+            userId: user._id,
+            adminFlag: !user.admin
+        })
+        .then(() => {
+            this.Messages.showInfo(`Admin right was successfully toggled for user: "${user.userName}"`);
+        })
+        .catch((res) => {
+            this.Messages.showError('Failed to toggle admin right for user: ', res);
+        });
+    }
+
+    prepareUsers(user) {
+        const { Countries } = this;
+
+        user.userName = user.firstName + ' ' + user.lastName;
+        user.countryCode = Countries.getByName(user.country).code;
+
+        return user;
+    }
+
+    loadUsers(params) {
+        return this.$http.post('/api/v1/admin/list', params)
+            .then(({ data }) => data)
+            .then((users) => _.map(users, this.prepareUsers.bind(this)))
+            .catch(this.Messages.showError);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/core/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/core/index.js b/modules/web-console/frontend/app/core/index.js
new file mode 100644
index 0000000..7f72ee3
--- /dev/null
+++ b/modules/web-console/frontend/app/core/index.js
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+import IgniteAdminData from './admin/Admin.data';
+import IgniteActivitiesData from './activities/Activities.data';
+
+angular.module('ignite-console.core', [])
+    .service('IgniteAdminData', IgniteAdminData)
+    .service('IgniteActivitiesData', IgniteActivitiesData);

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/data/i18n.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/data/i18n.js b/modules/web-console/frontend/app/data/i18n.js
new file mode 100644
index 0000000..bc8c700
--- /dev/null
+++ b/modules/web-console/frontend/app/data/i18n.js
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+export default {
+    '/agent/start': 'Agent start',
+    '/agent/download': 'Agent download',
+    '/configuration/clusters': 'Configure clusters',
+    '/configuration/caches': 'Configure caches',
+    '/configuration/domains': 'Configure domain model',
+    '/configuration/igfs': 'Configure IGFS',
+    '/configuration/summary': 'Configurations summary',
+    '/demo/resume': 'Demo resume',
+    '/demo/reset': 'Demo reset',
+    '/queries/execute': 'Query execute',
+    '/queries/explain': 'Query explain',
+    '/queries/scan': 'Scan',
+    '/queries/add/query': 'Add query',
+    '/queries/add/scan': 'Add scan',
+    '/queries/demo': 'SQL demo',
+    '/queries/notebook/': 'Query notebook',
+    '/settings/profile': 'User profile',
+    '/settings/admin': 'Admin panel',
+    '/logout': 'Logout'
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
deleted file mode 100644
index 8f1487e..0000000
--- a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
+++ /dev/null
@@ -1,33 +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.
-
-mixin ui-grid-settings()
-    .ui-grid-settings
-        i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
-        ul.select.dropdown-menu(role='menu')
-            li(ng-repeat='item in paragraph.gridOptions.categories|filter:{selectable:true}')
-                a(ng-click='paragraph.toggleColumns(item, !item.visible)')
-                    i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
-                    i.fa.fa-square-o.pull-left(ng-if='!item.visible')
-                    span {{::item.name}}
-            li.divider
-            li
-                a(ng-click='paragraph.selectAllColumns()') Select all
-            li
-                a(ng-click='paragraph.clearAllColumns()') Clear all
-            li.divider
-            li
-                a(ng-click='$hide()') Close

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
deleted file mode 100644
index 6517a60..0000000
--- a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
+++ /dev/null
@@ -1,38 +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.
- */
-
-.ui-grid-settings {
-    ul.select.dropdown-menu > li > a {
-        padding-top: 0;
-        padding-bottom: 0;
-    }
-
-    ul.select.dropdown-menu > li > a > i {
-        position: relative;
-        line-height: 26px;
-        width: 14px;
-        margin-left: 0;
-        color: inherit;
-    }
-
-    ul.select.dropdown-menu > li > a > span {
-        line-height: 26px;
-        padding-left: 5px;
-        padding-right: 8px;
-        cursor: pointer;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js b/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js
new file mode 100644
index 0000000..f36ae6e
--- /dev/null
+++ b/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+export default [() => {
+    return (arr, category) => {
+        return _.filter(arr, (item) => {
+            return item.colDef.categoryDisplayName === category;
+        });
+    };
+}];


[28/50] [abbrv] ignite git commit: .NET: Extract exceptions tests in CacheStoreTest and ignore due to IGNITE-4657

Posted by sb...@apache.org.
.NET: Extract exceptions tests in CacheStoreTest and ignore due to IGNITE-4657


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 543a65fbac20a6961f8d23baaeb6ff8c6c61f20d
Parents: a600caf
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Mon Feb 6 18:07:28 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Feb 10 12:45:07 2017 +0300

----------------------------------------------------------------------
 .../Cache/Store/CacheStoreTest.cs               | 30 ++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/543a65fb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
index 869336c..a66aea8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
@@ -208,12 +208,38 @@ namespace Apache.Ignite.Core.Tests.Cache.Store
             Assert.AreEqual("val", cache.Get(1));
 
             Assert.AreEqual(1, cache.GetSize());
+        }
+
+        [Test]
+        public void TestExceptions()
+        {
+            var cache = GetCache();
+
+            cache.Put(1, "val");
 
-            // Test errors
             CacheTestStore.ThrowError = true;
             CheckCustomStoreError(Assert.Throws<CacheStoreException>(() => cache.Put(-2, "fail")).InnerException);
 
-            cache.LocalEvict(new[] { 1 });
+            cache.LocalEvict(new[] {1});
+            CheckCustomStoreError(Assert.Throws<CacheStoreException>(() => cache.Get(1)).InnerException);
+
+            CacheTestStore.ThrowError = false;
+
+            cache.Remove(1);
+        }
+
+        [Test]
+        [Ignore("IGNITE-4657")]
+        public void TestExceptionsNoRemove()
+        {
+            var cache = GetCache();
+
+            cache.Put(1, "val");
+
+            CacheTestStore.ThrowError = true;
+            CheckCustomStoreError(Assert.Throws<CacheStoreException>(() => cache.Put(-2, "fail")).InnerException);
+
+            cache.LocalEvict(new[] {1});
             CheckCustomStoreError(Assert.Throws<CacheStoreException>(() => cache.Get(1)).InnerException);
         }
 


[49/50] [abbrv] ignite git commit: Megre 2.0

Posted by sb...@apache.org.
Megre 2.0


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 1748e226d4322b90c7a50d52e53e2e16119c8086
Parents: db548dc 85b08c5
Author: sboikov <sb...@gridgain.com>
Authored: Wed Feb 15 13:42:00 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Feb 15 13:42:00 2017 +0300

----------------------------------------------------------------------
 .gitignore                                      |   2 +-
 DEVNOTES.txt                                    |   3 +
 NOTICE                                          |   2 +-
 assembly/LICENSE_FABRIC                         |  35 +-
 assembly/LICENSE_HADOOP                         |  17 +-
 assembly/NOTICE_FABRIC                          |   2 +-
 assembly/NOTICE_HADOOP                          |   2 +-
 assembly/dependencies-fabric-lgpl.xml           |   1 +
 assembly/dependencies-fabric.xml                |   1 +
 examples/schema-import/bin/h2-server.bat        |   2 +-
 examples/schema-import/bin/h2-server.sh         |   4 +-
 .../schema-import/bin/schema-import.properties  |   2 +-
 .../src/main/resources/META-INF/licenses.txt.vm |   7 +-
 .../tcp/ipfinder/s3/TcpDiscoveryS3IpFinder.java |  37 +-
 .../TcpDiscoveryS3IpFinderAbstractSelfTest.java |  84 +++
 ...3IpFinderAwsCredentialsProviderSelfTest.java |  46 ++
 ...scoveryS3IpFinderAwsCredentialsSelfTest.java |  45 ++
 .../s3/TcpDiscoveryS3IpFinderSelfTest.java      |  79 ---
 .../ignite/testsuites/IgniteS3TestSuite.java    |  26 +-
 .../stream/camel/IgniteCamelStreamerTest.java   |   4 +-
 .../cassandra/persistence/PojoKeyField.java     |   2 +-
 .../ClientAbstractMultiNodeSelfTest.java        |   8 +-
 ...BinaryMarshallerInsertStatementSelfTest.java |   2 -
 ...cBinaryMarshallerMergeStatementSelfTest.java |   2 -
 .../internal/jdbc2/JdbcMetadataSelfTest.java    |   2 +-
 .../ignite/jdbc/JdbcMetadataSelfTest.java       |   4 +-
 .../jdbc/suite/IgniteJdbcDriverTestSuite.java   |   3 +-
 .../ignite/codegen/MessageCodeGenerator.java    |   2 +-
 modules/core/src/main/java/META-INF/NOTICE      |   2 +-
 .../apache/ignite/IgniteSystemProperties.java   |  14 +
 .../apache/ignite/binary/BinaryRawReader.java   |  13 +
 .../apache/ignite/binary/BinaryRawWriter.java   |  13 +
 .../org/apache/ignite/binary/BinaryReader.java  |  15 +
 .../org/apache/ignite/binary/BinaryWriter.java  |  15 +
 .../org/apache/ignite/cache/QueryEntity.java    |  22 +-
 .../org/apache/ignite/cache/query/SqlQuery.java |  25 +
 .../store/jdbc/CacheAbstractJdbcStore.java      |  11 +-
 .../store/jdbc/CacheJdbcBlobStoreFactory.java   |   2 +-
 .../store/jdbc/JdbcTypesDefaultTransformer.java |  19 +
 .../cache/store/jdbc/JdbcTypesTransformer.java  |  17 +
 .../configuration/CacheConfiguration.java       |  20 +-
 .../configuration/IgniteConfiguration.java      |  87 +--
 .../apache/ignite/internal/GridComponent.java   |  48 +-
 .../internal/GridEventConsumeHandler.java       |   5 +
 .../ignite/internal/GridKernalContext.java      |  23 +-
 .../ignite/internal/GridKernalContextImpl.java  |  47 +-
 .../internal/GridMessageListenHandler.java      |   5 +
 .../internal/GridPerformanceSuggestions.java    |  92 ---
 .../ignite/internal/GridPluginComponent.java    |  21 +-
 .../org/apache/ignite/internal/GridTopic.java   |   3 +
 .../ignite/internal/IgniteComputeImpl.java      |   2 +
 .../apache/ignite/internal/IgniteKernal.java    |  40 +-
 .../ignite/internal/IgniteVersionUtils.java     |   2 +-
 .../org/apache/ignite/internal/IgnitionEx.java  |  69 +-
 .../ignite/internal/MappingStoreTask.java       |  59 ++
 .../internal/MarshallerContextAdapter.java      | 211 ------
 .../ignite/internal/MarshallerContextImpl.java  | 690 +++++++++++++------
 .../internal/MarshallerMappingFileStore.java    | 174 +++++
 .../ignite/internal/MarshallerPlatformIds.java  |  30 +
 .../internal/binary/BinaryClassDescriptor.java  |  13 +
 .../ignite/internal/binary/BinaryContext.java   |  11 +-
 .../internal/binary/BinaryEnumObjectImpl.java   |   4 +-
 .../internal/binary/BinaryFieldAccessor.java    |  23 +
 .../internal/binary/BinaryMarshaller.java       |   1 -
 .../binary/BinaryMetadataCollector.java         |  11 +
 .../internal/binary/BinaryObjectImpl.java       |   9 +
 .../binary/BinaryObjectOffheapImpl.java         |   9 +
 .../internal/binary/BinaryReaderExImpl.java     |  58 ++
 .../binary/BinarySerializedFieldComparator.java |   3 +
 .../ignite/internal/binary/BinaryUtils.java     | 130 +++-
 .../ignite/internal/binary/BinaryWriteMode.java |   6 +
 .../internal/binary/BinaryWriterExImpl.java     |  80 ++-
 .../internal/binary/GridBinaryMarshaller.java   |   6 +
 .../binary/builder/BinaryBuilderReader.java     |  37 +
 .../GridClientOptimizedMarshaller.java          |  16 +-
 .../impl/GridRouterCommandLineStartup.java      |   4 +-
 .../cluster/ClusterNodeLocalMapImpl.java        |   1 -
 .../internal/igfs/common/IgfsMarshaller.java    |   4 +-
 .../internal/jdbc2/JdbcSqlFieldsQuery.java      |   1 -
 .../ignite/internal/jdbc2/JdbcStatement.java    |   2 -
 .../internal/managers/GridManagerAdapter.java   |  19 +-
 .../managers/communication/GridIoManager.java   |   6 +-
 .../communication/GridIoMessageFactory.java     |  12 +
 .../managers/communication/GridIoPolicy.java    |  10 +-
 .../discovery/GridDiscoveryManager.java         |  85 ++-
 .../internal/mxbean/IgniteStandardMXBean.java   |  12 +-
 .../processors/GridProcessorAdapter.java        |  21 +-
 .../cache/CacheEvictableEntryImpl.java          |   4 +-
 .../processors/cache/CacheMetricsImpl.java      |   6 +-
 .../internal/processors/cache/CacheType.java    |   8 +-
 .../processors/cache/EntryGetResult.java        |  65 ++
 .../processors/cache/GridCacheAdapter.java      | 195 +++---
 .../cache/GridCacheAffinityManager.java         |  60 +-
 .../processors/cache/GridCacheAtomicFuture.java |   3 +-
 .../processors/cache/GridCacheContext.java      |  21 +-
 .../cache/GridCacheDeploymentManager.java       |   4 +-
 .../processors/cache/GridCacheEntryEx.java      |  40 +-
 .../cache/GridCacheEvictionManager.java         |   6 +-
 .../processors/cache/GridCacheMapEntry.java     | 130 +++-
 .../GridCachePartitionExchangeManager.java      |   2 +-
 .../processors/cache/GridCacheProcessor.java    | 372 ++++++----
 .../processors/cache/GridCacheTtlManager.java   |   3 +-
 .../processors/cache/GridCacheUtils.java        |  36 +-
 .../processors/cache/IgniteCacheProxy.java      |   3 +
 .../processors/cache/QueryCursorImpl.java       |   6 +-
 .../processors/cache/ReaderArguments.java       |  74 ++
 .../cache/affinity/GridCacheAffinityImpl.java   |  16 +-
 .../binary/CacheObjectBinaryProcessorImpl.java  |   2 +-
 .../CacheDataStructuresManager.java             |   2 +-
 .../GridDistributedCacheAdapter.java            |  16 +-
 .../distributed/GridDistributedCacheEntry.java  |   3 -
 .../GridDistributedLockResponse.java            |   1 -
 .../dht/GridClientPartitionTopology.java        |   1 -
 .../dht/GridDhtAssignmentFetchFuture.java       |   3 +-
 .../distributed/dht/GridDhtCacheAdapter.java    |  33 +-
 .../distributed/dht/GridDhtCacheEntry.java      |   2 +-
 .../cache/distributed/dht/GridDhtGetFuture.java |  87 +--
 .../distributed/dht/GridDhtGetSingleFuture.java |  79 +--
 .../distributed/dht/GridDhtLocalPartition.java  | 125 +++-
 .../distributed/dht/GridDhtLockFuture.java      |  35 +-
 .../dht/GridDhtPartitionTopologyImpl.java       |   6 +-
 .../dht/GridDhtTransactionalCacheAdapter.java   |  21 +-
 .../distributed/dht/GridDhtTxFinishFuture.java  |   8 +-
 .../cache/distributed/dht/GridDhtTxLocal.java   |   1 -
 .../distributed/dht/GridDhtTxLocalAdapter.java  |  10 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |  13 +-
 .../cache/distributed/dht/GridDhtTxRemote.java  |   2 +-
 .../distributed/dht/GridDhtUnlockRequest.java   |   3 +-
 .../dht/GridPartitionedGetFuture.java           |  13 +-
 .../dht/GridPartitionedSingleGetFuture.java     |  14 +-
 .../GridDhtAtomicAbstractUpdateFuture.java      |   2 +-
 .../dht/atomic/GridDhtAtomicCache.java          |  34 +-
 .../atomic/GridNearAtomicFullUpdateRequest.java |   1 -
 .../GridNearAtomicSingleUpdateFuture.java       |   2 +-
 .../dht/atomic/GridNearAtomicUpdateFuture.java  |   4 +-
 .../dht/colocated/GridDhtColocatedCache.java    |  26 +-
 .../colocated/GridDhtColocatedLockFuture.java   |  64 +-
 .../dht/preloader/GridDhtForceKeysFuture.java   |   8 +-
 .../dht/preloader/GridDhtPartitionDemander.java |  16 +-
 .../dht/preloader/GridDhtPartitionMap2.java     |   3 +-
 .../dht/preloader/GridDhtPartitionSupplier.java |   2 +-
 .../GridDhtPartitionsExchangeFuture.java        |  51 +-
 .../dht/preloader/GridDhtPreloader.java         |   4 +-
 .../distributed/near/GridNearAtomicCache.java   |   3 +-
 .../distributed/near/GridNearCacheEntry.java    |   6 +-
 .../distributed/near/GridNearGetFuture.java     |  31 +-
 .../distributed/near/GridNearGetRequest.java    |  29 +-
 .../distributed/near/GridNearLockFuture.java    |   9 +-
 .../distributed/near/GridNearLockRequest.java   |  81 ++-
 ...arOptimisticSerializableTxPrepareFuture.java |   4 +-
 .../near/GridNearOptimisticTxPrepareFuture.java |  13 +-
 ...ridNearOptimisticTxPrepareFutureAdapter.java |  13 +
 .../GridNearPessimisticTxPrepareFuture.java     |   2 +-
 .../near/GridNearSingleGetRequest.java          |  57 +-
 .../near/GridNearTransactionalCache.java        |   8 +-
 .../near/GridNearTxFinishFuture.java            |  15 +-
 .../cache/distributed/near/GridNearTxLocal.java |  17 +-
 .../processors/cache/local/GridLocalCache.java  |   1 +
 .../local/atomic/GridLocalAtomicCache.java      |  12 +-
 .../processors/cache/query/CacheQuery.java      |   1 -
 .../cache/query/GridCacheQueryAdapter.java      |   8 +
 .../cache/query/GridCacheQueryManager.java      | 105 ++-
 .../cache/query/GridCacheSqlQuery.java          |   1 -
 .../continuous/CacheContinuousQueryHandler.java | 101 ++-
 .../continuous/CacheContinuousQueryManager.java |   2 +-
 .../cache/transactions/IgniteTxAdapter.java     |   4 +-
 .../cache/transactions/IgniteTxEntry.java       |   2 +-
 .../cache/transactions/IgniteTxHandler.java     |  16 +-
 .../transactions/IgniteTxLocalAdapter.java      | 101 ++-
 .../cache/transactions/IgniteTxLocalEx.java     |   3 +
 .../cache/transactions/IgniteTxManager.java     |   3 +-
 .../cache/transactions/TxDeadlockDetection.java |   2 +-
 .../cache/transactions/TxEntryValueHolder.java  |   6 +-
 .../IgniteCacheObjectProcessorImpl.java         |   2 +-
 .../processors/clock/GridClockServer.java       |   4 +-
 .../processors/cluster/ClusterProcessor.java    |  53 +-
 .../cluster/GridClusterStateProcessor.java      |  22 +-
 .../continuous/GridContinuousHandler.java       |   5 +
 .../continuous/GridContinuousProcessor.java     | 147 ++--
 .../datastreamer/DataStreamProcessor.java       |   2 +-
 .../datastreamer/DataStreamerImpl.java          |   6 +-
 .../datastructures/GridCacheSetImpl.java        |   2 +-
 .../datastructures/GridSetQueryPredicate.java   |   2 +-
 .../processors/hadoop/HadoopClasspathUtils.java |   4 +-
 .../processors/hadoop/HadoopDefaultJobInfo.java |   5 +-
 .../processors/hadoop/HadoopTaskContext.java    |  10 +
 .../internal/processors/igfs/IgfsFileImpl.java  |   5 +-
 .../internal/processors/igfs/IgfsProcessor.java |   2 +-
 .../internal/processors/igfs/IgfsUtils.java     | 105 +++
 .../igfs/client/IgfsClientSizeCallable.java     |   1 -
 .../processors/job/GridJobProcessor.java        |   2 +-
 .../internal/processors/job/GridJobWorker.java  |   4 +
 .../marshaller/ClientRequestFuture.java         | 183 +++++
 .../GridMarshallerMappingProcessor.java         | 363 ++++++++++
 .../processors/marshaller/MappedName.java       |  63 ++
 .../marshaller/MappingAcceptedMessage.java      |  71 ++
 .../marshaller/MappingExchangeResult.java       |  96 +++
 .../marshaller/MappingProposedMessage.java      | 137 ++++
 .../marshaller/MappingUpdatedListener.java      |  29 +
 .../marshaller/MarshallerMappingItem.java       |  99 +++
 .../marshaller/MarshallerMappingTransport.java  | 212 ++++++
 .../MissingMappingRequestMessage.java           | 146 ++++
 .../MissingMappingResponseMessage.java          | 169 +++++
 .../internal/processors/odbc/IgniteTypes.java   |  69 ++
 .../processors/odbc/OdbcRequestHandler.java     |   2 +
 .../internal/processors/odbc/OdbcTypes.java     | 131 ++++
 .../internal/processors/odbc/OdbcUtils.java     |  85 +++
 .../processors/odbc/escape/OdbcEscapeUtils.java |  52 +-
 .../platform/PlatformAbstractBootstrap.java     |   3 +-
 .../platform/PlatformConfigurationEx.java       |   3 +-
 .../platform/PlatformNoopProcessor.java         |   5 +
 .../platform/PlatformPluginExtension.java       |  39 ++
 .../processors/platform/PlatformProcessor.java  |   7 +
 .../platform/PlatformProcessorImpl.java         |  71 +-
 .../platform/cache/PlatformCache.java           |  23 +-
 .../cache/PlatformCacheEntryProcessorImpl.java  |   6 +-
 .../callback/PlatformCallbackGateway.java       |  96 +++
 .../platform/callback/PlatformCallbackOp.java   |  18 +
 .../plugin/PlatformPluginProcessor.java         |  46 ++
 .../cache/PlatformCachePluginConfiguration.java |  58 ++
 .../cache/PlatformCachePluginProvider.java      | 123 ++++
 .../transactions/PlatformTransactions.java      |   9 +
 .../utils/PlatformConfigurationUtils.java       |  51 +-
 .../platform/utils/PlatformUtils.java           |  58 +-
 .../processors/plugin/CachePluginManager.java   |  20 +-
 .../plugin/IgnitePluginProcessor.java           |  84 ++-
 .../internal/processors/pool/PoolProcessor.java |  10 +-
 .../processors/query/GridQueryIndexing.java     |   4 +-
 .../processors/query/GridQueryProcessor.java    | 182 ++---
 .../processors/query/GridQueryProperty.java     |  21 +-
 .../query/GridQueryTypeDescriptor.java          |   7 +
 .../resource/GridResourceProcessor.java         |   1 +
 .../handlers/cache/GridCacheCommandHandler.java |   2 -
 .../string/GridRedisSetCommandHandler.java      |   2 +-
 .../service/GridServiceProcessor.java           |  11 +-
 .../processors/task/GridTaskWorker.java         |   2 +-
 .../suggestions/GridPerformanceSuggestions.java | 105 +++
 .../JvmConfigurationSuggestions.java            | 104 +++
 .../suggestions/OsConfigurationSuggestions.java | 127 ++++
 .../internal/suggestions/package-info.java      |  21 +
 .../internal/util/GridStripedSpinBusyLock.java  |   2 +-
 .../ignite/internal/util/HostAndPortRange.java  |   2 +-
 .../ignite/internal/util/IgniteUtils.java       |  85 +--
 .../ignite/internal/util/StripedExecutor.java   |   2 +-
 .../ignite/lang/IgniteProductVersion.java       |   2 +-
 .../ignite/marshaller/MarshallerContext.java    |  23 +-
 .../ignite/marshaller/jdk/JdkMarshaller.java    |   1 -
 .../optimized/OptimizedClassDescriptor.java     |   2 +-
 .../optimized/OptimizedMarshallerUtils.java     |  16 +-
 .../ignite/plugin/CachePluginContext.java       |   5 +
 .../apache/ignite/plugin/PluginProvider.java    |  11 +-
 .../communication/tcp/TcpCommunicationSpi.java  |  18 +-
 .../tcp/TcpCommunicationSpiMBean.java           |   1 -
 .../ignite/spi/discovery/DiscoveryDataBag.java  | 299 ++++++++
 .../spi/discovery/DiscoverySpiDataExchange.java |  15 +-
 .../ignite/spi/discovery/tcp/ClientImpl.java    | 120 +++-
 .../ignite/spi/discovery/tcp/ServerImpl.java    | 167 ++---
 .../spi/discovery/tcp/TcpDiscoverySpi.java      |  70 +-
 .../tcp/internal/DiscoveryDataPacket.java       | 345 ++++++++++
 .../tcp/internal/TcpDiscoveryStatistics.java    |   8 +-
 .../messages/TcpDiscoveryAbstractMessage.java   |  21 +
 .../TcpDiscoveryJoinRequestMessage.java         |  18 +-
 .../TcpDiscoveryNodeAddFinishedMessage.java     |  10 +-
 .../messages/TcpDiscoveryNodeAddedMessage.java  |  78 +--
 modules/core/src/test/config/log4j-test.xml     |   6 +
 .../org.apache.ignite.plugin.PluginProvider     |   1 +
 .../CacheJdbcPojoStoreAbstractSelfTest.java     |  21 +-
 ...eJdbcStoreAbstractMultithreadedSelfTest.java |  17 +-
 .../ignite/cache/store/jdbc/model/Gender.java   |  41 ++
 .../ignite/cache/store/jdbc/model/Person.java   |  31 +-
 .../internal/ClusterGroupHostsSelfTest.java     |   6 +-
 .../ComputeJobCancelWithServiceSelfTest.java    |   2 +-
 .../ignite/internal/GridAffinitySelfTest.java   |   2 +-
 .../internal/GridContinuousTaskSelfTest.java    |  83 ++-
 .../GridEventStorageCheckAllEventsSelfTest.java |   2 +-
 .../IgniteClientReconnectApiExceptionTest.java  |   6 +-
 ...niteClientReconnectFailoverAbstractTest.java |   4 +-
 .../MarshallerContextLockingSelfTest.java       |  67 +-
 .../binary/BinaryMarshallerSelfTest.java        | 109 ++-
 ...GridBinaryMarshallerCtxDisabledSelfTest.java |  42 +-
 .../GridDiscoveryManagerAliveCacheSelfTest.java |   3 +-
 .../GridDiscoveryManagerAttributesSelfTest.java |   4 +-
 .../cache/CacheAffinityCallSelfTest.java        |   8 +-
 .../cache/CacheConcurrentReadThroughTest.java   | 184 +++++
 .../cache/CacheDeferredDeleteQueueTest.java     | 134 ++++
 .../cache/CacheGetEntryAbstractTest.java        |   2 +-
 .../CacheSerializableTransactionsTest.java      |   6 +-
 .../CacheStartupInDeploymentModesTest.java      |   7 +-
 .../cache/CacheStopAndDestroySelfTest.java      |   6 +-
 .../cache/GridCacheAbstractFullApiSelfTest.java |   6 +-
 .../cache/GridCacheEntryMemorySizeSelfTest.java |   8 +-
 .../cache/GridCacheMvccPartitionedSelfTest.java |  48 +-
 .../processors/cache/GridCacheMvccSelfTest.java | 208 +++---
 .../processors/cache/GridCacheStopSelfTest.java |   4 +-
 .../processors/cache/GridCacheTestEntryEx.java  |  32 +-
 .../cache/GridCacheUtilsSelfTest.java           |   2 +-
 ...ProjectionForCachesOnDaemonNodeSelfTest.java |   8 +-
 .../IgniteCacheConfigVariationsFullApiTest.java |   8 +-
 .../cache/IgniteCachePeekModesAbstractTest.java |   4 +-
 .../cache/IgniteCacheStoreCollectionTest.java   |   1 -
 .../cache/IgniteInternalCacheTypesTest.java     |  11 -
 ...iteMarshallerCacheClassNameConflictTest.java | 277 ++++++++
 ...lerCacheClientRequestsMappingOnMissTest.java | 341 +++++++++
 .../cache/IgniteSystemCacheOnClientTest.java    |  23 +-
 ...gniteTopologyValidatorAbstractCacheTest.java |   6 +-
 .../processors/cache/IgniteTxAbstractTest.java  |   3 +-
 .../cache/IgniteTxConfigCacheSelfTest.java      |   2 +-
 .../IgniteTxExceptionAbstractSelfTest.java      |   3 +-
 .../IgniteTxMultiThreadedAbstractTest.java      |   4 +-
 .../CacheKeepBinaryWithInterceptorTest.java     |   1 -
 .../GridBinaryCacheEntryMemorySizeSelfTest.java |  21 +-
 ...yAtomicEntryProcessorDeploymentSelfTest.java |   4 +-
 ...IgniteCacheAbstractExecutionContextTest.java |   2 -
 ...eAbstractDataStructuresFailoverSelfTest.java |  16 +-
 ...actQueueFailoverDataConsistencySelfTest.java |   2 +-
 ...CacheAtomicReferenceApiSelfAbstractTest.java |  60 +-
 ...idCacheAtomicStampedApiSelfAbstractTest.java |  59 ++
 .../GridCacheQueueApiSelfAbstractTest.java      |  58 ++
 .../GridCacheSetAbstractSelfTest.java           |  53 ++
 .../IgniteAtomicLongApiAbstractSelfTest.java    |  27 +
 .../IgniteCountDownLatchAbstractSelfTest.java   |  43 ++
 .../IgniteLockAbstractSelfTest.java             |  78 ++-
 .../IgniteSemaphoreAbstractSelfTest.java        |  52 +-
 .../CacheGetFutureHangsSelfTest.java            |   6 +-
 .../CacheLateAffinityAssignmentTest.java        |   2 +-
 ...ridCachePartitionNotLoadedEventSelfTest.java |   4 +-
 ...niteCacheClientNodeChangingTopologyTest.java |  20 +-
 .../IgniteCacheSystemTransactionsSelfTest.java  |  18 +-
 ...teSynchronizationModesMultithreadedTest.java |   8 +-
 .../IgniteCacheCrossCacheTxFailoverTest.java    |   6 +-
 ...ePrimaryNodeFailureRecoveryAbstractTest.java |   4 +-
 ...gniteCachePutRetryTransactionalSelfTest.java |   4 +-
 ...eAtomicInvalidPartitionHandlingSelfTest.java |  11 +-
 ...idCacheNearOnlyMultiNodeFullApiSelfTest.java |   4 +-
 ...achePartitionedMultiNodeFullApiSelfTest.java |   8 +-
 .../near/GridNearCacheStoreUpdateTest.java      | 466 +++++++++++++
 .../GridNearOffheapCacheStoreUpdateTest.java    |  35 +
 .../GridCacheReplicatedNodeRestartSelfTest.java |   3 +-
 .../GridCacheReplicatedPreloadSelfTest.java     |   1 -
 .../IgniteCacheExpiryPolicyAbstractTest.java    |   2 +-
 ...eCacheExpiryPolicyWithStoreAbstractTest.java | 100 ++-
 .../IgniteCacheTxExpiryPolicyWithStoreTest.java |  21 +
 .../IgniteCacheQueryCacheDestroySelfTest.java   | 142 ++++
 .../cache/query/IndexingSpiQuerySelfTest.java   |  69 +-
 .../IndexingSpiQueryWithH2IndexingSelfTest.java |  36 +
 ...ContinuousQueryFailoverAbstractSelfTest.java |   6 +-
 .../ClientReconnectContinuousQueryTest.java     | 201 ++++++
 ...ridCacheContinuousQueryAbstractSelfTest.java |   2 +-
 ...dCacheContinuousQueryNodesFilteringTest.java |   2 +-
 ...IgniteCacheContinuousQueryReconnectTest.java |  12 +-
 .../TxDeadlockDetectionNoHangsTest.java         |   2 +-
 .../transactions/TxDeadlockDetectionTest.java   |   2 +-
 .../TxOptimisticDeadlockDetectionTest.java      |   2 +-
 .../TxPessimisticDeadlockDetectionTest.java     |   2 +-
 ...ComputeJobExecutionErrorToLogManualTest.java |   4 +-
 .../datastreamer/DataStreamerImplSelfTest.java  |   8 +-
 .../datastreamer/DataStreamerTimeoutTest.java   |   6 +-
 .../processors/igfs/IgfsAbstractSelfTest.java   |  32 +-
 .../processors/igfs/IgfsFileInfoSelfTest.java   |   4 +-
 .../igfs/IgfsMetaManagerSelfTest.java           |   3 +-
 .../igfs/IgfsModeResolverSelfTest.java          |  10 +-
 .../processors/igfs/IgfsTaskSelfTest.java       |  87 +--
 .../igfs/benchmark/IgfsBenchmark.java           |   4 +-
 .../odbc/OdbcEscapeSequenceSelfTest.java        | 131 ++++
 .../cache/GridCacheCommandHandlerSelfTest.java  |   1 -
 ...rviceDeploymentExceptionPropagationTest.java |   2 +-
 .../GridServiceProcessorStopSelfTest.java       |   2 +-
 .../service/IgniteServiceReassignmentTest.java  |   2 +-
 .../internal/util/IgniteUtilsSelfTest.java      |  71 +-
 .../unsafe/GridOffheapSnapTreeSelfTest.java     |   7 +-
 .../lang/GridMetadataAwareAdapterSelfTest.java  |   4 +-
 .../marshaller/MarshallerContextSelfTest.java   | 150 +++-
 .../marshaller/MarshallerContextTestImpl.java   |  33 +-
 .../OptimizedMarshallerEnumSelfTest.java        |  25 +-
 .../p2p/GridP2PSameClassLoaderSelfTest.java     |  14 +-
 .../platform/PlatformComputeEchoTask.java       |  12 +
 .../platform/PlatformEventsWriteEventTask.java  |   9 -
 .../ignite/platform/PlatformExceptionTask.java  |  78 +++
 .../platform/plugin/PlatformTestPlugin.java     |  27 +
 .../plugin/PlatformTestPluginExtension.java     |  51 ++
 .../plugin/PlatformTestPluginProvider.java      |  97 +++
 .../plugin/PlatformTestPluginTarget.java        |  90 +++
 .../tcp/TcpCommunicationSpiDropNodesTest.java   | 322 +++++++++
 .../TcpCommunicationSpiFaultyClientTest.java    | 265 +++++++
 .../local/GridLocalDeploymentSpiSelfTest.java   |   6 +-
 .../discovery/AbstractDiscoverySelfTest.java    |   7 +-
 ...lientDiscoverySpiFailureTimeoutSelfTest.java |   4 +-
 .../spi/discovery/tcp/TcpDiscoverySelfTest.java | 111 ++-
 .../TcpDiscoverySpiFailureTimeoutSelfTest.java  |  14 +-
 .../tcp/TcpDiscoverySpiStartStopSelfTest.java   |  11 +-
 .../startup/GridRandomCommandLineLoader.java    |   2 +-
 .../testframework/GridSpiTestContext.java       |   5 +-
 .../ignite/testframework/GridTestNode.java      |   1 +
 .../ignite/testframework/IgniteTestSuite.java   |   2 +-
 .../testframework/junits/GridAbstractTest.java  |  15 +-
 .../junits/spi/GridSpiAbstractTest.java         |   9 +-
 .../testsuites/IgniteBinaryBasicTestSuite.java  |   5 +
 .../IgniteCacheDataStructuresSelfTestSuite.java |   2 -
 .../ignite/testsuites/IgniteCacheTestSuite.java |   2 +
 .../testsuites/IgniteCacheTestSuite2.java       |   7 +
 ...essagingConfigVariationFullApiTestSuite.java |   4 +-
 .../IgniteSpiCommunicationSelfTestSuite.java    |   5 +
 .../IgniteSpiDiscoverySelfTestSuite.java        |   2 +-
 .../ignite/thread/IgniteThreadPoolSizeTest.java |   8 -
 .../ignite/util/mbeans/GridMBeanSelfTest.java   |  10 +-
 .../CacheNoValueClassOnServerTestClient.java    |   3 +-
 .../CacheConfigurationP2PTestClient.java        |   3 +-
 .../gce/TcpDiscoveryGoogleStorageIpFinder.java  |   4 +-
 .../io/BytesWritablePartiallyRawComparator.java |  51 ++
 .../hadoop/io/TextPartiallyRawComparator.java   |  68 +-
 .../hadoop/igfs/HadoopIgfsEndpoint.java         |   4 +-
 .../processors/hadoop/impl/HadoopUtils.java     |  66 ++
 .../HadoopBasicFileSystemFactoryDelegate.java   |   2 +-
 .../hadoop/impl/igfs/HadoopIgfsInProc.java      |  40 +-
 .../hadoop/impl/v1/HadoopV1MapTask.java         |  89 ++-
 .../hadoop/impl/v1/HadoopV1ReduceTask.java      |  69 +-
 .../hadoop/impl/v2/HadoopV2Context.java         |  12 +-
 .../hadoop/impl/v2/HadoopV2MapTask.java         |  18 +-
 .../hadoop/impl/v2/HadoopV2ReduceTask.java      |  14 +
 .../hadoop/impl/v2/HadoopV2TaskContext.java     |  12 +-
 .../hadoop/shuffle/HadoopShuffleJob.java        |   7 -
 .../shuffle/direct/HadoopDirectDataInput.java   |   2 +-
 .../taskexecutor/HadoopExecutorService.java     |   6 +-
 .../hadoop/taskexecutor/HadoopRunnableTask.java |  12 +-
 .../child/HadoopChildProcessRunner.java         |  10 +-
 .../impl/HadoopAbstractMapReduceTest.java       |   2 +
 .../hadoop/impl/HadoopErrorSimulator.java       |  12 +-
 .../impl/HadoopMapReduceEmbeddedSelfTest.java   |   6 +-
 .../HadoopIgfs20FileSystemAbstractSelfTest.java |   3 +-
 .../IgniteHadoopFileSystemClientSelfTest.java   |   6 +-
 .../query/h2/DmlStatementsProcessor.java        |  69 +-
 .../query/h2/GridH2ResultSetIterator.java       |   3 +-
 .../processors/query/h2/IgniteH2Indexing.java   |  44 +-
 .../query/h2/dml/UpdatePlanBuilder.java         | 105 ++-
 .../query/h2/opt/GridH2IndexBase.java           |  23 +-
 .../processors/query/h2/sql/DmlAstUtils.java    |   2 +-
 .../query/h2/twostep/GridMapQueryExecutor.java  |   8 +-
 .../h2/twostep/GridReduceQueryExecutor.java     |   9 +-
 .../query/h2/twostep/msg/GridH2Geometry.java    |   2 +-
 .../cache/BinarySerializationQuerySelfTest.java |   2 -
 .../CacheRandomOperationsMultithreadedTest.java |   4 +-
 ...CacheScanPartitionQueryFallbackSelfTest.java |   2 +-
 .../ClientReconnectAfterClusterRestartTest.java |   4 +-
 .../GridCacheQueryIndexDisabledSelfTest.java    |  20 +-
 ...niteCacheAbstractInsertSqlQuerySelfTest.java |   4 +
 .../cache/IgniteCacheAbstractQuerySelfTest.java | 271 +++++++-
 .../IgniteCacheAbstractSqlDmlQuerySelfTest.java |   2 +-
 .../IgniteCacheInsertSqlQuerySelfTest.java      |  22 +
 ...eLockPartitionOnAffinityRunAbstractTest.java |   1 -
 ...PartitionOnAffinityRunAtomicCacheOpTest.java |  11 +-
 ...niteCacheLockPartitionOnAffinityRunTest.java |  50 +-
 ...titionOnAffinityRunWithCollisionSpiTest.java |  10 +-
 .../cache/IgniteCacheMergeSqlQuerySelfTest.java |  25 +-
 .../cache/IgniteCacheOffheapEvictQueryTest.java |   4 +-
 ...niteCacheP2pUnmarshallingQueryErrorTest.java |   4 +-
 .../IgniteCacheUpdateSqlQuerySelfTest.java      |  63 +-
 .../cache/QueryEntityCaseMismatchTest.java      | 107 +++
 ...niteCacheDistributedQueryCancelSelfTest.java |   4 +-
 .../IgniteCachePartitionedQuerySelfTest.java    |  85 +++
 .../IgniteCacheQueryNodeRestartSelfTest2.java   |   4 +-
 .../IgniteSqlEntryCacheModeAgnosticTest.java    | 140 ++++
 .../query/IgniteSqlQueryDedicatedPoolTest.java  | 110 +++
 .../query/IgniteSqlSchemaIndexingTest.java      |  17 +-
 .../query/IgniteSqlSplitterSelfTest.java        |   4 +-
 .../h2/GridIndexingSpiAbstractSelfTest.java     |  38 +-
 .../query/h2/sql/GridQueryParsingTest.java      |   4 -
 .../IgniteCacheQuerySelfTestSuite.java          |   8 +
 .../IgniteCacheQuerySelfTestSuite3.java         |   2 +
 .../apache/ignite/stream/jms11/JmsStreamer.java |   4 +-
 .../ignite/stream/kafka/KafkaStreamer.java      |   6 +-
 .../ignite/stream/kafka/TestKafkaBroker.java    |   2 +-
 .../connect/IgniteSourceConnectorTest.java      |   2 +-
 .../stream/mqtt/IgniteMqttStreamerTest.java     |   4 +-
 .../BundleDelegatingClassLoader.java            |   4 +-
 .../classloaders/ContainerSweepClassLoader.java |   4 +-
 modules/platforms/cpp/binary/Makefile.am        |   3 +
 .../platforms/cpp/binary/include/Makefile.am    |   6 +
 .../cpp/binary/include/ignite/binary/binary.h   |  15 +-
 .../binary/binary_array_identity_resolver.h     |  64 ++
 .../ignite/binary/binary_identity_resolver.h    |  61 ++
 .../include/ignite/binary/binary_object.h       |  92 +++
 .../binary/include/ignite/binary/binary_type.h  |  24 +-
 .../include/ignite/impl/binary/binary_common.h  |   6 +
 .../ignite/impl/binary/binary_object_header.h   | 257 +++++++
 .../ignite/impl/binary/binary_object_impl.h     | 162 +++++
 .../ignite/impl/binary/binary_reader_impl.h     |  29 +-
 .../include/ignite/impl/binary/binary_schema.h  |   2 +-
 .../ignite/impl/binary/binary_type_impl.h       | 149 ++++
 .../ignite/impl/binary/binary_type_snapshot.h   |  18 +-
 .../ignite/impl/binary/binary_type_updater.h    |   2 +-
 .../include/ignite/impl/binary/binary_utils.h   | 236 ++-----
 .../ignite/impl/binary/binary_writer_impl.h     |  11 +-
 .../ignite/impl/interop/interop_output_stream.h |  10 +-
 .../cpp/binary/project/vs/binary.vcxproj        |   9 +
 .../binary/project/vs/binary.vcxproj.filters    |  27 +
 .../binary/binary_array_identity_resolver.cpp   |  42 ++
 .../cpp/binary/src/binary/binary_type.cpp       |   4 +-
 .../src/impl/binary/binary_object_header.cpp    |  63 ++
 .../src/impl/binary/binary_object_impl.cpp      | 107 +++
 .../src/impl/binary/binary_type_manager.cpp     |  14 +-
 .../cpp/binary/src/impl/binary/binary_utils.cpp | 169 +++--
 .../src/impl/binary/binary_writer_impl.cpp      |   4 +-
 .../src/impl/interop/interop_output_stream.cpp  |   5 +
 modules/platforms/cpp/common/Makefile.am        |   6 +-
 .../platforms/cpp/common/include/Makefile.am    |   1 +
 .../common/include/ignite/common/concurrent.h   |  29 +-
 .../include/ignite/common/platform_utils.h      |  79 +++
 .../cpp/common/include/ignite/common/utils.h    | 249 +++++--
 .../cpp/common/include/ignite/ignite_error.h    |   2 +-
 .../include/ignite/common/dynamic_load_os.h     | 131 ++++
 .../os/linux/src/common/dynamic_load_os.cpp     |  90 +++
 .../os/linux/src/common/platform_utils.cpp      |  75 ++
 .../cpp/common/os/linux/src/common/utils.cpp    | 136 ----
 .../win/include/ignite/common/dynamic_load_os.h | 133 ++++
 .../os/win/src/common/dynamic_load_os.cpp       | 115 ++++
 .../common/os/win/src/common/platform_utils.cpp |  80 +++
 .../cpp/common/os/win/src/common/utils.cpp      | 142 ----
 .../cpp/common/project/vs/common.vcxproj        |   6 +-
 .../common/project/vs/common.vcxproj.filters    |  18 +-
 .../platforms/cpp/common/src/common/utils.cpp   | 154 +++++
 .../platforms/cpp/common/src/ignite_error.cpp   |  68 +-
 modules/platforms/cpp/core-test/Makefile.am     |  10 +-
 .../cpp/core-test/config/cache-identity.xml     | 121 ++++
 .../cpp/core-test/config/cache-query.xml        |  10 -
 .../core-test/include/ignite/binary_test_defs.h | 131 +++-
 .../cpp/core-test/include/ignite/complex_type.h | 135 ++++
 .../cpp/core-test/include/ignite/test_type.h    | 186 +++++
 .../cpp/core-test/include/ignite/test_utils.h   |  63 ++
 .../cpp/core-test/project/vs/core-test.vcxproj  |   9 +
 .../project/vs/core-test.vcxproj.filters        |  35 +-
 .../src/binary_identity_resolver_test.cpp       | 522 ++++++++++++++
 .../cpp/core-test/src/binary_object_test.cpp    | 282 ++++++++
 .../src/binary_reader_writer_raw_test.cpp       |  23 +-
 .../cpp/core-test/src/binary_session_test.cpp   |   4 +-
 .../cpp/core-test/src/cache_invoke_test.cpp     | 553 +++++++++++++++
 .../cpp/core-test/src/cache_query_test.cpp      | 149 ++--
 .../platforms/cpp/core-test/src/cache_test.cpp  |  48 +-
 .../cpp/core-test/src/cluster_test.cpp          |  98 +++
 .../cpp/core-test/src/continuous_query_test.cpp |  31 +-
 .../cpp/core-test/src/ignition_test.cpp         |  19 +-
 .../cpp/core-test/src/interop_memory_test.cpp   |   3 +-
 .../cpp/core-test/src/interop_test.cpp          |  42 +-
 .../platforms/cpp/core-test/src/test_utils.cpp  |  79 +++
 .../cpp/core-test/src/transactions_test.cpp     |  23 +-
 modules/platforms/cpp/core/Makefile.am          |   1 +
 modules/platforms/cpp/core/include/Makefile.am  |   8 +
 .../cpp/core/include/ignite/cache/cache.h       | 217 ++++--
 .../ignite/cache/cache_entry_processor.h        | 111 +++
 .../include/ignite/cache/mutable_cache_entry.h  | 176 +++++
 .../include/ignite/cache/query/query_cursor.h   |   2 +-
 .../platforms/cpp/core/include/ignite/ignite.h  |  18 +
 .../cpp/core/include/ignite/ignite_binding.h    | 119 ++++
 .../include/ignite/ignite_binding_context.h     |  88 +++
 .../core/include/ignite/ignite_configuration.h  |   2 -
 .../impl/binary/binary_type_updater_impl.h      |   2 +-
 .../impl/cache/cache_entry_processor_holder.h   | 282 ++++++++
 .../core/include/ignite/impl/cache/cache_impl.h |  71 +-
 .../ignite/impl/cluster/cluster_group_impl.h    |  77 +++
 .../include/ignite/impl/ignite_binding_impl.h   | 121 ++++
 .../include/ignite/impl/ignite_environment.h    |  61 +-
 .../cpp/core/include/ignite/impl/ignite_impl.h  |  50 +-
 .../ignite/impl/interop/interop_target.h        |  37 +-
 .../core/include/ignite/impl/module_manager.h   | 131 ++++
 .../cpp/core/include/ignite/impl/operations.h   |  62 +-
 .../platforms/cpp/core/project/vs/core.vcxproj  |   9 +
 .../cpp/core/project/vs/core.vcxproj.filters    |  30 +
 modules/platforms/cpp/core/src/ignite.cpp       |  12 +-
 modules/platforms/cpp/core/src/ignition.cpp     | 343 +++++----
 .../impl/binary/binary_type_updater_impl.cpp    |   2 +-
 .../cpp/core/src/impl/cache/cache_impl.cpp      |  66 +-
 .../continuous/continuous_query_handle_impl.cpp |   2 +-
 .../core/src/impl/cache/query/query_impl.cpp    |   8 +-
 .../src/impl/cluster/cluster_group_impl.cpp     |  64 ++
 .../cpp/core/src/impl/ignite_environment.cpp    |  92 ++-
 .../platforms/cpp/core/src/impl/ignite_impl.cpp |  36 +-
 .../core/src/impl/interop/interop_target.cpp    |  49 +-
 .../src/impl/transactions/transactions_impl.cpp |  14 +-
 .../cpp/jni/include/ignite/jni/exports.h        |   1 +
 .../platforms/cpp/jni/include/ignite/jni/java.h |   4 +-
 .../cpp/jni/include/ignite/jni/utils.h          |  69 +-
 .../platforms/cpp/jni/os/linux/src/utils.cpp    | 221 +++---
 modules/platforms/cpp/jni/os/win/src/utils.cpp  | 227 +++---
 modules/platforms/cpp/jni/project/vs/module.def |   1 +
 modules/platforms/cpp/jni/src/exports.cpp       |   4 +
 modules/platforms/cpp/jni/src/java.cpp          |  66 +-
 modules/platforms/cpp/odbc-test/Makefile.am     |   1 +
 .../odbc-test/include/sql_test_suite_fixture.h  |  13 +
 .../cpp/odbc-test/include/test_utils.h          |  51 +-
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |   1 +
 .../project/vs/odbc-test.vcxproj.filters        |   3 +
 .../cpp/odbc-test/src/api_robustness_test.cpp   |  37 +-
 .../src/application_data_buffer_test.cpp        |  24 +-
 .../cpp/odbc-test/src/queries_test.cpp          |  71 +-
 .../src/sql_aggregate_functions_test.cpp        |   5 +-
 .../src/sql_date_time_functions_test.cpp        |  26 +-
 .../src/sql_esc_convert_function_test.cpp       | 160 +++++
 .../src/sql_numeric_functions_test.cpp          |   1 +
 .../cpp/odbc-test/src/sql_outer_join_test.cpp   |   1 +
 .../odbc-test/src/sql_string_functions_test.cpp |   1 +
 .../odbc-test/src/sql_test_suite_fixture.cpp    |  88 ++-
 .../cpp/odbc-test/src/sql_types_test.cpp        | 131 +++-
 .../platforms/cpp/odbc-test/src/test_utils.cpp  |  60 +-
 .../odbc/src/app/application_data_buffer.cpp    |  66 +-
 .../platforms/cpp/odbc/src/app/parameter.cpp    |   4 +-
 .../cpp/odbc/src/config/connection_info.cpp     | 260 ++++++-
 modules/platforms/cpp/odbc/src/utility.cpp      |  17 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.AspNet.nuspec                 |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.Core.Tests.csproj             |   9 +
 .../Binary/BinaryBuilderSelfTest.cs             |  20 +-
 .../Binary/BinaryStructureTest.cs               | 122 ++++
 .../Cache/CacheAbstractTest.cs                  |  21 +
 .../Cache/CacheAbstractTransactionalTest.cs     | 339 +++++++++
 .../Cache/CacheConfigurationTest.cs             |  13 +-
 .../Cache/Query/CacheLinqTest.cs                |  96 +++
 .../Cache/Store/CacheParallelLoadStoreTest.cs   |   9 +-
 .../Cache/Store/CacheStoreSessionTest.cs        |  22 +-
 .../Cache/Store/CacheStoreTest.cs               | 363 ++++++----
 .../Cache/Store/CacheTestStore.cs               |  14 +
 .../Cache/Store/NamedNodeCacheStoreTest.cs      |  34 +
 .../Compute/ComputeApiTest.cs                   |  66 +-
 .../Apache.Ignite.Core.Tests/ExceptionsTest.cs  |  66 ++
 .../IgniteConfigurationSerializerTest.cs        |  25 +-
 .../IgniteConfigurationTest.cs                  |  13 +-
 .../Plugin/Cache/CachePlugin.cs                 | 127 ++++
 .../Plugin/Cache/CachePluginConfiguration.cs    |  40 ++
 .../Plugin/Cache/CachePluginTest.cs             | 215 ++++++
 .../Plugin/PluginTest.cs                        | 254 +++++++
 .../Plugin/TestIgnitePlugin.cs                  |  39 ++
 .../Plugin/TestIgnitePluginConfiguration.cs     |  33 +
 .../Plugin/TestIgnitePluginProvider.cs          | 132 ++++
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.Core.Schema.nuspec            |   2 +-
 .../Apache.Ignite.Core.csproj                   |  20 +
 .../Apache.Ignite.Core.nuspec                   |   2 +-
 .../Cache/Configuration/CacheConfiguration.cs   |  34 +
 .../Cache/Configuration/QueryEntity.cs          |   2 +-
 .../dotnet/Apache.Ignite.Core/Cache/ICache.cs   |   4 +-
 .../Apache.Ignite.Core/Common/JavaException.cs  |  62 +-
 .../Communication/Tcp/TcpCommunicationSpi.cs    |   2 +-
 .../Discovery/Tcp/TcpDiscoverySpi.cs            |   2 +-
 .../dotnet/Apache.Ignite.Core/IIgnite.cs        |  10 +
 .../Apache.Ignite.Core/IgniteConfiguration.cs   |  26 +-
 .../IgniteConfigurationSection.xsd              |  42 ++
 .../Impl/Binary/BinaryObjectBuilder.cs          |   2 +-
 .../Impl/Binary/BinaryReader.cs                 | 137 ++--
 .../Impl/Binary/BinarySystemHandlers.cs         |  14 +-
 .../Impl/Binary/BinaryUtils.cs                  |  44 +-
 .../Impl/Binary/BinaryWriter.cs                 |   6 +-
 .../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs  | 104 ++-
 .../Common/IgniteConfigurationXmlSerializer.cs  |   3 +
 .../Apache.Ignite.Core/Impl/ExceptionUtils.cs   |  10 +-
 .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs    |  26 +-
 .../Apache.Ignite.Core/Impl/IgniteProxy.cs      |   6 +
 .../Apache.Ignite.Core/Impl/PlatformTarget.cs   |  70 +-
 .../Impl/Plugin/Cache/CachePluginContext.cs     |  82 +++
 .../Impl/Plugin/Cache/CachePluginProcessor.cs   |  77 +++
 .../Plugin/Cache/CachePluginProviderProxy.cs    |  75 ++
 .../Plugin/Cache/ICachePluginProviderProxy.cs   |  52 ++
 .../Impl/Plugin/IPluginProviderProxy.cs         |  74 ++
 .../Impl/Plugin/PluginContext.cs                |  72 ++
 .../Impl/Plugin/PluginProcessor.cs              | 235 +++++++
 .../Impl/Plugin/PluginProviderProxy.cs          |  90 +++
 .../Transactions/CacheTransactionManager.cs     | 161 +++++
 .../Impl/Transactions/Transaction.cs            |   8 +
 .../Impl/Transactions/TransactionImpl.cs        |  13 +
 .../Impl/Transactions/TransactionsImpl.cs       |  10 +
 .../Impl/Unmanaged/IgniteJniNativeMethods.cs    |   3 +
 .../Impl/Unmanaged/UnmanagedCallbackOp.cs       |   8 +-
 .../Impl/Unmanaged/UnmanagedCallbacks.cs        |  88 ++-
 .../Impl/Unmanaged/UnmanagedUtils.cs            |   7 +
 .../Interop/IPlatformTarget.cs                  |  91 +++
 .../Cache/CachePluginProviderTypeAttribute.cs   |  52 ++
 .../Plugin/Cache/ICachePluginConfiguration.cs   |  50 ++
 .../Plugin/Cache/ICachePluginContext.cs         |  47 ++
 .../Plugin/Cache/ICachePluginProvider.cs        |  52 ++
 .../Plugin/IPluginConfiguration.cs              |  48 ++
 .../Apache.Ignite.Core/Plugin/IPluginContext.cs |  52 ++
 .../Plugin/IPluginProvider.cs                   |  69 ++
 .../Plugin/PluginNotFoundException.cs           |  65 ++
 .../Plugin/PluginProviderTypeAttribute.cs       |  52 ++
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.EntityFramework.nuspec        |   2 +-
 .../Apache.Ignite.Linq.nuspec                   |   2 +-
 .../Impl/CacheQueryExpressionVisitor.cs         | 127 +++-
 .../Impl/CacheQueryModelVisitor.cs              |   3 +
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.Log4Net.nuspec                |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite.NLog.nuspec                   |   2 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 .../Apache.Ignite/Properties/AssemblyInfo.cs    |   2 +-
 .../Apache.Ignite.Examples.csproj               |   2 +
 .../Datagrid/QueryDmlExample.cs                 | 162 +++++
 .../Datagrid/TransactionExample.cs              |  75 +-
 .../Properties/AssemblyInfo.cs                  |   2 +-
 modules/scalar-2.10/pom.xml                     |   2 +-
 modules/scalar/pom.xml                          |   2 +-
 .../spark/JavaStandaloneIgniteRDDSelfTest.java  |   3 +-
 .../util/spring/IgniteSpringHelperImpl.java     |   8 +-
 .../src/test/config/jdbc-pojo-store-builtin.xml |   8 +
 .../src/test/config/jdbc-pojo-store-obj.xml     |   8 +
 .../ignite/internal/GridFactorySelfTest.java    |   2 +-
 .../internal/IgniteDynamicCacheConfigTest.java  |   4 +-
 .../GridSpringTransactionManagerSelfTest.java   |   2 +-
 .../ignite/tools/classgen/ClassesGenerator.java |   2 +-
 .../twitter/IgniteTwitterStreamerTest.java      |   4 +-
 .../GridUriDeploymentFileProcessorSelfTest.java |   3 +-
 .../scala/org/apache/ignite/visor/visor.scala   | 115 ++--
 .../commands/mem/VisorMemoryCommandSpec.scala   |  33 +
 modules/web-console/backend/app/agent.js        |  56 +-
 modules/web-console/backend/app/browser.js      |  26 +
 modules/web-console/backend/app/mongo.js        |  49 +-
 modules/web-console/backend/app/routes.js       |   5 +-
 .../web-console/backend/routes/activities.js    |  52 ++
 modules/web-console/backend/routes/admin.js     |   2 +-
 modules/web-console/backend/routes/agent.js     |  10 +-
 modules/web-console/backend/routes/public.js    |   1 -
 .../web-console/backend/services/activities.js  | 136 ++++
 modules/web-console/backend/services/users.js   |  13 +-
 modules/web-console/frontend/app/app.config.js  |   9 +
 modules/web-console/frontend/app/app.js         |  29 +-
 .../activities-user-dialog.controller.js        |  60 ++
 .../activities-user-dialog.jade                 |  36 +
 .../components/activities-user-dialog/index.js  |  36 +
 .../form-field-datepicker.jade                  |  55 ++
 .../form-field-datepicker.scss                  |  20 +
 .../list-of-registered-users/index.js           |  28 +
 .../list-of-registered-users.categories.js      |  30 +
 .../list-of-registered-users.column-defs.js     |  80 +++
 .../list-of-registered-users.controller.js      | 207 ++++++
 .../list-of-registered-users.jade               |  54 ++
 .../ui-grid-header/ui-grid-header.jade          |  27 +
 .../ui-grid-header/ui-grid-header.scss          |  84 +++
 .../ui-grid-settings/ui-grid-settings.jade      |  33 +
 .../ui-grid-settings/ui-grid-settings.scss      |  70 ++
 .../app/core/activities/Activities.data.js      |  39 ++
 .../frontend/app/core/admin/Admin.data.js       |  77 +++
 modules/web-console/frontend/app/core/index.js  |  25 +
 modules/web-console/frontend/app/data/i18n.js   |  38 +
 .../ui-grid-settings/ui-grid-settings.jade      |  33 -
 .../ui-grid-settings/ui-grid-settings.scss      |  38 -
 .../app/filters/uiGridSubcategories.filter.js   |  24 +
 .../frontend/app/modules/Demo/Demo.module.js    | 166 -----
 .../app/modules/branding/branding.provider.js   |   2 +-
 .../generator/ConfigurationGenerator.js         |   9 +-
 .../frontend/app/modules/demo/Demo.module.js    | 172 +++++
 .../frontend/app/modules/sql/sql.controller.js  |  14 +-
 .../frontend/app/modules/sql/sql.module.js      |   2 +-
 .../frontend/app/modules/states/admin.state.js  |   2 +-
 .../configuration/summary/summary.controller.js |   6 +-
 .../app/modules/user/AclRoute.provider.js       |  31 +-
 .../frontend/app/modules/user/Auth.service.js   |   2 +-
 .../frontend/app/modules/user/permissions.js    |   2 +-
 .../frontend/app/modules/user/user.module.js    |   6 +-
 modules/web-console/frontend/app/vendor.js      |   1 +
 .../frontend/controllers/admin-controller.js    | 234 -------
 .../frontend/controllers/domains-controller.js  |  12 +-
 modules/web-console/frontend/package.json       |   3 +-
 .../stylesheets/_font-awesome-custom.scss       |  28 +
 .../frontend/public/stylesheets/style.scss      |  39 +-
 .../frontend/public/stylesheets/variables.scss  |   1 +
 .../frontend/views/settings/admin.jade          |  32 +-
 modules/web-console/frontend/views/sql/sql.jade |   4 +-
 .../views/templates/agent-download.jade         |   2 +-
 modules/web-console/web-agent/README.txt        |   2 +-
 .../ignite/console/agent/AgentLauncher.java     | 259 ++++---
 .../apache/ignite/console/agent/AgentUtils.java |  80 +++
 .../console/agent/handlers/AbstractHandler.java | 110 ---
 .../agent/handlers/AbstractListener.java        | 104 +++
 .../console/agent/handlers/DatabaseHandler.java | 298 --------
 .../agent/handlers/DatabaseListener.java        | 316 +++++++++
 .../console/agent/handlers/RestHandler.java     | 276 --------
 .../console/agent/handlers/RestListener.java    | 280 ++++++++
 .../ignite/console/demo/AgentClusterDemo.java   | 472 +------------
 .../ignite/console/demo/AgentDemoUtils.java     |  79 +++
 .../demo/service/DemoCachesLoadService.java     | 456 ++++++++++++
 .../service/DemoRandomCacheLoadService.java     | 120 ++++
 .../service/DemoServiceClusterSingleton.java    |  41 ++
 .../demo/service/DemoServiceKeyAffinity.java    |  41 ++
 .../service/DemoServiceMultipleInstances.java   |  41 ++
 .../demo/service/DemoServiceNodeSingleton.java  |  41 ++
 .../ignite/cache/websession/WebSessionV2.java   |   2 +-
 .../internal/websession/WebSessionSelfTest.java |   6 +-
 modules/yardstick/DEVNOTES-standalone.txt       |  15 +
 modules/yardstick/DEVNOTES.txt                  |  20 +
 modules/yardstick/README.txt                    | 117 +++-
 .../config/benchmark-sample.properties          |  62 ++
 modules/yardstick/pom-standalone.xml            | 209 ++++++
 modules/yardstick/pom.xml                       |  14 +-
 .../cache/IgnitePutRemoveBenchmark.java         |  42 ++
 .../cache/IgnitePutRemoveTxBenchmark.java       |  30 +
 .../cache/IgnitePutValue8Benchmark.java         |  42 ++
 .../apache/ignite/yarn/ApplicationMaster.java   |   4 +-
 .../org/apache/ignite/yarn/IgniteProvider.java  |   4 +-
 .../tcp/ipfinder/zk/ZookeeperIpFinderTest.java  |   2 +-
 parent/pom.xml                                  |   2 +-
 pom.xml                                         |  96 ++-
 802 files changed, 30200 insertions(+), 7567 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcMetadataSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index b229729,3f8b89f..ee665de
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@@ -279,13 -282,9 +282,16 @@@ public final class IgniteSystemProperti
      /** Maximum size for atomic cache queue delete history (default is 200 000 entries per partition). */
      public static final String IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE = "IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE";
  
+     /** Ttl of removed cache entries (ms). */
+     public static final String IGNITE_CACHE_REMOVED_ENTRIES_TTL = "IGNITE_CACHE_REMOVED_ENTRIES_TTL";
+ 
 +    /** Maximum amount of concurrent updates per system thread in atomic caches in case of PRIMARY_SYNC or FULL_ASYNC
 +     * write synchronization mode. If this limit is exceeded then update will be performed with FULL_SYNC
 +     * synchronization mode. If value is {@code 0} then limit is unbounded.
 +     */
 +    public static final String IGNITE_ATOMIC_CACHE_MAX_CONCURRENT_DHT_UPDATES =
 +        "IGNITE_ATOMIC_CACHE_MAX_CONCURRENT_DHT_UPDATES";
 +
      /**
       * Comma separated list of addresses in format "10.100.22.100:45000,10.100.22.101:45000".
       * Makes sense only for {@link org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder}.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
index 7bbe9e2,560d7f6..c91daae
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
@@@ -49,7 -49,7 +52,10 @@@ public interface GridComponent 
          CLUSTER_PROC,
  
          /** */
-         DISCOVERY_PROC
++        DISCOVERY_PROC,
++
++        /** */
+         MARSHALLER_PROC
      }
  
      /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
index 3c5b158,937a6f9..074496c
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
@@@ -49,7 -49,9 +49,8 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.igfs.IgfsProcessorAdapter;
  import org.apache.ignite.internal.processors.job.GridJobProcessor;
  import org.apache.ignite.internal.processors.jobmetrics.GridJobMetricsProcessor;
+ import org.apache.ignite.internal.processors.marshaller.GridMarshallerMappingProcessor;
  import org.apache.ignite.internal.processors.odbc.OdbcProcessor;
 -import org.apache.ignite.internal.processors.offheap.GridOffHeapProcessor;
  import org.apache.ignite.internal.processors.platform.PlatformProcessor;
  import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
  import org.apache.ignite.internal.processors.pool.PoolProcessor;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
index fae9d9a,d80d53c..29b6ff9
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
@@@ -65,9 -65,12 +65,11 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.igfs.IgfsProcessorAdapter;
  import org.apache.ignite.internal.processors.job.GridJobProcessor;
  import org.apache.ignite.internal.processors.jobmetrics.GridJobMetricsProcessor;
+ import org.apache.ignite.internal.processors.marshaller.GridMarshallerMappingProcessor;
  import org.apache.ignite.internal.processors.nodevalidation.DiscoveryNodeValidationProcessor;
  import org.apache.ignite.internal.processors.odbc.OdbcProcessor;
 -import org.apache.ignite.internal.processors.offheap.GridOffHeapProcessor;
  import org.apache.ignite.internal.processors.platform.PlatformProcessor;
+ import org.apache.ignite.internal.processors.platform.plugin.PlatformPluginProcessor;
  import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
  import org.apache.ignite.internal.processors.pool.PoolProcessor;
  import org.apache.ignite.internal.processors.port.GridPortProcessor;

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/GridPluginComponent.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/GridTopic.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index c71ab2c,750c316..ec17bb9
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@@ -122,8 -122,10 +123,9 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.nodevalidation.DiscoveryNodeValidationProcessor;
  import org.apache.ignite.internal.processors.nodevalidation.OsDiscoveryNodeValidationProcessor;
  import org.apache.ignite.internal.processors.odbc.OdbcProcessor;
 -import org.apache.ignite.internal.processors.offheap.GridOffHeapProcessor;
  import org.apache.ignite.internal.processors.platform.PlatformNoopProcessor;
  import org.apache.ignite.internal.processors.platform.PlatformProcessor;
+ import org.apache.ignite.internal.processors.platform.plugin.PlatformPluginProcessor;
  import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
  import org.apache.ignite.internal.processors.pool.PoolProcessor;
  import org.apache.ignite.internal.processors.port.GridPortProcessor;
@@@ -881,44 -896,40 +892,49 @@@ public class IgniteKernal implements Ig
  
              // Start processors before discovery manager, so they will
              // be able to start receiving messages once discovery completes.
 -            startProcessor(createComponent(DiscoveryNodeValidationProcessor.class, ctx));
 -            startProcessor(new GridClockSyncProcessor(ctx));
 -            startProcessor(new GridAffinityProcessor(ctx));
 -            startProcessor(createComponent(GridSegmentationProcessor.class, ctx));
 -            startProcessor(createComponent(IgniteCacheObjectProcessor.class, ctx));
 -            startProcessor(new GridCacheProcessor(ctx));
 -            startProcessor(new GridQueryProcessor(ctx));
 -            startProcessor(new OdbcProcessor(ctx));
 -            startProcessor(new GridServiceProcessor(ctx));
 -            startProcessor(new GridTaskSessionProcessor(ctx));
 -            startProcessor(new GridJobProcessor(ctx));
 -            startProcessor(new GridTaskProcessor(ctx));
 -            startProcessor((GridProcessor)SCHEDULE.createOptional(ctx));
 -            startProcessor(new GridRestProcessor(ctx));
 -            startProcessor(new DataStreamProcessor(ctx));
 -            startProcessor((GridProcessor)IGFS.create(ctx, F.isEmpty(cfg.getFileSystemConfiguration())));
 -            startProcessor(new GridContinuousProcessor(ctx));
 -            startProcessor(createHadoopComponent());
 -            startProcessor(new DataStructuresProcessor(ctx));
 -            startProcessor(createComponent(PlatformProcessor.class, ctx));
 -            startProcessor(new GridMarshallerMappingProcessor(ctx));
 +            try {
 +                startProcessor(createComponent(DiscoveryNodeValidationProcessor.class, ctx));
 +                startProcessor(new GridClockSyncProcessor(ctx));
 +                startProcessor(new GridAffinityProcessor(ctx));
 +                startProcessor(createComponent(GridSegmentationProcessor.class, ctx));
 +                startProcessor(createComponent(IgniteCacheObjectProcessor.class, ctx));
 +                startProcessor(new GridCacheProcessor(ctx));
 +                startProcessor(new GridClusterStateProcessor(ctx));
 +                startProcessor(new GridQueryProcessor(ctx));
 +                startProcessor(new OdbcProcessor(ctx));
 +                startProcessor(new GridServiceProcessor(ctx));
 +                startProcessor(new GridTaskSessionProcessor(ctx));
 +                startProcessor(new GridJobProcessor(ctx));
 +                startProcessor(new GridTaskProcessor(ctx));
 +                startProcessor((GridProcessor)SCHEDULE.createOptional(ctx));
 +                startProcessor(new GridRestProcessor(ctx));
 +                startProcessor(new DataStreamProcessor(ctx));
 +                startProcessor((GridProcessor)IGFS.create(ctx, F.isEmpty(cfg.getFileSystemConfiguration())));
 +                startProcessor(new GridContinuousProcessor(ctx));
 +                startProcessor(createHadoopComponent());
 +                startProcessor(new DataStructuresProcessor(ctx));
 +                startProcessor(createComponent(PlatformProcessor.class, ctx));
++                startProcessor(new GridMarshallerMappingProcessor(ctx));
 +
 +                // Start plugins.
 +                for (PluginProvider provider : ctx.plugins().allProviders()) {
 +                    ctx.add(new GridPluginComponent(provider));
 +
 +                    provider.start(ctx.plugins().pluginContextForProvider(provider));
 +                }
  
 -            // Start plugins.
 -            for (PluginProvider provider : ctx.plugins().allProviders()) {
 -                ctx.add(new GridPluginComponent(provider));
++                // Start platform plugins.
++                if (ctx.config().getPlatformConfiguration() != null)
++                    startProcessor(new PlatformPluginProcessor(ctx));
+ 
 -                provider.start(ctx.plugins().pluginContextForProvider(provider));
 +                fillNodeAttributes(clusterProc.updateNotifierEnabled());
              }
 +            catch (Throwable e) {
 +                // Stop discovery spi to close tcp socket.
 +                ctx.discovery().stop(true);
  
 -            // Start platform plugins.
 -            if (ctx.config().getPlatformConfiguration() != null)
 -                startProcessor(new PlatformPluginProcessor(ctx));
 -
 -            fillNodeAttributes(clusterProc.updateNotifierEnabled());
 +                throw e;
 +            }
  
              gw.writeLock();
  
@@@ -938,15 -949,17 +954,21 @@@
              // Suggest configuration optimizations.
              suggestOptimizations(cfg);
  
+             // Suggest JVM optimizations.
+             ctx.performance().addAll(JvmConfigurationSuggestions.getSuggestions());
+ 
+             // Suggest Operation System optimizations.
+             ctx.performance().addAll(OsConfigurationSuggestions.getSuggestions());
+ 
              // Notify discovery manager the first to make sure that topology is discovered.
 -            ctx.discovery().onKernalStart();
 +            ctx.discovery().onKernalStart(activeOnStart);
  
              // Notify IO manager the second so further components can send and receive messages.
 -            ctx.io().onKernalStart();
 +            ctx.io().onKernalStart(activeOnStart);
 +
 +            // Start plugins.
 +            for (PluginProvider provider : ctx.plugins().allProviders())
 +                provider.onIgniteStart();
  
              // Callbacks.
              for (GridComponent comp : ctx) {
@@@ -1983,11 -1988,9 +2004,9 @@@
  
              List<GridComponent> comps = ctx.components();
  
-             ctx.marshallerContext().onKernalStop();
- 
              // Callback component in reverse order while kernal is still functional
              // if called in the same thread, at least.
 -            for (ListIterator<GridComponent> it = comps.listIterator(comps.size()); it.hasPrevious();) {
 +            for (ListIterator<GridComponent> it = comps.listIterator(comps.size()); it.hasPrevious(); ) {
                  GridComponent comp = it.previous();
  
                  try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/GridProcessorAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEvictableEntryImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
index 60d42ea,753cca1..1613af7
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
@@@ -215,9 -222,9 +215,9 @@@ public class CacheMetricsImpl implement
      /** {@inheritDoc} */
      @Override public long getOffHeapPrimaryEntriesCount() {
          try {
 -            return cctx.swap().offheapEntriesCount(true, false, cctx.affinity().affinityTopologyVersion());
 +            return cctx.offheap().entriesCount(true, false, cctx.affinity().affinityTopologyVersion());
          }
-         catch (IgniteCheckedException e) {
+         catch (IgniteCheckedException ignored) {
              return 0;
          }
      }
@@@ -225,9 -232,9 +225,9 @@@
      /** {@inheritDoc} */
      @Override public long getOffHeapBackupEntriesCount() {
          try {
 -            return cctx.swap().offheapEntriesCount(false, true, cctx.affinity().affinityTopologyVersion());
 +            return cctx.offheap().entriesCount(false, true, cctx.affinity().affinityTopologyVersion());
          }
-         catch (IgniteCheckedException e) {
+         catch (IgniteCheckedException ignored) {
              return 0;
          }
      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 1937a5f,4507c53..d094366
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@@ -506,9 -501,8 +506,8 @@@ public abstract class GridCacheAdapter<
      @Override public final GridCacheProxyImpl<K, V> withExpiryPolicy(ExpiryPolicy plc) {
          assert !CU.isUtilityCache(ctx.name());
          assert !CU.isAtomicsCache(ctx.name());
-         assert !CU.isMarshallerCache(ctx.name());
  
 -        CacheOperationContext opCtx = new CacheOperationContext(false, null, false, plc, false, null);
 +        CacheOperationContext opCtx = new CacheOperationContext(false, null, false, plc, false, null, false);
  
          return new GridCacheProxyImpl<>(ctx, this, opCtx);
      }
@@@ -650,10 -646,10 +651,9 @@@
              /*subj id*/null,
              /*task name*/null,
              /*deserialize binary*/false,
-             /*skip values*/
+             /*skip values*/true,
              /*can remap*/true,
-             true,
-             false);
 -            false
 -        );
++            /*needVer*/false);
      }
  
      /** {@inheritDoc} */
@@@ -679,11 -673,10 +679,10 @@@
              /*subj id*/null,
              /*task name*/null,
              /*deserialize binary*/false,
 +            opCtx != null && opCtx.recovery(),
-             /*skip values*/
+             /*skip values*/true,
              /*can remap*/true,
-             true,
-             false).chain(new CX1<IgniteInternalFuture<Map<K, V>>, Boolean>() {
 -            false
 -        ).chain(new CX1<IgniteInternalFuture<Map<K, V>>, Boolean>() {
++            /*need ver*/false).chain(new CX1<IgniteInternalFuture<Map<K, V>>, Boolean>() {
              @Override public Boolean applyx(IgniteInternalFuture<Map<K, V>> fut) throws IgniteCheckedException {
                  Map<K, V> kvMap = fut.get();
  
@@@ -768,108 -764,92 +767,108 @@@
  
          PeekModes modes = parsePeekModes(peekModes, false);
  
 -        try {
 -            KeyCacheObject cacheKey = ctx.toCacheKeyObject(key);
 +        KeyCacheObject cacheKey = ctx.toCacheKeyObject(key);
 +
 +        CacheObject cacheVal = null;
 +
 +        if (!ctx.isLocal()) {
 +            AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
  
 -            CacheObject cacheVal = null;
 +            int part = ctx.affinity().partition(cacheKey);
  
 -            if (!ctx.isLocal()) {
 -                AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
 +            boolean nearKey;
  
 -                int part = ctx.affinity().partition(cacheKey);
 +            if (!(modes.near && modes.primary && modes.backup)) {
-                 boolean keyPrimary = ctx.affinity().primary(ctx.localNode(), part, topVer);
++                boolean keyPrimary = ctx.affinity().primaryByPartition(ctx.localNode(), part, topVer);
  
 -                boolean nearKey;
 +                if (keyPrimary) {
 +                    if (!modes.primary)
 +                        return null;
  
 -                if (!(modes.near && modes.primary && modes.backup)) {
 -                    boolean keyPrimary = ctx.affinity().primaryByPartition(ctx.localNode(), part, topVer);
 +                    nearKey = false;
 +                }
 +                else {
-                     boolean keyBackup = ctx.affinity().belongs(ctx.localNode(), part, topVer);
++                    boolean keyBackup = ctx.affinity().partitionBelongs(ctx.localNode(), part, topVer);
  
 -                    if (keyPrimary) {
 -                        if (!modes.primary)
 +                    if (keyBackup) {
 +                        if (!modes.backup)
                              return null;
  
                          nearKey = false;
                      }
                      else {
 -                        boolean keyBackup = ctx.affinity().partitionBelongs(ctx.localNode(), part, topVer);
 -
 -                        if (keyBackup) {
 -                            if (!modes.backup)
 -                                return null;
 -
 -                            nearKey = false;
 -                        }
 -                        else {
 -                            if (!modes.near)
 -                                return null;
 +                        if (!modes.near)
 +                            return null;
  
 -                            nearKey = true;
 +                        nearKey = true;
  
 -                            // Swap and offheap are disabled for near cache.
 -                            modes.offheap = false;
 -                            modes.swap = false;
 -                        }
 -                    }
 -                }
 -                else {
 -                    nearKey = !ctx.affinity().partitionBelongs(ctx.localNode(), part, topVer);
 -
 -                    if (nearKey) {
                          // Swap and offheap are disabled for near cache.
                          modes.offheap = false;
 -                        modes.swap = false;
                      }
                  }
 +            }
 +            else {
-                 nearKey = !ctx.affinity().belongs(ctx.localNode(), part, topVer);
++                nearKey = !ctx.affinity().partitionBelongs(ctx.localNode(), part, topVer);
  
 -                if (nearKey && !ctx.isNear())
 -                    return null;
 +                if (nearKey) {
 +                    // Swap and offheap are disabled for near cache.
 +                    modes.offheap = false;
 +                }
 +            }
  
 -                if (modes.heap) {
 -                    GridCacheEntryEx e = nearKey ? peekEx(cacheKey) :
 -                        (ctx.isNear() ? ctx.near().dht().peekEx(cacheKey) : peekEx(cacheKey));
 +            if (nearKey && !ctx.isNear())
 +                return null;
  
 -                    if (e != null) {
 -                        cacheVal = e.peek(modes.heap, modes.offheap, modes.swap, topVer, plc);
 +            GridCacheEntryEx e;
 +            GridCacheContext ctx0;
  
 -                        modes.offheap = false;
 -                        modes.swap = false;
 -                    }
 +            while (true) {
 +                if (nearKey) {
 +                    ctx0 = context();
 +                    e = peekEx(key);
 +                }
 +                else {
 +                    ctx0 = ctx.isNear() ? ctx.near().dht().context() : ctx;
 +                    e = modes.offheap ? ctx0.cache().entryEx(key) : ctx0.cache().peekEx(key);
                  }
  
 -                if (modes.offheap || modes.swap) {
 -                    GridCacheSwapManager swapMgr = ctx.isNear() ? ctx.near().dht().context().swap() : ctx.swap();
 +                if (e != null) {
 +                    try {
 +                        cacheVal = e.peek(modes.heap, modes.offheap, topVer, plc);
 +                    }
 +                    catch (GridCacheEntryRemovedException ignore) {
 +                        if (log.isDebugEnabled())
 +                            log.debug("Got removed entry during 'peek': " + key);
  
 -                    cacheVal = swapMgr.readValue(cacheKey, modes.offheap, modes.swap);
 +                        continue;
 +                    }
 +                    finally {
 +                        ctx0.evicts().touch(e, null);
 +                    }
                  }
 +
 +                break;
              }
 -            else
 -                cacheVal = localCachePeek0(cacheKey, modes.heap, modes.offheap, modes.swap, plc);
 +        }
 +        else {
 +            while (true) {
 +                try {
 +                    cacheVal = localCachePeek0(cacheKey, modes.heap, modes.offheap, plc);
  
 -            Object val = ctx.unwrapBinaryIfNeeded(cacheVal, ctx.keepBinary(), false);
 +                    break;
 +                }
 +                catch (GridCacheEntryRemovedException ignore) {
 +                    if (log.isDebugEnabled())
 +                        log.debug("Got removed entry during 'peek': " + key);
  
 -            return (V)val;
 +                    // continue
 +                }
 +            }
          }
 -        catch (GridCacheEntryRemovedException ignore) {
 -            if (log.isDebugEnabled())
 -                log.debug("Got removed entry during 'peek': " + key);
  
 -            return null;
 -        }
 +        Object val = ctx.unwrapBinaryIfNeeded(cacheVal, ctx.keepBinary(), false);
 +
 +        return (V)val;
      }
  
      /**
@@@ -1338,11 -1307,10 +1337,10 @@@
              /*subject id*/null,
              taskName,
              /*deserialize cache objects*/true,
 +            opCtx != null && opCtx.recovery(),
-             /*skip values*/
-             /*can remap*/false,
-             true,
+             /*skip values*/false,
+             /*can remap*/true,
 -            false
 -        ).get().get(key);
 +            false).get().get(key);
      }
  
      /** {@inheritDoc} */
@@@ -1357,11 -1323,11 +1355,11 @@@
              /*skip tx*/false,
              null,
              taskName,
--            true,
 -            false,
++            /*deserialize cache objects*/true,
 +            opCtx != null && opCtx.recovery(),
-             /*can remap*/false,
-             true,
-             false).chain(new CX1<IgniteInternalFuture<Map<K, V>>, V>() {
++            /*skip values*/false,
+             /*can remap*/true,
 -            false
 -        ).chain(new CX1<IgniteInternalFuture<Map<K, V>>, V>() {
++            /*need ver*/false).chain(new CX1<IgniteInternalFuture<Map<K, V>>, V>() {
              @Override public V applyx(IgniteInternalFuture<Map<K, V>> e) throws IgniteCheckedException {
                  return e.get().get(key);
              }
@@@ -1381,11 -1345,10 +1379,10 @@@
              /*subject id*/null,
              taskName,
              /*deserialize cache objects*/true,
 +            opCtx != null && opCtx.recovery(),
-             /*skip values*/
+             /*skip values*/false,
              /*can remap*/false,
-             false,
-             false).get().get(key);
 -            false
 -        ).get().get(key);
++            /*need ver*/false).get().get(key);
      }
  
      /** {@inheritDoc} */
@@@ -1404,11 -1365,10 +1401,11 @@@
              /*skip tx*/true,
              null,
              taskName,
 -            !ctx.keepBinary(),
 +            !(opCtx != null && opCtx.isKeepBinary()),
 +            opCtx != null && opCtx.recovery(),
-             /*skip values*/
-             /*can remap*/false,
-             true, false);
+             /*skip values*/false,
+             /*can remap*/true,
+             false);
      }
  
      /** {@inheritDoc} */
@@@ -1957,23 -1888,14 +1960,23 @@@
          }
  
          if (tx == null || tx.implicit()) {
-             Map<KeyCacheObject, GridCacheVersion> misses = null;
 -            try {
 -                final AffinityTopologyVersion topVer = tx == null ?
 -                    (canRemap ?
 -                        ctx.affinity().affinityTopologyVersion() : ctx.shared().exchange().readyAffinityVersion()) :
 -                    tx.topologyVersion();
++            Map<KeyCacheObject, EntryGetResult> misses = null;
 +
 +            final AffinityTopologyVersion topVer = tx == null ?
 +                (canRemap ?
 +                    ctx.affinity().affinityTopologyVersion() : ctx.shared().exchange().readyAffinityVersion()) :
 +                tx.topologyVersion();
  
 +            try {
                  int keysSize = keys.size();
  
 +                GridDhtTopologyFuture topFut = ctx.shared().exchange().lastFinishedFuture();
 +
 +                Throwable ex = topFut != null ? topFut.validateCache(ctx, recovery, /*read*/true, null, keys) : null;
 +
 +                if (ex != null)
 +                    return new GridFinishedFuture<>(ex);
 +
                  final Map<K1, V1> map = keysSize == 1 ?
                      (Map<K1, V1>)new IgniteBiTuple<>() :
                      U.<K1, V1>newHashMap(keysSize);
@@@ -1992,33 -1918,55 +1995,52 @@@
                          }
  
                          try {
-                             T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
-                                 null,
-                                 null,
-                                 /*update-metrics*/!skipVals,
-                                 /*event*/!skipVals,
-                                 subjId,
-                                 null,
-                                 taskName,
-                                 expiry,
-                                 !deserializeBinary);
- 
-                             if (res == null) {
-                                 if (storeEnabled) {
-                                     GridCacheVersion ver = entry.version();
+                             EntryGetResult res;
+ 
+                             boolean evt = !skipVals;
+                             boolean updateMetrics = !skipVals;
+ 
+                             if (storeEnabled) {
 -                                res = entry.innerGetAndReserveForLoad(ctx.isSwapOrOffheapEnabled(),
 -                                    updateMetrics,
++                                res = entry.innerGetAndReserveForLoad(updateMetrics,
+                                     evt,
+                                     subjId,
+                                     taskName,
+                                     expiry,
+                                     !deserializeBinary,
+                                     readerArgs);
  
+                                 assert res != null;
+ 
+                                 if (res.value() == null) {
                                      if (misses == null)
                                          misses = new HashMap<>();
  
-                                     misses.put(key, ver);
+                                     misses.put(key, res);
+ 
+                                     res = null;
                                  }
-                                 else
-                                     ctx.evicts().touch(entry, topVer);
                              }
                              else {
+                                 res = entry.innerGetVersioned(
+                                     null,
+                                     null,
 -                                    ctx.isSwapOrOffheapEnabled(),
 -                                    /*unmarshal*/true,
+                                     updateMetrics,
+                                     evt,
+                                     subjId,
+                                     null,
+                                     taskName,
+                                     expiry,
+                                     !deserializeBinary,
+                                     readerArgs);
+ 
+                                 if (res == null)
+                                     ctx.evicts().touch(entry, topVer);
+                             }
+ 
+                             if (res != null) {
                                  ctx.addResult(map,
                                      key,
-                                     res.get1(),
+                                     res.value(),
                                      skipVals,
                                      keepCacheObjects,
                                      deserializeBinary,

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
index 26e4ed3,f26288f..5dffe6e
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
@@@ -305,9 -324,11 +306,9 @@@ public interface GridCacheEntryEx 
       * @throws IgniteCheckedException If loading value failed.
       * @throws GridCacheEntryRemovedException If entry was removed.
       */
-     @Nullable public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+     public EntryGetResult innerGetVersioned(
          @Nullable GridCacheVersion ver,
          IgniteInternalTx tx,
 -        boolean readSwap,
 -        boolean unmarshal,
          boolean updateMetrics,
          boolean evt,
          UUID subjId,
@@@ -318,6 -340,34 +320,32 @@@
          throws IgniteCheckedException, GridCacheEntryRemovedException;
  
      /**
 -     * @param readSwap Flag indicating whether to check swap memory.
+      * @param updateMetrics If {@code true} then metrics should be updated.
+      * @param evt Flag to signal event notification.
+      * @param subjId Subject ID initiated this read.
+      * @param taskName Task name.
+      * @param expiryPlc Expiry policy.
+      * @param keepBinary Keep binary flag.
+      * @param readerArgs Reader will be added if not null.
+      * @throws IgniteCheckedException If loading value failed.
+      * @throws GridCacheEntryRemovedException If entry was removed.
+      * @return Cached value, entry version and flag indicating if entry was reserved.
+      */
 -    public EntryGetResult innerGetAndReserveForLoad(boolean readSwap,
 -        boolean updateMetrics,
++    public EntryGetResult innerGetAndReserveForLoad(boolean updateMetrics,
+         boolean evt,
+         UUID subjId,
+         String taskName,
+         @Nullable IgniteCacheExpiryPolicy expiryPlc,
+         boolean keepBinary,
+         @Nullable ReaderArguments readerArgs) throws IgniteCheckedException, GridCacheEntryRemovedException;
+ 
+     /**
+      * @param ver Expected entry version.
+      * @throws IgniteCheckedException If failed.
+      */
+     public void clearReserveForLoad(GridCacheVersion ver) throws IgniteCheckedException;
+ 
+     /**
       * Reloads entry from underlying storage.
       *
       * @return Reloaded value.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1748e226/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionManager.java
----------------------------------------------------------------------


[17/50] [abbrv] ignite git commit: IGNITE-4631: Added check to ensure QueryEntity 'keyFields' is subset of 'fields'. This closes #1484.

Posted by sb...@apache.org.
IGNITE-4631: Added check to ensure QueryEntity 'keyFields' is subset of 'fields'. This closes #1484.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 46ff66efda93fa91a44d44ae68e7ade9add1c697
Parents: bb1ac0a
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Wed Feb 8 17:11:30 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Feb 8 17:11:30 2017 +0300

----------------------------------------------------------------------
 .../processors/query/GridQueryProcessor.java    |   9 ++
 .../cache/QueryEntityCaseMismatchTest.java      | 107 +++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite.java          |   2 +
 3 files changed, 118 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/46ff66ef/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index a239ee2..fd06828 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -1530,6 +1530,15 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
         boolean isKeyClsSqlType = isSqlType(d.keyClass());
 
+        if (hasKeyFields && !isKeyClsSqlType) {
+            //ensure that 'keyFields' is case sensitive subset of 'fields'
+            for (String keyField : keyFields) {
+                if (!qryEntity.getFields().containsKey(keyField))
+                    throw new IgniteCheckedException("QueryEntity 'keyFields' property must be a subset of keys " +
+                        "from 'fields' property (case sensitive): " + keyField);
+            }
+        }
+
         for (Map.Entry<String, String> entry : qryEntity.getFields().entrySet()) {
             Boolean isKeyField;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ff66ef/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/QueryEntityCaseMismatchTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/QueryEntityCaseMismatchTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/QueryEntityCaseMismatchTest.java
new file mode 100644
index 0000000..4f8cfee
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/QueryEntityCaseMismatchTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.concurrent.Callable;
+
+/**
+ * Test reveals issue of null values in SQL query resultset columns that correspond to compound key.
+ * That happens when QueryEntity.keyFields has wrong register compared to QueryEntity.fields.
+ * Issue only manifests for BinaryMarshaller case. Otherwise the keyFields aren't taken into account.
+ */
+public class QueryEntityCaseMismatchTest extends GridCommonAbstractTest {
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setLocalHost("127.0.0.1");
+
+        cfg.setPeerClassLoadingEnabled(true);
+
+        TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+        ipFinder.setAddresses(Collections.singletonList("127.0.0.1:47500..47509"));
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(ipFinder);
+
+        cfg.setDiscoverySpi(discoSpi);
+
+        CacheConfiguration<Object, Integer> ccfg = new CacheConfiguration<>("");
+
+        cfg.setMarshaller(new BinaryMarshaller());
+
+        QueryEntity queryEntity = new QueryEntity("KeyType", Integer.class.getName());
+
+        LinkedHashMap<String, String> fields = new LinkedHashMap<>();
+
+        fields.put("a", "TypeA");
+        fields.put("b", "TypeB");
+
+        queryEntity.setFields(fields);
+
+        //Specify key fields in upper register
+        HashSet<String> keyFields = new HashSet<>();
+
+        keyFields.add("a");
+        keyFields.add("B");
+
+        queryEntity.setKeyFields(keyFields);
+
+        ccfg.setQueryEntities(F.asList(queryEntity));
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return cfg;
+    }
+
+    /**
+     * The cache must not initialize if QueryEntity.keyFields isn't subset of QueryEntity.fields
+     *
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+    public void testCacheInitializationFailure() throws Exception {
+        GridTestUtils.assertThrows(log, new Callable<Void>() {
+            @Override public Void call() throws Exception {
+                startGrid(1);
+
+                return null;
+            }
+        }, IgniteCheckedException.class, null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ff66ef/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index d85e111..386b8fd 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -68,6 +68,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheQueryIndexSelfTest
 import org.apache.ignite.internal.processors.cache.IgniteCacheQueryLoadSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCrossCachesJoinsQueryTest;
+import org.apache.ignite.internal.processors.cache.QueryEntityCaseMismatchTest;
 import org.apache.ignite.internal.processors.cache.SqlFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicNearEnabledFieldsQuerySelfTest;
@@ -242,6 +243,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         suite.addTestSuite(CacheSqlQueryValueCopySelfTest.class);
         suite.addTestSuite(IgniteCacheQueryCacheDestroySelfTest.class);
         suite.addTestSuite(IgniteSqlEntryCacheModeAgnosticTest.class);
+        suite.addTestSuite(QueryEntityCaseMismatchTest.class);
 
         return suite;
     }


[42/50] [abbrv] ignite git commit: IGNITE-4158: Added java.sql.Time support for BinaryMarshaller. This closes #1515.

Posted by sb...@apache.org.
IGNITE-4158: Added java.sql.Time support for BinaryMarshaller. This closes #1515.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 00dd3d815e0bf61784151891304ed01babed1e05
Parents: 2f57470
Author: Vyacheslav Daradur <da...@gmail.com>
Authored: Mon Feb 13 14:42:13 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Feb 13 14:42:13 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/binary/BinaryRawReader.java   | 13 ++++
 .../apache/ignite/binary/BinaryRawWriter.java   | 13 ++++
 .../org/apache/ignite/binary/BinaryReader.java  | 15 ++++
 .../org/apache/ignite/binary/BinaryWriter.java  | 15 ++++
 .../internal/binary/BinaryClassDescriptor.java  | 13 ++++
 .../ignite/internal/binary/BinaryContext.java   |  3 +
 .../internal/binary/BinaryFieldAccessor.java    | 23 ++++++
 .../binary/BinaryMetadataCollector.java         | 11 +++
 .../internal/binary/BinaryObjectImpl.java       |  9 +++
 .../binary/BinaryObjectOffheapImpl.java         |  9 +++
 .../internal/binary/BinaryReaderExImpl.java     | 58 ++++++++++++++
 .../binary/BinarySerializedFieldComparator.java |  3 +
 .../ignite/internal/binary/BinaryUtils.java     | 79 ++++++++++++++++++--
 .../ignite/internal/binary/BinaryWriteMode.java |  6 ++
 .../internal/binary/BinaryWriterExImpl.java     | 66 ++++++++++++++++
 .../internal/binary/GridBinaryMarshaller.java   |  6 ++
 .../binary/builder/BinaryBuilderReader.java     | 37 +++++++++
 .../processors/odbc/OdbcRequestHandler.java     |  2 +
 .../binary/BinaryMarshallerSelfTest.java        | 59 +++++++++++++++
 19 files changed, 432 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawReader.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawReader.java
index ce059d1..c51a9c6 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawReader.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.binary;
 
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -110,6 +111,12 @@ public interface BinaryRawReader {
     @Nullable public Timestamp readTimestamp() throws BinaryObjectException;
 
     /**
+     * @return Time.
+     * @throws BinaryObjectException In case of error.
+     */
+    @Nullable public Time readTime() throws BinaryObjectException;
+
+    /**
      * @return Object.
      * @throws BinaryObjectException In case of error.
      */
@@ -194,6 +201,12 @@ public interface BinaryRawReader {
     @Nullable public Timestamp[] readTimestampArray() throws BinaryObjectException;
 
     /**
+     * @return Time array.
+     * @throws BinaryObjectException In case of error.
+     */
+    @Nullable public Time[] readTimeArray() throws BinaryObjectException;
+
+    /**
      * @return Object array.
      * @throws BinaryObjectException In case of error.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawWriter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawWriter.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawWriter.java
index f283c06..84ce3de 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawWriter.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryRawWriter.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.binary;
 
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -110,6 +111,12 @@ public interface BinaryRawWriter {
     public void writeTimestamp(@Nullable Timestamp val) throws BinaryObjectException;
 
     /**
+     * @param val Time to write.
+     * @throws BinaryObjectException In case of error.
+     */
+    public void writeTime(@Nullable Time val) throws BinaryObjectException;
+
+    /**
      * @param obj Value to write.
      * @throws BinaryObjectException In case of error.
      */
@@ -197,6 +204,12 @@ public interface BinaryRawWriter {
      * @param val Value to write.
      * @throws BinaryObjectException In case of error.
      */
+    public void writeTimeArray(@Nullable Time[] val) throws BinaryObjectException;
+
+    /**
+     * @param val Value to write.
+     * @throws BinaryObjectException In case of error.
+     */
     public void writeObjectArray(@Nullable Object[] val) throws BinaryObjectException;
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/binary/BinaryReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryReader.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryReader.java
index 93a9469..b04e746 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryReader.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.binary;
 
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -130,6 +131,13 @@ public interface BinaryReader {
 
     /**
      * @param fieldName Field name.
+     * @return Time.
+     * @throws BinaryObjectException In case of error.
+     */
+    public Time readTime(String fieldName) throws BinaryObjectException;
+
+    /**
+     * @param fieldName Field name.
      * @return Object.
      * @throws BinaryObjectException In case of error.
      */
@@ -228,6 +236,13 @@ public interface BinaryReader {
 
     /**
      * @param fieldName Field name.
+     * @return Time array.
+     * @throws BinaryObjectException In case of error.
+     */
+    public Time[] readTimeArray(String fieldName) throws BinaryObjectException;
+
+    /**
+     * @param fieldName Field name.
      * @return Object array.
      * @throws BinaryObjectException In case of error.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/binary/BinaryWriter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryWriter.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryWriter.java
index b24b206..541d3d6 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryWriter.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryWriter.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.binary;
 
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -131,6 +132,13 @@ public interface BinaryWriter {
 
     /**
      * @param fieldName Field name.
+     * @param val Time to write.
+     * @throws BinaryObjectException In case of error.
+     */
+    public void writeTime(String fieldName, @Nullable Time val) throws BinaryObjectException;
+
+    /**
+     * @param fieldName Field name.
      * @param obj Value to write.
      * @throws BinaryObjectException In case of error.
      */
@@ -232,6 +240,13 @@ public interface BinaryWriter {
      * @param val Value to write.
      * @throws BinaryObjectException In case of error.
      */
+    public void writeTimeArray(String fieldName, @Nullable Time[] val) throws BinaryObjectException;
+
+    /**
+     * @param fieldName Field name.
+     * @param val Value to write.
+     * @throws BinaryObjectException In case of error.
+     */
     public void writeObjectArray(String fieldName, @Nullable Object[] val) throws BinaryObjectException;
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index 3a72a31..b63e674 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Collections;
@@ -222,6 +223,7 @@ public class BinaryClassDescriptor {
             case UUID:
             case DATE:
             case TIMESTAMP:
+            case TIME:
             case BYTE_ARR:
             case SHORT_ARR:
             case INT_ARR:
@@ -235,6 +237,7 @@ public class BinaryClassDescriptor {
             case UUID_ARR:
             case DATE_ARR:
             case TIMESTAMP_ARR:
+            case TIME_ARR:
             case OBJECT_ARR:
             case COL:
             case MAP:
@@ -611,6 +614,11 @@ public class BinaryClassDescriptor {
 
                 break;
 
+            case TIME:
+                writer.doWriteTime((Time)obj);
+
+                break;
+
             case BYTE_ARR:
                 writer.doWriteByteArray((byte[])obj);
 
@@ -676,6 +684,11 @@ public class BinaryClassDescriptor {
 
                 break;
 
+            case TIME_ARR:
+                writer.doWriteTimeArray((Time[]) obj);
+
+                break;
+
             case OBJECT_ARR:
                 writer.doWriteObjectArray((Object[])obj);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
index b291872..6d4cedd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
@@ -98,6 +98,7 @@ import java.math.BigDecimal;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -289,6 +290,7 @@ public class BinaryContext {
         registerPredefinedType(BigDecimal.class, GridBinaryMarshaller.DECIMAL);
         registerPredefinedType(Date.class, GridBinaryMarshaller.DATE);
         registerPredefinedType(Timestamp.class, GridBinaryMarshaller.TIMESTAMP);
+        registerPredefinedType(Time.class, GridBinaryMarshaller.TIME);
         registerPredefinedType(UUID.class, GridBinaryMarshaller.UUID);
 
         registerPredefinedType(byte[].class, GridBinaryMarshaller.BYTE_ARR);
@@ -304,6 +306,7 @@ public class BinaryContext {
         registerPredefinedType(UUID[].class, GridBinaryMarshaller.UUID_ARR);
         registerPredefinedType(Date[].class, GridBinaryMarshaller.DATE_ARR);
         registerPredefinedType(Timestamp[].class, GridBinaryMarshaller.TIMESTAMP_ARR);
+        registerPredefinedType(Time[].class, GridBinaryMarshaller.TIME_ARR);
         registerPredefinedType(Object[].class, GridBinaryMarshaller.OBJ_ARR);
 
         // Special collections.

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
index af33b63..aabb772 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.binary;
 
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -86,6 +87,7 @@ public abstract class BinaryFieldAccessor {
             case UUID:
             case DATE:
             case TIMESTAMP:
+            case TIME:
             case BYTE_ARR:
             case SHORT_ARR:
             case INT_ARR:
@@ -99,6 +101,7 @@ public abstract class BinaryFieldAccessor {
             case UUID_ARR:
             case DATE_ARR:
             case TIMESTAMP_ARR:
+            case TIME_ARR:
             case ENUM_ARR:
             case OBJECT_ARR:
             case BINARY_OBJ:
@@ -522,6 +525,11 @@ public abstract class BinaryFieldAccessor {
 
                     break;
 
+                case TIME:
+                    writer.writeTimeField((Time)val);
+
+                    break;
+
                 case BYTE_ARR:
                     writer.writeByteArrayField((byte[])val);
 
@@ -587,6 +595,11 @@ public abstract class BinaryFieldAccessor {
 
                     break;
 
+                case TIME_ARR:
+                    writer.writeTimeArrayField((Time[])val);
+
+                    break;
+
                 case OBJECT_ARR:
                     writer.writeObjectArrayField((Object[])val);
 
@@ -723,6 +736,11 @@ public abstract class BinaryFieldAccessor {
 
                     break;
 
+                case TIME:
+                    val = reader.readTime(id);
+
+                    break;
+
                 case BYTE_ARR:
                     val = reader.readByteArray(id);
 
@@ -788,6 +806,11 @@ public abstract class BinaryFieldAccessor {
 
                     break;
 
+                case TIME_ARR:
+                    val = reader.readTimeArray(id);
+
+                    break;
+
                 case OBJECT_ARR:
                     val = reader.readObjectArray(id);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java
index e8574ef..2585b3b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java
@@ -21,6 +21,7 @@ import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -144,6 +145,11 @@ class BinaryMetadataCollector implements BinaryWriter {
     }
 
     /** {@inheritDoc} */
+    @Override public void writeTime(String fieldName, @Nullable Time val) throws BinaryObjectException {
+        add(fieldName, BinaryWriteMode.TIME);
+    }
+
+    /** {@inheritDoc} */
     @Override public <T extends Enum<?>> void writeEnum(String fieldName, T val) throws BinaryObjectException {
         add(fieldName, BinaryWriteMode.ENUM);
     }
@@ -224,6 +230,11 @@ class BinaryMetadataCollector implements BinaryWriter {
     }
 
     /** {@inheritDoc} */
+    @Override public void writeTimeArray(String fieldName, @Nullable Time[] val) throws BinaryObjectException {
+        add(fieldName, BinaryWriteMode.TIME_ARR);
+    }
+
+    /** {@inheritDoc} */
     @Override public void writeObjectArray(String fieldName, @Nullable Object[] val) throws BinaryObjectException {
         add(fieldName, BinaryWriteMode.OBJECT_ARR);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
index 360c71a..7a81659 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
@@ -40,6 +40,7 @@ import java.io.ObjectOutput;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Date;
 import java.util.UUID;
@@ -430,6 +431,14 @@ public final class BinaryObjectImpl extends BinaryObjectExImpl implements Extern
                 break;
             }
 
+            case GridBinaryMarshaller.TIME: {
+                long time = BinaryPrimitives.readLong(arr, fieldPos + 1);
+
+                val = new Time(time);
+
+                break;
+            }
+
             case GridBinaryMarshaller.UUID: {
                 long most = BinaryPrimitives.readLong(arr, fieldPos + 1);
                 long least = BinaryPrimitives.readLong(arr, fieldPos + 1 + 8);

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
index f9a31db..3f095f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
@@ -24,6 +24,7 @@ import java.io.ObjectOutput;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Date;
 import java.util.UUID;
@@ -323,6 +324,14 @@ public class BinaryObjectOffheapImpl extends BinaryObjectExImpl implements Exter
                 break;
             }
 
+            case GridBinaryMarshaller.TIME: {
+                long time = BinaryPrimitives.readLong(ptr, fieldPos + 1);
+
+                val = new Time(time);
+
+                break;
+            }
+
             case GridBinaryMarshaller.UUID: {
                 long most = BinaryPrimitives.readLong(ptr, fieldPos + 1);
                 long least = BinaryPrimitives.readLong(ptr, fieldPos + 1 + 8);

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
index 775f237..246cf57 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
@@ -21,6 +21,7 @@ import java.io.EOFException;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -74,8 +75,10 @@ import static org.apache.ignite.internal.binary.GridBinaryMarshaller.SHORT;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.SHORT_ARR;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.STRING;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.STRING_ARR;
+import static org.apache.ignite.internal.binary.GridBinaryMarshaller.TIME;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.TIMESTAMP;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.TIMESTAMP_ARR;
+import static org.apache.ignite.internal.binary.GridBinaryMarshaller.TIME_ARR;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.UNREGISTERED_TYPE_ID;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.UUID;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.UUID_ARR;
@@ -1105,6 +1108,51 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
     }
 
     /** {@inheritDoc} */
+    @Override @Nullable public Time readTime(String fieldName) throws BinaryObjectException {
+        return findFieldByName(fieldName) ? this.readTime() : null;
+    }
+
+    /** {@inheritDoc} */
+    @Override @Nullable public Time readTime() throws BinaryObjectException {
+        return checkFlagNoHandles(TIME) == Flag.NORMAL ? BinaryUtils.doReadTime(in) : null;
+    }
+
+    /** {@inheritDoc} */
+    @Override @Nullable public Time[] readTimeArray(String fieldName) throws BinaryObjectException {
+        return findFieldByName(fieldName) ? this.readTimeArray() : null;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
+     * @throws BinaryObjectException In case of error.
+     */
+    @Nullable Time readTime(int fieldId) throws BinaryObjectException {
+        return findFieldById(fieldId) ? this.readTime() : null;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
+     * @throws BinaryObjectException In case of error.
+     */
+    @Nullable Time[] readTimeArray(int fieldId) throws BinaryObjectException {
+        return findFieldById(fieldId) ? this.readTimeArray() : null;
+    }
+
+    /** {@inheritDoc} */
+    @Override @Nullable public Time[] readTimeArray() throws BinaryObjectException {
+        switch (checkFlag(TIME_ARR)) {
+            case NORMAL:
+                return BinaryUtils.doReadTimeArray(in);
+            case HANDLE:
+                return readHandleField();
+            default:
+                return null;
+        }
+    }
+
+    /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Nullable @Override public <T> T readObject(String fieldName) throws BinaryObjectException {
         return findFieldByName(fieldName) ? (T)BinaryUtils.doReadObject(in, ctx, ldr, this) : null;
@@ -1566,6 +1614,11 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
                 break;
 
+            case TIME:
+                obj = BinaryUtils.doReadTime(in);
+
+                break;
+
             case BYTE_ARR:
                 obj = BinaryUtils.doReadByteArray(in);
 
@@ -1631,6 +1684,11 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
                 break;
 
+            case TIME_ARR:
+                obj = BinaryUtils.doReadTimeArray(in);
+
+                break;
+
             case OBJ_ARR:
                 obj = BinaryUtils.doReadObjectArray(in, ctx, ldr, this, true);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinarySerializedFieldComparator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinarySerializedFieldComparator.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinarySerializedFieldComparator.java
index 130bb0c..4375073 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinarySerializedFieldComparator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinarySerializedFieldComparator.java
@@ -229,6 +229,9 @@ public class BinarySerializedFieldComparator {
             case GridBinaryMarshaller.TIMESTAMP:
                 return c1.readLong(1) == c2.readLong(1) && c1.readInt(1 + 8) == c2.readInt(1 + 8);
 
+            case GridBinaryMarshaller.TIME:
+                return c1.readLong(1) == c2.readLong(1);
+
             case GridBinaryMarshaller.UUID:
                 return c1.readLong(1) == c2.readLong(1) && c1.readLong(1 + 8) == c2.readLong(1 + 8);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index 6831ef9..2b55b6c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -28,6 +28,7 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -158,6 +159,7 @@ public class BinaryUtils {
         PLAIN_CLASS_TO_FLAG.put(UUID.class, GridBinaryMarshaller.UUID);
         PLAIN_CLASS_TO_FLAG.put(Date.class, GridBinaryMarshaller.DATE);
         PLAIN_CLASS_TO_FLAG.put(Timestamp.class, GridBinaryMarshaller.TIMESTAMP);
+        PLAIN_CLASS_TO_FLAG.put(Time.class, GridBinaryMarshaller.TIME);
 
         PLAIN_CLASS_TO_FLAG.put(byte[].class, GridBinaryMarshaller.BYTE_ARR);
         PLAIN_CLASS_TO_FLAG.put(short[].class, GridBinaryMarshaller.SHORT_ARR);
@@ -172,6 +174,7 @@ public class BinaryUtils {
         PLAIN_CLASS_TO_FLAG.put(UUID[].class, GridBinaryMarshaller.UUID_ARR);
         PLAIN_CLASS_TO_FLAG.put(Date[].class, GridBinaryMarshaller.DATE_ARR);
         PLAIN_CLASS_TO_FLAG.put(Timestamp[].class, GridBinaryMarshaller.TIMESTAMP_ARR);
+        PLAIN_CLASS_TO_FLAG.put(Time[].class, GridBinaryMarshaller.TIME_ARR);
 
         for (Map.Entry<Class<?>, Byte> entry : PLAIN_CLASS_TO_FLAG.entrySet())
             FLAG_TO_CLASS.put(entry.getValue(), entry.getKey());
@@ -187,8 +190,8 @@ public class BinaryUtils {
 
         for (byte b : new byte[] {
             GridBinaryMarshaller.BYTE, GridBinaryMarshaller.SHORT, GridBinaryMarshaller.INT, GridBinaryMarshaller.LONG, GridBinaryMarshaller.FLOAT, GridBinaryMarshaller.DOUBLE,
-            GridBinaryMarshaller.CHAR, GridBinaryMarshaller.BOOLEAN, GridBinaryMarshaller.DECIMAL, GridBinaryMarshaller.STRING, GridBinaryMarshaller.UUID, GridBinaryMarshaller.DATE, GridBinaryMarshaller.TIMESTAMP,
-            GridBinaryMarshaller.BYTE_ARR, GridBinaryMarshaller.SHORT_ARR, GridBinaryMarshaller.INT_ARR, GridBinaryMarshaller.LONG_ARR, GridBinaryMarshaller.FLOAT_ARR, GridBinaryMarshaller.DOUBLE_ARR,
+            GridBinaryMarshaller.CHAR, GridBinaryMarshaller.BOOLEAN, GridBinaryMarshaller.DECIMAL, GridBinaryMarshaller.STRING, GridBinaryMarshaller.UUID, GridBinaryMarshaller.DATE, GridBinaryMarshaller.TIMESTAMP, GridBinaryMarshaller.TIME,
+            GridBinaryMarshaller.BYTE_ARR, GridBinaryMarshaller.SHORT_ARR, GridBinaryMarshaller.INT_ARR, GridBinaryMarshaller.LONG_ARR, GridBinaryMarshaller.FLOAT_ARR, GridBinaryMarshaller.DOUBLE_ARR, GridBinaryMarshaller.TIME_ARR,
             GridBinaryMarshaller.CHAR_ARR, GridBinaryMarshaller.BOOLEAN_ARR, GridBinaryMarshaller.DECIMAL_ARR, GridBinaryMarshaller.STRING_ARR, GridBinaryMarshaller.UUID_ARR, GridBinaryMarshaller.DATE_ARR, GridBinaryMarshaller.TIMESTAMP_ARR,
             GridBinaryMarshaller.ENUM, GridBinaryMarshaller.ENUM_ARR, GridBinaryMarshaller.NULL}) {
 
@@ -207,6 +210,7 @@ public class BinaryUtils {
         BINARY_CLS.add(UUID.class);
         BINARY_CLS.add(Date.class);
         BINARY_CLS.add(Timestamp.class);
+        BINARY_CLS.add(Time.class);
         BINARY_CLS.add(BigDecimal.class);
         BINARY_CLS.add(byte[].class);
         BINARY_CLS.add(short[].class);
@@ -220,6 +224,7 @@ public class BinaryUtils {
         BINARY_CLS.add(UUID[].class);
         BINARY_CLS.add(Date[].class);
         BINARY_CLS.add(Timestamp[].class);
+        BINARY_CLS.add(Time[].class);
         BINARY_CLS.add(BigDecimal[].class);
 
         FIELD_TYPE_NAMES = new String[104];
@@ -237,6 +242,7 @@ public class BinaryUtils {
         FIELD_TYPE_NAMES[GridBinaryMarshaller.STRING] = "String";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.DATE] = "Date";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.TIMESTAMP] = "Timestamp";
+        FIELD_TYPE_NAMES[GridBinaryMarshaller.TIME] = "Time";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.ENUM] = "Enum";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.OBJ] = "Object";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.BINARY_OBJ] = "Object";
@@ -256,6 +262,7 @@ public class BinaryUtils {
         FIELD_TYPE_NAMES[GridBinaryMarshaller.STRING_ARR] = "String[]";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.DATE_ARR] = "Date[]";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.TIMESTAMP_ARR] = "Timestamp[]";
+        FIELD_TYPE_NAMES[GridBinaryMarshaller.TIME_ARR] = "Time[]";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.OBJ_ARR] = "Object[]";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.ENUM_ARR] = "Enum[]";
 
@@ -445,6 +452,11 @@ public class BinaryUtils {
 
                 break;
 
+            case GridBinaryMarshaller.TIME:
+                writer.doWriteTime((Time)val);
+
+                break;
+
             case GridBinaryMarshaller.BYTE_ARR:
                 writer.doWriteByteArray((byte[])val);
 
@@ -510,6 +522,11 @@ public class BinaryUtils {
 
                 break;
 
+            case GridBinaryMarshaller.TIME_ARR:
+                writer.doWriteTimeArray((Time[])val);
+
+                break;
+
             default:
                 throw new IllegalArgumentException("Can't write object with type: " + val.getClass());
         }
@@ -560,7 +577,8 @@ public class BinaryUtils {
      * @return {@code true} if content of serialized array value cannot contain references to other object.
      */
     public static boolean isPlainArrayType(int type) {
-        return (type >= GridBinaryMarshaller.BYTE_ARR && type <= GridBinaryMarshaller.DATE_ARR) || type == GridBinaryMarshaller.TIMESTAMP_ARR;
+        return (type >= GridBinaryMarshaller.BYTE_ARR && type <= GridBinaryMarshaller.DATE_ARR)
+            || type == GridBinaryMarshaller.TIMESTAMP_ARR || type == GridBinaryMarshaller.TIME_ARR;
     }
 
     /**
@@ -577,7 +595,8 @@ public class BinaryUtils {
             return GridBinaryMarshaller.ENUM;
 
         if (cls.isArray())
-            return cls.getComponentType().isEnum() || cls.getComponentType() == Enum.class ? GridBinaryMarshaller.ENUM_ARR : GridBinaryMarshaller.OBJ_ARR;
+            return cls.getComponentType().isEnum() || cls.getComponentType() == Enum.class ?
+                GridBinaryMarshaller.ENUM_ARR : GridBinaryMarshaller.OBJ_ARR;
 
         if (isSpecialCollection(cls))
             return GridBinaryMarshaller.COL;
@@ -695,7 +714,7 @@ public class BinaryUtils {
         return cls == byte[].class || cls == short[].class || cls == int[].class || cls == long[].class ||
             cls == float[].class || cls == double[].class || cls == char[].class || cls == boolean[].class ||
             cls == String[].class || cls == UUID[].class || cls == Date[].class || cls == Timestamp[].class ||
-            cls == BigDecimal[].class;
+            cls == BigDecimal[].class || cls == Time[].class;
     }
 
     /**
@@ -1000,7 +1019,7 @@ public class BinaryUtils {
     public static BinaryWriteMode mode(Class<?> cls) {
         assert cls != null;
 
-        /** Primitives. */
+        // Primitives.
         if (cls == byte.class)
             return BinaryWriteMode.P_BYTE;
         else if (cls == boolean.class)
@@ -1018,7 +1037,7 @@ public class BinaryUtils {
         else if (cls == double.class)
             return BinaryWriteMode.P_DOUBLE;
 
-        /** Boxed primitives. */
+        // Boxed primitives.
         else if (cls == Byte.class)
             return BinaryWriteMode.BYTE;
         else if (cls == Boolean.class)
@@ -1036,7 +1055,7 @@ public class BinaryUtils {
         else if (cls == Double.class)
             return BinaryWriteMode.DOUBLE;
 
-        /** The rest types. */
+        // The rest types.
         else if (cls == BigDecimal.class)
             return BinaryWriteMode.DECIMAL;
         else if (cls == String.class)
@@ -1047,6 +1066,8 @@ public class BinaryUtils {
             return BinaryWriteMode.DATE;
         else if (cls == Timestamp.class)
             return BinaryWriteMode.TIMESTAMP;
+        else if (cls == Time.class)
+            return BinaryWriteMode.TIME;
         else if (cls == byte[].class)
             return BinaryWriteMode.BYTE_ARR;
         else if (cls == short[].class)
@@ -1073,6 +1094,8 @@ public class BinaryUtils {
             return BinaryWriteMode.DATE_ARR;
         else if (cls == Timestamp[].class)
             return BinaryWriteMode.TIMESTAMP_ARR;
+        else if (cls == Time[].class)
+            return BinaryWriteMode.TIME_ARR;
         else if (cls.isArray())
             return cls.getComponentType().isEnum() ? BinaryWriteMode.ENUM_ARR : BinaryWriteMode.OBJECT_ARR;
         else if (cls == BinaryObjectImpl.class)
@@ -1270,6 +1293,15 @@ public class BinaryUtils {
 
     /**
      * @return Value.
+     */
+    public static Time doReadTime(BinaryInputStream in) {
+        long time = in.readLong();
+
+        return new Time(time);
+    }
+
+    /**
+     * @return Value.
      * @throws BinaryObjectException In case of error.
      */
     public static BigDecimal[] doReadDecimalArray(BinaryInputStream in) throws BinaryObjectException {
@@ -1395,6 +1427,31 @@ public class BinaryUtils {
 
     /**
      * @return Value.
+     * @throws BinaryObjectException In case of error.
+     */
+    public static Time[] doReadTimeArray(BinaryInputStream in) throws BinaryObjectException {
+        int len = in.readInt();
+
+        Time[] arr = new Time[len];
+
+        for (int i = 0; i < len; i++) {
+            byte flag = in.readByte();
+
+            if (flag == GridBinaryMarshaller.NULL)
+                arr[i] = null;
+            else {
+                if (flag != GridBinaryMarshaller.TIME)
+                    throw new BinaryObjectException("Invalid flag value: " + flag);
+
+                arr[i] = doReadTime(in);
+            }
+        }
+
+        return arr;
+    }
+
+    /**
+     * @return Value.
      */
     public static BinaryObject doReadBinaryObject(BinaryInputStream in, BinaryContext ctx) {
         if (in.offheapPointer() > 0) {
@@ -1759,6 +1816,9 @@ public class BinaryUtils {
             case GridBinaryMarshaller.TIMESTAMP:
                 return doReadTimestamp(in);
 
+            case GridBinaryMarshaller.TIME:
+                return doReadTime(in);
+
             case GridBinaryMarshaller.BYTE_ARR:
                 return doReadByteArray(in);
 
@@ -1798,6 +1858,9 @@ public class BinaryUtils {
             case GridBinaryMarshaller.TIMESTAMP_ARR:
                 return doReadTimestampArray(in);
 
+            case GridBinaryMarshaller.TIME_ARR:
+                return doReadTimeArray(in);
+
             case GridBinaryMarshaller.OBJ_ARR:
                 return doReadObjectArray(in, ctx, ldr, handles, false);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriteMode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriteMode.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriteMode.java
index 7e8c9bd..fb000a0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriteMode.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriteMode.java
@@ -85,6 +85,9 @@ public enum BinaryWriteMode {
     TIMESTAMP(GridBinaryMarshaller.TIMESTAMP),
 
     /** */
+    TIME(GridBinaryMarshaller.TIME),
+
+    /** */
     BYTE_ARR(GridBinaryMarshaller.BYTE_ARR),
 
     /** */
@@ -124,6 +127,9 @@ public enum BinaryWriteMode {
     TIMESTAMP_ARR(GridBinaryMarshaller.TIMESTAMP_ARR),
 
     /** */
+    TIME_ARR(GridBinaryMarshaller.TIME_ARR),
+
+    /** */
     OBJECT_ARR(GridBinaryMarshaller.OBJ_ARR),
 
     /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
index 3289780..ba4822f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
@@ -23,6 +23,7 @@ import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Proxy;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
@@ -486,6 +487,19 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     }
 
     /**
+     * @param time Time.
+     */
+    public void doWriteTime(@Nullable Time time) {
+        if (time== null)
+            out.writeByte(GridBinaryMarshaller.NULL);
+        else {
+            out.unsafeEnsure(1 + 8);
+            out.unsafeWriteByte(GridBinaryMarshaller.TIME);
+            out.unsafeWriteLong(time.getTime());
+        }
+    }
+
+    /**
      * Write object.
      *
      * @param obj Object.
@@ -702,6 +716,22 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
      }
 
     /**
+     * @param val Array of time.
+     */
+    void doWriteTimeArray(@Nullable Time[] val) {
+        if (val == null)
+            out.writeByte(GridBinaryMarshaller.NULL);
+        else {
+            out.unsafeEnsure(1 + 4);
+            out.unsafeWriteByte(GridBinaryMarshaller.TIME_ARR);
+            out.unsafeWriteInt(val.length);
+
+            for (Time time : val)
+                doWriteTime(time);
+        }
+    }
+
+    /**
      * @param val Array of objects.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
@@ -1126,6 +1156,13 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     }
 
     /**
+     * @param val Value.
+     */
+    void writeTimeField(@Nullable Time val) {
+        doWriteTime(val);
+    }
+
+    /**
      * @param obj Object.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
@@ -1226,6 +1263,13 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
 
     /**
      * @param val Value.
+     */
+    void writeTimeArrayField(@Nullable Time[] val) {
+        doWriteTimeArray(val);
+    }
+
+    /**
+     * @param val Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     void writeObjectArrayField(@Nullable Object[] val) throws BinaryObjectException {
@@ -1414,6 +1458,17 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     }
 
     /** {@inheritDoc} */
+    @Override public void writeTime(String fieldName, @Nullable Time val) throws BinaryObjectException {
+        writeFieldId(fieldName);
+        writeTimeField(val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeTime(@Nullable Time val) throws BinaryObjectException {
+        doWriteTime(val);
+    }
+
+    /** {@inheritDoc} */
     @Override public void writeObject(String fieldName, @Nullable Object obj) throws BinaryObjectException {
         writeFieldId(fieldName);
         writeObjectField(obj);
@@ -1582,6 +1637,17 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
         doWriteTimestampArray(val);
     }
 
+    /** {@inheritDoc} */
+    @Override public void writeTimeArray(String fieldName, @Nullable Time[] val) throws BinaryObjectException {
+        writeFieldId(fieldName);
+        writeTimeArrayField(val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeTimeArray(@Nullable Time[] val) throws BinaryObjectException {
+        doWriteTimeArray(val);
+    }
+
      /** {@inheritDoc} */
     @Override public void writeObjectArray(String fieldName, @Nullable Object[] val) throws BinaryObjectException {
         writeFieldId(fieldName);

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
index 624fa33..8616155 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
@@ -147,6 +147,12 @@ public class GridBinaryMarshaller {
     /** Proxy. */
     public static final byte PROXY = 35;
 
+    /** Time. */
+    public static final byte TIME = 36;
+
+    /** Time array. */
+    public static final byte TIME_ARR = 37;
+
     /** */
     public static final byte NULL = (byte)101;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
index baaabd6..9cd032d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.binary.BinarySchema;
 import org.apache.ignite.internal.binary.streams.BinaryHeapInputStream;
 import org.apache.ignite.internal.binary.BinaryUtils;
 
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Date;
 import java.util.HashMap;
@@ -292,6 +293,11 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
 
                 break;
 
+            case GridBinaryMarshaller.TIME:
+                len = 8;
+
+                break;
+
             case GridBinaryMarshaller.CHAR_ARR:
             case GridBinaryMarshaller.SHORT_ARR:
                 len = 4 + readLength() * 2;
@@ -313,6 +319,7 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
             case GridBinaryMarshaller.DECIMAL_ARR:
             case GridBinaryMarshaller.DATE_ARR:
             case GridBinaryMarshaller.TIMESTAMP_ARR:
+            case GridBinaryMarshaller.TIME_ARR:
             case GridBinaryMarshaller.OBJ_ARR:
             case GridBinaryMarshaller.ENUM_ARR:
             case GridBinaryMarshaller.UUID_ARR:
@@ -428,6 +435,7 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
             case GridBinaryMarshaller.UUID:
             case GridBinaryMarshaller.DATE:
             case GridBinaryMarshaller.TIMESTAMP:
+            case GridBinaryMarshaller.TIME:
                 return new BinaryPlainLazyValue(this, pos, len);
 
             case GridBinaryMarshaller.BYTE_ARR:
@@ -441,6 +449,7 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
             case GridBinaryMarshaller.DECIMAL_ARR:
             case GridBinaryMarshaller.DATE_ARR:
             case GridBinaryMarshaller.TIMESTAMP_ARR:
+            case GridBinaryMarshaller.TIME_ARR:
             case GridBinaryMarshaller.UUID_ARR:
             case GridBinaryMarshaller.STRING_ARR:
             case GridBinaryMarshaller.ENUM_ARR:
@@ -587,6 +596,11 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
 
                 break;
 
+            case GridBinaryMarshaller.TIME:
+                plainLazyValLen = 8;
+
+                break;
+
             case GridBinaryMarshaller.BYTE_ARR:
                 plainLazyValLen = 4 + readLength();
                 modifiableLazyVal = true;
@@ -693,6 +707,29 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
                 return res;
             }
 
+            case GridBinaryMarshaller.TIME_ARR: {
+                int size = readInt();
+
+                Time[] res = new Time[size];
+
+                for (int i = 0; i < res.length; i++) {
+                    byte flag = arr[pos++];
+
+                    if (flag == GridBinaryMarshaller.NULL) continue;
+
+                    if (flag != GridBinaryMarshaller.TIME)
+                        throw new BinaryObjectException("Invalid flag value: " + flag);
+
+                    long time = BinaryPrimitives.readLong(arr, pos);
+
+                    pos += 8;
+
+                    res[i] = new Time(time);
+                }
+
+                return res;
+            }
+
             case GridBinaryMarshaller.UUID_ARR:
             case GridBinaryMarshaller.STRING_ARR:
             case GridBinaryMarshaller.DECIMAL_ARR: {

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
index f922d9a..311d2eb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
@@ -473,6 +473,8 @@ public class OdbcRequestHandler {
                 return GridBinaryMarshaller.SHORT;
 
             case Types.TIME:
+                return GridBinaryMarshaller.TIME;
+
             case Types.TIMESTAMP:
                 return GridBinaryMarshaller.TIMESTAMP;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00dd3d81/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
index 2d43559..5bfc95c 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
@@ -31,6 +31,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
 import java.net.InetSocketAddress;
+import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.AbstractQueue;
 import java.util.ArrayList;
@@ -316,6 +317,22 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
+    public void testTime() throws Exception {
+        Time time = new Time(System.currentTimeMillis());
+        assertEquals(time, marshalUnmarshal(time));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTimeArray() throws Exception {
+        Time[] times = new Time[]{new Time(System.currentTimeMillis()), new Time(123456789)};
+        assertArrayEquals(times, marshalUnmarshal(times));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testByteArray() throws Exception {
         byte[] arr = new byte[] {10, 20, 30};
 
@@ -629,10 +646,14 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
 
         Date date = new Date();
         Timestamp ts = new Timestamp(System.currentTimeMillis());
+        Time time = new Time(System.currentTimeMillis());
+        Time[] timeArr = new Time[]{time, new Time(date.getTime()), new Time(System.currentTimeMillis())};
 
         DateClass1 obj1 = new DateClass1();
         obj1.date = date;
         obj1.ts = ts;
+        obj1.time = time;
+        obj1.timeArr = timeArr;
 
         BinaryObject po1 = marshal(obj1, marsh);
 
@@ -640,10 +661,16 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         assertEquals(Date.class, po1.field("date").getClass());
         assertEquals(ts, po1.field("ts"));
         assertEquals(Timestamp.class, po1.field("ts").getClass());
+        assertEquals(time, po1.field("time"));
+        assertEquals(Time.class, po1.field("time").getClass());
+        assertArrayEquals(timeArr, (Object[])po1.field("timeArr"));
+        assertEquals(Time[].class, po1.field("timeArr").getClass());
 
         obj1 = po1.deserialize();
         assertEquals(date, obj1.date);
         assertEquals(ts, obj1.ts);
+        assertEquals(time, obj1.time);
+        assertArrayEquals(timeArr, obj1.timeArr);
     }
 
     /**
@@ -3976,6 +4003,9 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         private Timestamp ts;
 
         /** */
+        private Time time;
+
+        /** */
         private byte[] bArr;
 
         /** */
@@ -4009,6 +4039,9 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         private Date[] dateArr;
 
         /** */
+        private Time[] timeArr;
+
+        /** */
         private Object[] objArr;
 
         /** */
@@ -4124,6 +4157,12 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         private Timestamp tsRaw;
 
         /** */
+        private Time time;
+
+        /** */
+        private Time timeRaw;
+
+        /** */
         private byte[] bArr;
 
         /** */
@@ -4190,6 +4229,12 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         private Date[] dateArrRaw;
 
         /** */
+        private Time[] timeArr;
+
+        /** */
+        private Time[] timeArrRaw;
+
+        /** */
         private Object[] objArr;
 
         /** */
@@ -4245,6 +4290,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             writer.writeUuid("_uuid", uuid);
             writer.writeDate("_date", date);
             writer.writeTimestamp("_ts", ts);
+            writer.writeTime("_time", time);
             writer.writeByteArray("_bArr", bArr);
             writer.writeShortArray("_sArr", sArr);
             writer.writeIntArray("_iArr", iArr);
@@ -4256,6 +4302,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             writer.writeStringArray("_strArr", strArr);
             writer.writeUuidArray("_uuidArr", uuidArr);
             writer.writeDateArray("_dateArr", dateArr);
+            writer.writeTimeArray("_timeArr", timeArr);
             writer.writeObjectArray("_objArr", objArr);
             writer.writeCollection("_col", col);
             writer.writeMap("_map", map);
@@ -4278,6 +4325,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             raw.writeUuid(uuidRaw);
             raw.writeDate(dateRaw);
             raw.writeTimestamp(tsRaw);
+            raw.writeTime(timeRaw);
             raw.writeByteArray(bArrRaw);
             raw.writeShortArray(sArrRaw);
             raw.writeIntArray(iArrRaw);
@@ -4289,6 +4337,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             raw.writeStringArray(strArrRaw);
             raw.writeUuidArray(uuidArrRaw);
             raw.writeDateArray(dateArrRaw);
+            raw.writeTimeArray(timeArrRaw);
             raw.writeObjectArray(objArrRaw);
             raw.writeCollection(colRaw);
             raw.writeMap(mapRaw);
@@ -4312,6 +4361,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             uuid = reader.readUuid("_uuid");
             date = reader.readDate("_date");
             ts = reader.readTimestamp("_ts");
+            time = reader.readTime("_time");
             bArr = reader.readByteArray("_bArr");
             sArr = reader.readShortArray("_sArr");
             iArr = reader.readIntArray("_iArr");
@@ -4323,6 +4373,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             strArr = reader.readStringArray("_strArr");
             uuidArr = reader.readUuidArray("_uuidArr");
             dateArr = reader.readDateArray("_dateArr");
+            timeArr = reader.readTimeArray("_timeArr");
             objArr = reader.readObjectArray("_objArr");
             col = reader.readCollection("_col");
             map = reader.readMap("_map");
@@ -4345,6 +4396,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             uuidRaw = raw.readUuid();
             dateRaw = raw.readDate();
             tsRaw = raw.readTimestamp();
+            timeRaw = raw.readTime();
             bArrRaw = raw.readByteArray();
             sArrRaw = raw.readShortArray();
             iArrRaw = raw.readIntArray();
@@ -4356,6 +4408,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             strArrRaw = raw.readStringArray();
             uuidArrRaw = raw.readUuidArray();
             dateArrRaw = raw.readDateArray();
+            timeArrRaw = raw.readTimeArray();
             objArrRaw = raw.readObjectArray();
             colRaw = raw.readCollection();
             mapRaw = raw.readMap();
@@ -4873,6 +4926,12 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
 
         /** */
         private Timestamp ts;
+
+        /** */
+        private Time time;
+
+        /** */
+        private Time[] timeArr;
     }
 
     /**


[14/50] [abbrv] ignite git commit: Revert "IGNITE-4363: SQL: fixed inner property updates for DML operations."

Posted by sb...@apache.org.
Revert "IGNITE-4363: SQL: fixed inner property updates for DML operations."

This reverts commit 70cd8e452b94b806a2fe6fe00b4b67ce80eb4373.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: bb1ac0a5cfecf4af7e8dcfe86efc75997895c431
Parents: e6cc8cd
Author: devozerov <vo...@gridgain.com>
Authored: Wed Feb 8 13:40:02 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Feb 8 13:40:02 2017 +0300

----------------------------------------------------------------------
 .../configuration/CacheConfiguration.java       |  16 +--
 .../processors/query/GridQueryProcessor.java    |  81 ++++----------
 .../processors/query/GridQueryProperty.java     |  21 ++--
 .../query/h2/DmlStatementsProcessor.java        |  69 ++++++------
 .../query/h2/dml/UpdatePlanBuilder.java         | 105 ++++++-------------
 ...niteCacheAbstractInsertSqlQuerySelfTest.java |   4 -
 .../IgniteCacheAbstractSqlDmlQuerySelfTest.java |   2 +-
 .../IgniteCacheInsertSqlQuerySelfTest.java      |  22 ----
 .../cache/IgniteCacheMergeSqlQuerySelfTest.java |  24 -----
 .../IgniteCacheUpdateSqlQuerySelfTest.java      |  63 ++---------
 .../h2/GridIndexingSpiAbstractSelfTest.java     |   5 -
 11 files changed, 111 insertions(+), 301 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index f0179ca..0656dda 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -2358,13 +2358,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    // Add parent property before its possible nested properties so that
-                    // resulting parent column comes before columns corresponding to those
-                    // nested properties in the resulting table - that way nested
-                    // properties override will happen properly (first parent, then children).
-                    type.addProperty(prop, key, true);
-
                     processAnnotation(key, sqlAnn, txtAnn, field.getType(), prop, type);
+
+                    type.addProperty(prop, key, true);
                 }
             }
 
@@ -2384,13 +2380,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    // Add parent property before its possible nested properties so that
-                    // resulting parent column comes before columns corresponding to those
-                    // nested properties in the resulting table - that way nested
-                    // properties override will happen properly (first parent, then children).
-                    type.addProperty(prop, key, true);
-
                     processAnnotation(key, sqlAnn, txtAnn, mtd.getReturnType(), prop, type);
+
+                    type.addProperty(prop, key, true);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 5bfdde8..a239ee2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -64,7 +64,6 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.binary.BinaryObjectEx;
-import org.apache.ignite.internal.binary.BinaryObjectExImpl;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
@@ -1949,7 +1948,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     /**
      * Description of type property.
      */
-    private static class ClassProperty implements GridQueryProperty {
+    private static class ClassProperty extends GridQueryProperty {
         /** */
         private final PropertyAccessor accessor;
 
@@ -2042,17 +2041,12 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public String toString() {
             return S.toString(ClassProperty.class, this);
         }
-
-        /** {@inheritDoc} */
-        @Override public GridQueryProperty parent() {
-            return parent;
-        }
     }
 
     /**
      *
      */
-    private class BinaryProperty implements GridQueryProperty {
+    private class BinaryProperty extends GridQueryProperty {
         /** Property name. */
         private String propName;
 
@@ -2136,17 +2130,11 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                 obj = isKeyProp0 == 1 ? key : val;
             }
 
-            if (obj instanceof BinaryObject) {
-                BinaryObject obj0 = (BinaryObject) obj;
-                return fieldValue(obj0);
-            }
-            else if (obj instanceof BinaryObjectBuilder) {
-                BinaryObjectBuilder obj0 = (BinaryObjectBuilder)obj;
+            assert obj instanceof BinaryObject;
 
-                return obj0.getField(name());
-            }
-            else
-                throw new IgniteCheckedException("Unexpected binary object class [type=" + obj.getClass() + ']');
+            BinaryObject obj0 = (BinaryObject)obj;
+
+            return fieldValue(obj0);
         }
 
         /** {@inheritDoc} */
@@ -2156,38 +2144,10 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             if (obj == null)
                 return;
 
-            Object srcObj = obj;
-
-            if (!(srcObj instanceof BinaryObjectBuilder))
-                throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
-
-            if (parent != null)
-                obj = parent.value(key, val);
-
-            boolean needsBuild = false;
-
-            if (obj instanceof BinaryObjectExImpl) {
-                if (parent == null)
-                    throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
-
-                needsBuild = true;
-
-                obj = ((BinaryObjectExImpl)obj).toBuilder();
-            }
-
             if (!(obj instanceof BinaryObjectBuilder))
                 throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
 
             setValue0((BinaryObjectBuilder) obj, propName, propVal, type());
-
-            if (needsBuild) {
-                obj = ((BinaryObjectBuilder) obj).build();
-
-                assert parent != null;
-
-                // And now let's set this newly constructed object to parent
-                setValue0((BinaryObjectBuilder) srcObj, parent.propName, obj, obj.getClass());
-            }
         }
 
         /**
@@ -2264,11 +2224,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
             return isKeyProp0 == 1;
         }
-
-        /** {@inheritDoc} */
-        @Override public GridQueryProperty parent() {
-            return parent;
-        }
     }
 
     /**
@@ -2352,12 +2307,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
         /** {@inheritDoc} */
         @Override public GridQueryProperty property(String name) {
-            GridQueryProperty res = props.get(name);
-
-            if (res == null)
-                res = uppercaseProps.get(name.toUpperCase());
-
-            return res;
+            return getProperty(name);
         }
 
         /** {@inheritDoc} */
@@ -2365,7 +2315,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public <T> T value(String field, Object key, Object val) throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = property(field);
+            GridQueryProperty prop = getProperty(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2379,7 +2329,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = property(field);
+            GridQueryProperty prop = getProperty(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2519,6 +2469,19 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             fields.put(name, prop.type());
         }
 
+        /**
+         * @param field Property name.
+         * @return Property with given field name.
+         */
+        private GridQueryProperty getProperty(String field) {
+            GridQueryProperty res = props.get(field);
+
+            if (res == null)
+                res = uppercaseProps.get(field.toUpperCase());
+
+            return res;
+        }
+
         /** {@inheritDoc} */
         @Override public boolean valueTextIndex() {
             return valTextIdx;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
index fb4c037..5d74a2e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
@@ -22,7 +22,11 @@ import org.apache.ignite.IgniteCheckedException;
 /**
  * Description and access method for query entity field.
  */
-public interface GridQueryProperty {
+public abstract class GridQueryProperty {
+    /** */
+    public GridQueryProperty() {
+    }
+
     /**
      * Gets this property value from the given object.
      *
@@ -31,7 +35,7 @@ public interface GridQueryProperty {
      * @return Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public Object value(Object key, Object val) throws IgniteCheckedException;
+    public abstract Object value(Object key, Object val) throws IgniteCheckedException;
 
     /**
      * Sets this property value for the given object.
@@ -41,26 +45,21 @@ public interface GridQueryProperty {
      * @param propVal Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
+    public abstract void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
 
     /**
      * @return Property name.
      */
-    public String name();
+    public abstract String name();
 
     /**
      * @return Class member type.
      */
-    public Class<?> type();
+    public abstract Class<?> type();
 
     /**
      * Property ownership flag.
      * @return {@code true} if this property belongs to key, {@code false} if it belongs to value.
      */
-    public boolean key();
-
-    /**
-     * @return Parent property or {@code null} if this property is not nested.
-     */
-    public GridQueryProperty parent();
+    public abstract boolean key();
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
index 7995083..4030758 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
@@ -59,6 +59,7 @@ import org.apache.ignite.internal.processors.query.GridQueryProperty;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.h2.dml.FastUpdateArguments;
+import org.apache.ignite.internal.processors.query.h2.dml.KeyValueSupplier;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlanBuilder;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor;
@@ -480,6 +481,7 @@ public class DmlStatementsProcessor {
         while (it.hasNext()) {
             List<?> e = it.next();
             Object key = e.get(0);
+            Object val = (hasNewVal ? e.get(valColIdx) : e.get(1));
 
             Object newVal;
 
@@ -498,6 +500,9 @@ public class DmlStatementsProcessor {
             if (newVal == null)
                 throw new IgniteSQLException("New value for UPDATE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
+            if (bin && !(val instanceof BinaryObject))
+                val = cctx.grid().binary().toBinary(val);
+
             // Skip key and value - that's why we start off with 2nd column
             for (int i = 0; i < plan.tbl.getColumns().length - 2; i++) {
                 Column c = plan.tbl.getColumn(i + 2);
@@ -509,10 +514,13 @@ public class DmlStatementsProcessor {
 
                 boolean hasNewColVal = newColVals.containsKey(c.getName());
 
-                if (!hasNewColVal)
+                // Binary objects get old field values from the Builder, so we can skip what we're not updating
+                if (bin && !hasNewColVal)
                     continue;
 
-                Object colVal = newColVals.get(c.getName());
+                // Column values that have been explicitly specified have priority over field values in old or new _val
+                // If no value given for the column, then we expect to find it in value, and not in key - hence null arg.
+                Object colVal = hasNewColVal ? newColVals.get(c.getName()) : prop.value(null, val);
 
                 // UPDATE currently does not allow to modify key or its fields, so we must be safe to pass null as key.
                 desc.setColumnValue(null, newVal, colVal, i);
@@ -688,8 +696,8 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(),
-                plan);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
+                plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
 
             cctx.cache().put(t.getKey(), t.getValue());
             return 1;
@@ -701,7 +709,8 @@ public class DmlStatementsProcessor {
             for (Iterator<List<?>> it = cursor.iterator(); it.hasNext();) {
                 List<?> row = it.next();
 
-                IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
+                IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier, plan.valSupplier,
+                    plan.keyColIdx, plan.valColIdx, desc);
 
                 rows.put(t.getKey(), t.getValue());
 
@@ -733,7 +742,8 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(), plan);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes,
+                plan.keySupplier, plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
 
             if (cctx.cache().putIfAbsent(t.getKey(), t.getValue()))
                 return 1;
@@ -758,7 +768,8 @@ public class DmlStatementsProcessor {
             while (it.hasNext()) {
                 List<?> row = it.next();
 
-                final IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
+                final IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
+                    plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
 
                 rows.put(t.getKey(), new InsertEntryProcessor(t.getValue()));
 
@@ -826,14 +837,21 @@ public class DmlStatementsProcessor {
      * Convert row presented as an array of Objects into key-value pair to be inserted to cache.
      * @param cctx Cache context.
      * @param row Row to process.
-     * @param plan Update plan.
+     * @param cols Query cols.
+     * @param colTypes Column types to convert data from {@code row} to.
+     * @param keySupplier Key instantiation method.
+     * @param valSupplier Key instantiation method.
+     * @param keyColIdx Key column index, or {@code -1} if no key column is mentioned in {@code cols}.
+     * @param valColIdx Value column index, or {@code -1} if no value column is mentioned in {@code cols}.
+     * @param rowDesc Row descriptor.
      * @throws IgniteCheckedException if failed.
      */
     @SuppressWarnings({"unchecked", "ConstantConditions", "ResultOfMethodCallIgnored"})
-    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, List<?> row, UpdatePlan plan)
-        throws IgniteCheckedException {
-        Object key = plan.keySupplier.apply(row);
-        Object val = plan.valSupplier.apply(row);
+    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, Object[] row, String[] cols,
+        int[] colTypes, KeyValueSupplier keySupplier, KeyValueSupplier valSupplier, int keyColIdx, int valColIdx,
+        GridH2RowDescriptor rowDesc) throws IgniteCheckedException {
+        Object key = keySupplier.apply(F.asList(row));
+        Object val = valSupplier.apply(F.asList(row));
 
         if (key == null)
             throw new IgniteSQLException("Key for INSERT or MERGE must not be null",  IgniteQueryErrorCode.NULL_KEY);
@@ -841,32 +859,13 @@ public class DmlStatementsProcessor {
         if (val == null)
             throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
-        GridQueryTypeDescriptor desc = plan.tbl.rowDescriptor().type();
-
-        Map<String, Object> newColVals = new HashMap<>();
-
-        for (int i = 0; i < plan.colNames.length; i++) {
-            if (i == plan.keyColIdx || i == plan.valColIdx)
-                continue;
-
-            newColVals.put(plan.colNames[i], convert(row.get(i), plan.colNames[i],
-                plan.tbl.rowDescriptor(), plan.colTypes[i]));
-        }
-
-        // We update columns in the order specified by the table for a reason - table's
-        // column order preserves their precedence for correct update of nested properties.
-        Column[] cols = plan.tbl.getColumns();
+        GridQueryTypeDescriptor desc = rowDesc.type();
 
-        // First 2 columns are _key and _val, skip 'em.
-        for (int i = 2; i < cols.length; i++) {
-            String colName = cols[i].getName();
-
-            if (!newColVals.containsKey(colName))
+        for (int i = 0; i < cols.length; i++) {
+            if (i == keyColIdx || i == valColIdx)
                 continue;
 
-            Object colVal = newColVals.get(colName);
-
-            desc.setValue(colName, key, val, colVal);
+            desc.setValue(cols[i], key, val, convert(row[i], cols[i], rowDesc, colTypes[i]));
         }
 
         if (cctx.binaryMarshaller()) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
index ce2971a..fdcd164 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
@@ -48,7 +48,6 @@ import org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate;
 import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.h2.command.Prepared;
 import org.h2.table.Column;
@@ -193,8 +192,8 @@ public final class UpdatePlanBuilder {
                 hasValProps = true;
         }
 
-        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true, false);
-        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false, false);
+        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true);
+        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false);
 
         if (stmt instanceof GridSqlMerge)
             return UpdatePlan.forMerge(tbl.dataTable(), colNames, colTypes, keySupplier, valSupplier, keyColIdx,
@@ -254,6 +253,8 @@ public final class UpdatePlanBuilder {
             GridSqlSelect sel;
 
             if (stmt instanceof GridSqlUpdate) {
+                boolean bin = desc.context().binaryMarshaller();
+
                 List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
 
                 int valColIdx = -1;
@@ -281,10 +282,20 @@ public final class UpdatePlanBuilder {
                 if (hasNewVal)
                     valColIdx += 2;
 
-                int newValColIdx = (hasNewVal ? valColIdx : 1);
+                int newValColIdx;
+
+                if (!hasProps) // No distinct properties, only whole new value - let's take it
+                    newValColIdx = valColIdx;
+                else if (bin) // We update distinct columns in binary mode - let's choose correct index for the builder
+                    newValColIdx = (hasNewVal ? valColIdx : 1);
+                else // Distinct properties, non binary mode - let's instantiate.
+                    newValColIdx = -1;
 
-                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps,
-                    false, true);
+                // We want supplier to take present value only in case of binary mode as it will create
+                // whole new object as a result anyway, so we don't need to copy previous property values explicitly.
+                // Otherwise we always want it to instantiate new object whose properties we will later
+                // set to current values.
+                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false);
 
                 sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
 
@@ -308,11 +319,11 @@ public final class UpdatePlanBuilder {
      * @param hasProps Whether column list affects individual properties of key or value.
      * @param key Whether supplier should be created for key or for value.
      * @return Closure returning key or value.
-     * @throws IgniteCheckedException If failed.
+     * @throws IgniteCheckedException
      */
     @SuppressWarnings({"ConstantConditions", "unchecked"})
     private static KeyValueSupplier createSupplier(final GridCacheContext<?, ?> cctx, GridQueryTypeDescriptor desc,
-        final int colIdx, boolean hasProps, final boolean key, boolean forUpdate) throws IgniteCheckedException {
+                                                   final int colIdx, boolean hasProps, final boolean key) throws IgniteCheckedException {
         final String typeName = key ? desc.keyTypeName() : desc.valueTypeName();
 
         //Try to find class for the key locally.
@@ -321,10 +332,15 @@ public final class UpdatePlanBuilder {
 
         boolean isSqlType = GridQueryProcessor.isSqlType(cls);
 
-        // If we don't need to construct anything from scratch, just return value from given list.
-        if (isSqlType || !hasProps) {
+        // If we don't need to construct anything from scratch, just return value from array.
+        if (isSqlType || !hasProps || !cctx.binaryMarshaller()) {
             if (colIdx != -1)
-                return new PlainValueSupplier(colIdx);
+                return new KeyValueSupplier() {
+                    /** {@inheritDoc} */
+                    @Override public Object apply(List<?> arg) throws IgniteCheckedException {
+                        return arg.get(colIdx);
+                    }
+                };
             else if (isSqlType)
                 // Non constructable keys and values (SQL types) must be present in the query explicitly.
                 throw new IgniteCheckedException((key ? "Key" : "Value") + " is missing from query");
@@ -336,12 +352,7 @@ public final class UpdatePlanBuilder {
                 return new KeyValueSupplier() {
                     /** {@inheritDoc} */
                     @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                        Object obj = arg.get(colIdx);
-
-                        if (obj == null)
-                            return null;
-
-                        BinaryObject bin = cctx.grid().binary().toBinary(obj);
+                        BinaryObject bin = cctx.grid().binary().toBinary(arg.get(colIdx));
 
                         return cctx.grid().binary().builder(bin);
                     }
@@ -358,26 +369,6 @@ public final class UpdatePlanBuilder {
             }
         }
         else {
-            if (colIdx != -1) {
-                if (forUpdate && colIdx == 1) {
-                    // It's the case when the old value has to be taken as the basis for the new one on UPDATE,
-                    // so we have to clone it. And on UPDATE we don't expect any key supplier.
-                    assert !key;
-
-                    return new KeyValueSupplier() {
-                        /** {@inheritDoc} */
-                        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                            byte[] oldPropBytes = cctx.marshaller().marshal(arg.get(1));
-
-                            // colVal is another object now, we can mutate it
-                            return cctx.marshaller().unmarshal(oldPropBytes, U.resolveClassLoader(cctx.gridConfig()));
-                        }
-                    };
-                }
-                else // We either are not updating, or the new value is given explicitly, no cloning needed.
-                    return new PlainValueSupplier(colIdx);
-            }
-
             Constructor<?> ctor;
 
             try {
@@ -399,12 +390,8 @@ public final class UpdatePlanBuilder {
                             return ctor0.newInstance();
                         }
                         catch (Exception e) {
-                            if (S.INCLUDE_SENSITIVE)
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
-                            else
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + '.', e);
+                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
+                                (key ? "key" : "value"), e);
                         }
                     }
                 };
@@ -418,12 +405,8 @@ public final class UpdatePlanBuilder {
                             return GridUnsafe.allocateInstance(cls);
                         }
                         catch (InstantiationException e) {
-                            if (S.INCLUDE_SENSITIVE)
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
-                            else
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + '.', e);
+                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
+                                (key ? "key" : "value"), e);
                         }
                     }
                 };
@@ -431,6 +414,8 @@ public final class UpdatePlanBuilder {
         }
     }
 
+
+
     /**
      * @param target Expression to extract the table from.
      * @return Back end table for this element.
@@ -498,26 +483,4 @@ public final class UpdatePlanBuilder {
 
         return false;
     }
-
-    /**
-     * Simple supplier that just takes specified element of a given row.
-     */
-    private final static class PlainValueSupplier implements KeyValueSupplier {
-        /** Index of column to use. */
-        private final int colIdx;
-
-        /**
-         * Constructor.
-         *
-         * @param colIdx Column index.
-         */
-        private PlainValueSupplier(int colIdx) {
-            this.colIdx = colIdx;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-            return arg.get(colIdx);
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
index 626846b..86d01c7 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
@@ -46,8 +46,6 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.junits.IgniteTestResources;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
-import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
-
 /**
  *
  */
@@ -128,8 +126,6 @@ public abstract class IgniteCacheAbstractInsertSqlQuerySelfTest extends GridComm
             createCaches();
         else
             createBinaryCaches();
-
-        ignite(0).createCache(cacheConfig("I2AT", true, false, Integer.class, AllTypes.class));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
index 3c92fdf..649012f 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
@@ -65,7 +65,7 @@ public abstract class IgniteCacheAbstractSqlDmlQuerySelfTest extends GridCommonA
     /**
      * @return whether {@link #marsh} is an instance of {@link BinaryMarshaller} or not.
      */
-    protected boolean isBinaryMarshaller() {
+    private boolean isBinaryMarshaller() {
         return marsh instanceof BinaryMarshaller;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
index f91f405..e9c21dc 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
@@ -17,8 +17,6 @@
 
 package org.apache.ignite.internal.processors.cache;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.concurrent.Callable;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCache;
@@ -204,24 +202,4 @@ public class IgniteCacheInsertSqlQuerySelfTest extends IgniteCacheAbstractInsert
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
-
-    /**
-     *
-     */
-    public void testNestedFieldsHandling() {
-        IgniteCache<Integer, IgniteCacheUpdateSqlQuerySelfTest.AllTypes> p = ignite(0).cache("I2AT");
-
-        p.query(new SqlFieldsQuery("insert into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
-            "values (1, ?, ?, ?, 'sss')") .setArgs(new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L),
-            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L)));
-
-        IgniteCacheUpdateSqlQuerySelfTest.AllTypes res = p.get(1);
-
-        IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType resInner = new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L);
-
-        resInner.innerStrCol = "sss";
-        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
-
-        assertEquals(resInner, res.innerTypeCol);
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
index d9a2d9e..32b7a12 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
@@ -17,13 +17,9 @@
 
 package org.apache.ignite.internal.processors.cache;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 
-import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
-
 /**
  *
  */
@@ -153,24 +149,4 @@ public class IgniteCacheMergeSqlQuerySelfTest extends IgniteCacheAbstractInsertS
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
-
-    /**
-     *
-     */
-    public void testNestedFieldsHandling() {
-        IgniteCache<Integer, AllTypes> p = ignite(0).cache("I2AT");
-
-        p.query(new SqlFieldsQuery("merge into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
-            "values (1, ?, ?, ?, 'sss')") .setArgs(new AllTypes.InnerType(50L),
-            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new AllTypes(1L)));
-
-        AllTypes res = p.get(1);
-
-        AllTypes.InnerType resInner = new AllTypes.InnerType(50L);
-
-        resInner.innerStrCol = "sss";
-        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
-
-        assertEquals(resInner, res.innerTypeCol);
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
index c3d9d8e..575f617 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
@@ -44,12 +44,6 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         ignite(0).createCache(createAllTypesCacheConfig());
     }
 
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-        ignite(0).cache("L2AT").clear();
-    }
-
     /**
      *
      */
@@ -188,19 +182,17 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\"," +
             "\"tsCol\") values(2, ?, '2016-11-30 12:00:00', false, DATE '2016-12-01')").setArgs(new AllTypes(2L)));
 
-        // Look ma, no hands: first we set value of inner object column (innerTypeCol), then update only one of its
-        // fields (innerLongCol), while leaving another inner property (innerStrCol) as specified by innerTypeCol.
-        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = ?, \"doubleCol\" = CAST('50' as INT)," +
+        cache.query(new SqlFieldsQuery("select \"primitiveIntsCol\" from \"AllTypes\"")).getAll();
+
+        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"doubleCol\" = CAST('50' as INT)," +
             " \"booleanCol\" = 80, \"innerTypeCol\" = ?, \"strCol\" = PI(), \"shortCol\" = " +
             "CAST(WEEK(PARSEDATETIME('2016-11-30', 'yyyy-MM-dd')) as VARCHAR), " +
             "\"sqlDateCol\"=TIMESTAMP '2016-12-02 13:47:00', \"tsCol\"=TIMESTAMPADD('MI', 2, " +
             "DATEADD('DAY', 2, \"tsCol\")), \"primitiveIntsCol\" = ?, \"bytesCol\" = ?")
-            .setArgs(5, new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
+            .setArgs(new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
 
         AllTypes res = (AllTypes) cache.get(2L);
 
-        assertNotNull(res);
-
         assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
         assertEquals(50.0, res.doubleCol);
         assertEquals(2L, (long) res.longCol);
@@ -210,11 +202,7 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertTrue(Arrays.equals(new Byte[] {4, 5, 6}, res.bytesCol));
         assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
         assertTrue(Arrays.equals(new int[] {2, 3}, res.primitiveIntsCol));
-
-        AllTypes.InnerType expInnerType = new AllTypes.InnerType(80L);
-        expInnerType.innerLongCol = 5L;
-
-        assertEquals(expInnerType, res.innerTypeCol);
+        assertEquals(new AllTypes.InnerType(80L), res.innerTypeCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-12-03 00:02:00"), res.tsCol);
         assertEquals(2, res.intCol);
@@ -225,45 +213,6 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertEquals(49, res.shortCol);
     }
 
-    /** */
-    public void testSingleInnerFieldUpdate() throws ParseException {
-        IgniteCache cache = ignite(0).cache("L2AT");
-
-        cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\") values(2, ?," +
-            "'2016-11-30 12:00:00', false)").setArgs(new AllTypes(2L)));
-
-        assertFalse(cache.query(new SqlFieldsQuery("select * from \"AllTypes\"")).getAll().isEmpty());
-
-        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = 5"));
-
-        AllTypes res = (AllTypes) cache.get(2L);
-
-        assertNotNull(res);
-
-        assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
-        assertEquals(3.01, res.doubleCol);
-        assertEquals(2L, (long) res.longCol);
-        assertFalse(res.booleanCol);
-
-        assertEquals("2", res.strCol);
-        assertTrue(Arrays.equals(new byte[] {0, 1}, res.primitiveBytesCol));
-        assertTrue(Arrays.deepEquals(new Byte[] {0, 1}, res.bytesCol));
-        assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
-        assertTrue(Arrays.equals(new int[] {0, 1}, res.primitiveIntsCol));
-
-        AllTypes.InnerType expInnerType = new AllTypes.InnerType(2L);
-        expInnerType.innerLongCol = 5L;
-
-        assertEquals(expInnerType, res.innerTypeCol);
-        assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
-        assertNull(res.tsCol);
-        assertEquals(2, res.intCol);
-        assertEquals(AllTypes.EnumType.ENUMTRUE, res.enumCol);
-        assertNull(res.sqlDateCol);
-
-        assertEquals(-23000, res.shortCol);
-    }
-
     /**
      *
      */
@@ -359,7 +308,7 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         InnerType innerTypeCol;
 
         /** */
-        static class InnerType implements Serializable {
+        static final class InnerType implements Serializable {
             /** */
             @QuerySqlField
             Long innerLongCol;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index 69285f1..e412828 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -578,11 +578,6 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
                 @Override public boolean key() {
                     return false;
                 }
-
-                /** */
-                @Override public GridQueryProperty parent() {
-                    return null;
-                }
             };
         }
 


[06/50] [abbrv] ignite git commit: IGNITE-3793: Need to fix dependencies and it's licenses Reviewed and merged by Denis Magda (dmagda@apache.org)

Posted by sb...@apache.org.
IGNITE-3793: Need to fix dependencies and it's licenses
Reviewed and merged by Denis Magda (dmagda@apache.org)


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: d20b7f1d29fae7c7907fa9905ac39493ec66b465
Parents: 96527d9
Author: Alexander Fedotov <al...@gmail.com>
Authored: Fri Feb 3 10:10:49 2017 -0800
Committer: Denis Magda <dm...@gridgain.com>
Committed: Fri Feb 3 10:10:49 2017 -0800

----------------------------------------------------------------------
 assembly/LICENSE_FABRIC                         | 35 ++++++++++----------
 assembly/LICENSE_HADOOP                         | 17 +++++-----
 examples/schema-import/bin/h2-server.bat        |  2 +-
 examples/schema-import/bin/h2-server.sh         |  4 +--
 .../schema-import/bin/schema-import.properties  |  2 +-
 .../src/main/resources/META-INF/licenses.txt.vm |  7 ++--
 6 files changed, 32 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d20b7f1d/assembly/LICENSE_FABRIC
----------------------------------------------------------------------
diff --git a/assembly/LICENSE_FABRIC b/assembly/LICENSE_FABRIC
index b9c75b2..35a8529 100644
--- a/assembly/LICENSE_FABRIC
+++ b/assembly/LICENSE_FABRIC
@@ -214,9 +214,8 @@ licenses.
 ==============================================================================
 For SnapTree:
 ==============================================================================
-This product bundles SnapTree, which is available under a
-"3-clause BSD" license.  For details, see
-https://github.com/nbronson/snaptree/blob/master/LICENSE.
+This product bundles SnapTree, which is available under the following:
+"3-clause BSD" license. For details, see https://github.com/nbronson/snaptree/blob/master/LICENSE.
 
 ==============================================================================
 For JSR 166 classes in "org.jsr166" package
@@ -228,55 +227,55 @@ http://creativecommons.org/publicdomain/zero/1.0/
 ==============================================================================
 For JSR107 API and SPI (https://github.com/jsr107/jsr107spec) javax.cache:cache-api:jar:1.0.0
 ==============================================================================
-This product bundles JSR107 API and SPI which is available under a:
-JSR-000107 JCACHE 2.9 Public Review - Updated Specification License. For details, see https://raw.github.com/jsr107/jsr107spec/master/LICENSE.txt.
+This product bundles JSR107 API and SPI which is available under the following:
+JSR-000107 JCACHE 2.9 Public Review - Updated Specification License. https://raw.github.com/jsr107/jsr107spec/master/LICENSE.txt
 
 ==============================================================================
 For JSch (http://www.jcraft.com/jsch/) com.jcraft:jsch:jar:0.1.50
 ==============================================================================
-This product bundles JSch which is available under a:
+This product bundles JSch which is available under the following:
 Revised BSD. For details, see http://www.jcraft.com/jsch/LICENSE.txt.
 
 ==============================================================================
 For JLine (http://nexus.sonatype.org/oss-repository-hosting.html/jline) jline:jline:jar:2.12.1
 ==============================================================================
-This product bundles JLine which is available under a:
+This product bundles JLine which is available under the following:
 The BSD License. For details, see http://www.opensource.org/licenses/bsd-license.php.
 
 ==============================================================================
 For Scala Library (http://www.scala-lang.org/) org.scala-lang:scala-library:jar:2.*
 ==============================================================================
-This product bundles Scala Library which is available under a:
+This product bundles Scala Library which is available under the following:
 BSD 3-Clause. For details, see http://www.scala-lang.org/license.html.
 
 ==============================================================================
-For H2 Database Engine (http://www.h2database.com) com.h2database:h2:jar:1.3.175
+For H2 Database Engine (http://www.h2database.com) com.h2database:h2:jar:1.4.191
 ==============================================================================
-This product bundles H2 Database Engine which is available under a:
-The H2 License, Version 1.0. For details, see http://h2database.com/html/license.html.
+This product bundles H2 Database Engine which is available under the following:
+MPL 2.0, and EPL 1.0. For details, see http://h2database.com/html/license.html.
 
 ==============================================================================
 For JTidy (http://jtidy.sourceforge.net) net.sf.jtidy:jtidy:jar:r938
 ==============================================================================
-This product bundles JTidy which is available under a:
+This product bundles JTidy which is available under the following:
 Java HTML Tidy License. For details, see http://jtidy.svn.sourceforge.net/viewvc/jtidy/trunk/jtidy/LICENSE.txt?revision=95.
 
 ==============================================================================
 For tomcat-servlet-api (http://tomcat.apache.org/) org.apache.tomcat:tomcat-servlet-api:jar:8.0.23
 ==============================================================================
-This product bundles tomcat-servlet-api which is available under a:
+This product bundles tomcat-servlet-api which is available under the following:
 Apache License, Version 2.0 and Common Development And Distribution License (CDDL) Version 1.0. For details, see http://www.apache.org/licenses/LICENSE-2.0.txt and http://www.opensource.org/licenses/cddl1.txt.
 
 ==============================================================================
 For AOP alliance (http://aopalliance.sourceforge.net) aopalliance:aopalliance:jar:1.0
 ==============================================================================
-This product bundles AOP alliance which is available under a:
+This product bundles AOP alliance which is available under the following:
 Public Domain.
 
 ==============================================================================
 For AspectJ (http://www.aspectj.org) org.aspectj:*:jar:1.7.2
 ==============================================================================
-This product bundles AspectJ which is available under a:
+This product bundles AspectJ which is available under the following:
 Eclipse Public License - v 1.0. For details, see http://www.eclipse.org/legal/epl-v10.html.
 
 ==============================================================================
@@ -288,18 +287,18 @@ See http://download.oracle.com/otndocs/jcp/jta-1.1-classes-oth-JSpec/jta-1.1-cla
 ==============================================================================
 For ASM All (http://asm.objectweb.org/asm-all/) org.ow2.asm:asm-all:jar:4.2
 ==============================================================================
-This product bundles ASM All which is available under a:
+This product bundles ASM All which is available under the following:
 BSD. For details, see http://asm.objectweb.org/license.html.
 
 ==============================================================================
 For Jetty (http://www.eclipse.org/jetty) org.eclipse.jetty:*:jar:9.2.11.v20150529
 ==============================================================================
-This product bundles Jetty which is available under a:
+This product bundles Jetty which is available under the following:
 Apache Software License - Version 2.0. For details, see http://www.apache.org/licenses/LICENSE-2.0.
 Eclipse Public License - Version 1.0. For details, see http://www.eclipse.org/org/documents/epl-v10.php.
 
 ==============================================================================
 For SLF4J API Module (http://www.slf4j.org) org.slf4j:slf4j-api:jar:1.6.4
 ==============================================================================
-This product bundles SLF4J API Module which is available under a:
+This product bundles SLF4J API Module which is available under the following:
 MIT License. For details, see http://www.opensource.org/licenses/mit-license.php.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d20b7f1d/assembly/LICENSE_HADOOP
----------------------------------------------------------------------
diff --git a/assembly/LICENSE_HADOOP b/assembly/LICENSE_HADOOP
index 0256b20..f2128fe 100644
--- a/assembly/LICENSE_HADOOP
+++ b/assembly/LICENSE_HADOOP
@@ -214,9 +214,8 @@ licenses.
 ==============================================================================
 For SnapTree:
 ==============================================================================
-This product bundles SnapTree, which is available under a
-"3-clause BSD" license.  For details, see
-https://github.com/nbronson/snaptree/blob/master/LICENSE.
+This product bundles SnapTree, which is available under the following:
+"3-clause BSD" license. For details, see https://github.com/nbronson/snaptree/blob/master/LICENSE.
 
 ==============================================================================
 For JSR 166 classes in "org.jsr166" package
@@ -228,31 +227,31 @@ http://creativecommons.org/publicdomain/zero/1.0/
 ==============================================================================
 For JSR107 API and SPI (https://github.com/jsr107/jsr107spec) javax.cache:cache-api:jar:1.0.0
 ==============================================================================
-This product bundles JSR107 API and SPI which is available under a:
-JSR-000107 JCACHE 2.9 Public Review - Updated Specification License. For details, see https://raw.github.com/jsr107/jsr107spec/master/LICENSE.txt.
+This product bundles JSR107 API and SPI which is available under the following:
+JSR-000107 JCACHE 2.9 Public Review - Updated Specification License. https://raw.github.com/jsr107/jsr107spec/master/LICENSE.txt
 
 ==============================================================================
 For JSch (http://www.jcraft.com/jsch/) com.jcraft:jsch:jar:0.1.50
 ==============================================================================
-This product bundles JSch which is available under a:
+This product bundles JSch which is available under the following:
 Revised BSD. For details, see http://www.jcraft.com/jsch/LICENSE.txt.
 
 ==============================================================================
 For JLine (http://nexus.sonatype.org/oss-repository-hosting.html/jline) jline:jline:jar:2.12.1
 ==============================================================================
-This product bundles JLine which is available under a:
+This product bundles JLine which is available under the following:
 The BSD License. For details, see http://www.opensource.org/licenses/bsd-license.php.
 
 ==============================================================================
 For Scala Library (http://www.scala-lang.org/) org.scala-lang:scala-library:jar:2.11.2
 ==============================================================================
-This product bundles Scala Library which is available under a:
+This product bundles Scala Library which is available under the following:
 BSD 3-Clause. For details, see http://www.scala-lang.org/license.html.
 
 ==============================================================================
 For ASM All (http://asm.objectweb.org/asm-all/) org.ow2.asm:asm-all:jar:4.2
 ==============================================================================
-This product bundles ASM All which is available under a:
+This product bundles ASM All which is available under the following:
 BSD. For details, see http://asm.objectweb.org/license.html.
 
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d20b7f1d/examples/schema-import/bin/h2-server.bat
----------------------------------------------------------------------
diff --git a/examples/schema-import/bin/h2-server.bat b/examples/schema-import/bin/h2-server.bat
index 3f220d1..d445231 100644
--- a/examples/schema-import/bin/h2-server.bat
+++ b/examples/schema-import/bin/h2-server.bat
@@ -75,6 +75,6 @@ if exist "%IGNITE_HOME%\config" goto run
 :run
 
 :: Starts H2 server and console.
-"%JAVA_HOME%\bin\java.exe" -cp "%IGNITE_HOME%\libs\ignite-indexing\h2-1.3.175.jar" org.h2.tools.Console %*
+"%JAVA_HOME%\bin\java.exe" -cp "%IGNITE_HOME%\libs\ignite-indexing\h2-1.4.191.jar" org.h2.tools.Console %*
 
 :error_finish
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d20b7f1d/examples/schema-import/bin/h2-server.sh
----------------------------------------------------------------------
diff --git a/examples/schema-import/bin/h2-server.sh b/examples/schema-import/bin/h2-server.sh
index e714f4c..512a1d9 100755
--- a/examples/schema-import/bin/h2-server.sh
+++ b/examples/schema-import/bin/h2-server.sh
@@ -58,9 +58,9 @@ fi
 # Starts H2 server and console.
 case $osname in
     Darwin*)
-        "${JAVA}" "${DOCK_OPTS}" -cp "${IGNITE_HOME}/libs/ignite-indexing/h2-1.3.175.jar" org.h2.tools.Console ${ARGS}
+        "${JAVA}" "${DOCK_OPTS}" -cp "${IGNITE_HOME}/libs/ignite-indexing/h2-1.4.191.jar" org.h2.tools.Console ${ARGS}
         ;;
    *)
-        "${JAVA}" -cp "${IGNITE_HOME}/libs/ignite-indexing/h2-1.3.175.jar" org.h2.tools.Console ${ARGS}
+        "${JAVA}" -cp "${IGNITE_HOME}/libs/ignite-indexing/h2-1.4.191.jar" org.h2.tools.Console ${ARGS}
         ;;
 esac

http://git-wip-us.apache.org/repos/asf/ignite/blob/d20b7f1d/examples/schema-import/bin/schema-import.properties
----------------------------------------------------------------------
diff --git a/examples/schema-import/bin/schema-import.properties b/examples/schema-import/bin/schema-import.properties
index 5d31965..99ebab8 100644
--- a/examples/schema-import/bin/schema-import.properties
+++ b/examples/schema-import/bin/schema-import.properties
@@ -19,7 +19,7 @@
 #  Predefined properties for Ignite Schema Import Demo
 #
 jdbc.db.preset=0
-jdbc.driver.jar=libs/ignite-indexing/h2-1.3.175.jar
+jdbc.driver.jar=libs/ignite-indexing/h2-1.4.191.jar
 jdbc.driver.class=org.h2.Driver
 jdbc.url=jdbc:h2:tcp://localhost/~/schema-import/demo
 jdbc.user=sa

http://git-wip-us.apache.org/repos/asf/ignite/blob/d20b7f1d/modules/apache-license-gen/src/main/resources/META-INF/licenses.txt.vm
----------------------------------------------------------------------
diff --git a/modules/apache-license-gen/src/main/resources/META-INF/licenses.txt.vm b/modules/apache-license-gen/src/main/resources/META-INF/licenses.txt.vm
index ca1988b..ede7960 100644
--- a/modules/apache-license-gen/src/main/resources/META-INF/licenses.txt.vm
+++ b/modules/apache-license-gen/src/main/resources/META-INF/licenses.txt.vm
@@ -19,17 +19,16 @@
 ## $Id$
 ##
 // ------------------------------------------------------------------
-// List of #if ($projectName)$projectName#else${project.name}#end module's dependencies provided as a part of this distribution
-// which licenses differ from Apache Software License.
+// List of #if ($projectName)$projectName#else${project.name}#end module's dependencies provided as a part of this distribution.
 // ------------------------------------------------------------------
 
 #foreach ( $organizationName in $projectsSortedByOrganization.keySet() )
 #foreach ( $project in $projectsSortedByOrganization.get( $organizationName ) )
-#if((!($project.licenses.size() == 1 && $project.licenses.get(0).url.contains("www.apache.org/licenses/LICENSE-2.0") && !$project.licenses.get(0).url.contains("and"))) && $project.licenses.size() > 0)
+#if($project.licenses.size() > 0)
 ==============================================================================
 For $project.name #if ($project.url)($project.url)#end $project.artifact
 ==============================================================================
-This product bundles $project.name which is available under a:
+This product bundles $project.name which is available under the following:
 #foreach ( $license in $project.licenses )
 $license.name.replaceAll("[ ]{2,}"," ").replaceAll("\n",""). #if ($license.url)For details, see $license.url.replaceAll("[ ]{2,}"," ").replaceAll("\n","").#end
 


[37/50] [abbrv] ignite git commit: IGNITE-4688: Changed copyrights to 2017.

Posted by sb...@apache.org.
IGNITE-4688: Changed copyrights to 2017.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 5245214d316437b8ba82093cd356204083aee75b
Parents: d949b73
Author: devozerov <vo...@gridgain.com>
Authored: Mon Feb 13 13:04:37 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Feb 13 13:12:50 2017 +0300

----------------------------------------------------------------------
 .../main/java/org/apache/ignite/internal/IgniteVersionUtils.java   | 2 +-
 .../org/apache/ignite/startup/GridRandomCommandLineLoader.java     | 2 +-
 .../dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs   | 2 +-
 .../dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.nuspec        | 2 +-
 .../dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs         | 2 +-
 .../Apache.Ignite.Core.Tests.NuGet/Properties/AssemblyInfo.cs      | 2 +-
 .../dotnet/Apache.Ignite.Core/Apache.Ignite.Core.Schema.nuspec     | 2 +-
 .../platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.nuspec  | 2 +-
 .../platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs | 2 +-
 .../platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.nuspec  | 2 +-
 .../dotnet/Apache.Ignite.Log4Net/Apache.Ignite.Log4Net.nuspec      | 2 +-
 .../dotnet/Apache.Ignite.Log4Net/Properties/AssemblyInfo.cs        | 2 +-
 .../platforms/dotnet/Apache.Ignite.NLog/Apache.Ignite.NLog.nuspec  | 2 +-
 .../platforms/dotnet/Apache.Ignite.NLog/Properties/AssemblyInfo.cs | 2 +-
 .../web-console/frontend/app/modules/branding/branding.provider.js | 2 +-
 15 files changed, 15 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/core/src/main/java/org/apache/ignite/internal/IgniteVersionUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteVersionUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteVersionUtils.java
index bd8726f..7cb15be 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteVersionUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteVersionUtils.java
@@ -47,7 +47,7 @@ public class IgniteVersionUtils {
     public static final String ACK_VER_STR;
 
     /** Copyright blurb. */
-    public static final String COPYRIGHT = "2016 Copyright(C) Apache Software Foundation";
+    public static final String COPYRIGHT = "2017 Copyright(C) Apache Software Foundation";
 
     /**
      * Static initializer.

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java b/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
index 13c38ef..73a9760 100644
--- a/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
+++ b/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
@@ -61,7 +61,7 @@ public final class GridRandomCommandLineLoader {
     private static final String IGNITE_PROG_NAME = "IGNITE_PROG_NAME";
 
     /** Copyright text. Ant processed. */
-    private static final String COPYRIGHT = "2016 Copyright(C) Apache Software Foundation.";
+    private static final String COPYRIGHT = "2017 Copyright(C) Apache Software Foundation.";
 
     /** Version. Ant processed. */
     private static final String VER = "x.x.x";

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs
index 1bca0e8..72e65c0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs
@@ -27,7 +27,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright �  2016")]
+[assembly: AssemblyCopyright("Copyright �  2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.nuspec
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.nuspec b/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.nuspec
index 49f2fe8..7891614 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.nuspec
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.nuspec
@@ -45,7 +45,7 @@ Session State Store Provider: stores session state data in a distributed in-memo
 More info: https://apacheignite-net.readme.io/
         </description>
         <releaseNotes></releaseNotes>
-        <copyright>Copyright 2016</copyright>
+        <copyright>Copyright 2017</copyright>
         <tags>OutputCacheProvider Apache Ignite In-Memory Distributed Computing SQL NoSQL Grid Map Reduce Cache</tags>
         <dependencies>
             <dependency id="Apache.Ignite" version="[$version$]" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
index 0926a46..1073986 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
@@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.Core.Tests.NuGet/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.NuGet/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.NuGet/Properties/AssemblyInfo.cs
index b7d8e09..898397d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.NuGet/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.NuGet/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright �  2016")]
+[assembly: AssemblyCopyright("Copyright �  2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.Schema.nuspec
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.Schema.nuspec b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.Schema.nuspec
index e57e371..52dc1e0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.Schema.nuspec
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.Schema.nuspec
@@ -42,7 +42,7 @@ XSD file describes the structure of IgniteConfigurationSection and enables Intel
 More info on Apache Ignite.NET: https://apacheignite-net.readme.io/
         </description>
         <releaseNotes></releaseNotes>
-        <copyright>Copyright 2016</copyright>
+        <copyright>Copyright 2017</copyright>
         <tags>Apache Ignite XSD Intellisense</tags>
     </metadata>
     <files>

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.nuspec
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.nuspec b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.nuspec
index 8621103..8f562f1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.nuspec
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.nuspec
@@ -45,7 +45,7 @@ Apache Ignite In-Memory Data Fabric is a high-performance, integrated and distri
 More info: https://apacheignite-net.readme.io/
         </description>
         <releaseNotes></releaseNotes>
-        <copyright>Copyright 2016</copyright>
+        <copyright>Copyright 2017</copyright>
         <tags>Apache Ignite In-Memory Distributed Computing SQL NoSQL Grid Map Reduce Cache linqpad-samples</tags>
     </metadata>
     <files>

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
index c0462db..cb903aa 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
@@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2016")]
+[assembly: AssemblyCopyright("Copyright 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.nuspec
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.nuspec b/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.nuspec
index 330ed29..c71d672 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.nuspec
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.nuspec
@@ -47,7 +47,7 @@ All Ignite SQL features are supported: distributed joins, groupings, aggregates,
 More info: https://apacheignite-net.readme.io/
         </description>
         <releaseNotes></releaseNotes>
-        <copyright>Copyright 2016</copyright>
+        <copyright>Copyright 2017</copyright>
         <tags>Apache Ignite In-Memory Distributed Computing SQL NoSQL LINQ Grid Map Reduce Cache linqpad-samples</tags>
         <dependencies>
             <dependency id="Apache.Ignite" version="[$version$]" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.Log4Net/Apache.Ignite.Log4Net.nuspec
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Log4Net/Apache.Ignite.Log4Net.nuspec b/modules/platforms/dotnet/Apache.Ignite.Log4Net/Apache.Ignite.Log4Net.nuspec
index fa5c39a..a3f86c1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Log4Net/Apache.Ignite.Log4Net.nuspec
+++ b/modules/platforms/dotnet/Apache.Ignite.Log4Net/Apache.Ignite.Log4Net.nuspec
@@ -40,7 +40,7 @@ Creating NuGet package:
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <description>log4net Logger for Apache Ignite</description>
         <releaseNotes></releaseNotes>
-        <copyright>Copyright 2016</copyright>
+        <copyright>Copyright 2017</copyright>
         <tags>Apache Ignite In-Memory Distributed Computing SQL NoSQL LINQ Grid Map Reduce Cache log4net logger</tags>
         <dependencies>
             <dependency id="Apache.Ignite" version="[$version$]" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.Log4Net/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Log4Net/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Log4Net/Properties/AssemblyInfo.cs
index cc37917..396c837 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Log4Net/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Log4Net/Properties/AssemblyInfo.cs
@@ -24,7 +24,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright �  2016")]
+[assembly: AssemblyCopyright("Copyright �  2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.NLog/Apache.Ignite.NLog.nuspec
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.NLog/Apache.Ignite.NLog.nuspec b/modules/platforms/dotnet/Apache.Ignite.NLog/Apache.Ignite.NLog.nuspec
index 765e26f..e3a6f42 100644
--- a/modules/platforms/dotnet/Apache.Ignite.NLog/Apache.Ignite.NLog.nuspec
+++ b/modules/platforms/dotnet/Apache.Ignite.NLog/Apache.Ignite.NLog.nuspec
@@ -40,7 +40,7 @@ Creating NuGet package:
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <description>NLog Logger for Apache Ignite</description>
         <releaseNotes></releaseNotes>
-        <copyright>Copyright 2016</copyright>
+        <copyright>Copyright 2017</copyright>
         <tags>Apache Ignite In-Memory Distributed Computing SQL NoSQL LINQ Grid Map Reduce Cache NLog logger</tags>
         <dependencies>
             <dependency id="Apache.Ignite" version="[$version$]" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/platforms/dotnet/Apache.Ignite.NLog/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.NLog/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.NLog/Properties/AssemblyInfo.cs
index 2f0d89f..6802594 100644
--- a/modules/platforms/dotnet/Apache.Ignite.NLog/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.NLog/Properties/AssemblyInfo.cs
@@ -24,7 +24,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright �  2016")]
+[assembly: AssemblyCopyright("Copyright �  2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5245214d/modules/web-console/frontend/app/modules/branding/branding.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/branding.provider.js b/modules/web-console/frontend/app/modules/branding/branding.provider.js
index ce14b34..0545ff3 100644
--- a/modules/web-console/frontend/app/modules/branding/branding.provider.js
+++ b/modules/web-console/frontend/app/modules/branding/branding.provider.js
@@ -26,7 +26,7 @@ export default ['IgniteBranding', [function() {
 
     let footerHtml = [
         '<p>Apache Ignite Web Console</p>',
-        '<p>� 2016 The Apache Software Foundation.</p>',
+        '<p>� 2017 The Apache Software Foundation.</p>',
         '<p>Apache, Apache Ignite, the Apache feather and the Apache Ignite logo are trademarks of The Apache Software Foundation.</p>'
     ];
 


[23/50] [abbrv] ignite git commit: New benchmark for putting values with primitive fields only.

Posted by sb...@apache.org.
New benchmark for putting values with primitive fields only.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: e1c3ddaf6238545ade73cd5e0627584e16e8ddf1
Parents: 4a62232
Author: Igor Seliverstov <gv...@gmail.com>
Authored: Thu Feb 9 16:40:50 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Feb 9 17:50:35 2017 +0300

----------------------------------------------------------------------
 .../cache/IgnitePutValue8Benchmark.java         | 42 ++++++++++++++++++++
 1 file changed, 42 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c3ddaf/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutValue8Benchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutValue8Benchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutValue8Benchmark.java
new file mode 100644
index 0000000..6a3d492
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutValue8Benchmark.java
@@ -0,0 +1,42 @@
+/*
+ * 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.yardstick.cache;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.yardstick.cache.model.Person8;
+
+import java.util.Map;
+
+/**
+ * Ignite benchmark that performs put operations for entity with primitive fields.
+ */
+public class IgnitePutValue8Benchmark extends IgniteCacheAbstractBenchmark<Integer, Object> {
+    /** {@inheritDoc} */
+    @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+        int key = nextRandom(args.range());
+
+        cache.put(key, new Person8(key));
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Integer, Object> cache() {
+        return ignite().cache("atomic");
+    }
+}


[39/50] [abbrv] ignite git commit: IGNITE-4688: Changed copyrights to 2017.

Posted by sb...@apache.org.
IGNITE-4688: Changed copyrights to 2017.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: 0ace63c6c02656802b30d59bb51a0e4da84dbe1b
Parents: cff20e7
Author: devozerov <vo...@gridgain.com>
Authored: Mon Feb 13 13:19:56 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Feb 13 13:22:04 2017 +0300

----------------------------------------------------------------------
 NOTICE                                                             | 2 +-
 assembly/NOTICE_FABRIC                                             | 2 +-
 assembly/NOTICE_HADOOP                                             | 2 +-
 modules/core/src/main/java/META-INF/NOTICE                         | 2 +-
 .../examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs  | 2 +-
 modules/scalar-2.10/pom.xml                                        | 2 +-
 modules/scalar/pom.xml                                             | 2 +-
 parent/pom.xml                                                     | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 5ec3b0e..33e2479 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Ignite
-Copyright 2015 The Apache Software Foundation
+Copyright 2017 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/assembly/NOTICE_FABRIC
----------------------------------------------------------------------
diff --git a/assembly/NOTICE_FABRIC b/assembly/NOTICE_FABRIC
index 2e55768..c5e6f02 100644
--- a/assembly/NOTICE_FABRIC
+++ b/assembly/NOTICE_FABRIC
@@ -1,5 +1,5 @@
 Apache Ignite
-Copyright 2015 The Apache Software Foundation
+Copyright 2017 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/assembly/NOTICE_HADOOP
----------------------------------------------------------------------
diff --git a/assembly/NOTICE_HADOOP b/assembly/NOTICE_HADOOP
index 5ec3b0e..33e2479 100644
--- a/assembly/NOTICE_HADOOP
+++ b/assembly/NOTICE_HADOOP
@@ -1,5 +1,5 @@
 Apache Ignite
-Copyright 2015 The Apache Software Foundation
+Copyright 2017 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/modules/core/src/main/java/META-INF/NOTICE
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/META-INF/NOTICE b/modules/core/src/main/java/META-INF/NOTICE
index 5ec3b0e..33e2479 100644
--- a/modules/core/src/main/java/META-INF/NOTICE
+++ b/modules/core/src/main/java/META-INF/NOTICE
@@ -1,5 +1,5 @@
 Apache Ignite
-Copyright 2015 The Apache Software Foundation
+Copyright 2017 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
index 6d28b2b..cc78a5c 100644
--- a/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/examples/Apache.Ignite.ExamplesDll/Properties/AssemblyInfo.cs
@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Software Foundation")]
 [assembly: AssemblyProduct("Apache Ignite.NET")]
-[assembly: AssemblyCopyright("Copyright 2017")]
+[assembly: AssemblyCopyright("Copyright 2016")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/modules/scalar-2.10/pom.xml
----------------------------------------------------------------------
diff --git a/modules/scalar-2.10/pom.xml b/modules/scalar-2.10/pom.xml
index 569c13d..8d3d86d 100644
--- a/modules/scalar-2.10/pom.xml
+++ b/modules/scalar-2.10/pom.xml
@@ -158,7 +158,7 @@
                                             <!--<td>-->
                                                 <!--<nobr>Ignite&#153; - Scalar DSL, ver. <strong>${project.version}</strong></nobr>-->
                                                 <!--<br>-->
-                                                <!--<a target=_blank href="https://ignite.apache.org"><nobr>2015 Copyright &#169; Apache Software Foundation</nobr></a>-->
+                                                <!--<a target=_blank href="https://ignite.apache.org"><nobr>2017 Copyright &#169; Apache Software Foundation</nobr></a>-->
                                             <!--</td>-->
                                         <!--</tr>-->
                                         <!--</table>-->

http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/modules/scalar/pom.xml
----------------------------------------------------------------------
diff --git a/modules/scalar/pom.xml b/modules/scalar/pom.xml
index c8d12ff..2bb114f 100644
--- a/modules/scalar/pom.xml
+++ b/modules/scalar/pom.xml
@@ -143,7 +143,7 @@
                                             <td>
                                                 <nobr>Ignite&#153; - Scalar DSL, ver. <strong>${project.version}</strong></nobr>
                                                 <br>
-                                                <a target=_blank href="https://ignite.apache.org"><nobr>2015 Copyright &#169; Apache Software Foundation</nobr></a>
+                                                <a target=_blank href="https://ignite.apache.org"><nobr>2017 Copyright &#169; Apache Software Foundation</nobr></a>
                                             </td>
                                         </tr>
                                         </table>

http://git-wip-us.apache.org/repos/asf/ignite/blob/0ace63c6/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 2cb88b0..759e744 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -462,7 +462,7 @@
                                                 <tbody style="padding: 0; margin: 0">
                                                     <tr style="padding: 0; margin: 0">
                                                         <td>
-                                                            <a target=_blank href="https://ignite.apache.org"><nobr>2015 Copyright &#169; Apache Software Foundation</nobr></a>
+                                                            <a target=_blank href="https://ignite.apache.org"><nobr>2017 Copyright &#169; Apache Software Foundation</nobr></a>
                                                         </td>
                                                     </tr>
                                                 </tbody>


[10/50] [abbrv] ignite git commit: ignite-4552 Use for rmvQueue ConcurrentLinkedDeque instead of GridCircularBuffer to reduce memory usage. This closes #1465.

Posted by sb...@apache.org.
ignite-4552 Use for rmvQueue ConcurrentLinkedDeque instead of GridCircularBuffer to reduce memory usage.
This closes #1465.


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

Branch: refs/heads/ignite-3477-merge2.0
Commit: e6ea938d193353b173366fdd7ef132b8c2a12904
Parents: 70cd8e4
Author: sboikov <sb...@gridgain.com>
Authored: Tue Feb 7 14:19:16 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Feb 7 14:19:16 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/IgniteSystemProperties.java   |   3 +
 .../processors/cache/GridCacheProcessor.java    |  85 ++++++++++++
 .../distributed/dht/GridDhtCacheAdapter.java    |  10 +-
 .../distributed/dht/GridDhtLocalPartition.java  | 120 +++++++++++++----
 .../cache/CacheDeferredDeleteQueueTest.java     | 134 +++++++++++++++++++
 .../ignite/testsuites/IgniteCacheTestSuite.java |   2 +
 6 files changed, 322 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e6ea938d/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index c479076..703f52a 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -279,6 +279,9 @@ public final class IgniteSystemProperties {
     /** Maximum size for atomic cache queue delete history (default is 200 000 entries per partition). */
     public static final String IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE = "IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE";
 
+    /** Ttl of removed cache entries (ms). */
+    public static final String IGNITE_CACHE_REMOVED_ENTRIES_TTL = "IGNITE_CACHE_REMOVED_ENTRIES_TTL";
+
     /**
      * Comma separated list of addresses in format "10.100.22.100:45000,10.100.22.101:45000".
      * Makes sense only for {@link org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder}.

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6ea938d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 84126e4..87f5236 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -79,6 +79,8 @@ import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProce
 import org.apache.ignite.internal.processors.cache.datastructures.CacheDataStructuresManager;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCache;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
 import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache;
 import org.apache.ignite.internal.processors.cache.distributed.dht.colocated.GridDhtColocatedCache;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache;
@@ -99,6 +101,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersionManag
 import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.processors.plugin.CachePluginManager;
 import org.apache.ignite.internal.processors.query.GridQueryProcessor;
+import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
 import org.apache.ignite.internal.util.F0;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
@@ -120,6 +123,7 @@ import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.spi.IgniteNodeValidationResult;
 import org.jetbrains.annotations.Nullable;
 
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_REMOVED_ENTRIES_TTL;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK;
 import static org.apache.ignite.IgniteSystemProperties.getBoolean;
 import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
@@ -846,6 +850,17 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
         assert caches.containsKey(CU.MARSH_CACHE_NAME) : "Marshaller cache should be started";
         assert ctx.config().isDaemon() || caches.containsKey(CU.UTILITY_CACHE_NAME) : "Utility cache should be started";
+
+        if (!ctx.clientNode() && !ctx.isDaemon())
+            addRemovedItemsCleanupTask(Long.getLong(IGNITE_CACHE_REMOVED_ENTRIES_TTL, 10_000));
+
+    }
+
+    /**
+     * @param timeout Cleanup timeout.
+     */
+    private void addRemovedItemsCleanupTask(long timeout) {
+        ctx.timeout().addTimeoutObject(new RemovedItemsCleanupTask(timeout));
     }
 
     /** {@inheritDoc} */
@@ -3913,4 +3928,74 @@ public class GridCacheProcessor extends GridProcessorAdapter {
             // No-op.
         }
     }
+
+    /**
+     *
+     */
+    private class RemovedItemsCleanupTask implements GridTimeoutObject {
+        /** */
+        private final IgniteUuid id = IgniteUuid.randomUuid();
+
+        /** */
+        private final long endTime;
+
+        /** */
+        private final long timeout;
+
+        /**
+         * @param timeout Timeout.
+         */
+        RemovedItemsCleanupTask(long timeout) {
+            this.timeout = timeout;
+            this.endTime = U.currentTimeMillis() + timeout;
+        }
+
+        /** {@inheritDoc} */
+        @Override public IgniteUuid timeoutId() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public long endTime() {
+            return endTime;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onTimeout() {
+            ctx.closure().runLocalSafe(new Runnable() {
+                @Override public void run() {
+                    try {
+                        for (GridCacheContext cacheCtx : sharedCtx.cacheContexts()) {
+                            if (!cacheCtx.isLocal() && cacheCtx.affinityNode()) {
+                                GridDhtPartitionTopology top = null;
+
+                                try {
+                                    top = cacheCtx.topology();
+                                }
+                                catch (IllegalStateException ignore) {
+                                    // Cache stopped.
+                                }
+
+                                if (top != null) {
+                                    for (GridDhtLocalPartition part : top.currentLocalPartitions())
+                                        part.cleanupRemoveQueue();
+                                }
+
+                                if (ctx.isStopping())
+                                    return;
+                            }
+                        }
+                    }
+                    catch (Exception e) {
+                        U.error(log, "Failed to cleanup removed cache items: " + e, e);
+                    }
+
+                    if (ctx.isStopping())
+                        return;
+
+                    addRemovedItemsCleanupTask(timeout);
+                }
+            }, true);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6ea938d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
index 9e8788f..fb7a932 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
@@ -1183,14 +1183,8 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
         GridDhtLocalPartition part = topology().localPartition(entry.partition(), AffinityTopologyVersion.NONE,
             false);
 
-        if (part != null) {
-            try {
-                part.onDeferredDelete(entry.key(), ver);
-            }
-            catch (IgniteCheckedException e) {
-                U.error(log, "Failed to enqueue deleted entry [key=" + entry.key() + ", ver=" + ver + ']', e);
-            }
-        }
+        if (part != null)
+            part.onDeferredDelete(entry.key(), ver);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6ea938d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
index 67b29ca..9f8498a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
@@ -29,7 +29,6 @@ import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.internal.IgniteInternalFuture;
-import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
 import org.apache.ignite.internal.processors.cache.CacheObject;
@@ -46,21 +45,20 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.Gri
 import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntryExtras;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.processors.query.GridQueryProcessor;
-import org.apache.ignite.internal.util.GridCircularBuffer;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.lang.GridCloseableIterator;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
-import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jsr166.ConcurrentLinkedDeque8;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_REMOVED_ENTRIES_TTL;
 import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_OBJECT_UNLOADED;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.EVICTED;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.MOVING;
@@ -72,8 +70,13 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
  */
 public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>, GridReservable, GridCacheConcurrentMap {
     /** Maximum size for delete queue. */
-    public static final int MAX_DELETE_QUEUE_SIZE = Integer.getInteger(IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE,
-        200_000);
+    public static final int MAX_DELETE_QUEUE_SIZE = Integer.getInteger(IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE, 200_000);
+
+    /** Maximum size for {@link #rmvQueue}. */
+    private final int rmvQueueMaxSize;
+
+    /** Removed items TTL. */
+    private final long rmvdEntryTtl;
 
     /** Static logger to avoid re-creation. */
     private static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
@@ -109,7 +112,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
     private final ReentrantLock lock = new ReentrantLock();
 
     /** Remove queue. */
-    private final GridCircularBuffer<T2<KeyCacheObject, GridCacheVersion>> rmvQueue;
+    private final ConcurrentLinkedDeque8<RemovedEntryHolder> rmvQueue = new ConcurrentLinkedDeque8<>();
 
     /** Group reservations. */
     private final CopyOnWriteArrayList<GridDhtPartitionsReservation> reservations = new CopyOnWriteArrayList<>();
@@ -146,7 +149,9 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
         int delQueueSize = CU.isSystemCache(cctx.name()) ? 100 :
             Math.max(MAX_DELETE_QUEUE_SIZE / cctx.affinity().partitions(), 20);
 
-        rmvQueue = new GridCircularBuffer<>(U.ceilPow2(delQueueSize));
+        rmvQueueMaxSize = U.ceilPow2(delQueueSize);
+
+        rmvdEntryTtl = Long.getLong(IGNITE_CACHE_REMOVED_ENTRIES_TTL, 10_000);
     }
 
     /**
@@ -299,25 +304,43 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
     }
 
     /**
-     * @param key Removed key.
-     * @param ver Removed version.
-     * @throws IgniteCheckedException If failed.
+     *
      */
-    public void onDeferredDelete(KeyCacheObject key, GridCacheVersion ver) throws IgniteCheckedException {
-        try {
-            T2<KeyCacheObject, GridCacheVersion> evicted = rmvQueue.add(new T2<>(key, ver));
+    public void cleanupRemoveQueue() {
+        while (rmvQueue.sizex() >= rmvQueueMaxSize) {
+            RemovedEntryHolder item = rmvQueue.pollFirst();
 
-            if (evicted != null)
-                cctx.dht().removeVersionedEntry(evicted.get1(), evicted.get2());
+            if (item != null)
+                cctx.dht().removeVersionedEntry(item.key(), item.version());
         }
-        catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
 
-            throw new IgniteInterruptedCheckedException(e);
+        if (!cctx.isDrEnabled()) {
+            RemovedEntryHolder item = rmvQueue.peekFirst();
+
+            while (item != null && item.expireTime() < U.currentTimeMillis()) {
+                item = rmvQueue.pollFirst();
+
+                if (item == null)
+                    break;
+
+                cctx.dht().removeVersionedEntry(item.key(), item.version());
+
+                item = rmvQueue.peekFirst();
+            }
         }
     }
 
     /**
+     * @param key Removed key.
+     * @param ver Removed version.
+     */
+    public void onDeferredDelete(KeyCacheObject key, GridCacheVersion ver) {
+        cleanupRemoveQueue();
+
+        rmvQueue.add(new RemovedEntryHolder(key, ver, rmvdEntryTtl));
+    }
+
+    /**
      * Locks partition.
      */
     @SuppressWarnings({"LockAcquiredButNotSafelyReleased"})
@@ -807,11 +830,8 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
      *
      */
     private void clearDeferredDeletes() {
-        rmvQueue.forEach(new CI1<T2<KeyCacheObject, GridCacheVersion>>() {
-            @Override public void apply(T2<KeyCacheObject, GridCacheVersion> t) {
-                cctx.dht().removeVersionedEntry(t.get1(), t.get2());
-            }
-        });
+        for (RemovedEntryHolder e : rmvQueue)
+            cctx.dht().removeVersionedEntry(e.key(), e.version());
     }
 
     /** {@inheritDoc} */
@@ -841,4 +861,56 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
             "empty", isEmpty(),
             "createTime", U.format(createTime));
     }
+
+    /**
+     * Removed entry holder.
+     */
+    private static class RemovedEntryHolder {
+        /** Cache key */
+        private final KeyCacheObject key;
+
+        /** Entry version */
+        private final GridCacheVersion ver;
+
+        /** Entry expire time. */
+        private final long expireTime;
+
+        /**
+         * @param key Key.
+         * @param ver Entry version.
+         * @param ttl TTL.
+         */
+        private RemovedEntryHolder(KeyCacheObject key, GridCacheVersion ver, long ttl) {
+            this.key = key;
+            this.ver = ver;
+
+            expireTime = U.currentTimeMillis() + ttl;
+        }
+
+        /**
+         * @return Key.
+         */
+        KeyCacheObject key() {
+            return key;
+        }
+
+        /**
+         * @return Version.
+         */
+        GridCacheVersion version() {
+            return ver;
+        }
+
+        /**
+         * @return item expired time
+         */
+        long expireTime() {
+            return expireTime;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(RemovedEntryHolder.class, this);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6ea938d/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheDeferredDeleteQueueTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheDeferredDeleteQueueTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheDeferredDeleteQueueTest.java
new file mode 100644
index 0000000..b764d5b
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheDeferredDeleteQueueTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.Collection;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_REMOVED_ENTRIES_TTL;
+import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class CacheDeferredDeleteQueueTest extends GridCommonAbstractTest {
+    /** */
+    private static String ttlProp;
+
+    /** */
+    private static int NODES = 2;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        ttlProp = System.getProperty(IGNITE_CACHE_REMOVED_ENTRIES_TTL);
+
+        System.setProperty(IGNITE_CACHE_REMOVED_ENTRIES_TTL, "1000");
+
+        startGridsMultiThreaded(NODES);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        if (ttlProp != null)
+            System.setProperty(IGNITE_CACHE_REMOVED_ENTRIES_TTL, ttlProp);
+        else
+            System.clearProperty(IGNITE_CACHE_REMOVED_ENTRIES_TTL);
+
+        stopAllGrids();
+
+        super.afterTestsStopped();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDeferredDeleteQueue() throws Exception {
+        testQueue(ATOMIC, false);
+
+        testQueue(TRANSACTIONAL, false);
+
+        testQueue(ATOMIC, true);
+
+        testQueue(TRANSACTIONAL, true);
+    }
+
+    /**
+     * @param atomicityMode Cache atomicity mode.
+     * @param nearCache {@code True} if need create near cache.
+     *
+     * @throws Exception If failed.
+     */
+    private void testQueue(CacheAtomicityMode atomicityMode, boolean nearCache) throws Exception {
+        CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+
+        ccfg.setCacheMode(PARTITIONED);
+        ccfg.setAtomicityMode(atomicityMode);
+        ccfg.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg.setBackups(1);
+
+        if (nearCache)
+            ccfg.setNearConfiguration(new NearCacheConfiguration<Integer, Integer>());
+
+        IgniteCache<Integer, Integer> cache = ignite(0).createCache(ccfg);
+
+        try {
+            final int KEYS = cache.getConfiguration(CacheConfiguration.class).getAffinity().partitions() * 3;
+
+            for (int i = 0; i < KEYS; i++)
+                cache.put(i, i);
+
+            for (int i = 0; i < KEYS; i++)
+                cache.remove(i);
+
+            boolean wait = GridTestUtils.waitForCondition(new GridAbsPredicate() {
+                @Override public boolean apply() {
+                    for (int i = 0; i < NODES; i++) {
+                        final GridDhtPartitionTopology top =
+                            ((IgniteKernal)ignite(i)).context().cache().cache(null).context().topology();
+
+                        for (GridDhtLocalPartition p : top.currentLocalPartitions()) {
+                            Collection<Object> rmvQueue = GridTestUtils.getFieldValue(p, "rmvQueue");
+
+                            if (!rmvQueue.isEmpty() || p.size() != 0)
+                                return false;
+                        }
+                    }
+
+                    return true;
+                }
+            }, 5000);
+
+            assertTrue("Failed to wait for rmvQueue cleanup.", wait);
+        }
+        finally {
+            ignite(0).destroyCache(ccfg.getName());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6ea938d/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
index 092d95e..3f0073d 100755
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
@@ -46,6 +46,7 @@ import org.apache.ignite.internal.managers.communication.IgniteIoTestMessagesTes
 import org.apache.ignite.internal.managers.communication.IgniteVariousConnectionNumberTest;
 import org.apache.ignite.cache.store.jdbc.JdbcTypesDefaultTransformerTest;
 import org.apache.ignite.internal.processors.cache.CacheAffinityCallSelfTest;
+import org.apache.ignite.internal.processors.cache.CacheDeferredDeleteQueueTest;
 import org.apache.ignite.internal.processors.cache.CacheDeferredDeleteSanitySelfTest;
 import org.apache.ignite.internal.processors.cache.CacheEntryProcessorCopySelfTest;
 import org.apache.ignite.internal.processors.cache.CacheFutureExceptionSelfTest;
@@ -320,6 +321,7 @@ public class IgniteCacheTestSuite extends TestSuite {
         suite.addTestSuite(GridCacheTxPartitionedLocalStoreSelfTest.class);
         suite.addTestSuite(IgniteCacheSystemTransactionsSelfTest.class);
         suite.addTestSuite(CacheDeferredDeleteSanitySelfTest.class);
+        suite.addTestSuite(CacheDeferredDeleteQueueTest.class);
 
         suite.addTest(IgniteCacheTcpClientDiscoveryTestSuite.suite());