You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2017/04/12 12:46:58 UTC

[01/13] ignite git commit: IGNITE-3584: CPP: BinaryType refactored

Repository: ignite
Updated Branches:
  refs/heads/ignite-3477-master 0a69e45a2 -> 5839f481b


IGNITE-3584: CPP: BinaryType refactored


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

Branch: refs/heads/ignite-3477-master
Commit: 5c4d43c2b6414159fcf15d811d8ca365e01da4d8
Parents: aeacad6
Author: Igor Sapego <is...@gridgain.com>
Authored: Tue Apr 11 13:48:49 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Tue Apr 11 13:48:49 2017 +0300

----------------------------------------------------------------------
 .gitignore                                      |  31 ++++-
 .../binary/include/ignite/binary/binary_type.h  | 129 ++++++-------------
 .../ignite/impl/binary/binary_id_resolver.h     |  33 ++---
 .../ignite/impl/binary/binary_object_impl.h     |   3 +-
 .../ignite/impl/binary/binary_reader_impl.h     |  80 +++++++++++-
 .../ignite/impl/binary/binary_type_impl.h       |  12 +-
 .../include/ignite/impl/binary/binary_utils.h   |   6 +-
 .../ignite/impl/binary/binary_writer_impl.h     |  15 ++-
 .../core-test/include/ignite/binary_test_defs.h | 117 +++++++++--------
 .../cpp/core-test/include/ignite/complex_type.h |  30 ++---
 .../cpp/core-test/include/ignite/test_type.h    |  37 +++---
 .../src/binary_identity_resolver_test.cpp       |  92 +++++--------
 .../cpp/core-test/src/binary_object_test.cpp    |   4 +-
 .../cpp/core-test/src/binary_test_defs.cpp      |   5 +
 .../cpp/core-test/src/cache_invoke_test.cpp     |  18 +--
 .../cpp/core-test/src/cache_query_test.cpp      |  12 +-
 .../platforms/cpp/core-test/src/cache_test.cpp  |  38 +++---
 .../cpp/core-test/src/continuous_query_test.cpp |  34 +++--
 .../cpp/core/include/ignite/ignite_binding.h    |   6 +-
 .../impl/cache/cache_entry_processor_holder.h   |  33 +++--
 .../cpp/odbc-test/include/complex_type.h        |  26 ++--
 .../platforms/cpp/odbc-test/include/test_type.h |  37 +++---
 22 files changed, 393 insertions(+), 405 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index e118746..d8dd951 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,4 +59,33 @@ ipch/
 [Dd]ebug*/
 [Rr]elease*/
 packages
-*.nupkg
\ No newline at end of file
+*.nupkg
+
+#Autotools temp files
+/modules/platforms/cpp/**/Makefile
+/modules/platforms/cpp/**/Makefile.in
+/modules/platforms/cpp/**/aclocal.m4
+/modules/platforms/cpp/**/.libs/
+/modules/platforms/cpp/**/.dirstamp
+/modules/platforms/cpp/**/*.la
+/modules/platforms/cpp/ar-lib
+/modules/platforms/cpp/compile
+/modules/platforms/cpp/confdefs.h
+/modules/platforms/cpp/config.guess
+/modules/platforms/cpp/config.h
+/modules/platforms/cpp/config.h.in
+/modules/platforms/cpp/config.status
+/modules/platforms/cpp/config.sub
+/modules/platforms/cpp/configure
+/modules/platforms/cpp/core-test/ignite-tests
+/modules/platforms/cpp/core/ignite.pc
+/modules/platforms/cpp/depcomp
+/modules/platforms/cpp/ignite/ignite
+/modules/platforms/cpp/install-sh
+/modules/platforms/cpp/libtool
+/modules/platforms/cpp/ltmain.sh
+/modules/platforms/cpp/m4/
+/modules/platforms/cpp/missing
+/modules/platforms/cpp/odbc-test/ignite-odbc-tests
+/modules/platforms/cpp/stamp-h1
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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 f65c652..6bd95a1 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
@@ -51,7 +51,7 @@ struct BinaryType<T> \
  * Implementation of GetTypeId() which returns predefined constant.
  */
 #define IGNITE_BINARY_GET_TYPE_ID_AS_CONST(id) \
-int32_t GetTypeId() \
+static int32_t GetTypeId() \
 { \
     return id; \
 }
@@ -61,7 +61,7 @@ int32_t GetTypeId() \
  * Implementation of GetTypeId() which returns hash of passed type name.
  */
 #define IGNITE_BINARY_GET_TYPE_ID_AS_HASH(typeName) \
-int32_t GetTypeId() \
+static int32_t GetTypeId() \
 { \
     return GetBinaryStringHashCode(#typeName); \
 }
@@ -71,9 +71,9 @@ int32_t GetTypeId() \
  * Implementation of GetTypeName() which returns type name as is.
  */
 #define IGNITE_BINARY_GET_TYPE_NAME_AS_IS(typeName) \
-std::string GetTypeName() \
+static void GetTypeName(std::string& dst) \
 { \
-    return #typeName; \
+    dst = #typeName; \
 }
 
 /**
@@ -81,7 +81,7 @@ std::string GetTypeName() \
  * Default implementation of GetFieldId() function which returns Java-way hash code of the string.
  */
 #define IGNITE_BINARY_GET_FIELD_ID_AS_HASH \
-int32_t GetFieldId(const char* name) \
+static int32_t GetFieldId(const char* name) \
 { \
     return GetBinaryStringHashCode(name); \
 }
@@ -91,7 +91,7 @@ int32_t GetFieldId(const char* name) \
  * Implementation of GetHashCode() function which always returns 0.
  */
 #define IGNITE_BINARY_GET_HASH_CODE_ZERO(T) \
-int32_t GetHashCode(const T& obj) \
+static int32_t GetHashCode(const T& obj) \
 { \
     return 0; \
 }
@@ -101,7 +101,7 @@ int32_t GetHashCode(const T& obj) \
  * Implementation of IsNull() function which always returns false.
  */
 #define IGNITE_BINARY_IS_NULL_FALSE(T) \
-bool IsNull(const T& obj) \
+static bool IsNull(const T& obj) \
 { \
     return false; \
 }
@@ -111,7 +111,7 @@ bool IsNull(const T& obj) \
  * Implementation of IsNull() function which return true if passed object is null pointer.
  */
 #define IGNITE_BINARY_IS_NULL_IF_NULLPTR(T) \
-bool IsNull(const T& obj) \
+static bool IsNull(const T& obj) \
 { \
     return obj; \
 }
@@ -121,9 +121,9 @@ bool IsNull(const T& obj) \
  * Implementation of GetNull() function which returns an instance created with defult constructor.
  */
 #define IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(T) \
-T GetNull() \
+static void GetNull(T& dst) \
 { \
-    return T(); \
+    dst = T(); \
 }
 
 /**
@@ -131,11 +131,12 @@ T GetNull() \
  * Implementation of GetNull() function which returns NULL pointer.
  */
 #define IGNITE_BINARY_GET_NULL_NULLPTR(T) \
-T GetNull() \
+static void GetNull(T& dst) \
 { \
-    return NULL; \
+    dst = 0; \
 }
 
+
 namespace ignite
 {
     namespace binary
@@ -155,26 +156,35 @@ namespace ignite
          * Binary type structure. Defines a set of functions required for type to be serialized and deserialized.
          */
         template<typename T>
-        struct IGNITE_IMPORT_EXPORT BinaryType
+        struct IGNITE_IMPORT_EXPORT BinaryType { };
+
+        /**
+         * Templated binary type specification for pointers.
+         */
+        template <typename T>
+        struct IGNITE_IMPORT_EXPORT BinaryType<T*>
         {
+            /** Actual type. */
+            typedef BinaryType<T> BinaryTypeDereferenced;
+
             /**
              * Get binary object type ID.
              *
              * @return Type ID.
              */
-            int32_t GetTypeId()
+            static int32_t GetTypeId()
             {
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_BINARY, "GetTypeId function is not defined for binary type.");
+                return BinaryTypeDereferenced::GetTypeId();
             }
 
             /**
              * Get binary object type name.
              *
-             * @return Type name.
+             * @param dst Output type name.
              */
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_BINARY, "GetTypeName function is not defined for binary type.");
+                BinaryTypeDereferenced::GetTypeName(dst);
             }
 
             /**
@@ -183,9 +193,9 @@ namespace ignite
              * @param name Field name.
              * @return Field ID.
              */
-            int32_t GetFieldId(const char* name)
+            static int32_t GetFieldId(const char* name)
             {
-                return GetBinaryStringHashCode(name);
+                return BinaryTypeDereferenced::GetFieldId(name);
             }
 
             /**
@@ -194,20 +204,22 @@ namespace ignite
              * @param writer Writer.
              * @param obj Object.
              */
-            void Write(BinaryWriter& writer, const T& obj)
+            static void Write(BinaryWriter& writer, T* const& obj)
             {
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_BINARY, "Write function is not defined for binary type.");
+                BinaryTypeDereferenced::Write(writer, *obj);
             }
 
             /**
              * Read binary object.
              *
              * @param reader Reader.
-             * @return Object.
+             * @param dst Output object.
              */
-            T Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, T*& dst)
             {
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_BINARY, "Read function is not defined for binary type.");
+                dst = new T();
+
+                BinaryTypeDereferenced::Read(reader, *dst);
             }
 
             /**
@@ -216,76 +228,19 @@ namespace ignite
              * @param obj Binary object to test.
              * @return True if binary object should be interpreted as NULL.
              */
-            bool IsNull(const T& obj)
+            static bool IsNull(T* const& obj)
             {
-                return false;
+                return !obj || BinaryTypeDereferenced::IsNull(*obj);
             }
 
             /**
              * Get NULL value for the given binary type.
              *
-             * @return NULL value.
-             */
-            T GetNull()
-            {
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_BINARY, "GetNull function is not defined for binary type.");
-            }
-        };
-
-        /**
-         * Templated binary type specification for pointers.
-         */
-        template <typename T>
-        struct IGNITE_IMPORT_EXPORT BinaryType<T*>
-        {
-            /** Actual type. */
-            BinaryType<T> typ;
-
-            /**
-             * Constructor.
+             * @param dst Null value for the type.
              */
-            BinaryType() : typ()
-            {
-                // No-op.
-            }
-
-            int32_t GetTypeId()
-            {
-                return typ.GetTypeId();
-            }
-
-            std::string GetTypeName()
-            {
-                return typ.GetTypeName();
-            }
-
-            int32_t GetFieldId(const char* name)
-            {
-                return typ.GetFieldId(name);
-            }
-
-            void Write(BinaryWriter& writer, T* const& obj)
-            {
-                typ.Write(writer, *obj);
-            }
-
-            T* Read(BinaryReader& reader)
-            {
-                T* res = new T();
-
-                *res = typ.Read(reader);
-
-                return res;
-            }
-
-            bool IsNull(T* const& obj)
-            {
-                return !obj || typ.IsNull(*obj);
-            }
-
-            T* GetNull()
+            static void GetNull(T*& dst)
             {
-                return 0;
+                dst = 0;
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_id_resolver.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_id_resolver.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_id_resolver.h
index 7d6b12b..123299c 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_id_resolver.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_id_resolver.h
@@ -78,46 +78,29 @@ namespace ignite
                 /**
                  * Constructor.
                  */
-                TemplatedBinaryIdResolver() : 
-                    type()
-                {
-                    // No-op.
-                }
-
-                /**
-                 * Constructor.
-                 *
-                 * @param type Binary type.
-                 */
-                TemplatedBinaryIdResolver(ignite::binary::BinaryType<T> type) :
-                    type(type)
+                TemplatedBinaryIdResolver()
                 {
                     // No-op.
                 }
 
                 virtual int32_t GetTypeId()
                 {
-                    return type.GetTypeId();
+                    return ignite::binary::BinaryType<T>::GetTypeId();
                 }
 
-                virtual int32_t GetFieldId(const int32_t typeId, const char* name) {
+                virtual int32_t GetFieldId(const int32_t typeId, const char* name)
+                {
                     if (name)
-                        return type.GetFieldId(name);
-                    else
-                    {
-                        IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_BINARY,
-                            "Field name cannot be NULL.", "typeId", typeId);
-                    }
+                        return ignite::binary::BinaryType<T>::GetFieldId(name);
+
+                    IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_BINARY,
+                        "Field name cannot be NULL.", "typeId", typeId);
                 }
 
                 virtual BinaryIdResolver* Clone() const
                 {
                     return new TemplatedBinaryIdResolver<T>(*this);
                 }
-
-            private:
-                /** Actual type.  */
-                ignite::binary::BinaryType<T> type; 
             };
 
             /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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 880fff2..976ba29 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
@@ -109,9 +109,8 @@ namespace ignite
                 template<typename T>
                 T Deserialize() const
                 {
-                    ignite::binary::BinaryType<T> bt;
                     int32_t actualTypeId = GetTypeId();
-                    int32_t requestedTypeId = bt.GetTypeId();
+                    int32_t requestedTypeId = ignite::binary::BinaryType<T>::GetTypeId();
 
                     if (requestedTypeId != actualTypeId)
                     {

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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 8be9172..6d66416 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
@@ -916,6 +916,8 @@ namespace ignite
 
                         case IGNITE_HDR_FULL:
                         {
+                            typedef ignite::binary::BinaryType<T> BType;
+
                             int8_t protoVer = stream->ReadInt8();
 
                             if (protoVer != IGNITE_PROTO_VER) {
@@ -976,14 +978,14 @@ namespace ignite
 
                             bool usrType = (flags & IGNITE_BINARY_FLAG_USER_TYPE) != 0;
 
-                            ignite::binary::BinaryType<T> type;
-                            TemplatedBinaryIdResolver<T> idRslvr(type);
+                            TemplatedBinaryIdResolver<T> idRslvr;
                             BinaryReaderImpl readerImpl(stream, &idRslvr, pos, usrType,
                                                         typeId, hashCode, len, rawOff,
                                                         footerBegin, footerEnd, schemaType);
                             ignite::binary::BinaryReader reader(&readerImpl);
 
-                            T val = type.Read(reader);
+                            T val;
+                            BType::Read(reader, val);
 
                             stream->Position(pos + len);
 
@@ -1004,9 +1006,11 @@ namespace ignite
                 template<typename T>
                 T GetNull() const
                 {
-                    ignite::binary::BinaryType<T> type;
+                    T res;
+
+                    ignite::binary::BinaryType<T>::GetNull(res);
 
-                    return type.GetNull();
+                    return res;
                 }
 
                 /**
@@ -1439,6 +1443,72 @@ namespace ignite
 
             template<>
             std::string IGNITE_IMPORT_EXPORT BinaryReaderImpl::ReadTopObject<std::string>();
+
+            template<>
+            inline int8_t BinaryReaderImpl::GetNull() const
+            {
+                return 0;
+            }
+
+            template<>
+            inline int16_t BinaryReaderImpl::GetNull() const
+            {
+                return 0;
+            }
+
+            template<>
+            inline int32_t BinaryReaderImpl::GetNull() const
+            {
+                return 0;
+            }
+
+            template<>
+            inline int64_t BinaryReaderImpl::GetNull() const
+            {
+                return 0;
+            }
+
+            template<>
+            inline float BinaryReaderImpl::GetNull() const
+            {
+                return 0.0f;
+            }
+
+            template<>
+            inline double BinaryReaderImpl::GetNull() const
+            {
+                return 0.0;
+            }
+
+            template<>
+            inline Guid BinaryReaderImpl::GetNull() const
+            {
+                return Guid();
+            }
+
+            template<>
+            inline Date BinaryReaderImpl::GetNull() const
+            {
+                return Date();
+            }
+
+            template<>
+            inline Timestamp BinaryReaderImpl::GetNull() const
+            {
+                return Timestamp();
+            }
+
+            template<>
+            inline Time BinaryReaderImpl::GetNull() const
+            {
+                return Time();
+            }
+
+            template<>
+            inline std::string BinaryReaderImpl::GetNull() const
+            {
+                return std::string();
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_impl.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_impl.h
index 08c60c0..269db61 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_impl.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_impl.h
@@ -57,9 +57,9 @@ namespace ignite
     {
         namespace binary
         {
-            IGNITE_DECLARE_BINARY_TYPE_METHOD_CHECKER(GetHashCode, int32_t(ignite::binary::BinaryType<T>::*)(const T&));
+            IGNITE_DECLARE_BINARY_TYPE_METHOD_CHECKER(GetHashCode, int32_t(*)(const T&));
             IGNITE_DECLARE_BINARY_TYPE_METHOD_CHECKER(GetIdentityResolver,
-                ignite::Reference<ignite::binary::BinaryIdentityResolver>(ignite::binary::BinaryType<T>::*)());
+                ignite::Reference<ignite::binary::BinaryIdentityResolver>(*)());
 
             /**
              * This type is used to get hash code for binary types which have not
@@ -85,9 +85,7 @@ namespace ignite
             {
                 static int32_t Get(const T& obj, const ignite::binary::BinaryObject&)
                 {
-                    ignite::binary::BinaryType<T> bt;
-
-                    return bt.GetHashCode(obj);
+                    return ignite::binary::BinaryType<T>::GetHashCode(obj);
                 }
             };
 
@@ -100,8 +98,8 @@ namespace ignite
             {
                 static int32_t Get(const T&, const ignite::binary::BinaryObject& obj)
                 {
-                    ignite::binary::BinaryType<T> bt;
-                    ignite::Reference<ignite::binary::BinaryIdentityResolver> resolver = bt.GetIdentityResolver();
+                    ignite::Reference<ignite::binary::BinaryIdentityResolver> resolver =
+                        ignite::binary::BinaryType<T>::GetIdentityResolver();
 
                     return resolver.Get()->GetHashCode(obj);
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
index 268c2d8..84d7a19 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
@@ -471,9 +471,11 @@ namespace ignite
                 template<typename T>
                 static T GetDefaultValue()
                 {
-                    ignite::binary::BinaryType<T> binType;
+                    T res;
 
-                    return binType.GetNull();
+                    ignite::binary::BinaryType<T>::GetNull(res);
+
+                    return res;
                 }
             };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_writer_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_writer_impl.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_writer_impl.h
index 50b2375..e7dafb2 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_writer_impl.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_writer_impl.h
@@ -681,17 +681,20 @@ namespace ignite
                 template<typename T>
                 void WriteTopObject(const T& obj)
                 {
-                    ignite::binary::BinaryType<T> type;
+                    typedef ignite::binary::BinaryType<T> BType;
 
-                    if (type.IsNull(obj))
+                    if (BType::IsNull(obj))
                         stream->WriteInt8(IGNITE_HDR_NULL);
                     else
                     {
-                        TemplatedBinaryIdResolver<T> idRslvr(type);
-                        ignite::common::concurrent::SharedPointer<BinaryTypeHandler> metaHnd;
+                        TemplatedBinaryIdResolver<T> idRslvr;
+                        common::concurrent::SharedPointer<BinaryTypeHandler> metaHnd;
+
+                        std::string typeName;
+                        BType::GetTypeName(typeName);
 
                         if (metaMgr)
-                            metaHnd = metaMgr->GetHandler(type.GetTypeName(), idRslvr.GetTypeId());
+                            metaHnd = metaMgr->GetHandler(typeName, idRslvr.GetTypeId());
 
                         int32_t pos = stream->Position();
 
@@ -708,7 +711,7 @@ namespace ignite
                         // Reserve space for the Object Lenght, Schema ID and Schema or Raw Offset.
                         stream->Reserve(12);
 
-                        type.Write(writer, obj);
+                        BType::Write(writer, obj);
 
                         writerImpl.PostWrite();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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 196c6d3..0870997 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
@@ -49,6 +49,8 @@ namespace ignite_test
             class BinaryOuter
             {
             public:
+                BinaryOuter();
+
                 BinaryOuter(int32_t valIn, int32_t valOut);
 
                 BinaryInner GetInner() const;
@@ -141,175 +143,175 @@ namespace ignite
         template<>
         struct BinaryType<gt::BinaryDummy>
         {
-            int32_t GetTypeId()
+            static int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryDummy");
             }
 
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
-                return "BinaryDummy";
+                dst = "BinaryDummy";
             }
 
-            int32_t GetFieldId(const char* name)
+            static int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            int32_t GetHashCode(const gt::BinaryInner& obj)
+            static int32_t GetHashCode(const gt::BinaryDummy& obj)
             {
-                return obj.GetValue();
+                return 0;
             }
 
-            bool IsNull(const gt::BinaryInner& obj)
+            static bool IsNull(const gt::BinaryDummy& obj)
             {
-                return obj.GetValue() == 0;
+                return false;
             }
 
-            gt::BinaryInner GetNull()
+            static void GetNull(gt::BinaryDummy& dst)
             {
-                return gt::BinaryInner(0);
+                dst = gt::BinaryDummy();
             }
 
-            void Write(BinaryWriter& writer, const gt::BinaryDummy& obj)
+            static void Write(BinaryWriter& writer, const gt::BinaryDummy& obj)
             {
                 // No-op.
             }
 
-            gt::BinaryDummy Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, gt::BinaryDummy& dst)
             {
-                return gt::BinaryDummy();
+                dst = gt::BinaryDummy();
             }
         };
 
         template<> 
         struct BinaryType<gt::BinaryInner>
         {
-            int32_t GetTypeId() 
+            static int32_t GetTypeId() 
             { 
                 return GetBinaryStringHashCode("BinaryInner"); 
             }
 
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
-                return "BinaryInner";
+                dst = "BinaryInner";
             }
 
-            int32_t GetFieldId(const char* name) 
+            static int32_t GetFieldId(const char* name) 
             { 
                 return GetBinaryStringHashCode(name); 
             }
 
-            int32_t GetHashCode(const gt::BinaryInner& obj)
+            static int32_t GetHashCode(const gt::BinaryInner& obj)
             {
                 return obj.GetValue();
             }
 
-            bool IsNull(const gt::BinaryInner& obj)
+            static bool IsNull(const gt::BinaryInner& obj)
             {
                 return obj.GetValue() == 0;
             }
 
-            gt::BinaryInner GetNull()
+            static void GetNull(gt::BinaryInner& dst)
             {
-                return gt::BinaryInner(0);
+                dst = gt::BinaryInner(0);
             }
 
-            void Write(BinaryWriter& writer, const gt::BinaryInner& obj)
+            static void Write(BinaryWriter& writer, const gt::BinaryInner& obj)
             {
                 writer.WriteInt32("val", obj.GetValue());
             }
 
-            gt::BinaryInner Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, gt::BinaryInner& dst)
             {
                 int val = reader.ReadInt32("val");
 
-                return gt::BinaryInner(val);
+                dst = gt::BinaryInner(val);
             }
         };
 
         template<>
         struct BinaryType<gt::BinaryOuter>
         {
-            int32_t GetTypeId()
+            static int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryOuter");
             }
 
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
-                return "BinaryOuter";
+                dst = "BinaryOuter";
             }
 
-            int32_t GetFieldId(const char* name)
+            static int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            int32_t GetHashCode(const gt::BinaryOuter& obj)
+            static int32_t GetHashCode(const gt::BinaryOuter& obj)
             {
                 return obj.GetValue() + obj.GetInner().GetValue();
             }
 
-            bool IsNull(const gt::BinaryOuter& obj)
+            static bool IsNull(const gt::BinaryOuter& obj)
             {
                 return obj.GetValue() == 0 && obj.GetInner().GetValue();
             }
 
-            gt::BinaryOuter GetNull()
+            static void GetNull(gt::BinaryOuter& dst)
             {
-                return gt::BinaryOuter(0, 0);
+                dst = gt::BinaryOuter(0, 0);
             }
 
-            void Write(BinaryWriter& writer, const gt::BinaryOuter& obj)
+            static void Write(BinaryWriter& writer, const gt::BinaryOuter& obj)
             {
                 writer.WriteObject("inner", obj.GetInner());
                 writer.WriteInt32("val", obj.GetValue());                
             }
 
-            gt::BinaryOuter Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, gt::BinaryOuter& dst)
             {
                 gt::BinaryInner inner = reader.ReadObject<gt::BinaryInner>("inner");
                 int val = reader.ReadInt32("val");
 
-                return gt::BinaryOuter(inner.GetValue(), val);
+                dst = gt::BinaryOuter(inner.GetValue(), val);
             }
         };
 
         template<>
         struct BinaryType<gt::BinaryFields>
         {
-            int32_t GetTypeId()
+            static int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("BinaryFields");
             }
 
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
-                return "BinaryFields";
+                dst = "BinaryFields";
             }
 
-            int32_t GetFieldId(const char* name)
+            static int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            int32_t GetHashCode(const gt::BinaryFields& obj)
+            static int32_t GetHashCode(const gt::BinaryFields& obj)
             {
                 return obj.val1 + obj.val2 + obj.rawVal1 + obj.rawVal2;
             }
 
-            bool IsNull(const gt::BinaryFields& obj)
+            static bool IsNull(const gt::BinaryFields& obj)
             {
                 return false;
             }
 
-            gt::BinaryFields GetNull()
+            static void GetNull(gt::BinaryFields&)
             {
                 throw std::runtime_error("Must not be called.");
             }
 
-            void Write(BinaryWriter& writer, const gt::BinaryFields& obj)
+            static void Write(BinaryWriter& writer, const gt::BinaryFields& obj)
             {
                 writer.WriteInt32("val1", obj.val1);
                 writer.WriteInt32("val2", obj.val2);
@@ -320,7 +322,7 @@ namespace ignite
                 rawWriter.WriteInt32(obj.rawVal2);
             }
 
-            gt::BinaryFields Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, gt::BinaryFields& dst)
             {
                 int32_t val1 = reader.ReadInt32("val1");
                 int32_t val2 = reader.ReadInt32("val2");
@@ -330,44 +332,44 @@ namespace ignite
                 int32_t rawVal1 = rawReader.ReadInt32();
                 int32_t rawVal2 = rawReader.ReadInt32();
 
-                return gt::BinaryFields(val1, val2, rawVal1, rawVal2);
+                dst = gt::BinaryFields(val1, val2, rawVal1, rawVal2);
             }
         };
 
         template<>
         struct BinaryType<gt::PureRaw>
         {
-            int32_t GetTypeId()
+            static int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("PureRaw");
             }
 
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
-                return "PureRaw";
+                dst = "PureRaw";
             }
 
-            int32_t GetFieldId(const char* name)
+            static int32_t GetFieldId(const char* name)
             {
                 return GetBinaryStringHashCode(name);
             }
 
-            int32_t GetHashCode(const gt::PureRaw& obj)
+            static int32_t GetHashCode(const gt::PureRaw& obj)
             {
                 return GetBinaryStringHashCode(obj.val1.c_str()) ^ obj.val2;
             }
 
-            bool IsNull(const gt::PureRaw& obj)
+            static bool IsNull(const gt::PureRaw& obj)
             {
                 return false;
             }
 
-            gt::PureRaw GetNull()
+            static void GetNull(gt::PureRaw&)
             {
                 throw std::runtime_error("Must not be called.");
             }
 
-            void Write(BinaryWriter& writer, const gt::PureRaw& obj)
+            static void Write(BinaryWriter& writer, const gt::PureRaw& obj)
             {
                 BinaryRawWriter rawWriter = writer.RawWriter();
 
@@ -375,15 +377,12 @@ namespace ignite
                 rawWriter.WriteInt32(obj.val2);
             }
 
-            gt::PureRaw Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, gt::PureRaw& dst)
             {
                 BinaryRawReader rawReader = reader.RawReader();
 
-                gt::PureRaw res;
-                res.val1 = rawReader.ReadString();
-                res.val2 = rawReader.ReadInt32();
-
-                return res;
+                dst.val1 = rawReader.ReadString();
+                dst.val2 = rawReader.ReadInt32();
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/core-test/include/ignite/complex_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/complex_type.h b/modules/platforms/cpp/core-test/include/ignite/complex_type.h
index cb4a8a1..e1a0351 100644
--- a/modules/platforms/cpp/core-test/include/ignite/complex_type.h
+++ b/modules/platforms/cpp/core-test/include/ignite/complex_type.h
@@ -18,11 +18,9 @@
 #ifndef _IGNITE_ODBC_TEST_COMPLEX_TYPE
 #define _IGNITE_ODBC_TEST_COMPLEX_TYPE
 
+#include <stdint.h>
 #include <string>
 
-#include "ignite/ignite.h"
-#include "ignite/ignition.h"
-
 namespace ignite
 {
     struct InnerObject
@@ -81,20 +79,16 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(InnerObject)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(InnerObject)
 
-            void Write(BinaryWriter& writer, InnerObject obj)
+            static void Write(BinaryWriter& writer, const InnerObject& obj)
             {
                 writer.WriteInt32("f1", obj.f1);
                 writer.WriteString("f2", obj.f2);
             }
 
-            InnerObject Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, InnerObject& dst)
             {
-                InnerObject obj;
-
-                obj.f1 = reader.ReadInt32("f1");
-                obj.f2 = reader.ReadString("f2");
-
-                return obj;
+                dst.f1 = reader.ReadInt32("f1");
+                dst.f2 = reader.ReadString("f2");
             }
 
         IGNITE_BINARY_TYPE_END
@@ -110,22 +104,18 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(ComplexType)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType)
 
-            void Write(BinaryWriter& writer, ComplexType obj)
+            static void Write(BinaryWriter& writer, const ComplexType& obj)
             {
                 writer.WriteInt32("i32Field", obj.i32Field);
                 writer.WriteObject("objField", obj.objField);
                 writer.WriteString("strField", obj.strField);
             }
 
-            ComplexType Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, ComplexType& dst)
             {
-                ComplexType obj;
-
-                obj.i32Field = reader.ReadInt32("i32Field");
-                obj.objField = reader.ReadObject<InnerObject>("objField");
-                obj.strField = reader.ReadString("strField");
-
-                return obj;
+                dst.i32Field = reader.ReadInt32("i32Field");
+                dst.objField = reader.ReadObject<InnerObject>("objField");
+                dst.strField = reader.ReadString("strField");
             }
 
         IGNITE_BINARY_TYPE_END

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/core-test/include/ignite/test_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/test_type.h b/modules/platforms/cpp/core-test/include/ignite/test_type.h
index d1dd967..40ada55 100644
--- a/modules/platforms/cpp/core-test/include/ignite/test_type.h
+++ b/modules/platforms/cpp/core-test/include/ignite/test_type.h
@@ -111,7 +111,7 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(TestType)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestType)
 
-            void Write(BinaryWriter& writer, TestType obj)
+            static void Write(BinaryWriter& writer, const TestType& obj)
             {
                 if (!obj.allNulls)
                 {
@@ -154,32 +154,27 @@ namespace ignite
                 }
             }
 
-            TestType Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, TestType& dst)
             {
-                int8_t i8Field = reader.ReadInt8("i8Field");
-                int16_t i16Field = reader.ReadInt16("i16Field");
-                int32_t i32Field = reader.ReadInt32("i32Field");
-                int64_t i64Field = reader.ReadInt64("i64Field");
-                std::string strField = reader.ReadString("strField");
-                float floatField = reader.ReadFloat("floatField");
-                double doubleField = reader.ReadDouble("doubleField");
-                bool boolField = reader.ReadBool("boolField");
-                Guid guidField = reader.ReadGuid("guidField");
-                Date dateField = reader.ReadDate("dateField");
-                Time timeField = reader.ReadTime("timeField");
-                Timestamp timestampField = reader.ReadTimestamp("timestampField");
-
-                TestType result(i8Field, i16Field, i32Field, i64Field, strField,
-                    floatField, doubleField, boolField, guidField, dateField,
-                    timeField, timestampField);
+                dst.i8Field = reader.ReadInt8("i8Field");
+                dst.i16Field = reader.ReadInt16("i16Field");
+                dst.i32Field = reader.ReadInt32("i32Field");
+                dst.i64Field = reader.ReadInt64("i64Field");
+                dst.strField = reader.ReadString("strField");
+                dst.floatField = reader.ReadFloat("floatField");
+                dst.doubleField = reader.ReadDouble("doubleField");
+                dst.boolField = reader.ReadBool("boolField");
+                dst.guidField = reader.ReadGuid("guidField");
+                dst.dateField = reader.ReadDate("dateField");
+                dst.timeField = reader.ReadTime("timeField");
+                dst.timestampField = reader.ReadTimestamp("timestampField");
 
                 int32_t len = reader.ReadInt8Array("i8ArrayField", 0, 0);
                 if (len > 0)
                 {
-                    result.i8ArrayField.resize(len);
-                    reader.ReadInt8Array("i8ArrayField", &result.i8ArrayField[0], len);
+                    dst.i8ArrayField.resize(len);
+                    reader.ReadInt8Array("i8ArrayField", &dst.i8ArrayField[0], len);
                 }
-                return result;
             }
 
         IGNITE_BINARY_TYPE_END

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp b/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
index 55b77bd..802ec97 100644
--- a/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
@@ -198,18 +198,14 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(DefaultHashing)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(DefaultHashing)
 
-            void Write(BinaryWriter& writer, const DefaultHashing& obj)
+            static void Write(BinaryWriter& writer, const DefaultHashing& obj)
             {
                 writer.WriteInt32("field", obj.field);
             }
 
-            DefaultHashing Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, DefaultHashing& dst)
             {
-                DefaultHashing val;
-
-                val.field = reader.ReadInt32("field");
-
-                return val;
+                dst.field = reader.ReadInt32("field");
             }
         };
 
@@ -222,23 +218,19 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(GetHashDefined)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(GetHashDefined)
 
-            int32_t GetHashCode(const GetHashDefined& obj)
+            static int32_t GetHashCode(const GetHashDefined& obj)
             {
                 return obj.field * 10;
             }
 
-            void Write(BinaryWriter& writer, const GetHashDefined& obj)
+            static void Write(BinaryWriter& writer, const GetHashDefined& obj)
             {
                 writer.WriteInt32("field", obj.field);
             }
 
-            GetHashDefined Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, GetHashDefined& dst)
             {
-                GetHashDefined val;
-
-                val.field = reader.ReadInt32("field");
-
-                return val;
+                dst.field = reader.ReadInt32("field");
             }
         };
 
@@ -251,23 +243,19 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(ResolverDefined)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ResolverDefined)
 
-            ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
+            static ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
             {
                 return ignite::MakeReferenceFromCopy(CustomIdResolver());
             }
 
-            void Write(BinaryWriter& writer, const ResolverDefined& obj)
+            static void Write(BinaryWriter& writer, const ResolverDefined& obj)
             {
                 writer.WriteInt32("field", obj.field);
             }
 
-            ResolverDefined Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, ResolverDefined& dst)
             {
-                ResolverDefined val;
-
-                val.field = reader.ReadInt32("field");
-
-                return val;
+                dst.field = reader.ReadInt32("field");
             }
         };
 
@@ -280,28 +268,24 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(BothDefined)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(BothDefined)
 
-            int32_t GetHashCode(const GetHashDefined& obj)
+            static int32_t GetHashCode(const GetHashDefined& obj)
             {
                 return obj.field * 10;
             }
 
-            ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
+            static ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
             {
                 return ignite::MakeReferenceFromCopy(CustomIdResolver());
             }
 
-            void Write(BinaryWriter& writer, const BothDefined& obj)
+            static void Write(BinaryWriter& writer, const BothDefined& obj)
             {
                 writer.WriteInt32("field", obj.field);
             }
 
-            BothDefined Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, BothDefined& dst)
             {
-                BothDefined val;
-
-                val.field = reader.ReadInt32("field");
-
-                return val;
+                dst.field = reader.ReadInt32("field");
             }
         };
 
@@ -318,22 +302,18 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(CompositeKey)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(CompositeKey)
 
-            void Write(BinaryWriter& writer, const CompositeKey& obj)
+            static void Write(BinaryWriter& writer, const CompositeKey& obj)
             {
                 writer.WriteString("str", obj.str);
                 writer.WriteTimestamp("ts", obj.ts);
                 writer.WriteGuid("guid", obj.guid);
             }
 
-            CompositeKey Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, CompositeKey& dst)
             {
-                CompositeKey val;
-
-                val.str = reader.ReadString("str");
-                val.ts = reader.ReadTimestamp("ts");
-                val.guid = reader.ReadGuid("guid");
-
-                return val;
+                dst.str = reader.ReadString("str");
+                dst.ts = reader.ReadTimestamp("ts");
+                dst.guid = reader.ReadGuid("guid");
             }
         };
 
@@ -349,22 +329,18 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(CompositeKeySimple)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(CompositeKeySimple)
 
-            void Write(BinaryWriter& writer, const CompositeKeySimple& obj)
+            static void Write(BinaryWriter& writer, const CompositeKeySimple& obj)
             {
                 writer.WriteString("str", obj.str);
                 writer.WriteTimestamp("ts", obj.ts);
                 writer.WriteInt64("i64", obj.i64);
             }
 
-            CompositeKeySimple Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, CompositeKeySimple& dst)
             {
-                CompositeKeySimple val;
-
-                val.str = reader.ReadString("str");
-                val.ts = reader.ReadTimestamp("ts");
-                val.i64 = reader.ReadInt64("i64");
-
-                return val;
+                dst.str = reader.ReadString("str");
+                dst.ts = reader.ReadTimestamp("ts");
+                dst.i64 = reader.ReadInt64("i64");
             }
         };
 
@@ -380,27 +356,23 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(ComplexType2)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType2)
 
-            ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
+            static ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
             {
                 return ignite::MakeReferenceFromCopy(CustomFieldIdResolver());
             }
 
-            void Write(BinaryWriter& writer, ComplexType2 obj)
+            static void Write(BinaryWriter& writer, const ComplexType2& obj)
             {
                 writer.WriteInt32("i32Field", obj.i32Field);
                 writer.WriteObject("objField", obj.objField);
                 writer.WriteString("strField", obj.strField);
             }
 
-            ComplexType2 Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, ComplexType2& dst)
             {
-                ComplexType2 obj;
-
-                obj.i32Field = reader.ReadInt32("i32Field");
-                obj.objField = reader.ReadObject<InnerObject>("objField");
-                obj.strField = reader.ReadString("strField");
-
-                return obj;
+                dst.i32Field = reader.ReadInt32("i32Field");
+                dst.objField = reader.ReadObject<InnerObject>("objField");
+                dst.strField = reader.ReadString("strField");
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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 bc30428..16e8c83 100644
--- a/modules/platforms/cpp/core-test/src/binary_object_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
@@ -86,9 +86,7 @@ void GetObjectData(const T& obj, common::FixedSizeArray<int8_t>& data)
     BinaryWriterImpl writerImpl(&stream, &idResolver, 0, 0, 0);
     BinaryWriter writer(&writerImpl);
 
-    BinaryType<T> bt;
-
-    bt.Write(writer, obj);
+    BinaryType<T>::Write(writer, obj);
 
     data.Assign(mem.Data(), stream.Position());
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/core-test/src/binary_test_defs.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_test_defs.cpp b/modules/platforms/cpp/core-test/src/binary_test_defs.cpp
index 500ecd8..932f486 100644
--- a/modules/platforms/cpp/core-test/src/binary_test_defs.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_test_defs.cpp
@@ -46,6 +46,11 @@ namespace ignite_test
                 return val;
             }
 
+            BinaryOuter::BinaryOuter()
+            {
+                // No-op.
+            }
+
             BinaryOuter::BinaryOuter(int32_t valIn, int32_t valOut) : inner(valIn), val(valOut)
             {
                 // No-op.

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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
index 4f1f30a..81261b3 100644
--- a/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
@@ -133,16 +133,16 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(CacheEntryModifier)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(CacheEntryModifier)
 
-            void Write(BinaryWriter& writer, CacheEntryModifier obj)
+            static void Write(BinaryWriter& writer, const CacheEntryModifier& obj)
             {
                 writer.WriteInt32("num", obj.GetNum());
             }
 
-            CacheEntryModifier Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, CacheEntryModifier& dst)
             {
                 int num = reader.ReadInt32("num");
 
-                return CacheEntryModifier(num);
+                dst = CacheEntryModifier(num);
             }
         IGNITE_BINARY_TYPE_END
     }
@@ -244,16 +244,16 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(Divisor)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(Divisor)
 
-            void Write(BinaryWriter& writer, Divisor obj)
+            static void Write(BinaryWriter& writer, const Divisor& obj)
             {
                 writer.WriteDouble("scale", obj.GetScale());
             }
 
-            Divisor Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, Divisor& dst)
             {
                 double scale = reader.ReadDouble("scale");
 
-                return Divisor(scale);
+                dst = Divisor(scale);
             }
         IGNITE_BINARY_TYPE_END
     }
@@ -365,16 +365,16 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(CharRemover)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(CharRemover)
 
-            void Write(BinaryWriter& writer, CharRemover obj)
+            static void Write(BinaryWriter& writer, const CharRemover& obj)
             {
                 writer.WriteInt8("toRemove", obj.GetCharToRemove());
             }
 
-            CharRemover Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, CharRemover& dst)
             {
                 char toRemove = static_cast<char>(reader.ReadInt8("toRemove"));
 
-                return CharRemover(toRemove);
+                dst = CharRemover(toRemove);
             }
         IGNITE_BINARY_TYPE_END
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/core-test/src/cache_query_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_query_test.cpp b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
index 871f66a..328efd9 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -249,7 +249,7 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(QueryPerson)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(QueryPerson)
 
-            void Write(BinaryWriter& writer, QueryPerson obj)
+            static void Write(BinaryWriter& writer, const QueryPerson& obj)
             {
                 writer.WriteString("name", obj.GetName());
                 writer.WriteInt32("age", obj.GetAge());
@@ -257,14 +257,14 @@ namespace ignite
                 writer.WriteTimestamp("recordCreated", obj.GetCreationTime());
             }
 
-            QueryPerson Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, QueryPerson& dst)
             {
                 std::string name = reader.ReadString("name");
                 int age = reader.ReadInt32("age");
                 Date birthday = reader.ReadDate("birthday");
                 Timestamp recordCreated = reader.ReadTimestamp("recordCreated");
             
-                return QueryPerson(name, age, birthday, recordCreated);
+                dst = QueryPerson(name, age, birthday, recordCreated);
             }
         IGNITE_BINARY_TYPE_END
 
@@ -279,18 +279,18 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(QueryRelation)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(QueryRelation)
 
-            void Write(BinaryWriter& writer, QueryRelation obj)
+            static void Write(BinaryWriter& writer, QueryRelation obj)
             {
                 writer.WriteInt32("personId", obj.GetPersonId());
                 writer.WriteInt32("someVal", obj.GetHobbyId());
             }
 
-            QueryRelation Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, QueryRelation& dst)
             {
                 int32_t personId = reader.ReadInt32("personId");
                 int32_t someVal = reader.ReadInt32("someVal");
 
-                return QueryRelation(personId, someVal);
+                dst = QueryRelation(personId, someVal);
             }
         IGNITE_BINARY_TYPE_END
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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 fef777a..99e0f1b 100644
--- a/modules/platforms/cpp/core-test/src/cache_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_test.cpp
@@ -50,26 +50,24 @@ namespace ignite
     namespace binary
     {
         IGNITE_BINARY_TYPE_START(Person)
-        IGNITE_BINARY_GET_TYPE_ID_AS_HASH(Person)
-        IGNITE_BINARY_GET_TYPE_NAME_AS_IS(Person)
-        IGNITE_BINARY_GET_FIELD_ID_AS_HASH
-        IGNITE_BINARY_GET_HASH_CODE_ZERO(Person)
-        IGNITE_BINARY_IS_NULL_FALSE(Person)
-        IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(Person)
-
-        void Write(BinaryWriter& writer, Person obj)
-        {
-            writer.WriteString("name", obj.name);
-            writer.WriteInt32("age", obj.age);            
-        }
-
-        Person Read(BinaryReader& reader)
-        {
-            std::string name = reader.ReadString("name");
-            int age = reader.ReadInt32("age");
-            
-            return Person(name, age);
-        }
+            IGNITE_BINARY_GET_TYPE_ID_AS_HASH(Person)
+            IGNITE_BINARY_GET_TYPE_NAME_AS_IS(Person)
+            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+            IGNITE_BINARY_GET_HASH_CODE_ZERO(Person)
+            IGNITE_BINARY_IS_NULL_FALSE(Person)
+            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(Person)
+
+            static void Write(BinaryWriter& writer, const Person& obj)
+            {
+                writer.WriteString("name", obj.name);
+                writer.WriteInt32("age", obj.age);            
+            }
+
+            static void Read(BinaryReader& reader, Person& dst)
+            {
+                dst.name = reader.ReadString("name");
+                dst.age = reader.ReadInt32("age");
+            }
 
         IGNITE_BINARY_TYPE_END
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/core-test/src/continuous_query_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/continuous_query_test.cpp b/modules/platforms/cpp/core-test/src/continuous_query_test.cpp
index f81eb5d..8579c54 100644
--- a/modules/platforms/cpp/core-test/src/continuous_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/continuous_query_test.cpp
@@ -269,62 +269,58 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(TestEntry)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestEntry)
 
-            void Write(BinaryWriter& writer, const TestEntry& obj)
+            static void Write(BinaryWriter& writer, const TestEntry& obj)
             {
                 writer.WriteInt32("value", obj.value);
             }
 
-            TestEntry Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, TestEntry& dst)
             {
-                TestEntry res;
-                res.value = reader.ReadInt32("value");
-
-                return res;
+                dst.value = reader.ReadInt32("value");
             }
         };
 
         template<typename K, typename V>
         struct BinaryType< RangeFilter<K,V> >
         {
-            int32_t GetTypeId()
+            static int32_t GetTypeId()
             {
                 return GetBinaryStringHashCode("RangeFilter");
             }
 
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
-                return "RangeFilter";
+                dst = "RangeFilter";
 
             }
+
             IGNITE_BINARY_GET_FIELD_ID_AS_HASH
 
-            int32_t GetHashCode(const RangeFilter<K,V>&)
+            static int32_t GetHashCode(const RangeFilter<K,V>&)
             {
                 return 0;
             }
 
-            bool IsNull(const RangeFilter<K,V>&)
+            static bool IsNull(const RangeFilter<K,V>&)
             {
                 return false;
             }
 
-            RangeFilter<K,V> GetNull()
+            static void GetNull(RangeFilter<K, V>& dst)
             {
-                return RangeFilter<K,V>();
+                dst = RangeFilter<K,V>();
             }
 
-            void Write(BinaryWriter& writer, const RangeFilter<K,V>& obj)
+            static void Write(BinaryWriter& writer, const RangeFilter<K,V>& obj)
             {
                 writer.WriteObject("rangeBegin", obj.rangeBegin);
                 writer.WriteObject("rangeEnd", obj.rangeEnd);
             }
 
-            RangeFilter<K,V> Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, RangeFilter<K, V>& dst)
             {
-                K begin = reader.ReadObject<K>("rangeBegin");
-                K end = reader.ReadObject<K>("rangeEnd");
-
-                return RangeFilter<K,V>(begin, end);
+                dst.rangeBegin = reader.ReadObject<K>("rangeBegin");
+                dst.rangeEnd = reader.ReadObject<K>("rangeEnd");
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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
index a84a1c1..70bdedb 100644
--- a/modules/platforms/cpp/core/include/ignite/ignite_binding.h
+++ b/modules/platforms/cpp/core/include/ignite/ignite_binding.h
@@ -80,13 +80,12 @@ namespace ignite
         template<typename P>
         void RegisterCacheEntryProcessor(IgniteError& err)
         {
-            binary::BinaryType<P> bt;
             impl::IgniteBindingImpl *im = impl.Get();
 
             if (im)
             {
                 im->RegisterCallback(impl::IgniteBindingImpl::CACHE_ENTRY_PROCESSOR_APPLY,
-                    bt.GetTypeId(), impl::binding::ListenerApply<P, typename P::KeyType,
+                    binary::BinaryType<P>::GetTypeId(), impl::binding::ListenerApply<P, typename P::KeyType,
                         typename P::ValueType, typename P::ReturnType, typename P::ArgumentType>, err);
             }
             else
@@ -105,10 +104,9 @@ namespace ignite
         template<typename F>
         void RegisterCacheEntryEventFilter()
         {
-            binary::BinaryType<F> bt;
             impl::IgniteBindingImpl *im = impl.Get();
 
-            int32_t typeId = bt.GetTypeId();
+            int32_t typeId = binary::BinaryType<F>::GetTypeId();
 
             if (im)
             {

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/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
index c979b4a..decbaa9 100644
--- 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
@@ -191,7 +191,7 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(UnderlyingType)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(UnderlyingType)
 
-            int32_t GetTypeId()
+            static int32_t GetTypeId()
             {
                 static bool typeIdInited = false;
                 static int32_t typeId;
@@ -205,13 +205,16 @@ namespace ignite
                 if (typeIdInited)
                     return typeId;
 
-                typeId = GetBinaryStringHashCode(GetTypeName().c_str());
+                std::string typeName;
+                GetTypeName(typeName);
+
+                typeId = GetBinaryStringHashCode(typeName.c_str());
                 typeIdInited = true;
 
                 return typeId;
             }
 
-            std::string GetTypeName()
+            static void GetTypeName(std::string& dst)
             {
                 // Using static variable and only initialize it once for better
                 // performance. Type name can't change in the course of the
@@ -221,17 +224,25 @@ namespace ignite
 
                 // Name has been constructed already. Return it.
                 if (!name.empty())
-                    return name;
+                {
+                    dst = name;
+
+                    return;
+                }
 
                 common::concurrent::CsLockGuard guard(initLock);
 
                 if (!name.empty())
-                    return name;
+                {
+                    dst = name;
+
+                    return;
+                }
 
                 // Constructing name here.
-                BinaryType<P> p;
+                std::string procName;
 
-                std::string procName = p.GetTypeName();
+                BinaryType<P>::GetTypeName(procName);
 
                 // -1 is for unnessecary null byte at the end of the C-string.
                 name.reserve(sizeof("CacheEntryProcessorHolder<>") - 1 + procName.size());
@@ -240,10 +251,10 @@ namespace ignite
                 // forbidden to register the same processor type several times.
                 name.append("CacheEntryProcessorHolder<").append(procName).push_back('>');
 
-                return name;
+                dst = name;
             }
 
-            void Write(BinaryWriter& writer, UnderlyingType obj)
+            static void Write(BinaryWriter& writer, const UnderlyingType& obj)
             {
                 BinaryRawWriter raw = writer.RawWriter();
 
@@ -251,14 +262,14 @@ namespace ignite
                 raw.WriteObject(obj.getArgument());
             }
 
-            UnderlyingType Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, UnderlyingType& dst)
             {
                 BinaryRawReader raw = reader.RawReader();
 
                 const P& proc = raw.ReadObject<P>();
                 const A& arg = raw.ReadObject<A>();
 
-                return UnderlyingType(proc, arg);
+                dst = UnderlyingType(proc, arg);
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/odbc-test/include/complex_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/complex_type.h b/modules/platforms/cpp/odbc-test/include/complex_type.h
index a84b033..dd68c9b 100644
--- a/modules/platforms/cpp/odbc-test/include/complex_type.h
+++ b/modules/platforms/cpp/odbc-test/include/complex_type.h
@@ -68,20 +68,16 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(TestObject)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestObject)
 
-            void Write(BinaryWriter& writer, TestObject obj)
+            static void Write(BinaryWriter& writer, const TestObject& obj)
             {
                 writer.WriteInt32("f1", obj.f1);
                 writer.WriteString("f2", obj.f2);
             }
 
-            TestObject Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, TestObject& dst)
             {
-                TestObject obj;
-
-                obj.f1 = reader.ReadInt32("f1");
-                obj.f2 = reader.ReadString("f2");
-
-                return obj;
+                dst.f1 = reader.ReadInt32("f1");
+                dst.f2 = reader.ReadString("f2");
             }
 
         IGNITE_BINARY_TYPE_END
@@ -97,22 +93,18 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(ComplexType)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType)
 
-            void Write(BinaryWriter& writer, ComplexType obj)
+            static void Write(BinaryWriter& writer, const ComplexType& obj)
             {
                 writer.WriteInt32("i32Field", obj.i32Field);
                 writer.WriteObject("objField", obj.objField);
                 writer.WriteString("strField", obj.strField);
             }
 
-            ComplexType Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, ComplexType& dst)
             {
-                ComplexType obj;
-
-                obj.i32Field = reader.ReadInt32("i32Field");
-                obj.objField = reader.ReadObject<TestObject>("objField");
-                obj.strField = reader.ReadString("strField");
-
-                return obj;
+                dst.i32Field = reader.ReadInt32("i32Field");
+                dst.objField = reader.ReadObject<TestObject>("objField");
+                dst.strField = reader.ReadString("strField");
             }
 
         IGNITE_BINARY_TYPE_END

http://git-wip-us.apache.org/repos/asf/ignite/blob/5c4d43c2/modules/platforms/cpp/odbc-test/include/test_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/test_type.h b/modules/platforms/cpp/odbc-test/include/test_type.h
index 51271b5..7bc6b3e 100644
--- a/modules/platforms/cpp/odbc-test/include/test_type.h
+++ b/modules/platforms/cpp/odbc-test/include/test_type.h
@@ -111,7 +111,7 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(TestType)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestType)
 
-            void Write(BinaryWriter& writer, TestType obj)
+            static void Write(BinaryWriter& writer, const TestType& obj)
             {
                 if (!obj.allNulls)
                 {
@@ -154,32 +154,27 @@ namespace ignite
                 }
             }
 
-            TestType Read(BinaryReader& reader)
+            static void Read(BinaryReader& reader, TestType& dst)
             {
-                int8_t i8Field = reader.ReadInt8("i8Field");
-                int16_t i16Field = reader.ReadInt16("i16Field");
-                int32_t i32Field = reader.ReadInt32("i32Field");
-                int64_t i64Field = reader.ReadInt64("i64Field");
-                std::string strField = reader.ReadString("strField");
-                float floatField = reader.ReadFloat("floatField");
-                double doubleField = reader.ReadDouble("doubleField");
-                bool boolField = reader.ReadBool("boolField");
-                Guid guidField = reader.ReadGuid("guidField");
-                Date dateField = reader.ReadDate("dateField");
-                Time timeField = reader.ReadTime("timeField");
-                Timestamp timestampField = reader.ReadTimestamp("timestampField");
-
-                TestType result(i8Field, i16Field, i32Field, i64Field, strField,
-                    floatField, doubleField, boolField, guidField, dateField,
-                    timeField, timestampField);
+                dst.i8Field = reader.ReadInt8("i8Field");
+                dst.i16Field = reader.ReadInt16("i16Field");
+                dst.i32Field = reader.ReadInt32("i32Field");
+                dst.i64Field = reader.ReadInt64("i64Field");
+                dst.strField = reader.ReadString("strField");
+                dst.floatField = reader.ReadFloat("floatField");
+                dst.doubleField = reader.ReadDouble("doubleField");
+                dst.boolField = reader.ReadBool("boolField");
+                dst.guidField = reader.ReadGuid("guidField");
+                dst.dateField = reader.ReadDate("dateField");
+                dst.timeField = reader.ReadTime("timeField");
+                dst.timestampField = reader.ReadTimestamp("timestampField");
 
                 int32_t len = reader.ReadInt8Array("i8ArrayField", 0, 0);
                 if (len > 0)
                 {
-                    result.i8ArrayField.resize(len);
-                    reader.ReadInt8Array("i8ArrayField", &result.i8ArrayField[0], len);
+                    dst.i8ArrayField.resize(len);
+                    reader.ReadInt8Array("i8ArrayField", &dst.i8ArrayField[0], len);
                 }
-                return result;
             }
 
         IGNITE_BINARY_TYPE_END


[10/13] ignite git commit: IGNITE-4943 Improve design of table on Admin Panel screen: minor fixes.

Posted by is...@apache.org.
IGNITE-4943 Improve design of table on Admin Panel screen: minor fixes.


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

Branch: refs/heads/ignite-3477-master
Commit: 775c6e57f9515a6f3390d598a5eaa1914329eff1
Parents: 8c9c60a
Author: Dmitriy Shabalin <ds...@gridgain.com>
Authored: Wed Apr 12 19:20:24 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Apr 12 19:20:24 2017 +0700

----------------------------------------------------------------------
 .../list-of-registered-users.controller.js               | 11 ++++++++++-
 .../list-of-registered-users.tpl.pug                     |  7 +++++--
 .../frontend/app/primitives/ui-grid/index.scss           |  8 ++++++++
 3 files changed, 23 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/775c6e57/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
index 3590229..0fc1cd6 100644
--- 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
@@ -166,6 +166,9 @@ export default class IgniteListOfRegisteredUsersCtrl {
                 api.selection.on.rowSelectionChanged($scope, $ctrl._updateSelected.bind($ctrl));
                 api.selection.on.rowSelectionChangedBatch($scope, $ctrl._updateSelected.bind($ctrl));
 
+                api.core.on.filterChanged($scope, $ctrl._filteredRows.bind($ctrl));
+                api.core.on.rowsVisibleChanged($scope, $ctrl._filteredRows.bind($ctrl));
+
                 api.grid.registerRowsProcessor(companiesExcludeFilter, 50);
 
                 $scope.$watch(() => $ctrl.gridApi.grid.getVisibleRows().length, (rows) => $ctrl.adjustHeight(rows));
@@ -211,6 +214,13 @@ export default class IgniteListOfRegisteredUsersCtrl {
         this.gridApi.core.handleWindowResize();
     }
 
+    _filteredRows() {
+        const filtered = _.filter(this.gridApi.grid.rows, ({ visible}) => visible);
+        const entities = _.map(filtered, 'entity');
+
+        this.filteredRows = entities;
+    }
+
     _updateSelected() {
         const ids = this.gridApi.selection.getSelectedRows().map(({ _id }) => _id).sort();
 
@@ -241,7 +251,6 @@ export default class IgniteListOfRegisteredUsersCtrl {
 
         // Check to all selected columns.
         this.gridOptions.selectedAll = true;
-
         _.forEach(this._selectableColumns(), ({ visible }) => this.gridOptions.selectedAll = visible);
 
         // Workaround for this.gridApi.grid.refresh() didn't return promise.

http://git-wip-us.apache.org/repos/asf/ignite/blob/775c6e57/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
index c4fec37..0b8bf7e 100644
--- a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
@@ -21,7 +21,7 @@ mixin grid-settings()
         i.fa.fa-cog(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
-                a(ng-click='$ctrl.gridOptions.selectedAll ? $ctrl.clearAllColumns() : $ctrl.selectAllColumns()') 
+                a(ng-click='$ctrl.gridOptions.selectedAll ? $ctrl.clearAllColumns() : $ctrl.selectAllColumns()')
                     i.fa.fa-check-square-o.pull-left(ng-if='$ctrl.gridOptions.selectedAll')
                     i.fa.fa-square-o.pull-left(ng-if='!$ctrl.gridOptions.selectedAll')
                     span All
@@ -36,7 +36,10 @@ mixin grid-settings()
         li(role='presentation' ng-class='{ active: $ctrl.groupBy === "user" }') 
             a(ng-click='$ctrl.groupByUser()') 
                 span Users
-                span.badge.badge--blue {{ $ctrl.gridOptions.data.length }}
+                span.badge.badge--blue(ng-hide='$ctrl.groupBy === "user"')
+                    | {{ $ctrl.gridOptions.data.length }}
+                span.badge.badge--blue(ng-show='$ctrl.groupBy === "user"')
+                    | {{ $ctrl.filteredRows.length }}
         li(role='presentation' ng-class='{ active: $ctrl.groupBy === "company" }')
             a(ng-click='$ctrl.groupByCompany()') 
                 span Companies

http://git-wip-us.apache.org/repos/asf/ignite/blob/775c6e57/modules/web-console/frontend/app/primitives/ui-grid/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/ui-grid/index.scss b/modules/web-console/frontend/app/primitives/ui-grid/index.scss
index 504cf5a..8e2fbaa 100644
--- a/modules/web-console/frontend/app/primitives/ui-grid/index.scss
+++ b/modules/web-console/frontend/app/primitives/ui-grid/index.scss
@@ -236,6 +236,10 @@
 
     .ui-grid-header,
     .ui-grid-viewport {
+        .ui-grid-icon-cancel {
+            right: 20px;
+        }
+
         .ui-grid-tree-base-row-header-buttons {
             .ui-grid-icon-plus-squared,
             .ui-grid-icon-minus-squared,
@@ -305,6 +309,10 @@
 
                     &.disabled {
                         opacity: .5;
+
+                        .ui-grid-icon-ok {
+                            cursor: default;
+                        }
                     }
                 }
             }


[09/13] ignite git commit: IGNITE-4943 Improve design of table on Admin Panel screen.

Posted by is...@apache.org.
IGNITE-4943 Improve design of table on Admin Panel screen.


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

Branch: refs/heads/ignite-3477-master
Commit: 8c9c60a48e3431950791c8cfeb9236f6d034e1cb
Parents: 4ad2657
Author: Dmitriy Shabalin <ds...@gridgain.com>
Authored: Wed Apr 12 10:19:06 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Wed Apr 12 10:19:06 2017 +0700

----------------------------------------------------------------------
 modules/web-console/frontend/.eslintrc          |   2 +-
 modules/web-console/frontend/app/app.js         |   3 -
 .../form-field-datepicker.pug                   |  59 ----
 .../form-field-datepicker.scss                  |  20 --
 .../list-of-registered-users.categories.js      |   4 +-
 .../list-of-registered-users.column-defs.js     |  44 +--
 .../list-of-registered-users.controller.js      | 132 ++++++--
 .../list-of-registered-users.scss               |   4 +
 .../list-of-registered-users.tpl.pug            |  73 ++---
 .../ui-grid-header/ui-grid-header.scss          |  91 ------
 .../ui-grid-header/ui-grid-header.tpl.pug       |  29 --
 .../ui-grid-settings/ui-grid-settings.pug       |  33 --
 .../ui-grid-settings/ui-grid-settings.scss      | 144 ---------
 .../frontend/app/helpers/jade/mixins.pug        |   3 +
 .../frontend/app/modules/states/admin.state.js  |  11 +-
 .../frontend/app/primitives/badge/index.scss    |   4 +
 .../frontend/app/primitives/btn/index.scss      |  41 +++
 .../app/primitives/datepicker/index.pug         |  60 ++++
 .../app/primitives/datepicker/index.scss        |  64 ++++
 .../frontend/app/primitives/dropdown/index.pug  |  43 +++
 .../frontend/app/primitives/dropdown/index.scss |  82 +++++
 .../frontend/app/primitives/index.js            |   8 +
 .../frontend/app/primitives/page/index.scss     |  35 ++
 .../frontend/app/primitives/panel/index.scss    |  51 +++
 .../frontend/app/primitives/tabs/index.scss     |  15 +
 .../app/primitives/ui-grid-header/index.scss    |  91 ++++++
 .../app/primitives/ui-grid-header/index.tpl.pug |  29 ++
 .../app/primitives/ui-grid-settings/index.pug   |  33 ++
 .../app/primitives/ui-grid-settings/index.scss  | 171 ++++++++++
 .../frontend/app/primitives/ui-grid/index.scss  | 321 +++++++++++++++++++
 .../frontend/public/stylesheets/style.scss      |   5 -
 modules/web-console/frontend/views/base2.pug    |  22 ++
 .../frontend/views/settings/admin.tpl.pug       |   3 +-
 .../web-console/frontend/views/sql/sql.tpl.pug  |   1 -
 34 files changed, 1249 insertions(+), 482 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/.eslintrc
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/.eslintrc b/modules/web-console/frontend/.eslintrc
index 958c6d1..adbeb84 100644
--- a/modules/web-console/frontend/.eslintrc
+++ b/modules/web-console/frontend/.eslintrc
@@ -143,7 +143,7 @@ rules:
     no-script-url: 0
     no-self-compare: 2
     no-sequences: 2
-    no-shadow: 2
+    no-shadow: 0
     no-shadow-restricted-names: 2
     no-spaced-func: 2
     no-sparse-arrays: 1

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/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 26d3ad5..80e32a1 100644
--- a/modules/web-console/frontend/app/app.js
+++ b/modules/web-console/frontend/app/app.js
@@ -17,9 +17,6 @@
 
 import '../public/stylesheets/style.scss';
 import '../app/primitives';
-import './components/ui-grid-header/ui-grid-header.scss';
-import './components/ui-grid-settings/ui-grid-settings.scss';
-import './components/form-field-datepicker/form-field-datepicker.scss';
 
 import './app.config';
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.pug b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.pug
deleted file mode 100644
index d70476f..0000000
--- a/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.pug
+++ /dev/null
@@ -1,59 +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 ignite-form-field-datepicker(label, model, name, mindate, maxdate, 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-min-date=mindate ? `{{ ${mindate} }}` : false
-            data-max-date=maxdate ? `{{ ${maxdate} }}` : `today`
-
-            data-container='body > .wrapper'
-
-            tabindex='0'
-
-            onkeydown="return false"
-
-            data-ignite-form-panel-field=''
-        )&attributes(attributes.attributes)
-
-    .ignite-form-field
-        if name
-            +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/8c9c60a4/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
deleted file mode 100644
index 0f6fe6e..0000000
--- a/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss
+++ /dev/null
@@ -1,20 +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.
- */
-
-.datepicker.dropdown-menu tbody button {
-    height: 100%;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/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
index 95edf8b..01b1fc8 100644
--- 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
@@ -16,8 +16,8 @@
  */
 
 export default [
-    {name: 'Actions', visible: true, selectable: true},
-    {name: 'User', visible: true, selectable: true},
+    {name: 'Actions', visible: false, selectable: false},
+    {name: 'User', visible: true, selectable: false},
     {name: 'Email', visible: true, selectable: true},
     {name: 'Company', visible: true, selectable: true},
     {name: 'Country', visible: true, selectable: true},

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/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
index e859acf..54bfb03 100644
--- 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
@@ -17,7 +17,7 @@
 
 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 USER_TEMPLATE = '<div class="ui-grid-cell-contents"><i class="pull-left" ng-class="row.entity.admin ? \'icon-admin\' : \'icon-user\'"></i>&nbsp;{{ 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>`;
@@ -49,32 +49,32 @@ const ACTIONS_TEMPLATE = `
 const EMAIL_TEMPLATE = '<div class="ui-grid-cell-contents"><a ng-href="mailto:{{ COL_FIELD }}">{{ COL_FIELD }}</a></div>';
 
 export default [
-    {name: 'actions', displayName: 'Actions', categoryDisplayName: 'Actions', cellTemplate: ACTIONS_TEMPLATE, field: 'actions', minWidth: 70, width: 70, enableFiltering: false, enableSorting: false},
+    {name: 'actions', displayName: 'Actions', categoryDisplayName: 'Actions', cellTemplate: ACTIONS_TEMPLATE, field: 'actions', minWidth: 70, width: 70, enableFiltering: false, enableSorting: false, visible: false},
     {name: 'user', displayName: 'User', categoryDisplayName: 'User', field: 'userName', cellTemplate: USER_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by name...' }},
-    {name: 'email', displayName: 'Email', categoryDisplayName: 'Email', field: 'email', cellTemplate: EMAIL_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by email...' }},
+    {name: 'email', displayName: 'Email', categoryDisplayName: 'Email', field: 'email', cellTemplate: EMAIL_TEMPLATE, minWidth: 160, enableFiltering: false, filter: { placeholder: 'Filter by email...' }},
     {name: 'company', displayName: 'Company', categoryDisplayName: 'Company', field: 'company', minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by company...' }},
-    {name: 'country', displayName: 'Country', categoryDisplayName: 'Country', field: 'countryCode', minWidth: 80, enableFiltering: true, filter: { placeholder: 'Filter by country...' }},
+    {name: 'country', displayName: 'Country', categoryDisplayName: 'Country', field: 'countryCode', minWidth: 120, enableFiltering: true, filter: { placeholder: 'Filter by country...' }},
     {name: 'lastlogin', displayName: 'Last login', categoryDisplayName: 'Last login', field: 'lastLogin', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 105, width: 105, enableFiltering: false, visible: false},
-    {name: 'lastactivity', displayName: 'Last activity', categoryDisplayName: 'Last activity', field: 'lastActivity', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 115, width: 115, enableFiltering: false, visible: true, sort: { direction: 'desc', priority: 0 }},
+    {name: 'lastactivity', displayName: 'Last activity', categoryDisplayName: 'Last activity', field: 'lastActivity', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 130, width: 130, enableFiltering: false, visible: true, sort: { direction: 'desc', priority: 0 }},
     // Configurations
-    {name: 'cfg_clusters', displayName: 'Clusters count', categoryDisplayName: 'Configurations', headerCellTemplate: CLUSTER_HEADER_TEMPLATE, field: 'counters.clusters', type: 'number', headerTooltip: 'Clusters count', minWidth: 55, width: 55, enableFiltering: false, visible: false},
-    {name: 'cfg_models', displayName: 'Models count', categoryDisplayName: 'Configurations', headerCellTemplate: MODEL_HEADER_TEMPLATE, field: 'counters.models', type: 'number', headerTooltip: 'Models count', minWidth: 55, width: 55, enableFiltering: false, visible: false},
-    {name: 'cfg_caches', displayName: 'Caches count', categoryDisplayName: 'Configurations', headerCellTemplate: CACHE_HEADER_TEMPLATE, field: 'counters.caches', type: 'number', headerTooltip: 'Caches count', minWidth: 55, width: 55, enableFiltering: false, visible: false},
-    {name: 'cfg_igfs', displayName: 'IGFS count', categoryDisplayName: 'Configurations', headerCellTemplate: IGFS_HEADER_TEMPLATE, field: 'counters.igfs', type: 'number', headerTooltip: 'IGFS count', minWidth: 55, width: 55, enableFiltering: false, visible: false},
+    {name: 'cfg_clusters', displayName: 'Clusters count', categoryDisplayName: 'Configurations', headerCellTemplate: CLUSTER_HEADER_TEMPLATE, field: 'counters.clusters', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Clusters count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
+    {name: 'cfg_models', displayName: 'Models count', categoryDisplayName: 'Configurations', headerCellTemplate: MODEL_HEADER_TEMPLATE, field: 'counters.models', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Models count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
+    {name: 'cfg_caches', displayName: 'Caches count', categoryDisplayName: 'Configurations', headerCellTemplate: CACHE_HEADER_TEMPLATE, field: 'counters.caches', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Caches count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
+    {name: 'cfg_igfs', displayName: 'IGFS count', categoryDisplayName: 'Configurations', headerCellTemplate: IGFS_HEADER_TEMPLATE, field: 'counters.igfs', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'IGFS count', minWidth: 65, width: 65, enableFiltering: false, visible: false},
     // Activities Total
-    {name: 'cfg', displayName: 'Cfg', categoryDisplayName: 'Total activities', field: 'activitiesTotal["configuration"] || 0', type: 'number', headerTooltip: 'Total count of configuration usages', minWidth: 55, width: 55, enableFiltering: false},
-    {name: 'qry', displayName: 'Qry', categoryDisplayName: 'Total activities', field: 'activitiesTotal["queries"] || 0', type: 'number', headerTooltip: 'Total count of queries usages', minWidth: 55, width: 55, enableFiltering: false},
-    {name: 'demo', displayName: 'Demo', categoryDisplayName: 'Total activities', field: 'activitiesTotal["demo"] || 0', type: 'number', headerTooltip: 'Total count of demo startup', minWidth: 65, width: 65, enableFiltering: false},
-    {name: 'dnld', displayName: 'Dnld', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/download"] || 0', type: 'number', headerTooltip: 'Total count of agent downloads', minWidth: 55, width: 55, enableFiltering: false},
-    {name: 'starts', displayName: 'Starts', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/start"] || 0', type: 'number', headerTooltip: 'Total count of agent startup', minWidth: 65, width: 65, enableFiltering: false},
+    {name: 'cfg', displayName: 'Cfg', categoryDisplayName: 'Total activities', field: 'activitiesTotal["configuration"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of configuration usages', minWidth: 70, width: 70, enableFiltering: false},
+    {name: 'qry', displayName: 'Qry', categoryDisplayName: 'Total activities', field: 'activitiesTotal["queries"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of queries usages', minWidth: 70, width: 70, enableFiltering: false},
+    {name: 'demo', displayName: 'Demo', categoryDisplayName: 'Total activities', field: 'activitiesTotal["demo"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of demo startup', minWidth: 85, width: 85, enableFiltering: false},
+    {name: 'dnld', displayName: 'Dnld', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/download"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of agent downloads', minWidth: 80, width: 80, enableFiltering: false},
+    {name: 'starts', displayName: 'Starts', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/start"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Total count of agent startup', minWidth: 80, width: 80, enableFiltering: false},
     // Activities Configuration
-    {name: 'clusters', displayName: 'Clusters', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/clusters"] || 0', type: 'number', headerTooltip: 'Configuration clusters', minWidth: 55, width: 80, enableFiltering: false, visible: false},
-    {name: 'model', displayName: 'Model', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/domains"] || 0', type: 'number', headerTooltip: 'Configuration model', minWidth: 55, width: 80, enableFiltering: false, visible: false},
-    {name: 'caches', displayName: 'Caches', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/caches"] || 0', type: 'number', headerTooltip: 'Configuration caches', minWidth: 55, width: 80, enableFiltering: false, visible: false},
-    {name: 'igfs', displayName: 'IGFS', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/igfs"] || 0', type: 'number', headerTooltip: 'Configuration IGFS', minWidth: 55, width: 80, enableFiltering: false, visible: false},
-    {name: 'summary', displayName: 'Summary', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/summary"] || 0', type: 'number', headerTooltip: 'Configuration summary', minWidth: 55, width: 80, enableFiltering: false, visible: false},
+    {name: 'clusters', displayName: 'Clusters', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/clusters"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration clusters', minWidth: 80, width: 80, enableFiltering: false, visible: false},
+    {name: 'model', displayName: 'Model', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/domains"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration model', minWidth: 80, width: 80, enableFiltering: false, visible: false},
+    {name: 'caches', displayName: 'Caches', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/caches"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration caches', minWidth: 80, width: 80, enableFiltering: false, visible: false},
+    {name: 'igfs', displayName: 'IGFS', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/igfs"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration IGFS', minWidth: 80, width: 80, enableFiltering: false, visible: false},
+    {name: 'summary', displayName: 'Summary', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/summary"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Configuration summary', minWidth: 80, width: 80, enableFiltering: false, visible: false},
     // Activities Queries
-    {name: 'execute', displayName: 'Execute', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/execute"] || 0', type: 'number', headerTooltip: 'Query executions', minWidth: 55, width: 80, enableFiltering: false, visible: false},
-    {name: 'explain', displayName: 'Explain', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/explain"] || 0', type: 'number', headerTooltip: 'Query explain executions', minWidth: 55, width: 80, enableFiltering: false, visible: false},
-    {name: 'scan', displayName: 'Scan', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/scan"] || 0', type: 'number', headerTooltip: 'Scan query executions', minWidth: 55, width: 80, enableFiltering: false, visible: false}
+    {name: 'execute', displayName: 'Execute', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/execute"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Query executions', minWidth: 65, width: 80, enableFiltering: false, visible: false},
+    {name: 'explain', displayName: 'Explain', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/explain"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Query explain executions', minWidth: 65, width: 80, enableFiltering: false, visible: false},
+    {name: 'scan', displayName: 'Scan', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/scan"] || 0', type: 'number', cellClass: 'ui-grid-number-cell', headerTooltip: 'Scan query executions', minWidth: 65, width: 80, enableFiltering: false, visible: false}
 ];

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/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
index acf76fa..3590229 100644
--- 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
@@ -15,14 +15,13 @@
  * limitations under the License.
  */
 
-import headerTemplate from 'app/components/ui-grid-header/ui-grid-header.tpl.pug';
+import headerTemplate from 'app/primitives/ui-grid-header/index.tpl.pug';
 
 import columnDefs from './list-of-registered-users.column-defs';
 import categories from './list-of-registered-users.categories';
 
 const rowTemplate = `<div
   ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid"
-  ng-mouseover="grid.api.selection.selectRow(row.entity);"
   ui-grid-one-bind-id-grid="rowRenderIndex + '-' + col.uid + '-cell'"
   class="ui-grid-cell"
   ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }"
@@ -39,6 +38,8 @@ export default class IgniteListOfRegisteredUsersCtrl {
 
         $ctrl.groupBy = 'user';
 
+        $ctrl.selected = [];
+
         $ctrl.params = {
             startDate: new Date(),
             endDate: new Date()
@@ -46,14 +47,20 @@ export default class IgniteListOfRegisteredUsersCtrl {
 
         $ctrl.uiGridGroupingConstants = uiGridGroupingConstants;
 
-        const becomeUser = (user) => {
+        User.read().then((user) => $ctrl.user = user);
+
+        const becomeUser = () => {
+            const user = this.gridApi.selection.getSelectedRows()[0];
+
             AdminData.becomeUser(user._id)
                 .then(() => User.load())
                 .then(() => $state.go('base.configuration.clusters'))
                 .then(() => NotebookData.load());
         };
 
-        const removeUser = (user) => {
+        const removeUser = () => {
+            const user = this.gridApi.selection.getSelectedRows()[0];
+
             Confirm.confirm(`Are you sure you want to remove user: "${user.userName}"?`)
                 .then(() => AdminData.removeUser(user))
                 .then(() => {
@@ -65,7 +72,9 @@ export default class IgniteListOfRegisteredUsersCtrl {
                 .then(() => $ctrl.adjustHeight($ctrl.gridOptions.data.length));
         };
 
-        const toggleAdmin = (user) => {
+        const toggleAdmin = () => {
+            const user = this.gridApi.selection.getSelectedRows()[0];
+
             if (user.adminChanging)
                 return;
 
@@ -76,7 +85,9 @@ export default class IgniteListOfRegisteredUsersCtrl {
                 .finally(() => user.adminChanging = false);
         };
 
-        const showActivities = (user) => {
+        const showActivities = () => {
+            const user = this.gridApi.selection.getSelectedRows()[0];
+
             return new ActivitiesUserDialog({ user });
         };
 
@@ -92,6 +103,34 @@ export default class IgniteListOfRegisteredUsersCtrl {
             return renderableRows;
         };
 
+        $ctrl.actionOptions = [
+            {
+                action: 'Become this user',
+                click: becomeUser.bind(this),
+                available: true
+            },
+            {
+                action: 'Revoke admin',
+                click: toggleAdmin.bind(this),
+                available: true
+            },
+            {
+                action: 'Grant admin',
+                click: toggleAdmin.bind(this),
+                available: false
+            },
+            {
+                action: 'Remove user',
+                click: removeUser.bind(this),
+                available: true
+            },
+            {
+                action: 'Activity detail',
+                click: showActivities.bind(this),
+                available: true
+            }
+        ];
+
         $ctrl._userGridOptions = {
             columnDefs,
             categories
@@ -99,30 +138,38 @@ export default class IgniteListOfRegisteredUsersCtrl {
 
         $ctrl.gridOptions = {
             data: [],
-            columnVirtualizationThreshold: 30,
+
             columnDefs,
             categories,
+
             headerTemplate,
+            columnVirtualizationThreshold: 30,
             rowTemplate,
+            rowHeight: 46,
+            selectWithCheckboxOnly: true,
+            selectionRowHeaderWidth: 52,
+            suppressRemoveSort: false,
             enableFiltering: true,
+            enableSelectAll: true,
             enableRowSelection: true,
-            enableRowHeaderSelection: false,
+            enableFullRowSelection: true,
             enableColumnMenus: false,
             multiSelect: false,
             modifierKeysToMultiSelect: true,
-            noUnselect: true,
+            noUnselect: false,
             fastWatch: true,
             exporterSuppressColumns: ['actions'],
             exporterCsvColumnSeparator: ';',
             onRegisterApi: (api) => {
                 $ctrl.gridApi = api;
 
-                api.becomeUser = becomeUser;
-                api.removeUser = removeUser;
-                api.toggleAdmin = toggleAdmin;
-                api.showActivities = showActivities;
+                api.selection.on.rowSelectionChanged($scope, $ctrl._updateSelected.bind($ctrl));
+                api.selection.on.rowSelectionChangedBatch($scope, $ctrl._updateSelected.bind($ctrl));
 
                 api.grid.registerRowsProcessor(companiesExcludeFilter, 50);
+
+                $scope.$watch(() => $ctrl.gridApi.grid.getVisibleRows().length, (rows) => $ctrl.adjustHeight(rows));
+                $scope.$watch(() => $ctrl.params.companiesExclude, () => $ctrl.gridApi.grid.refreshRows());
             }
         };
 
@@ -142,7 +189,7 @@ export default class IgniteListOfRegisteredUsersCtrl {
                 });
         };
 
-        const fitlerDates = (sdt, edt) => {
+        const filterDates = (sdt, edt) => {
             $ctrl.gridOptions.exporterCsvFilename = `web_console_users_${dtFilter(sdt, 'yyyy_MM')}.csv`;
 
             const startDate = Date.UTC(sdt.getFullYear(), sdt.getMonth(), 1);
@@ -151,25 +198,37 @@ export default class IgniteListOfRegisteredUsersCtrl {
             reloadUsers({ startDate, endDate });
         };
 
-        $scope.$watch(() => $ctrl.params.companiesExclude, () => {
-            $ctrl.gridApi.grid.refreshRows();
-        });
-
-        $scope.$watch(() => $ctrl.params.startDate, (sdt) => fitlerDates(sdt, $ctrl.params.endDate));
-        $scope.$watch(() => $ctrl.params.endDate, (edt) => fitlerDates($ctrl.params.startDate, edt));
-
-        $scope.$watch(() => $ctrl.gridApi.grid.getVisibleRows().length, (length) => $ctrl.adjustHeight(length >= 20 ? 20 : length));
+        $scope.$watch(() => $ctrl.params.startDate, (sdt) => filterDates(sdt, $ctrl.params.endDate));
+        $scope.$watch(() => $ctrl.params.endDate, (edt) => filterDates($ctrl.params.startDate, edt));
     }
 
     adjustHeight(rows) {
-        const height = Math.min(rows, 20) * 30 + 75;
+        // Add header height.
+        const height = Math.min(rows, 20) * 48 + 78;
 
-        // Remove header height.
         this.gridApi.grid.element.css('height', height + 'px');
 
         this.gridApi.core.handleWindowResize();
     }
 
+    _updateSelected() {
+        const ids = this.gridApi.selection.getSelectedRows().map(({ _id }) => _id).sort();
+
+        if (ids.length) {
+            const user = this.gridApi.selection.getSelectedRows()[0];
+            const other = this.user._id !== user._id;
+
+            this.actionOptions[1].available = other && user.admin;
+            this.actionOptions[2].available = other && !user.admin;
+
+            this.actionOptions[0].available = other;
+            this.actionOptions[3].available = other;
+        }
+
+        if (!_.isEqual(ids, this.selected))
+            this.selected = ids;
+    }
+
     _enableColumns(_categories, visible) {
         _.forEach(_categories, (cat) => {
             cat.visible = visible;
@@ -180,6 +239,11 @@ export default class IgniteListOfRegisteredUsersCtrl {
             });
         });
 
+        // Check to all selected columns.
+        this.gridOptions.selectedAll = true;
+
+        _.forEach(this._selectableColumns(), ({ visible }) => this.gridOptions.selectedAll = 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))
@@ -220,7 +284,6 @@ export default class IgniteListOfRegisteredUsersCtrl {
         this.groupBy = 'user';
 
         this.gridApi.grouping.clearGrouping();
-
         this.gridOptions.categories = this._userGridOptions.categories;
         this.gridOptions.columnDefs = this._userGridOptions.columnDefs;
     }
@@ -229,6 +292,7 @@ export default class IgniteListOfRegisteredUsersCtrl {
         this.groupBy = 'company';
 
         this.gridApi.grouping.clearGrouping();
+
         this.gridApi.grouping.groupColumn('company');
         this.gridApi.grouping.aggregateColumn('user', this.uiGridGroupingConstants.aggregation.COUNT);
 
@@ -242,17 +306,18 @@ export default class IgniteListOfRegisteredUsersCtrl {
         const _categories = _.cloneDeep(categories);
         const _columnDefs = _.cloneDeep(columnDefs);
 
-        // Cut company category;
+        // Cut company category.
         const company = _categories.splice(3, 1)[0];
+        company.selectable = false;
 
-        // Hide Actions category;
+        // Hide Actions category.
         _categories.splice(0, 1);
 
         _.forEach(_.filter(_columnDefs, {displayName: 'Actions'}), (col) => {
             col.visible = false;
         });
 
-        // Add company as first column;
+        // Add company as first column.
         _categories.unshift(company);
 
         _.forEach(_columnDefs, (col) => {
@@ -265,7 +330,7 @@ export default class IgniteListOfRegisteredUsersCtrl {
             col.customTreeAggregationFinalizerFn = (agg) => agg.rendered = agg.value;
         });
 
-        // Set grouping to last activity column
+        // Set grouping to last activity column.
         const lastactivity = _.find(_columnDefs, { name: 'lastactivity' });
 
         if (_.nonNil(lastactivity)) {
@@ -296,17 +361,18 @@ export default class IgniteListOfRegisteredUsersCtrl {
         const _categories = _.cloneDeep(categories);
         const _columnDefs = _.cloneDeep(columnDefs);
 
-        // Cut country category;
+        // Cut country category.
         const country = _categories.splice(4, 1)[0];
+        country.selectable = false;
 
-        // Hide Actions category;
+        // Hide Actions category.
         _categories.splice(0, 1);
 
         _.forEach(_.filter(_columnDefs, {displayName: 'Actions'}), (col) => {
             col.visible = false;
         });
 
-        // Add company as first column;
+        // Add company as first column.
         _categories.unshift(country);
 
         _.forEach(_columnDefs, (col) => {
@@ -319,7 +385,7 @@ export default class IgniteListOfRegisteredUsersCtrl {
             col.customTreeAggregationFinalizerFn = (agg) => agg.rendered = agg.value;
         });
 
-        // Set grouping to last activity column
+        // Set grouping to last activity column.
         const lastactivity = _.find(_columnDefs, { name: 'lastactivity' });
 
         if (_.nonNil(lastactivity)) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.scss b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.scss
index 8059d70..d94fb2e 100644
--- a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.scss
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.scss
@@ -15,6 +15,10 @@
  * limitations under the License.
  */
 
+ignite-list-of-registered-users {
+  display: block;
+}
+
 .list-of-registered-users {
   & > a {
     display: inline-block;

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
index ec4b4fd..c4fec37 100644
--- a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.tpl.pug
@@ -15,58 +15,59 @@
     limitations under the License.
 
 include /app/helpers/jade/mixins
-include /app/components/form-field-datepicker/form-field-datepicker.pug
 
 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
-
+    .grid-settings
+        i.fa.fa-cog(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
+                a(ng-click='$ctrl.gridOptions.selectedAll ? $ctrl.clearAllColumns() : $ctrl.selectAllColumns()') 
+                    i.fa.fa-check-square-o.pull-left(ng-if='$ctrl.gridOptions.selectedAll')
+                    i.fa.fa-square-o.pull-left(ng-if='!$ctrl.gridOptions.selectedAll')
+                    span All
+            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}}
 
 .list-of-registered-users
-    ul.tabs
+    ul.tabs.tabs--blue
         li(role='presentation' ng-class='{ active: $ctrl.groupBy === "user" }') 
             a(ng-click='$ctrl.groupByUser()') 
                 span Users
-                span.badge {{ $ctrl.gridOptions.data.length }}
+                span.badge.badge--blue {{ $ctrl.gridOptions.data.length }}
         li(role='presentation' ng-class='{ active: $ctrl.groupBy === "company" }')
             a(ng-click='$ctrl.groupByCompany()') 
                 span Companies
-                span.badge {{ $ctrl.companies.length }}
+                span.badge.badge--blue {{ $ctrl.companies.length }}
         li(role='presentation' ng-class='{ active: $ctrl.groupBy === "country" }')
             a(ng-click='$ctrl.groupByCountry()')
                 span Countries
-                span.badge {{ $ctrl.countries.length }}
+                span.badge.badge--blue {{ $ctrl.countries.length }}
 
-    .panel.panel-default
+    .panel--ignite
         .panel-heading.ui-grid-settings
-            +grid-settings
-            label(ng-show='$ctrl.groupBy === "user"') Showing users:&nbsp;
-                strong {{ $ctrl.gridApi.grid.getVisibleRows().length }}
-                sub(ng-show='users.length === $ctrl.gridApi.grid.getVisibleRows().length') all
-
-            -var form = 'admin'
-            form.pull-right(name=form novalidate)
-                button.btn.btn-primary(ng-click='$ctrl.exportCsv()' bs-tooltip data-title='Export table to csv') Export
-
-                .ui-grid-settings-dateperiod
-                    +ignite-form-field-datepicker('Period:', '$ctrl.params.startDate', '"period"', null, '$ctrl.params.endDate')
-                    +ignite-form-field-datepicker('Period:', '$ctrl.params.endDate', null, '$ctrl.params.startDate', null)
-
-                .ui-grid-settings-filter
+            .panel-title(ng-hide='$ctrl.selected.length')
+                span(ng-if='$ctrl.groupBy === "user"') List of registered users
+                span(ng-if='$ctrl.groupBy === "company"') List of registered companies
+                span(ng-if='$ctrl.groupBy === "country"') List of registered countries
+                +grid-settings
+                button.btn.btn--stroke(ng-click='$ctrl.exportCsv()' bs-tooltip data-title='Export table to csv')
+                    i.fa.fa-file-excel-o.export-icon
+                form.ui-grid-settings-dateperiod(name=form novalidate)
+                    -var form = 'admin'
+                    +ignite-form-field-datepicker('Period: from', '$ctrl.params.startDate', '"startDate"', null, '$ctrl.params.endDate')
+                    +ignite-form-field-datepicker('to', '$ctrl.params.endDate', '"endDate"', '$ctrl.params.startDate', null)
+                form.ui-grid-settings-filter
+                    -var form = 'admin'
                     +ignite-form-field-text('Exclude:', '$ctrl.params.companiesExclude', '"exclude"', false, false, 'Exclude by company name...')
 
+            .panel-selected(ng-show='$ctrl.selected.length')
+                .pull-right
+                    +ignite-form-field-bsdropdown('Actions', '$ctrl.action', 'action', false, false, '$ctrl.actionOptions')
+                div
+                    | {{ $ctrl.selected.length }} item{{ $ctrl.selected.length > 1 ? 's' : '' }} selected
+
         .panel-collapse
             .grid.ui-grid--ignite(ui-grid='$ctrl.gridOptions' ui-grid-resize-columns ui-grid-selection ui-grid-exporter ui-grid-pinning ui-grid-grouping)

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/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
deleted file mode 100644
index 4530c02..0000000
--- a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss
+++ /dev/null
@@ -1,91 +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-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 {
-        .ui-grid-cell-contents > span:not(.ui-grid-header-cell-label) {
-            right: 3px;
-        }
-    }
-
-    .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;
-        background: #f5f5f5;
-
-        .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/8c9c60a4/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
deleted file mode 100644
index 9b14fca..0000000
--- a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
+++ /dev/null
@@ -1,29 +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-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.ui-grid-category(ng-repeat='cat in grid.options.categories', ng-if='cat.visible && \
-                        (colContainer.renderedColumns | uiGridSubcategories: cat.name).length > 0')
-                            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')
-                        .ui-grid-header-cell.ui-grid-clearfix(ng-if='col.colDef.name === "treeBaseRowHeaderCol"' ng-repeat='col in colContainer.renderedColumns track by col.uid' ui-grid-header-cell='' col='col' render-index='$index')

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.pug b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.pug
deleted file mode 100644
index 8f1487e..0000000
--- a/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.pug
+++ /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/8c9c60a4/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
deleted file mode 100644
index d0a31f0..0000000
--- a/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss
+++ /dev/null
@@ -1,144 +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;
-    }
-
-    .btn {
-        float: right;
-
-        line-height: 20px;
-        margin-right: 0;
-    }
-
-    &-filter {
-        float: right;
-
-        .ignite-form-field {
-            width: 280px;
-            margin-right: 10px;
-
-            &__label {
-            }
-
-            &__control {
-            }
-
-            &:nth-child(1) {
-                float: left;
-
-                .ignite-form-field__label {
-                    width: 30%;
-                }
-
-                .ignite-form-field__control {
-                    width: 70%;
-                }
-            }
-        }
-    }
-
-    &-number-filter {
-        float: right;
-
-        .ignite-form-field {
-            width: 180px;
-            margin-right: 0;
-
-            &__label {
-            }
-
-            &__control {
-            }
-
-            &:nth-child(1) {
-                float: left;
-
-                .ignite-form-field__label {
-                    margin-right: 0;
-                    width: 70%;
-                    max-width: 100%;
-                }
-
-                .ignite-form-field__control {
-                    width: 30%;
-                }
-            }
-        }
-
-        button {
-            width: auto;
-            display: inline-block;
-            margin-left: 5px;
-        }
-    }
-
-    &-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%;
-                }
-            }
-
-            &:nth-child(2) {
-                float: left;
-
-                width: 100px;
-
-                .ignite-form-field__control {
-                    width: 100%;
-                }
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/helpers/jade/mixins.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/mixins.pug b/modules/web-console/frontend/app/helpers/jade/mixins.pug
index bf49fa9..3b6cd19 100644
--- a/modules/web-console/frontend/app/helpers/jade/mixins.pug
+++ b/modules/web-console/frontend/app/helpers/jade/mixins.pug
@@ -16,6 +16,9 @@
 
 include ./form
 include ../../primitives/tooltip/index
+include ../../primitives/datepicker/index
+include ../../primitives/dropdown/index
+include ../../primitives/ui-grid-settings/index
 
 //- Mixin for advanced options toggle.
 mixin advanced-options-toggle(click, cond, showMessage, hideMessage)

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/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 93a38dd..ea9ba49 100644
--- a/modules/web-console/frontend/app/modules/states/admin.state.js
+++ b/modules/web-console/frontend/app/modules/states/admin.state.js
@@ -18,6 +18,7 @@
 import angular from 'angular';
 
 import templateUrl from 'views/settings/admin.tpl.pug';
+import template from 'views/base2.pug';
 
 angular
 .module('ignite-console.states.admin', [
@@ -28,7 +29,15 @@ angular
     $stateProvider
     .state('settings.admin', {
         url: '/admin',
-        templateUrl,
+        views: {
+            '@': {
+                template
+            },
+            '@settings.admin': {
+                templateUrl
+            }
+        },
+        // templateUrl,
         onEnter: AclRoute.checkAccess('admin_page'),
         metaTags: {
             title: 'Admin panel'

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/badge/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/badge/index.scss b/modules/web-console/frontend/app/primitives/badge/index.scss
index 837ab5b..8ce477f 100644
--- a/modules/web-console/frontend/app/primitives/badge/index.scss
+++ b/modules/web-console/frontend/app/primitives/badge/index.scss
@@ -33,4 +33,8 @@
   line-height: 12px;
 
   background-color: $brand-primary;
+}
+
+.badge--blue {
+  background-color: #0067b9;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/btn/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/btn/index.scss b/modules/web-console/frontend/app/primitives/btn/index.scss
new file mode 100644
index 0000000..1eb027f
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/btn/index.scss
@@ -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.
+ */
+
+.btn.btn--stroke {
+    min-width: 36px;
+    height: 36px;
+
+    line-height: 36px;
+    text-align: center;
+
+    color: #ee2b27;
+    border: 1px solid #ee2b27;
+    background: initial;
+
+    &:hover, &:focus {
+        color: #a8110f;
+        border-color: #a8110f;
+    }
+
+    &:focus {
+        outline: none;
+    }
+
+    i {
+        margin: 0;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/datepicker/index.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/datepicker/index.pug b/modules/web-console/frontend/app/primitives/datepicker/index.pug
new file mode 100644
index 0000000..10453c0
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/datepicker/index.pug
@@ -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.
+
+mixin ignite-form-field-datepicker(label, model, name, mindate, maxdate, 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-min-date=mindate ? `{{ ${mindate} }}` : false
+            data-max-date=maxdate ? `{{ ${maxdate} }}` : `today`
+
+            data-placement='bottom'
+            data-container='.docs-content'
+
+            tabindex='0'
+
+            onkeydown="return false"
+
+            data-ignite-form-panel-field=''
+        )&attributes(attributes.attributes)
+
+    .datepicker--ignite.ignite-form-field
+        if name
+            +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/8c9c60a4/modules/web-console/frontend/app/primitives/datepicker/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/datepicker/index.scss b/modules/web-console/frontend/app/primitives/datepicker/index.scss
new file mode 100644
index 0000000..786a2c1
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/datepicker/index.scss
@@ -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.
+ */
+
+.datepicker.dropdown-menu tbody button {
+    height: 100%;
+}
+
+.datepicker--ignite {
+    $height: 36px;
+
+    display: inline-block;
+    width: auto;
+
+    font-size: 14px;
+
+    label.ignite-form-field__label {
+        width: auto;
+        max-width: initial;
+
+        font-size: inherit;
+        line-height: $height;
+    }
+
+    .ignite-form-field__control {
+        width: auto;
+
+        input {
+            width: auto;
+            height: $height;
+            min-width: 70px;
+            max-width: 70px;
+            padding: 0;
+            padding-left: 5px;
+
+            cursor: pointer;
+            color: transparent;
+            font-size: inherit;
+            line-height: $height;
+            text-align: left;
+            text-shadow: 0 0 0 #ee2b27;
+
+            border: none;
+            box-shadow: none;
+
+            &:hover, &:focus {
+                text-shadow: 0 0 0 #a8110f;
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/dropdown/index.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/dropdown/index.pug b/modules/web-console/frontend/app/primitives/dropdown/index.pug
new file mode 100644
index 0000000..a6476eb
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/dropdown/index.pug
@@ -0,0 +1,43 @@
+//-
+    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-bsdropdown(label, model, name, disabled, required, options, tip)
+    .dropdown--ignite.ignite-form-field
+        .ignite-form-field__control(
+            data-ng-model=model
+
+            data-ng-required=required && `${required}`
+            data-ng-disabled=disabled && `${disabled}` || `!${options}.length`
+
+            bs-dropdown=''
+
+            data-trigger='hover focus'
+            data-placement='bottom-right'
+            data-container='self'
+            data-animation=''
+
+            tabindex='0'
+            aria-haspopup='true'
+            aria-expanded='false'
+        )&attributes(attributes.attributes)
+            a.dropdown-toggle
+                span !{label}
+                span.caret
+
+        ul.dropdown-menu(role='menu')
+            li(ng-repeat=`item in ${options}` ng-if='item.available')
+                a(ng-click='item.click()') {{ item.action }}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/dropdown/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/dropdown/index.scss b/modules/web-console/frontend/app/primitives/dropdown/index.scss
new file mode 100644
index 0000000..e474534
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/dropdown/index.scss
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+.ignite-form-field {
+    & &__control {
+        &:first-child:last-child {
+          width: 100% !important;
+        }
+    }
+}
+
+.dropdown--ignite {
+    font-style: normal;
+
+    .ignite-form-field__control {
+        outline: none;
+
+        & > a {
+            display: inline-block;
+            height: 36px;
+
+            padding: 0 15px;
+
+            border: 1px solid #ee2b27;
+            border-radius: 4px;
+
+            color: #de4538;
+            line-height: 36px;
+
+            .caret {
+                margin-left: 9px;
+                margin-right: -6px;
+            }
+        }
+
+        &:hover, &:focus {
+            & > a {
+                border-color: #a8110f;
+
+                color: #a8110f;
+                text-decoration: none;
+            }
+        }
+
+        ul {
+            padding: 0;
+
+            border-color: #c5c5c5;
+            box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.3);
+
+            a {
+                padding-left: 15px;
+                padding-right: 15px;
+
+                color: #393939;
+                line-height: 26px;
+
+                &:hover {
+                    color: #a8110f;
+                }
+            }
+
+            li:not(:last-child) {
+                border-bottom: 1px solid #dddddd;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/index.js b/modules/web-console/frontend/app/primitives/index.js
index 7940f7a..e72f087 100644
--- a/modules/web-console/frontend/app/primitives/index.js
+++ b/modules/web-console/frontend/app/primitives/index.js
@@ -16,4 +16,12 @@
  */
 
 import './badge/index.scss';
+import './btn/index.scss';
+import './datepicker/index.scss';
 import './tabs/index.scss';
+import './panel/index.scss';
+import './dropdown/index.scss';
+import './ui-grid/index.scss';
+import './ui-grid-header/index.scss';
+import './ui-grid-settings/index.scss';
+import './page/index.scss';

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/page/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/page/index.scss b/modules/web-console/frontend/app/primitives/page/index.scss
new file mode 100644
index 0000000..fb749e7
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/page/index.scss
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+.docs-content {
+    header {
+        margin: 40px 0 30px;
+        border: none;
+        background-color: initial;
+
+        h1 {
+            color: #393939;
+            font-family: Roboto;
+            font-size: 24px;
+            font-weight: normal;
+            font-style: normal;
+            font-stretch: normal;
+            line-height: 24px;
+            letter-spacing: normal;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/panel/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/panel/index.scss b/modules/web-console/frontend/app/primitives/panel/index.scss
new file mode 100644
index 0000000..826d33e
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/panel/index.scss
@@ -0,0 +1,51 @@
+/*
+ * 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 '../../../public/stylesheets/variables';
+
+.panel--ignite {
+  border: none;
+  border-radius: 0;
+
+  font-family: Roboto;
+
+  background-color: white;
+  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
+
+  .panel-heading {
+    height: auto;
+    padding: 22px 20px;
+
+    background-color: initial;
+    border-bottom: 1px solid $panel-default-border;
+
+    &:hover {
+      text-decoration: none;
+    }
+  }
+
+  .panel-title {
+    font-size: 16px;
+    line-height: 36px;
+  }
+
+  .panel-selected {
+    font-size: 14px;
+    font-style: italic;
+    line-height: 36px;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/tabs/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/tabs/index.scss b/modules/web-console/frontend/app/primitives/tabs/index.scss
index eed88cb..ade990d 100644
--- a/modules/web-console/frontend/app/primitives/tabs/index.scss
+++ b/modules/web-console/frontend/app/primitives/tabs/index.scss
@@ -27,6 +27,8 @@ ul.tabs {
     list-style: none;
 
     padding-left: 0;
+    margin-bottom: 0;
+
     border-bottom: 1px solid $nav-tabs-border-color;
 
     li {
@@ -46,6 +48,7 @@ ul.tabs {
 
             color: $text-color;
             font-size: $font-size;
+            font-family: Roboto;
             text-align: center;
             line-height: $height - 2*$offset-vertical;
 
@@ -70,4 +73,16 @@ ul.tabs {
             margin-left: 45px;
         }
     }
+}
+
+ul.tabs.tabs--blue {
+    li {
+        &.active {
+            border-color: #0067b9;
+        }
+
+        &:not(.active):hover {
+            border-color: #94bbdd;
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/ui-grid-header/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/ui-grid-header/index.scss b/modules/web-console/frontend/app/primitives/ui-grid-header/index.scss
new file mode 100644
index 0000000..4530c02
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/ui-grid-header/index.scss
@@ -0,0 +1,91 @@
+/*
+ * 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 {
+        .ui-grid-cell-contents > span:not(.ui-grid-header-cell-label) {
+            right: 3px;
+        }
+    }
+
+    .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;
+        background: #f5f5f5;
+
+        .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/8c9c60a4/modules/web-console/frontend/app/primitives/ui-grid-header/index.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/ui-grid-header/index.tpl.pug b/modules/web-console/frontend/app/primitives/ui-grid-header/index.tpl.pug
new file mode 100644
index 0000000..1b91d9e
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/ui-grid-header/index.tpl.pug
@@ -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.
+
+.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.ui-grid-category(ng-repeat='cat in grid.options.categories', ng-if='cat.visible && \
+                        (colContainer.renderedColumns | uiGridSubcategories: cat.name).length > 0')
+                            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')
+                        .ui-grid-header-cell.ui-grid-clearfix(ng-if='col.colDef.name === "treeBaseRowHeaderCol" || col.colDef.name === "selectionRowHeaderCol"' ng-repeat='col in colContainer.renderedColumns track by col.uid' ui-grid-header-cell='' col='col' render-index='$index' ng-class='{ disabled: !grid.options.multiSelect && col.colDef.name === "selectionRowHeaderCol"}')

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/ui-grid-settings/index.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/ui-grid-settings/index.pug b/modules/web-console/frontend/app/primitives/ui-grid-settings/index.pug
new file mode 100644
index 0000000..8f1487e
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/ui-grid-settings/index.pug
@@ -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/8c9c60a4/modules/web-console/frontend/app/primitives/ui-grid-settings/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/ui-grid-settings/index.scss b/modules/web-console/frontend/app/primitives/ui-grid-settings/index.scss
new file mode 100644
index 0000000..3519eb2
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/ui-grid-settings/index.scss
@@ -0,0 +1,171 @@
+/*
+ * 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 {
+        padding: 0;
+
+        & > li {
+            & > a {
+                padding: 3px 12px;
+
+                & > span {
+                    line-height: 26px;
+                    padding-left: 10px;
+                    padding-right: 8px;
+                    cursor: pointer;
+                }
+
+                & > i {
+                    position: relative;
+                    
+                    width: 12px;
+                    height: 12px;
+                    margin-top: 7px;
+                    margin-left: 0;
+
+                    color: inherit;
+                    line-height: 26px;
+
+                    border: 1px solid #afafaf;
+                    border-radius: 2px;
+                    background-color: #FFF;
+
+                    box-shadow: inset 0 1px 1px #ccc;
+
+                    &.fa-square-o:before,
+                    &.fa-check-square-o:before {
+                        content: '';
+                    }
+
+                    &.fa-check-square-o {
+                        border-color: #0067b9;
+                        background-color: #0067b9;
+
+                        box-shadow: none;
+                    }
+
+                    &.fa-check-square-o:before {
+                        content: '';
+
+                        position: absolute;
+                        top: 0px;
+                        left: 3px;
+
+                        width: 4px;
+                        height: 8px;
+
+                        border: solid #FFF;
+                        border-width: 0 2px 2px 0;
+
+                        transform: rotate(35deg);
+                    }
+                }
+            }
+
+            &:not(:last-child) {
+                border-bottom: 1px solid #dddddd;
+            }
+        }
+    }
+
+    .btn {
+        float: right;
+
+        line-height: 20px;
+        margin-right: 0;
+    }
+
+    &-filter {
+        float: right;
+        margin-right: 35px;
+
+        .ignite-form-field {
+            $height: 36px;
+
+            width: 260px;
+
+            font-size: 14px;
+
+            label {
+                width: auto;
+                max-width: initial;
+                margin-right: 10px;
+
+                font-size: inherit;
+                line-height: $height;
+            }
+
+            &__control {
+                width: 190px;
+
+                input {
+                    &:focus {
+                        box-shadow: none;
+                    }
+                }
+            }
+        }
+    }
+
+    &-number-filter {
+        float: right;
+
+        .ignite-form-field {
+            width: 180px;
+            margin-right: 0;
+
+            &__label {
+            }
+
+            &__control {
+            }
+
+            &:nth-child(1) {
+                float: left;
+
+                .ignite-form-field__label {
+                    margin-right: 0;
+                    width: 70%;
+                    max-width: 100%;
+                }
+
+                .ignite-form-field__control {
+                    width: 30%;
+                }
+            }
+        }
+
+        button {
+            width: auto;
+            display: inline-block;
+            margin-left: 5px;
+        }
+    }
+
+    &-dateperiod {
+        float: right;
+        display: block;
+        margin-right: 35px;
+    }
+}
+
+.grid-settings {
+    display: inline-block;
+
+    margin-left: 10px;
+}
\ No newline at end of file


[02/13] ignite git commit: ignite-1977 - fixed IgniteSemaphore fault tolerance.

Posted by is...@apache.org.
ignite-1977 - fixed IgniteSemaphore fault tolerance.


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

Branch: refs/heads/ignite-3477-master
Commit: 902bf42c36f46b0aaa605b779a699eb8e0c0aca3
Parents: aeacad6
Author: Vladisav Jelisavcic <vl...@gmail.com>
Authored: Tue Apr 11 14:09:12 2017 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Tue Apr 11 14:09:12 2017 +0300

----------------------------------------------------------------------
 .../datastructures/GridCacheSemaphoreImpl.java  | 74 +++++++++++++++++---
 .../datastructures/GridCacheSemaphoreState.java | 22 ++++++
 ...eAbstractDataStructuresFailoverSelfTest.java | 21 ++++--
 3 files changed, 102 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/902bf42c/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java
index a1c0515..159e735 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java
@@ -232,6 +232,10 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
 
         /** {@inheritDoc} */
         @Override protected final boolean tryReleaseShared(int releases) {
+            // Fail-fast path.
+            if(broken)
+                return true;
+
             // Check if some other node updated the state.
             // This method is called with release==0 only when trying to wake through update.
             if (releases == 0)
@@ -295,6 +299,13 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
                                     throw new IgniteCheckedException("Failed to find semaphore with given name: " +
                                         name);
 
+                                // Abort if state is already broken.
+                                if (val.isBroken()) {
+                                    tx.rollback();
+
+                                    return true;
+                                }
+
                                 boolean retVal = val.getCount() == expVal;
 
                                 if (retVal) {
@@ -349,11 +360,13 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
 
         /**
          * This method is used for releasing the permits acquired by failing node.
+         * In case the semaphore is broken, no permits are released and semaphore is set (globally) to broken state.
          *
          * @param nodeId ID of the failing node.
+         * @param broken Flag indicating that this semaphore is broken.
          * @return True if this is the call that succeeded to change the global state.
          */
-        protected boolean releaseFailedNode(final UUID nodeId) {
+        protected boolean releaseFailedNode(final UUID nodeId, final boolean broken) {
             try {
                 return CU.outTx(
                     retryTopologySafe(new Callable<Boolean>() {
@@ -369,6 +382,25 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
                                     throw new IgniteCheckedException("Failed to find semaphore with given name: " +
                                         name);
 
+                                // Quit early if semaphore is already broken.
+                                if( val.isBroken()) {
+                                    tx.rollback();
+
+                                    return false;
+                                }
+
+                                // Mark semaphore as broken. No permits are released,
+                                // since semaphore is useless from now on.
+                                if (broken) {
+                                    val.setBroken(true);
+
+                                    semView.put(key, val);
+
+                                    tx.commit();
+
+                                    return true;
+                                }
+
                                 Map<UUID, Integer> map = val.getWaiters();
 
                                 if (!map.containsKey(nodeId)) {
@@ -473,7 +505,11 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
 
                                 tx.commit();
 
-                                return new Sync(cnt, waiters, failoverSafe);
+                                Sync sync = new Sync(cnt, waiters, failoverSafe);
+
+                                sync.setBroken(val.isBroken());
+
+                                return sync;
                             }
                         }
                     }),
@@ -520,6 +556,9 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
         if (sync == null)
             return;
 
+        // Update broken flag.
+        sync.setBroken(val.isBroken());
+
         // Update permission count.
         sync.setPermits(val.getCount());
 
@@ -535,10 +574,13 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
         int numPermits = sync.getPermitsForNode(nodeId);
 
         if (numPermits > 0) {
-            if (sync.failoverSafe)
-                // Release permits acquired by threads on failing node.
-                sync.releaseFailedNode(nodeId);
-            else {
+            // Semaphore is broken if reaches this point in non-failover safe mode.
+            boolean broken = !sync.failoverSafe;
+
+            // Release permits acquired by threads on failing node.
+            sync.releaseFailedNode(nodeId, broken);
+
+            if (broken) {
                 // Interrupt every waiting thread if this semaphore is not failover safe.
                 sync.setBroken(true);
 
@@ -614,8 +656,11 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
 
             sync.acquireSharedInterruptibly(permits);
 
-            if (isBroken())
+            if (isBroken()) {
+                Thread.interrupted(); // Clear interrupt flag.
+
                 throw new InterruptedException();
+            }
         }
         catch (IgniteCheckedException e) {
             throw U.convertException(e);
@@ -731,8 +776,11 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
 
             boolean result = sync.nonfairTryAcquireShared(1) >= 0;
 
-            if (isBroken())
+            if (isBroken()) {
+                Thread.interrupted(); // Clear interrupt flag.
+
                 throw new InterruptedException();
+            }
 
             return result;
         }
@@ -756,8 +804,11 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
 
             boolean result = sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
 
-            if (isBroken())
+            if (isBroken()) {
+                Thread.interrupted(); // Clear interrupt flag.
+
                 throw new InterruptedException();
+            }
 
             return result;
         }
@@ -825,8 +876,11 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter
 
             boolean result = sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
 
-            if (isBroken())
+            if (isBroken()) {
+                Thread.interrupted();
+
                 throw new InterruptedException();
+            }
 
             return result;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/902bf42c/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreState.java
index 50cdf10..cdff9c5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreState.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreState.java
@@ -46,6 +46,9 @@ public class GridCacheSemaphoreState implements GridCacheInternal, Externalizabl
     /** FailoverSafe flag. */
     private boolean failoverSafe;
 
+    /** Flag indicating that semaphore is no longer safe to use. */
+    private boolean broken;
+
     /**
      * Constructor.
      *
@@ -101,6 +104,21 @@ public class GridCacheSemaphoreState implements GridCacheInternal, Externalizabl
         return failoverSafe;
     }
 
+    /**
+     * @return broken flag.
+     */
+    public boolean isBroken() {
+        return broken;
+    }
+
+    /**
+     *
+     * @param broken Flag indicating that this semaphore should be no longer used.
+     */
+    public void setBroken(boolean broken) {
+        this.broken = broken;
+    }
+
     /** {@inheritDoc} */
     @Override public Object clone() throws CloneNotSupportedException {
         return super.clone();
@@ -120,6 +138,8 @@ public class GridCacheSemaphoreState implements GridCacheInternal, Externalizabl
                 out.writeInt(e.getValue());
             }
         }
+
+        out.writeBoolean(broken);
     }
 
     /** {@inheritDoc} */
@@ -135,6 +155,8 @@ public class GridCacheSemaphoreState implements GridCacheInternal, Externalizabl
             for (int i = 0; i < size; i++)
                 waiters.put(U.readUuid(in), in.readInt());
         }
+
+        broken = in.readBoolean();
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/902bf42c/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractDataStructuresFailoverSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractDataStructuresFailoverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractDataStructuresFailoverSelfTest.java
index 285ea6e..f918acd 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractDataStructuresFailoverSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/GridCacheAbstractDataStructuresFailoverSelfTest.java
@@ -530,8 +530,6 @@ public abstract class GridCacheAbstractDataStructuresFailoverSelfTest extends Ig
      * @throws Exception If failed.
      */
     private void doTestSemaphore(ConstantTopologyChangeWorker topWorker, final boolean failoverSafe) throws Exception {
-        fail("https://issues.apache.org/jira/browse/IGNITE-1977");
-
         final int permits = topWorker instanceof MultipleTopologyChangeWorker ||
             topWorker instanceof PartitionedMultipleTopologyChangeWorker ? TOP_CHANGE_THREAD_CNT * 3 :
             TOP_CHANGE_CNT;
@@ -548,9 +546,14 @@ public abstract class GridCacheAbstractDataStructuresFailoverSelfTest extends Ig
                             break;
                         }
                         catch (IgniteInterruptedException e) {
-                            // Exception may happen in non failover safe mode.
+                           // Exception may happen in non failover safe mode.
                             if (failoverSafe)
                                 throw e;
+                            else {
+                                // In non-failoverSafe mode semaphore is not safe to be reused,
+                                // and should always be discarded after exception is caught.
+                                break;
+                            }
                         }
                     }
 
@@ -569,6 +572,11 @@ public abstract class GridCacheAbstractDataStructuresFailoverSelfTest extends Ig
                         // Exception may happen in non failover safe mode.
                         if (failoverSafe)
                             throw e;
+                        else {
+                            // In non-failoverSafe mode semaphore is not safe to be reused,
+                            // and should always be discarded after exception is caught.
+                            break;
+                        }
                     }
                 }
 
@@ -581,8 +589,11 @@ public abstract class GridCacheAbstractDataStructuresFailoverSelfTest extends Ig
 
             fut.get();
 
-            for (Ignite g : G.allGrids())
-                assertEquals(permits, g.semaphore(STRUCTURE_NAME, permits, false, false).availablePermits());
+            // Semaphore is left in proper state only if failoverSafe mode is used.
+            if (failoverSafe) {
+                for (Ignite g : G.allGrids())
+                    assertEquals(permits, g.semaphore(STRUCTURE_NAME, permits, false, false).availablePermits());
+            }
         }
     }
 


[13/13] ignite git commit: Merge remote-tracking branch 'upstream/ignite-3477-master' into ignite-3477-master

Posted by is...@apache.org.
Merge remote-tracking branch 'upstream/ignite-3477-master' into ignite-3477-master


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

Branch: refs/heads/ignite-3477-master
Commit: 5839f481b7ff755bc68a521014ae308ac675baec
Parents: 21dcef2 0a69e45
Author: Igor Sapego <is...@gridgain.com>
Authored: Wed Apr 12 15:46:27 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Wed Apr 12 15:46:27 2017 +0300

----------------------------------------------------------------------
 .../dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs    | 1 -
 .../dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs          | 2 --
 2 files changed, 3 deletions(-)
----------------------------------------------------------------------



[04/13] ignite git commit: ignite-4828 Improve the distribution of keys within partitions

Posted by is...@apache.org.
ignite-4828 Improve the distribution of keys within partitions


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

Branch: refs/heads/ignite-3477-master
Commit: 55ab10eee485ef47a1c0794cbc90da0376ecd738
Parents: c9d08d3
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Tue Apr 11 19:47:10 2017 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Tue Apr 11 19:47:10 2017 +0300

----------------------------------------------------------------------
 .../rendezvous/RendezvousAffinityFunction.java  | 26 ++++++++--
 .../GridCachePartitionExchangeManager.java      |  2 +-
 ...inityFunctionFastPowerOfTwoHashSelfTest.java | 50 ++++++++++++++++++++
 ...ousAffinityFunctionStandardHashSelfTest.java | 50 ++++++++++++++++++++
 .../testsuites/IgniteCacheTestSuite2.java       |  8 +++-
 5 files changed, 129 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/55ab10ee/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
index 0fee1af..dcac7d4 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
@@ -101,6 +101,9 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /** Number of partitions. */
     private int parts;
 
+    /** Mask to use in calculation when partitions count is power of 2. */
+    private transient int mask = -1;
+
     /** Exclude neighbors flag. */
     private boolean exclNeighbors;
 
@@ -188,7 +191,9 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
         A.ensure(parts > 0, "parts > 0");
 
         this.exclNeighbors = exclNeighbors;
-        this.parts = parts;
+
+        setPartitions(parts);
+
         this.backupFilter = backupFilter;
 
         try {
@@ -216,16 +221,22 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     }
 
     /**
-     * Sets total number of partitions.
+     * Sets total number of partitions.If the number of partitions is a power of two,
+     * the PowerOfTwo hashing method will be used.  Otherwise the Standard hashing
+     * method will be applied.
      *
      * @param parts Total number of partitions.
      * @return {@code this} for chaining.
      */
     public RendezvousAffinityFunction setPartitions(int parts) {
-        A.ensure(parts <= CacheConfiguration.MAX_PARTITIONS_COUNT, "parts <= " + CacheConfiguration.MAX_PARTITIONS_COUNT);
+        A.ensure(parts <= CacheConfiguration.MAX_PARTITIONS_COUNT,
+            "parts <= " + CacheConfiguration.MAX_PARTITIONS_COUNT);
+        A.ensure(parts > 0, "parts > 0");
 
         this.parts = parts;
 
+        mask = (parts & (parts - 1)) == 0 ? parts - 1 : -1;
+
         return this;
     }
 
@@ -507,6 +518,12 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
             throw new IllegalArgumentException("Null key is passed for a partition calculation. " +
                 "Make sure that an affinity key that is used is initialized properly.");
 
+        if (mask >= 0) {
+            int h;
+
+            return ((h = key.hashCode()) ^ (h >>> 16)) & mask;
+        }
+
         return U.safeAbs(key.hashCode() % parts);
     }
 
@@ -553,7 +570,8 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        parts = in.readInt();
+        setPartitions(in.readInt());
+
         exclNeighbors = in.readBoolean();
         hashIdRslvr = (AffinityNodeHashResolver)in.readObject();
         backupFilter = (IgniteBiPredicate<ClusterNode, ClusterNode>)in.readObject();

http://git-wip-us.apache.org/repos/asf/ignite/blob/55ab10ee/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index 885106d..1297c38 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -42,7 +42,6 @@ import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.IgniteNeedReconnectException;
 import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cluster.ClusterNode;
@@ -52,6 +51,7 @@ import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
 import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.IgniteNeedReconnectException;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
 import org.apache.ignite.internal.managers.discovery.DiscoCache;

http://git-wip-us.apache.org/repos/asf/ignite/blob/55ab10ee/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest.java
new file mode 100644
index 0000000..683ffa2
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.cache.affinity.rendezvous;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cache.affinity.AbstractAffinityFunctionSelfTest;
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.testframework.GridTestUtils;
+
+/**
+ * Tests for {@link RendezvousAffinityFunction}.
+ */
+public class RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest extends AbstractAffinityFunctionSelfTest {
+    /** Ignite. */
+    private static Ignite ignite;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        ignite = startGrid();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        AffinityFunction aff = new RendezvousAffinityFunction(512, null);
+
+        GridTestUtils.setFieldValue(aff, "ignite", ignite);
+
+        return aff;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/55ab10ee/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionStandardHashSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionStandardHashSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionStandardHashSelfTest.java
new file mode 100644
index 0000000..ed47c57
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionStandardHashSelfTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.cache.affinity.rendezvous;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cache.affinity.AbstractAffinityFunctionSelfTest;
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.testframework.GridTestUtils;
+
+/**
+ * Tests for {@link RendezvousAffinityFunction}.
+ */
+public class RendezvousAffinityFunctionStandardHashSelfTest extends AbstractAffinityFunctionSelfTest {
+    /** Ignite. */
+    private static Ignite ignite;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        ignite = startGrid();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        AffinityFunction aff = new RendezvousAffinityFunction(513, null);
+
+        GridTestUtils.setFieldValue(aff, "ignite", ignite);
+
+        return aff;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/55ab10ee/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
index e37a8a1..0db7d06 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
@@ -22,6 +22,8 @@ import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionBackupFilterSel
 import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionExcludeNeighborsSelfTest;
 import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionBackupFilterSelfTest;
 import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionExcludeNeighborsSelfTest;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionStandardHashSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheConcurrentReadThroughTest;
 import org.apache.ignite.internal.processors.cache.CacheConfigurationLeakTest;
 import org.apache.ignite.internal.processors.cache.CacheDhtLocalPartitionAfterRemoveSelfTest;
@@ -114,11 +116,11 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePar
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxSingleThreadedSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxTimeoutSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheRendezvousAffinityClientSelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridPartitionedBackupLoadSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheStoreUpdateTest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearOffheapCacheStoreUpdateTest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridPartitionedBackupLoadSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.NearCacheSyncUpdateTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.NoneRebalanceModeSelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridNearOffheapCacheStoreUpdateTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedEvictionSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedJobExecutionTest;
 import org.apache.ignite.internal.processors.cache.local.GridCacheLocalAtomicBasicStoreSelfTest;
@@ -181,6 +183,8 @@ public class IgniteCacheTestSuite2 extends TestSuite {
         suite.addTest(new TestSuite(GridCacheAtomicNearReadersSelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedAffinitySelfTest.class));
         suite.addTest(new TestSuite(RendezvousAffinityFunctionExcludeNeighborsSelfTest.class));
+        suite.addTest(new TestSuite(RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest.class));
+        suite.addTest(new TestSuite(RendezvousAffinityFunctionStandardHashSelfTest.class));
         suite.addTest(new TestSuite(FairAffinityFunctionExcludeNeighborsSelfTest.class));
         suite.addTest(new TestSuite(GridCacheRendezvousAffinityClientSelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedProjectionAffinitySelfTest.class));


[05/13] ignite git commit: IGNITE-4948 - Fix for web session clustering with security

Posted by is...@apache.org.
IGNITE-4948 - Fix for web session clustering with security


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

Branch: refs/heads/ignite-3477-master
Commit: 55b9b8beb4a3d93ea733b6bc56a566dbf0918fcf
Parents: 55ab10e
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Apr 11 22:50:18 2017 +0200
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Apr 11 22:50:18 2017 +0200

----------------------------------------------------------------------
 .../cache/websession/WebSessionFilter.java      | 22 +++++++-------------
 1 file changed, 8 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/55b9b8be/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
----------------------------------------------------------------------
diff --git a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
index 96c1717..0644c0f 100644
--- a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
+++ b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
@@ -31,8 +31,9 @@ import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
-import javax.servlet.http.*;
-
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteClientDisconnectedException;
@@ -560,18 +561,10 @@ public class WebSessionFilter implements Filter {
 
         chain.doFilter(httpReq, res);
 
-        if (!cached.isValid())
-            binaryCache.remove(cached.id());
-        // Changed session ID.
-        else if (!cached.getId().equals(sesId)) {
-            final String oldId = cached.getId();
-
-            cached.invalidate();
+        WebSessionV2 cachedNew = (WebSessionV2)httpReq.getSession(false);
 
-            binaryCache.remove(oldId);
-        }
-        else
-            updateAttributesV2(cached.getId(), cached);
+        if (cachedNew != null && cachedNew.isValid())
+            updateAttributesV2(cachedNew.getId(), cachedNew);
 
         return sesId;
     }
@@ -762,6 +755,7 @@ public class WebSessionFilter implements Filter {
      */
     public void destroySession(String sesId) {
         assert sesId != null;
+
         for (int i = 0; i < retries; i++) {
             try {
                 if (cache.remove(sesId) && log.isDebugEnabled())
@@ -1016,7 +1010,7 @@ public class WebSessionFilter implements Filter {
                     }
                 }
                 else
-                    return null;
+                    ses = null;
             }
 
             return ses;


[07/13] ignite git commit: IGNITE-1192: Apache Ignite Spring Data integration

Posted by is...@apache.org.
IGNITE-1192: Apache Ignite Spring Data integration


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

Branch: refs/heads/ignite-3477-master
Commit: 4ad2657d4c2a4914966399d39bf609c1301e47b1
Parents: 55b9b8b
Author: Denis Magda <dm...@gridgain.com>
Authored: Tue Apr 11 20:13:51 2017 -0700
Committer: Denis Magda <dm...@gridgain.com>
Committed: Tue Apr 11 20:13:51 2017 -0700

----------------------------------------------------------------------
 examples/pom.xml                                |   6 +
 .../examples/springdata/PersonRepository.java   |  59 ++++
 .../examples/springdata/SpringAppCfg.java       |  69 +++++
 .../examples/springdata/SpringDataExample.java  | 154 ++++++++++
 .../examples/SpringDataExampleSelfTest.java     |  32 ++
 .../testsuites/IgniteExamplesSelfTestSuite.java |   2 +
 modules/spring-data/README.txt                  |  32 ++
 modules/spring-data/licenses/apache-2.0.txt     | 202 ++++++++++++
 modules/spring-data/pom.xml                     |  79 +++++
 .../springdata/repository/IgniteRepository.java |  58 ++++
 .../config/EnableIgniteRepositories.java        | 119 ++++++++
 .../config/IgniteRepositoriesRegistar.java      |  36 +++
 .../IgniteRepositoryConfigurationExtension.java |  49 +++
 .../springdata/repository/config/Query.java     |  37 +++
 .../repository/config/RepositoryConfig.java     |  39 +++
 .../repository/config/package-info.java         |  22 ++
 .../springdata/repository/package-info.java     |  22 ++
 .../repository/query/IgniteQuery.java           |  83 +++++
 .../repository/query/IgniteQueryGenerator.java  | 243 +++++++++++++++
 .../repository/query/IgniteRepositoryQuery.java | 306 +++++++++++++++++++
 .../repository/query/package-info.java          |  22 ++
 .../support/IgniteRepositoryFactory.java        | 168 ++++++++++
 .../support/IgniteRepositoryFactoryBean.java    |  85 ++++++
 .../support/IgniteRepositoryImpl.java           | 160 ++++++++++
 .../repository/support/package-info.java        |  22 ++
 .../IgniteSpringDataCrudSelfTest.java           | 233 ++++++++++++++
 .../IgniteSpringDataQueriesSelfTest.java        | 291 ++++++++++++++++++
 .../misc/ApplicationConfiguration.java          |  46 +++
 .../apache/ignite/springdata/misc/Person.java   |  97 ++++++
 .../springdata/misc/PersonRepository.java       |  92 ++++++
 .../springdata/misc/PersonSecondRepository.java |  40 +++
 .../testsuites/IgniteSpringDataTestSuite.java   |  41 +++
 parent/pom.xml                                  |   1 +
 pom.xml                                         |   1 +
 34 files changed, 2948 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index 2bbcc8a..cdb72ca 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -81,6 +81,12 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-spring-data</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
             <groupId>com.google.code.simple-spring-memcached</groupId>
             <artifactId>spymemcached</artifactId>
             <version>2.7.3</version>

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/examples/src/main/java/org/apache/ignite/examples/springdata/PersonRepository.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/springdata/PersonRepository.java b/examples/src/main/java/org/apache/ignite/examples/springdata/PersonRepository.java
new file mode 100644
index 0000000..0517311
--- /dev/null
+++ b/examples/src/main/java/org/apache/ignite/examples/springdata/PersonRepository.java
@@ -0,0 +1,59 @@
+/*
+ * 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.examples.springdata;
+
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.examples.model.Person;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.data.domain.Pageable;
+
+/**
+ * Apache Ignite Spring Data repository backed by Ignite Person's cache.
+ * </p>
+ * To link the repository with an Ignite cache use {@link RepositoryConfig#cacheName()} annotation's parameter.
+ */
+@RepositoryConfig(cacheName = "PersonCache")
+public interface PersonRepository extends IgniteRepository<Person, Long> {
+    /**
+     * Gets all the persons with the given name.
+     * @param name Person name.
+     * @return A list of Persons with the given first name.
+     */
+    public List<Person> findByFirstName(String name);
+
+    /**
+     * Returns top Person with the specified surname.
+     * @param name Person surname.
+     * @return Person that satisfy the query.
+     */
+    public Cache.Entry<Long, Person> findTopByLastNameLike(String name);
+
+    /**
+     * Getting ids of all the Person satisfying the custom query from {@link Query} annotation.
+     *
+     * @param orgId Query parameter.
+     * @param pageable Pageable interface.
+     * @return A list of Persons' ids.
+     */
+    @Query("SELECT id FROM Person WHERE orgId > ?")
+    public List<Long> selectId(long orgId, Pageable pageable);
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/examples/src/main/java/org/apache/ignite/examples/springdata/SpringAppCfg.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/springdata/SpringAppCfg.java b/examples/src/main/java/org/apache/ignite/examples/springdata/SpringAppCfg.java
new file mode 100644
index 0000000..0dcf5d6
--- /dev/null
+++ b/examples/src/main/java/org/apache/ignite/examples/springdata/SpringAppCfg.java
@@ -0,0 +1,69 @@
+/*
+ * 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.examples.springdata;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.examples.model.Person;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Every {@link IgniteRepository} is bound to a specific Apache Ignite that it communicates to in order to mutate and
+ * read data via Spring Data API. To pass an instance of Apache Ignite cache to an {@link IgniteRepository} it's
+ * required to initialize {@link IgniteRepositoryFactoryBean} with on of the following:
+ * <ul>
+ * <li>{@link Ignite} instance bean named "igniteInstance"</li>
+ * <li>{@link IgniteConfiguration} bean named "igniteCfg"</li>
+ * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
+ * <ul/>
+ * In this example the first approach is utilized.
+ */
+@Configuration
+@EnableIgniteRepositories
+public class SpringAppCfg {
+    /**
+     * Creating Apache Ignite instance bean. A bean will be passed to {@link IgniteRepositoryFactoryBean} to initialize
+     * all Ignite based Spring Data repositories and connect to a cluster.
+     */
+    @Bean
+    public Ignite igniteInstance() {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        // Setting some custom name for the node.
+        cfg.setIgniteInstanceName("springDataNode");
+
+        // Enabling peer-class loading feature.
+        cfg.setPeerClassLoadingEnabled(true);
+
+        // Defining and creating a new cache to be used by Ignite Spring Data repository.
+        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
+
+        // Setting SQL schema for the cache.
+        ccfg.setIndexedTypes(Long.class, Person.class);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return Ignition.start(cfg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/examples/src/main/java/org/apache/ignite/examples/springdata/SpringDataExample.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/springdata/SpringDataExample.java b/examples/src/main/java/org/apache/ignite/examples/springdata/SpringDataExample.java
new file mode 100644
index 0000000..6233698
--- /dev/null
+++ b/examples/src/main/java/org/apache/ignite/examples/springdata/SpringDataExample.java
@@ -0,0 +1,154 @@
+/*
+ * 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.examples.springdata;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+import javax.cache.Cache;
+import org.apache.ignite.examples.ExampleNodeStartup;
+import org.apache.ignite.examples.model.Person;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.data.domain.PageRequest;
+
+/**
+ * The example demonstrates how to interact with an Apache Ignite cluster by means of Spring Data API.
+ *
+ * Additional cluster nodes can be started with special configuration file which
+ * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}.
+ * <p>
+ * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will
+ * start an additional node with {@code examples/config/example-ignite.xml} configuration.
+ */
+public class SpringDataExample {
+    /** Spring Application Context. */
+    private static AnnotationConfigApplicationContext ctx;
+
+    /** Ignite Spring Data repository. */
+    private static PersonRepository repo;
+
+    /**
+     * Executes the example.
+     * @param args Command line arguments, none required.
+     */
+    public static void main(String[] args) {
+        // Initializing Spring Data context and Ignite repository.
+        igniteSpringDataInit();
+
+        populateRepository();
+
+        findPersons();
+
+        queryRepository();
+
+        System.out.println("\n>>> Cleaning out the repository...");
+
+        repo.deleteAll();
+
+        System.out.println("\n>>> Repository size: " + repo.count());
+
+        // Destroying the context.
+        ctx.destroy();
+    }
+
+    /**
+     * Initializes Spring Data and Ignite repositories.
+     */
+    private static void igniteSpringDataInit() {
+        ctx = new AnnotationConfigApplicationContext();
+
+        // Explicitly registering Spring configuration.
+        ctx.register(SpringAppCfg.class);
+
+        ctx.refresh();
+
+        // Getting a reference to PersonRepository.
+        repo = ctx.getBean(PersonRepository.class);
+    }
+
+    /**
+     * Fills the repository in with sample data.
+     */
+    private static void populateRepository() {
+        TreeMap<Long, Person> persons = new TreeMap<>();
+
+        persons.put(1L, new Person(1L, 2000L, "John", "Smith", 15000, "Worked for Apple"));
+        persons.put(2L, new Person(2L, 2000L, "Brad", "Pitt", 16000, "Worked for Oracle"));
+        persons.put(3L, new Person(3L, 1000L, "Mark", "Tomson", 10000, "Worked for Sun"));
+        persons.put(4L, new Person(4L, 2000L, "Erick", "Smith", 13000, "Worked for Apple"));
+        persons.put(5L, new Person(5L, 1000L, "John", "Rozenberg", 25000, "Worked for RedHat"));
+        persons.put(6L, new Person(6L, 2000L, "Denis", "Won", 35000, "Worked for CBS"));
+        persons.put(7L, new Person(7L, 1000L, "Abdula", "Adis", 45000, "Worked for NBC"));
+        persons.put(8L, new Person(8L, 2000L, "Roman", "Ive", 15000, "Worked for Sun"));
+
+        // Adding data into the repository.
+        repo.save(persons);
+
+        System.out.println("\n>>> Added " + repo.count() + " Persons into the repository.");
+    }
+
+    /**
+     * Gets a list of Persons using standard read operations.
+     */
+    private static void findPersons() {
+        // Getting Person with specific ID.
+        Person person = repo.findOne(2L);
+
+        System.out.println("\n>>> Found Person [id=" + 2L + ", val=" + person + "]");
+
+        // Getting a list of Persons.
+
+        ArrayList<Long> ids = new ArrayList<>();
+
+        for (long i = 0; i < 5; i++)
+            ids.add(i);
+
+        Iterator<Person> persons = repo.findAll(ids).iterator();
+
+        System.out.println("\n>>> Persons list for specific ids: ");
+
+        while (persons.hasNext())
+            System.out.println("   >>>   " + persons.next());
+    }
+
+    /**
+     * Execute advanced queries over the repository.
+     */
+    private static void queryRepository() {
+        System.out.println("\n>>> Persons with name 'John':");
+
+        List<Person> persons = repo.findByFirstName("John");
+
+        for (Person person: persons)
+            System.out.println("   >>>   " + person);
+
+
+        Cache.Entry<Long, Person> topPerson = repo.findTopByLastNameLike("Smith");
+
+        System.out.println("\n>>> Top Person with surname 'Smith': " + topPerson.getValue());
+
+
+        List<Long> ids = repo.selectId(1000L, new PageRequest(0, 4));
+
+        System.out.println("\n>>> Persons working for organization with ID > 1000: ");
+
+        for (Long id: ids)
+            System.out.println("   >>>   [id=" + id + "]");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/examples/src/test/java/org/apache/ignite/examples/SpringDataExampleSelfTest.java
----------------------------------------------------------------------
diff --git a/examples/src/test/java/org/apache/ignite/examples/SpringDataExampleSelfTest.java b/examples/src/test/java/org/apache/ignite/examples/SpringDataExampleSelfTest.java
new file mode 100644
index 0000000..516ad45
--- /dev/null
+++ b/examples/src/test/java/org/apache/ignite/examples/SpringDataExampleSelfTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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.examples;
+
+import org.apache.ignite.examples.springdata.SpringDataExample;
+import org.apache.ignite.testframework.junits.common.GridAbstractExamplesTest;
+
+/**
+ * Spring Data example test.
+ */
+public class SpringDataExampleSelfTest extends GridAbstractExamplesTest {
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSpringDataExample() throws Exception {
+        SpringDataExample.main(EMPTY_ARGS);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/examples/src/test/java/org/apache/ignite/testsuites/IgniteExamplesSelfTestSuite.java
----------------------------------------------------------------------
diff --git a/examples/src/test/java/org/apache/ignite/testsuites/IgniteExamplesSelfTestSuite.java b/examples/src/test/java/org/apache/ignite/testsuites/IgniteExamplesSelfTestSuite.java
index fcf9be9..3e29e5c 100644
--- a/examples/src/test/java/org/apache/ignite/testsuites/IgniteExamplesSelfTestSuite.java
+++ b/examples/src/test/java/org/apache/ignite/testsuites/IgniteExamplesSelfTestSuite.java
@@ -42,6 +42,7 @@ import org.apache.ignite.examples.MessagingExamplesSelfTest;
 import org.apache.ignite.examples.MonteCarloExamplesMultiNodeSelfTest;
 import org.apache.ignite.examples.MonteCarloExamplesSelfTest;
 import org.apache.ignite.examples.SpringBeanExamplesSelfTest;
+import org.apache.ignite.examples.SpringDataExampleSelfTest;
 import org.apache.ignite.examples.TaskExamplesMultiNodeSelfTest;
 import org.apache.ignite.examples.TaskExamplesSelfTest;
 
@@ -73,6 +74,7 @@ public class IgniteExamplesSelfTestSuite extends TestSuite {
         suite.addTest(new TestSuite(MonteCarloExamplesSelfTest.class));
         suite.addTest(new TestSuite(TaskExamplesSelfTest.class));
         suite.addTest(new TestSuite(SpringBeanExamplesSelfTest.class));
+        suite.addTest(new TestSuite(SpringDataExampleSelfTest.class));
         suite.addTest(new TestSuite(IgfsExamplesSelfTest.class));
         suite.addTest(new TestSuite(CheckpointExamplesSelfTest.class));
         suite.addTest(new TestSuite(ClusterGroupExampleSelfTest.class));

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/README.txt
----------------------------------------------------------------------
diff --git a/modules/spring-data/README.txt b/modules/spring-data/README.txt
new file mode 100644
index 0000000..d957fb6
--- /dev/null
+++ b/modules/spring-data/README.txt
@@ -0,0 +1,32 @@
+Apache Ignite Spring Module
+---------------------------
+
+Apache Ignite Spring Data module provides an integration with Spring Data framework.
+
+To enable Spring Data module when starting a standalone node, move 'optional/ignite-spring-data' folder to
+'libs' folder before running 'ignite.{sh|bat}' script. The content of the module folder will
+be added to classpath in this case.
+
+Importing Spring Data Module In Maven Project
+----------------------------------------
+
+If you are using Maven to manage dependencies of your project, you can add Spring module
+dependency like this (replace '${ignite.version}' with actual Ignite version you are
+interested in):
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                        http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    ...
+    <dependencies>
+        ...
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-spring-data</artifactId>
+            <version>${ignite.version}</version>
+        </dependency>
+        ...
+    </dependencies>
+    ...
+</project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/spring-data/licenses/apache-2.0.txt b/modules/spring-data/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/spring-data/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/pom.xml
----------------------------------------------------------------------
diff --git a/modules/spring-data/pom.xml b/modules/spring-data/pom.xml
new file mode 100644
index 0000000..4d8107b
--- /dev/null
+++ b/modules/spring-data/pom.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<!--
+    POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>ignite-spring-data</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+    <url>http://ignite.apache.org</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-indexing</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-log4j</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
+            <version>1.12.2.RELEASE</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-spring</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
new file mode 100644
index 0000000..472d2e0
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
@@ -0,0 +1,58 @@
+/*
+ * 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.springdata.repository;
+
+import java.io.Serializable;
+import java.util.Map;
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * Apache Ignite repository that extends basic capabilities of {@link CrudRepository}.
+ */
+public interface IgniteRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
+    /**
+     * Saves a given entity using provided key.
+     * </p>
+     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates
+     * IDs (keys) that are not unique cluster wide.
+     *
+     * @param key Entity's key.
+     * @param entity Entity to save.
+     * @param <S> Entity type.
+     * @return Saved entity.
+     */
+    <S extends T> S save(ID key, S entity);
+
+    /**
+     * Saves all given keys and entities combinations.
+     * </p>
+     * It's suggested to use this method instead of default {@link CrudRepository#save(Iterable)} that generates
+     * IDs (keys) that are not unique cluster wide.
+     *
+     * @param entities Map of key-entities pairs to save.
+     * @param <S> type of entities.
+     * @return Saved entities.
+     */
+    <S extends T> Iterable<S> save(Map<ID, S> entities);
+
+    /**
+     * Deletes all the entities for the provided ids.
+     *
+     * @param ids List of ids to delete.
+     */
+    void deleteAll(Iterable<ID> ids);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
new file mode 100644
index 0000000..667342a
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
@@ -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.
+ */
+package org.apache.ignite.springdata.repository.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryImpl;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Import;
+import org.springframework.data.repository.query.QueryLookupStrategy;
+import org.springframework.data.repository.query.QueryLookupStrategy.Key;
+
+/**
+ * Annotation to activate Apache Ignite repositories. If no base package is configured through either {@link #value()},
+ * {@link #basePackages()} or {@link #basePackageClasses()} it will trigger scanning of the package of annotated class.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import(IgniteRepositoriesRegistar.class)
+public @interface EnableIgniteRepositories {
+    /**
+     * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
+     * {@code @EnableIgniteRepositories("org.my.pkg")} instead of
+     * {@code @EnableIgniteRepositories(basePackages="org.my.pkg")}.
+     */
+    String[] value() default {};
+
+    /**
+     * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with)
+     * this attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
+     */
+    String[] basePackages() default {};
+
+    /**
+     * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components.
+     * The package of each class specified will be scanned. Consider creating a special no-op marker class or interface
+     * in each package that serves no purpose other than being referenced by this attribute.
+     */
+    Class<?>[] basePackageClasses() default {};
+
+    /**
+     * Specifies which types are not eligible for component scanning.
+     */
+    Filter[] excludeFilters() default {};
+
+    /**
+     * Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
+     * everything in {@link #basePackages()} to everything in the base packages that matches the given filter or
+     * filters.
+     */
+    Filter[] includeFilters() default {};
+
+    /**
+     * Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
+     * for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
+     * for {@code PersonRepositoryImpl}.
+     *
+     * @return
+     */
+    String repositoryImplementationPostfix() default "Impl";
+
+    /**
+     * Configures the location of where to find the Spring Data named queries properties file.
+     *
+     * @return
+     */
+    String namedQueriesLocation() default "";
+
+    /**
+     * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
+     * {@link Key#CREATE_IF_NOT_FOUND}.
+     *
+     * @return
+     */
+    Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
+
+    /**
+     * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to
+     * {@link IgniteRepositoryFactoryBean}.
+     *
+     * @return
+     */
+    Class<?> repositoryFactoryBeanClass() default IgniteRepositoryFactoryBean.class;
+
+    /**
+     * Configure the repository base class to be used to create repository proxies for this particular configuration.
+     *
+     * @return
+     */
+    Class<?> repositoryBaseClass() default IgniteRepositoryImpl.class;
+
+    /**
+     * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
+     * repositories infrastructure.
+     */
+    boolean considerNestedRepositories() default false;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
new file mode 100644
index 0000000..0f65c32
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
@@ -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.
+ */
+package org.apache.ignite.springdata.repository.config;
+
+import java.lang.annotation.Annotation;
+import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
+import org.springframework.data.repository.config.RepositoryConfigurationExtension;
+
+/**
+ * Apache Ignite specific implementation of {@link RepositoryBeanDefinitionRegistrarSupport}.
+ */
+public class IgniteRepositoriesRegistar extends RepositoryBeanDefinitionRegistrarSupport {
+    /** {@inheritDoc} */
+    @Override protected Class<? extends Annotation> getAnnotation() {
+        return EnableIgniteRepositories.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected RepositoryConfigurationExtension getExtension() {
+        return new IgniteRepositoryConfigurationExtension();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
new file mode 100644
index 0000000..630690a
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
@@ -0,0 +1,49 @@
+/*
+ * 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.springdata.repository.config;
+
+import java.util.Collection;
+import java.util.Collections;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
+import org.springframework.data.repository.config.RepositoryConfigurationExtension;
+import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
+
+/**
+ * Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}.
+ */
+public class IgniteRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
+    /** {@inheritDoc} */
+    @Override public String getModuleName() {
+        return "Apache Ignite";
+    }
+
+    /** {@inheritDoc} */
+    @Override protected String getModulePrefix() {
+        return "ignite";
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getRepositoryFactoryClassName() {
+        return IgniteRepositoryFactoryBean.class.getName();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Collection<Class<?>> getIdentifyingTypes() {
+        return Collections.<Class<?>>singleton(IgniteRepository.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/Query.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
new file mode 100644
index 0000000..1095942
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
@@ -0,0 +1,37 @@
+/*
+ * 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.springdata.repository.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to provide a user defined SQL query for a method.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Query {
+    /**
+     * SQL query text string.
+     */
+    String value() default "";
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
new file mode 100644
index 0000000..8027874
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
@@ -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.
+ */
+
+package org.apache.ignite.springdata.repository.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The annotation can be used to pass Ignite specific parameters to a bound repository.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface RepositoryConfig {
+    /**
+     * @return A name of a distributed Apache Ignite cache an annotated repository will be mapped to.
+     */
+    String cacheName() default "";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
new file mode 100644
index 0000000..4b75f7a
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Package includes Spring Data integration related configuration files.
+ */
+package org.apache.ignite.springdata.repository.config;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/package-info.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/package-info.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/package-info.java
new file mode 100644
index 0000000..d5951a3
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Package contains Apache Ignite Spring Data integration.
+ */
+package org.apache.ignite.springdata.repository;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
new file mode 100644
index 0000000..f630ca0
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
@@ -0,0 +1,83 @@
+/*
+ * 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.springdata.repository.query;
+
+/**
+ * Ignite query helper class. For internal use only.
+ */
+public class IgniteQuery {
+    /** */
+    enum Option {
+        /** Query will be used with Sort object. */
+        SORTING,
+
+        /** Query will be used with Pageable object. */
+        PAGINATION,
+
+        /** No advanced option. */
+        NONE
+    }
+
+    /** Sql query text string. */
+    private final String sql;
+
+    /** */
+    private final boolean isFieldQuery;
+
+    /** Type of option. */
+    private final Option option;
+
+    /**
+     * @param sql Sql.
+     * @param isFieldQuery Is field query.
+     * @param option Option.
+     */
+    public IgniteQuery(String sql, boolean isFieldQuery, Option option) {
+        this.sql = sql;
+        this.isFieldQuery = isFieldQuery;
+        this.option = option;
+    }
+
+    /**
+     * Text string of the query.
+     *
+     * @return SQL query text string.
+     */
+    public String sql() {
+        return sql;
+    }
+
+    /**
+     * Returns {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
+     *
+     * @return {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
+     */
+    public boolean isFieldQuery() {
+        return isFieldQuery;
+    }
+
+    /**
+     * Advanced querying option.
+     *
+     * @return querying option.
+     */
+    public Option options() {
+        return option;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
new file mode 100644
index 0000000..2db2789
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
@@ -0,0 +1,243 @@
+/*
+ * 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.springdata.repository.query;
+
+import java.lang.reflect.Method;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.query.parser.Part;
+import org.springframework.data.repository.query.parser.PartTree;
+
+/**
+ * Ignite query generator for Spring Data framework.
+ */
+public class IgniteQueryGenerator {
+
+    /**
+     * @param mtd Method.
+     * @param metadata Metadata.
+     */
+    @NotNull public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
+        PartTree parts = new PartTree(mtd.getName(), metadata.getDomainType());
+
+        StringBuilder sql = new StringBuilder();
+
+        if (parts.isDelete())
+            throw new UnsupportedOperationException("DELETE clause is not supported now.");
+        else {
+            sql.append("SELECT ");
+
+            if (parts.isDistinct())
+                throw new UnsupportedOperationException("DISTINCT clause in not supported.");
+
+            if (parts.isCountProjection())
+                sql.append("COUNT(1) ");
+            else
+                sql.append(" * ");
+        }
+
+        sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
+
+        if (parts.iterator().hasNext()) {
+            sql.append(" WHERE ");
+
+            for (PartTree.OrPart orPart : parts) {
+                sql.append("(");
+                for (Part part : orPart) {
+                    handleQueryPart(sql, part);
+                    sql.append(" AND ");
+                }
+
+                sql.delete(sql.length() - 5, sql.length());
+
+                sql.append(") OR ");
+            }
+
+            sql.delete(sql.length() - 4, sql.length());
+        }
+
+        addSorting(sql, parts.getSort());
+
+        if (parts.isLimiting()) {
+            sql.append(" LIMIT ");
+            sql.append(parts.getMaxResults().intValue());
+        }
+
+        return new IgniteQuery(sql.toString(), parts.isCountProjection(), getOptions(mtd));
+    }
+
+    /**
+     * Add a dynamic part of query for the sorting support.
+     *
+     * @param sql SQL text string.
+     * @param sort Sort method.
+     */
+    public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
+        if (sort != null) {
+            sql.append(" ORDER BY ");
+
+            for (Sort.Order order : sort) {
+                sql.append(order.getProperty()).append(" ").append(order.getDirection());
+
+                if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
+                    sql.append(" ").append("NULL ");
+                    switch (order.getNullHandling()) {
+                        case NULLS_FIRST:
+                            sql.append("FIRST");
+                            break;
+                        case NULLS_LAST:
+                            sql.append("LAST");
+                            break;
+                    }
+                }
+                sql.append(", ");
+            }
+
+            sql.delete(sql.length() - 2, sql.length());
+        }
+
+        return sql;
+    }
+
+    /**
+     * Add a dynamic part of a query for the pagination support.
+     *
+     * @param sql
+     * @param pageable
+     * @return
+     */
+    public static StringBuilder addPaging(StringBuilder sql, Pageable pageable) {
+        if (pageable.getSort() != null)
+            addSorting(sql, pageable.getSort());
+
+        sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET ").append(pageable.getOffset());
+
+        return sql;
+    }
+
+    /**
+     * Determines whether query is dynamic or not (by list of method parameters)
+     *
+     * @param mtd
+     * @return type of options
+     */
+    public static IgniteQuery.Option getOptions(Method mtd) {
+        IgniteQuery.Option option;
+
+        Class<?>[] types = mtd.getParameterTypes();
+        Class<?> type = types[types.length - 1];
+
+        if (Sort.class.isAssignableFrom(type))
+            option = IgniteQuery.Option.SORTING;
+        else if (Pageable.class.isAssignableFrom(type))
+            option = IgniteQuery.Option.PAGINATION;
+        else
+            option = IgniteQuery.Option.NONE;
+
+        for (int i = 0; i < types.length - 1; i++) {
+            Class<?> tp = types[i];
+            if (tp == Sort.class || tp == Pageable.class)
+                throw new AssertionError("Sort and Pageable parameters are allowed only in the last position");
+        }
+
+        return option;
+    }
+
+    /**
+     * Transform part to sql expression
+     */
+    private static void handleQueryPart(StringBuilder sql, Part part) {
+        sql.append("(");
+
+        sql.append(part.getProperty());
+
+        switch (part.getType()) {
+            case SIMPLE_PROPERTY:
+                sql.append("=?");
+                break;
+            case NEGATING_SIMPLE_PROPERTY:
+                sql.append("<>?");
+                break;
+            case GREATER_THAN:
+                sql.append(">?");
+                break;
+            case GREATER_THAN_EQUAL:
+                sql.append(">=?");
+                break;
+            case LESS_THAN:
+                sql.append("<?");
+                break;
+            case LESS_THAN_EQUAL:
+                sql.append("<=?");
+                break;
+            case IS_NOT_NULL:
+                sql.append(" IS NOT NULL");
+                break;
+            case IS_NULL:
+                sql.append(" IS NULL");
+                break;
+            case BETWEEN:
+                sql.append(" BETWEEN ? AND ?");
+                break;
+            case FALSE:
+                sql.append(" = FALSE");
+                break;
+            case TRUE:
+                sql.append(" = TRUE");
+                break;
+            case CONTAINING:
+                sql.append(" LIKE '%' || ? || '%'");
+                break;
+            case NOT_CONTAINING:
+                sql.append(" NOT LIKE '%' || ? || '%'");
+                break;
+            case LIKE:
+                sql.append(" LIKE '%' || ? || '%'");
+                break;
+            case NOT_LIKE:
+                sql.append(" NOT LIKE '%' || ? || '%'");
+                break;
+            case STARTING_WITH:
+                sql.append(" LIKE  ? || '%'");
+                break;
+            case ENDING_WITH:
+                sql.append(" LIKE '%' || ?");
+                break;
+            case IN:
+                sql.append(" IN ?");
+                break;
+            case NOT_IN:
+                sql.append(" NOT IN ?");
+                break;
+            case REGEX:
+                sql.append(" REGEXP ?");
+                break;
+            case NEAR:
+            case AFTER:
+            case BEFORE:
+            case EXISTS:
+            default:
+                throw new UnsupportedOperationException(part.getType() + " is not supported!");
+        }
+
+        sql.append(")");
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
new file mode 100644
index 0000000..c6e171f
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
@@ -0,0 +1,306 @@
+/*
+ * 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.springdata.repository.query;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.Query;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.domain.SliceImpl;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.projection.ProjectionFactory;
+import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.query.QueryMethod;
+import org.springframework.data.repository.query.RepositoryQuery;
+
+/**
+ * Ignite SQL query implementation.
+ */
+@SuppressWarnings("unchecked")
+public class IgniteRepositoryQuery implements RepositoryQuery {
+    /** Defines the way how to process query result */
+    private enum ReturnStrategy {
+        /** Need to return only one value. */
+        ONE_VALUE,
+
+        /** Need to return one cache entry */
+        CACHE_ENTRY,
+
+        /** Need to return list of cache entries */
+        LIST_OF_CACHE_ENTRIES,
+
+        /** Need to return list of values */
+        LIST_OF_VALUES,
+
+        /** Need to return list of lists */
+        LIST_OF_LISTS,
+
+        /** Need to return slice */
+        SLICE_OF_VALUES,
+
+        /** Slice of cache entries. */
+        SLICE_OF_CACHE_ENTRIES,
+
+        /** Slice of lists. */
+        SLICE_OF_LISTS
+    }
+
+    /** Type. */
+    private final Class<?> type;
+    /** Sql. */
+    private final IgniteQuery qry;
+    /** Cache. */
+    private final IgniteCache cache;
+
+    /** Method. */
+    private final Method mtd;
+    /** Metadata. */
+    private final RepositoryMetadata metadata;
+    /** Factory. */
+    private final ProjectionFactory factory;
+
+    /** Return strategy. */
+    private final ReturnStrategy returnStgy;
+
+    /**
+     * @param metadata Metadata.
+     * @param qry Query.
+     * @param mtd Method.
+     * @param factory Factory.
+     * @param cache Cache.
+     */
+    public IgniteRepositoryQuery(RepositoryMetadata metadata, IgniteQuery qry,
+        Method mtd, ProjectionFactory factory, IgniteCache cache) {
+        type = metadata.getDomainType();
+        this.qry = qry;
+        this.cache = cache;
+
+        this.metadata = metadata;
+        this.mtd = mtd;
+        this.factory = factory;
+
+        returnStgy = calcReturnType(mtd, qry.isFieldQuery());
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object execute(Object[] prmtrs) {
+        Query qry = prepareQuery(prmtrs);
+
+        QueryCursor qryCursor = cache.query(qry);
+
+        return transformQueryCursor(prmtrs, qryCursor);
+    }
+
+    /** {@inheritDoc} */
+    @Override public QueryMethod getQueryMethod() {
+        return new QueryMethod(mtd, metadata, factory);
+    }
+
+    /**
+     * @param mtd Method.
+     * @param isFieldQry Is field query.
+     */
+    private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
+        Class<?> returnType = mtd.getReturnType();
+
+        if (returnType.isAssignableFrom(ArrayList.class)) {
+            if (isFieldQry) {
+                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
+                    return ReturnStrategy.LIST_OF_LISTS;
+            }
+            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
+                return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
+
+            return ReturnStrategy.LIST_OF_VALUES;
+        }
+        else if (returnType == Slice.class) {
+            if (isFieldQry) {
+                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
+                    return ReturnStrategy.SLICE_OF_LISTS;
+            }
+            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
+                return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
+
+            return ReturnStrategy.SLICE_OF_VALUES;
+        }
+        else if (Cache.Entry.class.isAssignableFrom(returnType))
+            return ReturnStrategy.CACHE_ENTRY;
+        else
+            return ReturnStrategy.ONE_VALUE;
+    }
+
+    /**
+     * @param cls Class 1.
+     * @param mtd Method.
+     */
+    private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
+        Type[] actualTypeArguments = ((ParameterizedType)mtd.getGenericReturnType()).getActualTypeArguments();
+
+        if (actualTypeArguments.length == 0)
+            return false;
+
+        if (actualTypeArguments[0] instanceof ParameterizedType) {
+            ParameterizedType type = (ParameterizedType)actualTypeArguments[0];
+
+            Class<?> type1 = (Class)type.getRawType();
+
+            return type1.isAssignableFrom(cls);
+        }
+
+        if (actualTypeArguments[0] instanceof Class) {
+            Class typeArg = (Class)actualTypeArguments[0];
+
+            return typeArg.isAssignableFrom(cls);
+        }
+
+        return false;
+    }
+
+    /**
+     * @param prmtrs Prmtrs.
+     * @param qryCursor Query cursor.
+     */
+    @Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor qryCursor) {
+        if (this.qry.isFieldQuery()) {
+            Iterable<ArrayList> qryIter = (Iterable<ArrayList>)qryCursor;
+
+            switch (returnStgy) {
+                case LIST_OF_VALUES:
+                    ArrayList list = new ArrayList();
+
+                    for (ArrayList entry : qryIter)
+                        list.add(entry.get(0));
+
+                    return list;
+                case ONE_VALUE:
+                    Iterator<ArrayList> iter = qryIter.iterator();
+
+                    if (iter.hasNext())
+                        return iter.next().get(0);
+
+                    return null;
+                case SLICE_OF_VALUES:
+                    ArrayList content = new ArrayList();
+
+                    for (ArrayList entry : qryIter)
+                        content.add(entry.get(0));
+
+                    return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+                case SLICE_OF_LISTS:
+                    return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+                case LIST_OF_LISTS:
+                    return qryCursor.getAll();
+                default:
+                    throw new IllegalStateException();
+            }
+        }
+        else {
+            Iterable<CacheEntryImpl> qryIter = (Iterable<CacheEntryImpl>)qryCursor;
+
+            switch (returnStgy) {
+                case LIST_OF_VALUES:
+                    ArrayList list = new ArrayList();
+
+                    for (CacheEntryImpl entry : qryIter)
+                        list.add(entry.getValue());
+
+                    return list;
+                case ONE_VALUE:
+                    Iterator<CacheEntryImpl> iter1 = qryIter.iterator();
+
+                    if (iter1.hasNext())
+                        return iter1.next().getValue();
+
+                    return null;
+                case CACHE_ENTRY:
+                    Iterator<CacheEntryImpl> iter2 = qryIter.iterator();
+
+                    if (iter2.hasNext())
+                        return iter2.next();
+
+                    return null;
+                case SLICE_OF_VALUES:
+                    ArrayList content = new ArrayList();
+
+                    for (CacheEntryImpl entry : qryIter)
+                        content.add(entry.getValue());
+
+                    return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+                case SLICE_OF_CACHE_ENTRIES:
+                    return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+                case LIST_OF_CACHE_ENTRIES:
+                    return qryCursor.getAll();
+                default:
+                    throw new IllegalStateException();
+            }
+        }
+    }
+
+    /**
+     * @param prmtrs Prmtrs.
+     * @return prepared query for execution
+     */
+    @NotNull private Query prepareQuery(Object[] prmtrs) {
+        Object[] parameters = prmtrs;
+        String sql = qry.sql();
+
+        Query query;
+
+        switch (qry.options()) {
+            case SORTING:
+                sql = IgniteQueryGenerator.addSorting(new StringBuilder(sql),
+                    (Sort)parameters[parameters.length - 1]).toString();
+                parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+                break;
+            case PAGINATION:
+                sql = IgniteQueryGenerator.addPaging(new StringBuilder(sql),
+                    (Pageable)parameters[parameters.length - 1]).toString();
+                parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+                break;
+        }
+
+        if (qry.isFieldQuery()) {
+            SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(sql);
+            sqlFieldsQry.setArgs(parameters);
+
+            query = sqlFieldsQry;
+        }
+        else {
+            SqlQuery sqlQry = new SqlQuery(type, sql);
+            sqlQry.setArgs(parameters);
+
+            query = sqlQry;
+        }
+
+        return query;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
new file mode 100644
index 0000000..e4cde20
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Package includes classes that integrates with Apache Ignite SQL engine.
+ */
+package org.apache.ignite.springdata.repository.query;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
new file mode 100644
index 0000000..bceee1f
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
@@ -0,0 +1,168 @@
+/*
+ * 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.springdata.repository.support;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.query.IgniteQuery;
+import org.apache.ignite.springdata.repository.query.IgniteQueryGenerator;
+import org.apache.ignite.springdata.repository.query.IgniteRepositoryQuery;
+import org.springframework.data.projection.ProjectionFactory;
+import org.springframework.data.repository.core.EntityInformation;
+import org.springframework.data.repository.core.NamedQueries;
+import org.springframework.data.repository.core.RepositoryInformation;
+import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.core.support.AbstractEntityInformation;
+import org.springframework.data.repository.core.support.RepositoryFactorySupport;
+import org.springframework.data.repository.query.EvaluationContextProvider;
+import org.springframework.data.repository.query.QueryLookupStrategy;
+import org.springframework.data.repository.query.RepositoryQuery;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * Crucial for spring-data functionality class. Create proxies for repositories.
+ */
+public class IgniteRepositoryFactory extends RepositoryFactorySupport {
+    /** Ignite instance */
+    private Ignite ignite;
+
+    /** Mapping of a repository to a cache. */
+    private final Map<Class<?>, String> repoToCache = new HashMap<>();
+
+    /**
+     * Creates the factory with initialized {@link Ignite} instance.
+     *
+     * @param ignite
+     */
+    public IgniteRepositoryFactory(Ignite ignite) {
+        this.ignite = ignite;
+    }
+
+    /**
+     * Initializes the factory with provided {@link IgniteConfiguration} that is used to start up an underlying
+     * {@link Ignite} instance.
+     *
+     * @param cfg Ignite configuration.
+     */
+    public IgniteRepositoryFactory(IgniteConfiguration cfg) {
+        this.ignite = Ignition.start(cfg);
+    }
+
+    /**
+     * Initializes the factory with provided a configuration under {@code springCfgPath} that is used to start up
+     * an underlying {@link Ignite} instance.
+     *
+     * @param springCfgPath A path to Ignite configuration.
+     */
+    public IgniteRepositoryFactory(String springCfgPath) {
+        this.ignite = Ignition.start(springCfgPath);
+    }
+
+    /** {@inheritDoc} */
+    @Override public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
+        return new AbstractEntityInformation<T, ID>(domainClass) {
+            @Override public ID getId(T entity) {
+                return null;
+            }
+
+            @Override public Class<ID> getIdType() {
+                return null;
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
+        return IgniteRepositoryImpl.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected RepositoryMetadata getRepositoryMetadata(Class<?> repoItf) {
+        Assert.notNull(repoItf, "Repository interface must be set.");
+        Assert.isAssignable(IgniteRepository.class, repoItf, "Repository must implement IgniteRepository interface.");
+
+        RepositoryConfig annotation = repoItf.getAnnotation(RepositoryConfig.class);
+
+        Assert.notNull(annotation, "Set a name of an Apache Ignite cache using @RepositoryConfig annotation to map " +
+            "this repository to the underlying cache.");
+
+        Assert.hasText(annotation.cacheName(), "Set a name of an Apache Ignite cache using @RepositoryConfig " +
+            "annotation to map this repository to the underlying cache.");
+
+        repoToCache.put(repoItf, annotation.cacheName());
+
+        return super.getRepositoryMetadata(repoItf);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Object getTargetRepository(RepositoryInformation metadata) {
+        return getTargetRepositoryViaReflection(metadata,
+            ignite.getOrCreateCache(repoToCache.get(metadata.getRepositoryInterface())));
+    }
+
+    /** {@inheritDoc} */
+    @Override protected QueryLookupStrategy getQueryLookupStrategy(final QueryLookupStrategy.Key key,
+        EvaluationContextProvider evaluationCtxProvider) {
+
+        return new QueryLookupStrategy() {
+            @Override public RepositoryQuery resolveQuery(final Method mtd, final RepositoryMetadata metadata,
+                final ProjectionFactory factory, NamedQueries namedQueries) {
+
+                final Query annotation = mtd.getAnnotation(Query.class);
+
+                if (annotation != null) {
+                    String qryStr = annotation.value();
+
+                    if (key != Key.CREATE && StringUtils.hasText(qryStr))
+                        return new IgniteRepositoryQuery(metadata,
+                            new IgniteQuery(qryStr, isFieldQuery(qryStr), IgniteQueryGenerator.getOptions(mtd)),
+                            mtd, factory, ignite.getOrCreateCache(repoToCache.get(metadata.getRepositoryInterface())));
+                }
+
+                if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY)
+                    throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass " +
+                        "a query string via org.apache.ignite.springdata.repository.config.Query annotation.");
+
+                return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd,
+                    factory, ignite.getOrCreateCache(repoToCache.get(metadata.getRepositoryInterface())));
+            }
+        };
+    }
+
+    /**
+     * @param s
+     * @return
+     */
+    private boolean isFieldQuery(String s) {
+        return s.matches("^SELECT.*") && !s.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+    }
+}
+
+
+
+
+
+


[08/13] ignite git commit: IGNITE-4943 Improve design of table on Admin Panel screen.

Posted by is...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/app/primitives/ui-grid/index.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/primitives/ui-grid/index.scss b/modules/web-console/frontend/app/primitives/ui-grid/index.scss
new file mode 100644
index 0000000..504cf5a
--- /dev/null
+++ b/modules/web-console/frontend/app/primitives/ui-grid/index.scss
@@ -0,0 +1,321 @@
+/*
+ * 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 '../../../public/stylesheets/variables';
+
+.ui-grid--ignite {
+    $height: 46px;
+
+    border-top: none;
+
+    [role="button"] {
+      outline: none;
+    }
+
+    .ui-grid-top-panel {
+        background: initial;
+    }
+
+    .ui-grid-canvas {
+        padding-top: 0;
+    }
+
+    .ui-grid-cell {
+        height: $height;
+
+        border-color: transparent;
+    }
+
+    .ui-grid-cell-contents {
+        font-family: Roboto;
+
+        padding: 13px 20px;
+    }
+
+    .ui-grid-render-container-body {
+        .ui-grid-cell {
+            .ui-grid-cell-contents {
+                text-align: left;
+            }
+
+            &.ui-grid-number-cell {
+                .ui-grid-cell-contents {
+                    text-align: right;
+                }
+            }
+
+            &:first-child {
+                .ui-grid-cell-contents {
+                    padding-left: 0;
+                }            
+            }
+        }
+    }
+
+    .ui-grid-header--subcategories {
+        .ui-grid-header-span {
+            background: initial;
+
+            &:first-child {
+                .ui-grid-cell-contents {
+                    padding-left: 0;
+                }
+
+                .ng-hide + .ui-grid-header-cell-row {
+                    .ui-grid-cell-contents,
+                    .ui-grid-filter-container {
+                        padding-left: 0;
+                    }
+                }
+            }
+
+            .ui-grid-cell-contents {
+                color: $gray-light;
+                font-size: 14px;
+                font-weight: normal;
+                font-style: normal;
+                line-height: 18px;
+                text-align: left;
+
+                padding: 8px 20px;
+
+                & > i {
+                    line-height: 18px;
+                }
+            }
+
+            [ng-show] .ui-grid-cell-contents {
+                text-align: center;
+            }
+
+            .ui-grid-filter-container {
+                padding-left: 20px;
+                padding-right: 20px;
+            }
+
+            .ng-hide + .ui-grid-header-cell-row .ui-grid-header-cell {
+                height: 69px;
+            }
+
+            .ng-hide + .ui-grid-header-cell-row {
+                .ui-grid-cell-contents {
+                    padding: 8px 20px;
+                }
+
+                .ui-grid-filter-container {
+                    padding-left: 20px;
+                    padding-right: 20px;
+                }
+            }
+
+            .ui-grid-header-cell-label + span {
+                position: relative;
+            }
+        }
+    }
+
+    .ui-grid-pinned-container {
+        &.ui-grid-pinned-container-left {
+            width: auto;
+
+            .ui-grid-render-container-left {
+                .ui-grid-viewport, 
+                .ui-grid-header-viewport {
+                    width: auto;
+
+                    .ui-grid-canvas {
+                        width: auto;
+                    }
+                }
+            }
+        }
+    }
+
+    .ui-grid-pinned-container-left .ui-grid-header-cell:last-child {
+        max-width: 52px;
+        min-width: 52px;
+
+        border-width: 0;
+    }
+
+    .ui-grid-pinned-container-left .ui-grid-cell:last-child {
+        min-width: 52px;
+        max-width: 52px;
+
+        border-width: 0;
+        background-color: initial;
+    }
+
+    .ui-grid-row {
+        height: $height;
+
+        &:nth-child(odd) {
+            .ui-grid-cell {
+                background-color: initial;
+            }
+        }
+
+        &:nth-child(even) {
+            .ui-grid-cell {
+                background-color: #f9f9f9;
+            }
+        }
+
+        &:not(:first-child) {
+            border-top: 1px solid $table-border-color;
+        }
+
+        &.ui-grid-row-selected > [ui-grid-row] > .ui-grid-cell {
+            background-color: #e5f2f9;
+
+            box-shadow: 0 -1px 0 0 rgba(117, 117, 117, 0.25), 0 1px 0 0 rgba(117, 117, 117, 0.25);
+        }
+    }
+
+    .ui-grid-selection-row-header-buttons {
+        position: relative;
+        opacity: 1;
+
+        &::before {
+            content: '';
+
+            width: 12px;
+            height: 12px;
+
+            margin-left: 0;
+            margin-right: 0;
+
+            border: 1px solid #afafaf;
+            border-radius: 2px;
+            background-color: #FFF;
+
+            box-shadow: inset 0 1px 1px #ccc;
+        }
+
+        &.ui-grid-all-selected,
+        &.ui-grid-row-selected {
+
+            &::before {
+                border-color: #0067b9;
+                background-color: #0067b9;
+
+                box-shadow: none;
+            }
+
+            &::after {
+              content: '';
+
+              position: absolute;
+              top: 4px;
+              left: 4px;
+              
+              width: 4px;
+              height: 8px;
+
+              border: solid #FFF;
+              border-width: 0 2px 2px 0;
+
+              transform: rotate(35deg);
+            }
+        }
+    }
+
+    .ui-grid-header,
+    .ui-grid-viewport {
+        .ui-grid-tree-base-row-header-buttons {
+            .ui-grid-icon-plus-squared,
+            .ui-grid-icon-minus-squared,
+            &.ui-grid-icon-plus-squared,
+            &.ui-grid-icon-minus-squared {
+                position: relative;
+                top: 3px;
+
+                display: block;
+                width: 13px;
+                height: 13px;
+
+                margin-top: -1px;
+                margin-left: -4px;
+                margin-right: 0;
+
+                cursor: pointer;
+
+                border: 1px solid #757575;
+                border-radius: 2px;
+                background-color: #757575;
+
+                &::before,
+                &::after {
+                  content: '';
+                }
+            }
+
+            .ui-grid-icon-plus-squared,
+            .ui-grid-icon-minus-squared,
+            &.ui-grid-icon-plus-squared,
+            &.ui-grid-icon-minus-squared {
+                &::before {
+                    position: absolute;
+                    top: 5px;
+                    left: 2px;
+                    
+                    width: 7px;
+                    margin: 0;
+
+                    border-top: 1px solid white;
+                }
+            }
+
+            .ui-grid-icon-plus-squared,
+            &.ui-grid-icon-plus-squared {
+                &::after {
+                    position: absolute;
+                    top: 2px;
+                    left: 5px;
+                    
+                    height: 7px;
+                    margin: 0;
+
+                    border-left: 1px solid white;
+                }
+            }
+        }
+    }
+
+    .ui-grid-pinned-container {
+        .ui-grid-header {
+            .ui-grid-header-cell-row {
+                .ui-grid-header-cell {
+                    border-right: none;
+                    padding-top: 12px;
+
+                    &.disabled {
+                        opacity: .5;
+                    }
+                }
+            }
+        }
+
+        .ui-grid-viewport {
+            .ui-grid-row {
+                .ui-grid-cell {
+                    border-bottom: none;
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/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 8dbf123..882a363 100644
--- a/modules/web-console/frontend/public/stylesheets/style.scss
+++ b/modules/web-console/frontend/public/stylesheets/style.scss
@@ -2313,11 +2313,6 @@ html,body,.splash-screen {
             margin-right: 10px;
         }
 
-        label {
-            cursor: default;
-            line-height: 28px;
-        }
-
         sub {
             bottom: 0;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/views/base2.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/base2.pug b/modules/web-console/frontend/views/base2.pug
new file mode 100644
index 0000000..eacfb5b
--- /dev/null
+++ b/modules/web-console/frontend/views/base2.pug
@@ -0,0 +1,22 @@
+//-
+    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 ./includes/header
+
+.container.body-container
+    div(ui-view='')
+
+include ./includes/footer

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/views/settings/admin.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/settings/admin.tpl.pug b/modules/web-console/frontend/views/settings/admin.tpl.pug
index a09fda9..a8df240 100644
--- a/modules/web-console/frontend/views/settings/admin.tpl.pug
+++ b/modules/web-console/frontend/views/settings/admin.tpl.pug
@@ -16,9 +16,8 @@
 
 .admin-page.row
     .docs-content.greedy
-        .docs-header
+        header
             h1 Admin panel
-            hr
         .docs-body
             .row
                 .col-xs-12

http://git-wip-us.apache.org/repos/asf/ignite/blob/8c9c60a4/modules/web-console/frontend/views/sql/sql.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/sql/sql.tpl.pug b/modules/web-console/frontend/views/sql/sql.tpl.pug
index dcfc531..b28d602 100644
--- a/modules/web-console/frontend/views/sql/sql.tpl.pug
+++ b/modules/web-console/frontend/views/sql/sql.tpl.pug
@@ -15,7 +15,6 @@
     limitations under the License.
 
 include /app/helpers/jade/mixins
-include /app/components/ui-grid-settings/ui-grid-settings
 
 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')


[11/13] ignite git commit: Merge remote-tracking branch 'upstream/master' into ignite-3477-master

Posted by is...@apache.org.
Merge remote-tracking branch 'upstream/master' into ignite-3477-master


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

Branch: refs/heads/ignite-3477-master
Commit: 5f724512a9997d8e2b2a4ec7d482772fbeb741a3
Parents: 7883668 775c6e5
Author: Igor Sapego <is...@gridgain.com>
Authored: Wed Apr 12 15:40:11 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Wed Apr 12 15:40:11 2017 +0300

----------------------------------------------------------------------
 .gitignore                                      |  31 +-
 examples/pom.xml                                |   6 +
 .../examples/springdata/PersonRepository.java   |  59 ++++
 .../examples/springdata/SpringAppCfg.java       |  69 ++++
 .../examples/springdata/SpringDataExample.java  | 154 +++++++++
 .../examples/SpringDataExampleSelfTest.java     |  32 ++
 .../testsuites/IgniteExamplesSelfTestSuite.java |   2 +
 .../rendezvous/RendezvousAffinityFunction.java  |  26 +-
 .../datastructures/GridCacheSemaphoreImpl.java  |  74 ++++-
 .../datastructures/GridCacheSemaphoreState.java |  22 ++
 ...inityFunctionFastPowerOfTwoHashSelfTest.java |  50 +++
 ...ousAffinityFunctionStandardHashSelfTest.java |  50 +++
 ...eAbstractDataStructuresFailoverSelfTest.java |  21 +-
 .../testsuites/IgniteCacheTestSuite2.java       |   8 +
 .../binary/include/ignite/binary/binary_type.h  | 127 +++----
 .../ignite/impl/binary/binary_id_resolver.h     |  33 +-
 .../ignite/impl/binary/binary_object_impl.h     |   3 +-
 .../ignite/impl/binary/binary_reader_impl.h     |  80 ++++-
 .../include/ignite/impl/binary/binary_utils.h   |   6 +-
 .../ignite/impl/binary/binary_writer_impl.h     |  15 +-
 .../core-test/include/ignite/binary_test_defs.h |  95 +++---
 .../cpp/core-test/include/ignite/complex_type.h |  30 +-
 .../cpp/core-test/include/ignite/test_type.h    |  37 +--
 .../src/binary_identity_resolver_test.cpp       |  38 +--
 .../cpp/core-test/src/binary_object_test.cpp    |   4 +-
 .../cpp/core-test/src/binary_test_defs.cpp      |   5 +
 .../cpp/core-test/src/cache_invoke_test.cpp     |  18 +-
 .../cpp/core-test/src/cache_query_test.cpp      |  12 +-
 .../platforms/cpp/core-test/src/cache_test.cpp  |  36 +-
 .../cpp/core-test/src/continuous_query_test.cpp |  30 +-
 .../cpp/core/include/ignite/ignite_binding.h    |   6 +-
 .../impl/cache/cache_entry_processor_holder.h   |  33 +-
 .../cpp/odbc-test/include/complex_type.h        |  26 +-
 .../platforms/cpp/odbc-test/include/test_type.h |  37 +--
 modules/spring-data/README.txt                  |  32 ++
 modules/spring-data/licenses/apache-2.0.txt     | 202 ++++++++++++
 modules/spring-data/pom.xml                     |  79 +++++
 .../springdata/repository/IgniteRepository.java |  58 ++++
 .../config/EnableIgniteRepositories.java        | 119 +++++++
 .../config/IgniteRepositoriesRegistar.java      |  36 ++
 .../IgniteRepositoryConfigurationExtension.java |  49 +++
 .../springdata/repository/config/Query.java     |  37 +++
 .../repository/config/RepositoryConfig.java     |  39 +++
 .../repository/config/package-info.java         |  22 ++
 .../springdata/repository/package-info.java     |  22 ++
 .../repository/query/IgniteQuery.java           |  83 +++++
 .../repository/query/IgniteQueryGenerator.java  | 243 ++++++++++++++
 .../repository/query/IgniteRepositoryQuery.java | 306 +++++++++++++++++
 .../repository/query/package-info.java          |  22 ++
 .../support/IgniteRepositoryFactory.java        | 168 ++++++++++
 .../support/IgniteRepositoryFactoryBean.java    |  85 +++++
 .../support/IgniteRepositoryImpl.java           | 160 +++++++++
 .../repository/support/package-info.java        |  22 ++
 .../IgniteSpringDataCrudSelfTest.java           | 233 +++++++++++++
 .../IgniteSpringDataQueriesSelfTest.java        | 291 ++++++++++++++++
 .../misc/ApplicationConfiguration.java          |  46 +++
 .../apache/ignite/springdata/misc/Person.java   |  97 ++++++
 .../springdata/misc/PersonRepository.java       |  92 ++++++
 .../springdata/misc/PersonSecondRepository.java |  40 +++
 .../testsuites/IgniteSpringDataTestSuite.java   |  41 +++
 modules/web-console/frontend/.eslintrc          |   2 +-
 modules/web-console/frontend/app/app.js         |   3 -
 .../form-field-datepicker.pug                   |  59 ----
 .../form-field-datepicker.scss                  |  20 --
 .../list-of-registered-users.categories.js      |   4 +-
 .../list-of-registered-users.column-defs.js     |  44 +--
 .../list-of-registered-users.controller.js      | 141 ++++++--
 .../list-of-registered-users.scss               |   4 +
 .../list-of-registered-users.tpl.pug            |  76 +++--
 .../ui-grid-header/ui-grid-header.scss          |  91 -----
 .../ui-grid-header/ui-grid-header.tpl.pug       |  29 --
 .../ui-grid-settings/ui-grid-settings.pug       |  33 --
 .../ui-grid-settings/ui-grid-settings.scss      | 144 --------
 .../frontend/app/helpers/jade/mixins.pug        |   3 +
 .../frontend/app/modules/states/admin.state.js  |  11 +-
 .../frontend/app/primitives/badge/index.scss    |   4 +
 .../frontend/app/primitives/btn/index.scss      |  41 +++
 .../app/primitives/datepicker/index.pug         |  60 ++++
 .../app/primitives/datepicker/index.scss        |  64 ++++
 .../frontend/app/primitives/dropdown/index.pug  |  43 +++
 .../frontend/app/primitives/dropdown/index.scss |  82 +++++
 .../frontend/app/primitives/index.js            |   8 +
 .../frontend/app/primitives/page/index.scss     |  35 ++
 .../frontend/app/primitives/panel/index.scss    |  51 +++
 .../frontend/app/primitives/tabs/index.scss     |  15 +
 .../app/primitives/ui-grid-header/index.scss    |  91 +++++
 .../app/primitives/ui-grid-header/index.tpl.pug |  29 ++
 .../app/primitives/ui-grid-settings/index.pug   |  33 ++
 .../app/primitives/ui-grid-settings/index.scss  | 171 ++++++++++
 .../frontend/app/primitives/ui-grid/index.scss  | 329 +++++++++++++++++++
 .../frontend/public/stylesheets/style.scss      |   5 -
 modules/web-console/frontend/views/base2.pug    |  22 ++
 .../frontend/views/settings/admin.tpl.pug       |   3 +-
 .../web-console/frontend/views/sql/sql.tpl.pug  |   1 -
 .../cache/websession/WebSessionFilter.java      |  22 +-
 parent/pom.xml                                  |   1 +
 pom.xml                                         |   1 +
 97 files changed, 4811 insertions(+), 863 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
index c9081fc,dcac7d4..8d52564
--- a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
@@@ -186,10 -189,11 +189,12 @@@ public class RendezvousAffinityFunctio
      private RendezvousAffinityFunction(boolean exclNeighbors, int parts,
          IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter) {
          A.ensure(parts > 0, "parts > 0");
 +        A.ensure(parts <= CacheConfiguration.MAX_PARTITIONS_COUNT, "parts <=" + CacheConfiguration.MAX_PARTITIONS_COUNT);
  
          this.exclNeighbors = exclNeighbors;
-         this.parts = parts;
+ 
+         setPartitions(parts);
+ 
          this.backupFilter = backupFilter;
  
          try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/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 f902242,0db7d06..6f9b401
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
@@@ -18,8 -18,12 +18,10 @@@
  package org.apache.ignite.testsuites;
  
  import junit.framework.TestSuite;
 -import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionBackupFilterSelfTest;
 -import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionExcludeNeighborsSelfTest;
  import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionBackupFilterSelfTest;
  import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionExcludeNeighborsSelfTest;
+ import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest;
+ import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionStandardHashSelfTest;
  import org.apache.ignite.internal.processors.cache.CacheConcurrentReadThroughTest;
  import org.apache.ignite.internal.processors.cache.CacheConfigurationLeakTest;
  import org.apache.ignite.internal.processors.cache.CacheDhtLocalPartitionAfterRemoveSelfTest;
@@@ -107,9 -117,11 +109,12 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxTimeoutSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheRendezvousAffinityClientSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheStoreUpdateTest;
 +import org.apache.ignite.internal.processors.cache.distributed.near.GridPartitionedBackupLoadSelfTest;
+ import org.apache.ignite.internal.processors.cache.distributed.near.GridNearOffheapCacheStoreUpdateTest;
+ import org.apache.ignite.internal.processors.cache.distributed.near.GridPartitionedBackupLoadSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.NearCacheSyncUpdateTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.NoneRebalanceModeSelfTest;
+ import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedEvictionSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedJobExecutionTest;
  import org.apache.ignite.internal.processors.cache.local.GridCacheLocalAtomicBasicStoreSelfTest;
  import org.apache.ignite.internal.processors.cache.local.GridCacheLocalAtomicGetAndTransformStoreSelfTest;

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/binary/include/ignite/binary/binary_type.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_writer_impl.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
----------------------------------------------------------------------
diff --cc modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
index 07e8a14,0870997..6c2bde7
--- a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
+++ b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
@@@ -156,17 -158,22 +158,17 @@@ namespace ignit
                  return GetBinaryStringHashCode(name);
              }
  
 -            static int32_t GetHashCode(const gt::BinaryDummy& obj)
 -            {
 -                return 0;
 -            }
 -
 -            static bool IsNull(const gt::BinaryDummy& obj)
 +            bool IsNull(const gt::BinaryInner& obj)
              {
-                 return obj.GetValue() == 0;
+                 return false;
              }
  
-             gt::BinaryInner GetNull()
+             static void GetNull(gt::BinaryDummy& dst)
              {
-                 return gt::BinaryInner(0);
+                 dst = gt::BinaryDummy();
              }
  
-             void Write(BinaryWriter& writer, const gt::BinaryDummy& obj)
+             static void Write(BinaryWriter& writer, const gt::BinaryDummy& obj)
              {
                  // No-op.
              }
@@@ -180,17 -187,17 +182,17 @@@
          template<> 
          struct BinaryType<gt::BinaryInner>
          {
-             int32_t GetTypeId() 
 -            static int32_t GetTypeId() 
++            static int32_t GetTypeId()
              { 
                  return GetBinaryStringHashCode("BinaryInner"); 
              }
  
-             std::string GetTypeName()
+             static void GetTypeName(std::string& dst)
              {
-                 return "BinaryInner";
+                 dst = "BinaryInner";
              }
  
-             int32_t GetFieldId(const char* name) 
 -            static int32_t GetFieldId(const char* name) 
++            static int32_t GetFieldId(const char* name)
              { 
                  return GetBinaryStringHashCode(name); 
              }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/include/ignite/complex_type.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/include/ignite/test_type.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
----------------------------------------------------------------------
diff --cc modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
index 62f37f9,802ec97..dd1e790
--- a/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
@@@ -212,17 -336,45 +204,13 @@@ namespace ignit
                  writer.WriteInt64("i64", obj.i64);
              }
  
-             CompositeKeySimple Read(BinaryReader& reader)
+             static void Read(BinaryReader& reader, CompositeKeySimple& dst)
              {
-                 CompositeKeySimple val;
- 
-                 val.str = reader.ReadString("str");
-                 val.ts = reader.ReadTimestamp("ts");
-                 val.i64 = reader.ReadInt64("i64");
- 
-                 return val;
+                 dst.str = reader.ReadString("str");
+                 dst.ts = reader.ReadTimestamp("ts");
+                 dst.i64 = reader.ReadInt64("i64");
              }
          };
 -
 -        /**
 -         * Binary type definition for ComplexType2.
 -         */
 -        template<>
 -        struct BinaryType<ComplexType2>
 -        {
 -            IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ComplexType2)
 -            IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ComplexType2)
 -            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
 -            IGNITE_BINARY_IS_NULL_FALSE(ComplexType2)
 -            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType2)
 -
 -            static ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
 -            {
 -                return ignite::MakeReferenceFromCopy(CustomFieldIdResolver());
 -            }
 -
 -            static void Write(BinaryWriter& writer, const ComplexType2& obj)
 -            {
 -                writer.WriteInt32("i32Field", obj.i32Field);
 -                writer.WriteObject("objField", obj.objField);
 -                writer.WriteString("strField", obj.strField);
 -            }
 -
 -            static void Read(BinaryReader& reader, ComplexType2& dst)
 -            {
 -                dst.i32Field = reader.ReadInt32("i32Field");
 -                dst.objField = reader.ReadObject<InnerObject>("objField");
 -                dst.strField = reader.ReadString("strField");
 -            }
 -        };
      }
  }
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/src/binary_object_test.cpp
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/src/cache_query_test.cpp
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/src/cache_test.cpp
----------------------------------------------------------------------
diff --cc modules/platforms/cpp/core-test/src/cache_test.cpp
index d269f65,99e0f1b..d222009
--- a/modules/platforms/cpp/core-test/src/cache_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_test.cpp
@@@ -50,25 -50,24 +50,23 @@@ namespace ignit
      namespace binary
      {
          IGNITE_BINARY_TYPE_START(Person)
-         IGNITE_BINARY_GET_TYPE_ID_AS_HASH(Person)
-         IGNITE_BINARY_GET_TYPE_NAME_AS_IS(Person)
-         IGNITE_BINARY_GET_FIELD_ID_AS_HASH
-         IGNITE_BINARY_IS_NULL_FALSE(Person)
-         IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(Person)
+             IGNITE_BINARY_GET_TYPE_ID_AS_HASH(Person)
+             IGNITE_BINARY_GET_TYPE_NAME_AS_IS(Person)
+             IGNITE_BINARY_GET_FIELD_ID_AS_HASH
 -            IGNITE_BINARY_GET_HASH_CODE_ZERO(Person)
+             IGNITE_BINARY_IS_NULL_FALSE(Person)
+             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(Person)
  
-         void Write(BinaryWriter& writer, Person obj)
-         {
-             writer.WriteString("name", obj.name);
-             writer.WriteInt32("age", obj.age);            
-         }
+             static void Write(BinaryWriter& writer, const Person& obj)
+             {
+                 writer.WriteString("name", obj.name);
 -                writer.WriteInt32("age", obj.age);            
++                writer.WriteInt32("age", obj.age);
+             }
  
-         Person Read(BinaryReader& reader)
-         {
-             std::string name = reader.ReadString("name");
-             int age = reader.ReadInt32("age");
-             
-             return Person(name, age);
-         }
+             static void Read(BinaryReader& reader, Person& dst)
+             {
+                 dst.name = reader.ReadString("name");
+                 dst.age = reader.ReadInt32("age");
+             }
  
          IGNITE_BINARY_TYPE_END
      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/core-test/src/continuous_query_test.cpp
----------------------------------------------------------------------
diff --cc modules/platforms/cpp/core-test/src/continuous_query_test.cpp
index 2d1a2ee,8579c54..ea3d665
--- a/modules/platforms/cpp/core-test/src/continuous_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/continuous_query_test.cpp
@@@ -290,14 -288,20 +287,15 @@@ namespace ignit
                  return GetBinaryStringHashCode("RangeFilter");
              }
  
-             std::string GetTypeName()
+             static void GetTypeName(std::string& dst)
              {
-                 return "RangeFilter";
+                 dst = "RangeFilter";
  
              }
+ 
              IGNITE_BINARY_GET_FIELD_ID_AS_HASH
  
 -            static int32_t GetHashCode(const RangeFilter<K,V>&)
 -            {
 -                return 0;
 -            }
 -
 -            static bool IsNull(const RangeFilter<K,V>&)
 +            bool IsNull(const RangeFilter<K,V>&)
              {
                  return false;
              }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/odbc-test/include/complex_type.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/modules/platforms/cpp/odbc-test/include/test_type.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/5f724512/pom.xml
----------------------------------------------------------------------


[06/13] ignite git commit: IGNITE-1192: Apache Ignite Spring Data integration

Posted by is...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
new file mode 100644
index 0000000..f4131ba
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
@@ -0,0 +1,85 @@
+/*
+ * 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.springdata.repository.support;
+
+import java.io.Serializable;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.data.repository.Repository;
+import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
+import org.springframework.data.repository.core.support.RepositoryFactorySupport;
+
+/**
+ * Apache Ignite repository factory bean.
+ *
+ * The repository requires to define one of the parameters below in your Spring application configuration in order
+ * to get an access to Apache Ignite cluster:
+ * <ul>
+ * <li>{@link Ignite} instance bean named "igniteInstance"</li>
+ * <li>{@link IgniteConfiguration} bean named "igniteCfg"</li>
+ * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
+ * <ul/>
+ *
+ * @param <T> Repository type, {@link IgniteRepository}
+ * @param <S> Domain object class.
+ * @param <ID> Domain object key, super expects {@link Serializable}.
+ */
+public class IgniteRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
+    extends RepositoryFactoryBeanSupport<T, S, ID> implements ApplicationContextAware {
+    /** Application context. */
+    private ApplicationContext ctx;
+
+    /** {@inheritDoc} */
+    @Override public void setApplicationContext(ApplicationContext context) throws BeansException {
+        this.ctx = context;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected RepositoryFactorySupport createRepositoryFactory() {
+        try {
+            Ignite ignite = (Ignite)ctx.getBean("igniteInstance");
+
+            return new IgniteRepositoryFactory(ignite);
+        }
+        catch (BeansException ex) {
+            try {
+                IgniteConfiguration cfg = (IgniteConfiguration)ctx.getBean("igniteCfg");
+
+                return new IgniteRepositoryFactory(cfg);
+            }
+            catch (BeansException ex2) {
+                try {
+                    String path = (String)ctx.getBean("igniteSpringCfgPath");
+
+                    return new IgniteRepositoryFactory(path);
+                }
+                catch (BeansException ex3) {
+                    throw new IgniteException("Failed to initialize Ignite repository factory. Ignite instance or" +
+                        " IgniteConfiguration or a path to Ignite's spring XML configuration must be defined in the" +
+                        " application configuration");
+                }
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
new file mode 100644
index 0000000..4290272
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
@@ -0,0 +1,160 @@
+/*
+ * 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.springdata.repository.support;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+
+/**
+ * General Apache Ignite repository implementation.
+ */
+public class IgniteRepositoryImpl<T, ID extends Serializable> implements IgniteRepository<T, ID> {
+    /** Ignite Cache bound to the repository */
+    private final IgniteCache<ID, T> cache;
+
+    /**
+     * Repository constructor.
+     *
+     * @param cache Initialized cache instance.
+     */
+    public IgniteRepositoryImpl(IgniteCache<ID, T> cache) {
+        this.cache = cache;
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends T> S save(ID key, S entity) {
+        cache.put(key, entity);
+
+        return entity;
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends T> Iterable<S> save(Map<ID, S> entities) {
+        cache.putAll(entities);
+
+        return entities.values();
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends T> S save(S entity) {
+        throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends T> Iterable<S> save(Iterable<S> entities) {
+        throw new UnsupportedOperationException("Use IgniteRepository.save(Map<keys,value>) method instead.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public T findOne(ID id) {
+        return cache.get(id);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean exists(ID id) {
+        return cache.containsKey(id);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterable<T> findAll() {
+        final Iterator<Cache.Entry<ID, T>> iter = cache.iterator();
+
+        return new Iterable<T>() {
+            @Override public Iterator<T> iterator() {
+                return new Iterator<T>() {
+                    @Override public boolean hasNext() {
+                        return iter.hasNext();
+                    }
+
+                    @Override public T next() {
+                        return iter.next().getValue();
+                    }
+
+                    @Override public void remove() {
+                        iter.remove();
+                    }
+                };
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterable<T> findAll(Iterable<ID> ids) {
+        if (ids instanceof Set)
+            return cache.getAll((Set<ID>)ids).values();
+
+        if (ids instanceof Collection)
+            return cache.getAll(new HashSet<>((Collection<ID>)ids)).values();
+
+        TreeSet<ID> keys = new TreeSet<>();
+
+        for (ID id : ids)
+            keys.add(id);
+
+        return cache.getAll(keys).values();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long count() {
+        return cache.size(CachePeekMode.PRIMARY);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void delete(ID id) {
+        cache.remove(id);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void delete(T entity) {
+        throw new UnsupportedOperationException("Use IgniteRepository.delete(key) method instead.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void delete(Iterable<? extends T> entities) {
+        throw new UnsupportedOperationException("Use IgniteRepository.deleteAll(keys) method instead.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void deleteAll(Iterable<ID> ids) {
+        if (ids instanceof Set)
+            cache.removeAll((Set<ID>)ids);
+
+        if (ids instanceof Collection)
+            cache.removeAll(new HashSet<>((Collection<ID>)ids));
+
+        TreeSet<ID> keys = new TreeSet<>();
+
+        for (ID id : ids)
+            keys.add(id);
+
+        cache.removeAll(keys);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void deleteAll() {
+        cache.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
new file mode 100644
index 0000000..95ab21d
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Package contains supporting files required by Spring Data framework.
+ */
+package org.apache.ignite.springdata.repository.support;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
new file mode 100644
index 0000000..14d6844
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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.springdata;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.apache.ignite.springdata.misc.ApplicationConfiguration;
+import org.apache.ignite.springdata.misc.Person;
+import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+/**
+ *
+ */
+public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
+    /** Repository. */
+    private static PersonRepository repo;
+
+    /** Context. */
+    private static AnnotationConfigApplicationContext ctx;
+
+    /** Number of entries to store */
+    private static int CACHE_SIZE = 1000;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        ctx = new AnnotationConfigApplicationContext();
+
+        ctx.register(ApplicationConfiguration.class);
+
+        ctx.refresh();
+
+        repo = ctx.getBean(PersonRepository.class);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        fillInRepository();
+
+        assertEquals(CACHE_SIZE, repo.count());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        repo.deleteAll();
+
+        assertEquals(0, repo.count());
+
+        super.afterTest();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+
+        ctx.destroy();
+    }
+
+    /**
+     *
+     */
+    public void testPutGet() {
+        Person person = new Person("some_name", "some_surname");
+
+        int id = CACHE_SIZE + 1;
+
+        assertEquals(person, repo.save(id, person));
+
+        assertTrue(repo.exists(id));
+
+        assertEquals(person, repo.findOne(id));
+
+        try {
+            repo.save(person);
+
+            fail("Managed to save a Person without ID");
+        }
+        catch (UnsupportedOperationException e) {
+            //excepted
+        }
+    }
+
+    /**
+     *
+     */
+    public void testPutAllGetAll() {
+        LinkedHashMap<Integer, Person> map = new LinkedHashMap<>();
+
+        for (int i = CACHE_SIZE; i < CACHE_SIZE + 50; i++)
+            map.put(i, new Person("some_name" + i, "some_surname" + i));
+
+        Iterator<Person> persons = repo.save(map).iterator();
+
+        assertEquals(CACHE_SIZE + 50, repo.count());
+
+        Iterator<Person> origPersons = map.values().iterator();
+
+        while (persons.hasNext())
+            assertEquals(origPersons.next(), persons.next());
+
+        try {
+            repo.save(map.values());
+
+            fail("Managed to save a list of Persons with ids");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
+
+        persons = repo.findAll(map.keySet()).iterator();
+
+        int counter = 0;
+
+        while (persons.hasNext()) {
+            persons.next();
+            counter++;
+        }
+
+        assertEquals(map.size(), counter);
+    }
+
+    /**
+     *
+     */
+    public void testGetAll() {
+        assertEquals(CACHE_SIZE, repo.count());
+
+        Iterator<Person> persons = repo.findAll().iterator();
+
+        int counter = 0;
+
+        while (persons.hasNext()) {
+            persons.next();
+            counter++;
+        }
+
+        assertEquals(repo.count(), counter);
+    }
+
+    /**
+     *
+     */
+    public void testDelete() {
+        assertEquals(CACHE_SIZE, repo.count());
+
+        repo.delete(0);
+
+        assertEquals(CACHE_SIZE - 1, repo.count());
+        assertNull(repo.findOne(0));
+
+        try {
+            repo.delete(new Person("", ""));
+
+            fail("Managed to delete a Person without id");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
+    }
+
+    /**
+     *
+     */
+    public void testDeleteSet() {
+        assertEquals(CACHE_SIZE, repo.count());
+
+        TreeSet<Integer> ids = new TreeSet<>();
+
+        for (int i = 0; i < CACHE_SIZE / 2; i++)
+            ids.add(i);
+
+        repo.deleteAll(ids);
+
+        assertEquals(CACHE_SIZE / 2, repo.count());
+
+        try {
+            ArrayList<Person> persons = new ArrayList<>();
+
+            for (int i = 0; i < 3; i++)
+                persons.add(new Person(String.valueOf(i), String.valueOf(i)));
+
+            repo.delete(persons);
+
+            fail("Managed to delete Persons without ids");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
+    }
+
+    /**
+     *
+     */
+    public void testDeleteAll() {
+        assertEquals(CACHE_SIZE, repo.count());
+
+        repo.deleteAll();
+
+        assertEquals(0, repo.count());
+    }
+
+    /**
+     *
+     */
+    private void fillInRepository() {
+        for (int i = 0; i < CACHE_SIZE; i++)
+            repo.save(i, new Person("person" + Integer.toHexString(i),
+                "lastName" + Integer.toHexString((i + 16) % 256)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
new file mode 100644
index 0000000..40b7df2
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
@@ -0,0 +1,291 @@
+/*
+ * 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.springdata;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.springdata.misc.ApplicationConfiguration;
+import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.springdata.misc.Person;
+import org.apache.ignite.springdata.misc.PersonSecondRepository;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.domain.Sort;
+
+/**
+ *
+ */
+public class IgniteSpringDataQueriesSelfTest extends GridCommonAbstractTest {
+    /** Repository. */
+    private static PersonRepository repo;
+
+    /** Repository 2. */
+    private static PersonSecondRepository repo2;
+
+    /** Context. */
+    private static AnnotationConfigApplicationContext ctx;
+
+    /** Number of entries to store */
+    private static int CACHE_SIZE = 1000;
+
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        ctx = new AnnotationConfigApplicationContext();
+
+        ctx.register(ApplicationConfiguration.class);
+
+        ctx.refresh();
+
+        repo = ctx.getBean(PersonRepository.class);
+        repo2 = ctx.getBean(PersonSecondRepository.class);
+
+        for (int i = 0; i < CACHE_SIZE; i++)
+            repo.save(i, new Person("person" + Integer.toHexString(i),
+                "lastName" + Integer.toHexString((i + 16) % 256)));
+    }
+
+    @Override protected void afterTestsStopped() throws Exception {
+        ctx.destroy();
+
+        super.afterTestsStopped();
+    }
+
+    /** */
+    public void testExplicitQuery() {
+        List<Person> persons = repo.simpleQuery("person4a");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("person4a", person.getFirstName());
+    }
+
+    /** */
+    public void testEqualsPart() {
+        List<Person> persons = repo.findByFirstName("person4e");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("person4e", person.getFirstName());
+    }
+
+    /** */
+    public void testContainingPart() {
+        List<Person> persons = repo.findByFirstNameContaining("person4");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertTrue(person.getFirstName().startsWith("person4"));
+    }
+
+    /** */
+    public void testTopPart() {
+        Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
+
+        Iterator<Person> iter = top.iterator();
+
+        Person person = iter.next();
+
+        assertFalse(iter.hasNext());
+
+        assertTrue(person.getFirstName().startsWith("person4"));
+    }
+
+    /** */
+    public void testLikeAndLimit() {
+        Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
+
+        int cnt = 0;
+
+        for (Person next : like) {
+            assertTrue(next.getFirstName().contains("person"));
+
+            cnt++;
+        }
+
+        assertEquals(10, cnt);
+    }
+
+    /** */
+    public void testCount() {
+        int cnt = repo.countByFirstNameLike("person");
+
+        assertEquals(1000, cnt);
+    }
+
+    /** */
+    public void testCount2() {
+        int cnt = repo.countByFirstNameLike("person4");
+
+        assertTrue(cnt < 1000);
+    }
+
+    /** */
+    public void testPageable() {
+        PageRequest pageable = new PageRequest(1, 5, Sort.Direction.DESC, "firstName");
+
+        HashSet<String> firstNames = new HashSet<>();
+
+        List<Person> pageable1 = repo.findByFirstNameRegex("^[a-z]+$", pageable);
+
+        assertEquals(5, pageable1.size());
+
+        for (Person person : pageable1) {
+            firstNames.add(person.getFirstName());
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+        }
+
+        List<Person> pageable2 = repo.findByFirstNameRegex("^[a-z]+$", pageable.next());
+
+        assertEquals(5, pageable2.size());
+
+        for (Person person : pageable2) {
+            firstNames.add(person.getFirstName());
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+        }
+
+        assertEquals(10, firstNames.size());
+    }
+
+    /** */
+    public void testAndAndOr() {
+        int cntAnd = repo.countByFirstNameLikeAndSecondNameLike("person1", "lastName1");
+
+        int cntOr = repo.countByFirstNameStartingWithOrSecondNameStartingWith("person1", "lastName1");
+
+        assertTrue(cntAnd <= cntOr);
+    }
+
+    /** */
+    public void testQueryWithSort() {
+        List<Person> persons = repo.queryWithSort("^[a-z]+$", new Sort(Sort.Direction.DESC, "secondName"));
+
+        Person previous = persons.get(0);
+
+        for (Person person : persons) {
+            assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
+
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+
+            previous = person;
+        }
+    }
+
+    /** */
+    public void testQueryWithPaging() {
+        List<Person> persons = repo.queryWithPageable("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
+
+        assertEquals(7, persons.size());
+
+        Person previous = persons.get(0);
+
+        for (Person person : persons) {
+            assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
+
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+
+            previous = person;
+        }
+    }
+
+    /** */
+    public void testQueryFields() {
+        List<String> persons = repo.selectField("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
+
+        assertEquals(7, persons.size());
+    }
+
+    /** */
+    public void testFindCacheEntries() {
+        List<Cache.Entry<Integer, Person>> cacheEntries = repo.findBySecondNameLike("stName1");
+
+        assertFalse(cacheEntries.isEmpty());
+
+        for (Cache.Entry<Integer, Person> entry : cacheEntries)
+            assertTrue(entry.getValue().getSecondName().contains("stName1"));
+    }
+
+    /** */
+    public void testFindOneCacheEntry() {
+        Cache.Entry<Integer, Person> cacheEntry = repo.findTopBySecondNameLike("tName18");
+
+        assertNotNull(cacheEntry);
+
+        assertTrue(cacheEntry.getValue().getSecondName().contains("tName18"));
+    }
+
+    /** */
+    public void testFindOneValue() {
+        Person person = repo.findTopBySecondNameStartingWith("lastName18");
+
+        assertNotNull(person);
+
+        assertTrue(person.getSecondName().startsWith("lastName18"));
+    }
+
+    /** */
+    public void testSelectSeveralFields() {
+        List<List> lists = repo.selectSeveralField("^[a-z]+$", new PageRequest(2, 6));
+
+        assertEquals(6, lists.size());
+
+        for (List list : lists) {
+            assertEquals(2, list.size());
+
+            assertTrue(list.get(0) instanceof Integer);
+        }
+    }
+
+    /** */
+    public void testCountQuery() {
+        int cnt = repo.countQuery(".*");
+
+        assertEquals(256, cnt);
+    }
+
+    /** */
+    public void testSliceOfCacheEntries() {
+        Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", new PageRequest(3, 4));
+
+        assertEquals(4, slice.getSize());
+
+        for (Cache.Entry<Integer, Person> entry : slice)
+            assertFalse("lastName18".equals(entry.getValue().getSecondName()));
+    }
+
+    /** */
+    public void testSliceOfLists() {
+        Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", new PageRequest(0, 3));
+
+        assertEquals(3, lists.getSize());
+
+        for (List list : lists) {
+            assertEquals(2, list.size());
+
+            assertTrue(list.get(0) instanceof Integer);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
new file mode 100644
index 0000000..731e6d9
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * 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.springdata.misc;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+
+/**
+ *
+ */
+@Configuration
+@EnableIgniteRepositories
+public class ApplicationConfiguration {
+    @Bean
+    public Ignite igniteInstance() {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
+
+        ccfg.setIndexedTypes(Integer.class, Person.class);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return Ignition.start(cfg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
new file mode 100644
index 0000000..a0adde5
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
@@ -0,0 +1,97 @@
+/*
+ * 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.springdata.misc;
+
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+
+public class Person {
+    /** First name. */
+    @QuerySqlField(index = true)
+    private String firstName;
+
+    /** Second name. */
+    @QuerySqlField(index = true)
+    private String secondName;
+
+    /**
+     * @param firstName First name.
+     * @param secondName Second name.
+     */
+    public Person(String firstName, String secondName) {
+        this.firstName = firstName;
+        this.secondName = secondName;
+    }
+
+    /**
+     *
+     */
+    public String getFirstName() {
+        return firstName;
+    }
+
+    /**
+     * @param firstName First name.
+     */
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    /**
+     *
+     */
+    public String getSecondName() {
+        return secondName;
+    }
+
+    /**
+     * @param secondName Second name.
+     */
+    public void setSecondName(String secondName) {
+        this.secondName = secondName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Person{" +
+            "firstName='" + firstName + '\'' +
+            ", secondName='" + secondName + '\'' +
+            '}';
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        Person person = (Person)o;
+
+        if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null)
+            return false;
+        return secondName != null ? secondName.equals(person.secondName) : person.secondName == null;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int result = firstName != null ? firstName.hashCode() : 0;
+        result = 31 * result + (secondName != null ? secondName.hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
new file mode 100644
index 0000000..88f47d9
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
@@ -0,0 +1,92 @@
+
+/*
+ * 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.springdata.misc;
+
+import java.util.Collection;
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+
+/**
+ *
+ */
+@RepositoryConfig(cacheName = "PersonCache")
+public interface PersonRepository extends IgniteRepository<Person, Integer> {
+    /** */
+    public List<Person> findByFirstName(String val);
+
+    /** */
+    public List<Person> findByFirstNameContaining(String val);
+
+    /** */
+    public List<Person> findByFirstNameRegex(String val, Pageable pageable);
+
+    /** */
+    public Collection<Person> findTopByFirstNameContaining(String val);
+
+    /** */
+    public Iterable<Person> findFirst10ByFirstNameLike(String val);
+
+    /** */
+    public int countByFirstNameLike(String val);
+
+    /** */
+    public int countByFirstNameLikeAndSecondNameLike(String like1, String like2);
+
+    /** */
+    public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2);
+
+    /** */
+    public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
+
+    /** */
+    public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
+
+    /** */
+    public Person findTopBySecondNameStartingWith(String val);
+
+    /** */
+    @Query("firstName = ?")
+    public List<Person> simpleQuery(String val);
+
+    /** */
+    @Query("firstName REGEXP ?")
+    public List<Person> queryWithSort(String val, Sort sort);
+
+    /** */
+    @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
+    public List<Person> queryWithPageable(String val, Pageable pageable);
+
+    /** */
+    @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
+    public List<String> selectField(String val, Pageable pageable);
+
+    /** */
+    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
+    public List<List> selectSeveralField(String val, Pageable pageable);
+
+    /** */
+    @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
+    public int countQuery(String val);
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
new file mode 100644
index 0000000..a82e822
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
@@ -0,0 +1,40 @@
+/*
+ * 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.springdata.misc;
+
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.data.domain.AbstractPageRequest;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Slice;
+
+/**
+ *
+ */
+@RepositoryConfig(cacheName = "PersonCache")
+public interface PersonSecondRepository extends IgniteRepository<Person, Integer> {
+    /** */
+    public Slice<Cache.Entry<Integer, Person>> findBySecondNameIsNot(String val, PageRequest pageReq);
+
+    /** */
+    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
+    public Slice<List> querySliceOfList(String val, AbstractPageRequest pageReq);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
new file mode 100644
index 0000000..0d6c519
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.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.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
+import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
+
+/**
+ * Ignite Spring Data test suite.
+ */
+public class IgniteSpringDataTestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new TestSuite("Spring Data Test Suite");
+
+        suite.addTestSuite(IgniteSpringDataCrudSelfTest.class);
+        suite.addTestSuite(IgniteSpringDataQueriesSelfTest.class);
+
+        return suite;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index e3fa558..61bf077 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -38,6 +38,7 @@
         <hadoop.version>2.4.1</hadoop.version>
         <spark.version>2.1.0</spark.version>
         <spring.version>4.1.0.RELEASE</spring.version>
+        <spring.data.version>1.2.1.RELEASE</spring.data.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <maven.build.timestamp.format>MMMM d yyyy</maven.build.timestamp.format>
         <doxygen.exec>doxygen</doxygen.exec>

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 41338dd..bc9b5d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,7 @@
         <module>modules/extdata/uri</module>
         <module>modules/clients</module>
         <module>modules/spring</module>
+        <module>modules/spring-data</module>
         <module>modules/web</module>
         <module>modules/aop</module>
         <module>modules/urideploy</module>


[03/13] ignite git commit: Merge remote-tracking branch 'origin/master'

Posted by is...@apache.org.
Merge remote-tracking branch 'origin/master'


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

Branch: refs/heads/ignite-3477-master
Commit: c9d08d39eecc216a788bf023929d74a011ebdd0e
Parents: 902bf42 5c4d43c
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Tue Apr 11 14:09:30 2017 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Tue Apr 11 14:09:30 2017 +0300

----------------------------------------------------------------------
 .gitignore                                      |  31 ++++-
 .../binary/include/ignite/binary/binary_type.h  | 129 ++++++-------------
 .../ignite/impl/binary/binary_id_resolver.h     |  33 ++---
 .../ignite/impl/binary/binary_object_impl.h     |   3 +-
 .../ignite/impl/binary/binary_reader_impl.h     |  80 +++++++++++-
 .../ignite/impl/binary/binary_type_impl.h       |  12 +-
 .../include/ignite/impl/binary/binary_utils.h   |   6 +-
 .../ignite/impl/binary/binary_writer_impl.h     |  15 ++-
 .../core-test/include/ignite/binary_test_defs.h | 117 +++++++++--------
 .../cpp/core-test/include/ignite/complex_type.h |  30 ++---
 .../cpp/core-test/include/ignite/test_type.h    |  37 +++---
 .../src/binary_identity_resolver_test.cpp       |  92 +++++--------
 .../cpp/core-test/src/binary_object_test.cpp    |   4 +-
 .../cpp/core-test/src/binary_test_defs.cpp      |   5 +
 .../cpp/core-test/src/cache_invoke_test.cpp     |  18 +--
 .../cpp/core-test/src/cache_query_test.cpp      |  12 +-
 .../platforms/cpp/core-test/src/cache_test.cpp  |  38 +++---
 .../cpp/core-test/src/continuous_query_test.cpp |  34 +++--
 .../cpp/core/include/ignite/ignite_binding.h    |   6 +-
 .../impl/cache/cache_entry_processor_holder.h   |  33 +++--
 .../cpp/odbc-test/include/complex_type.h        |  26 ++--
 .../platforms/cpp/odbc-test/include/test_type.h |  37 +++---
 22 files changed, 393 insertions(+), 405 deletions(-)
----------------------------------------------------------------------



[12/13] ignite git commit: Merge-related fixes

Posted by is...@apache.org.
Merge-related fixes


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

Branch: refs/heads/ignite-3477-master
Commit: 21dcef207f7bc2beab7fa50a4346b2a33fd34611
Parents: 5f72451
Author: Igor Sapego <is...@gridgain.com>
Authored: Wed Apr 12 15:43:10 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Wed Apr 12 15:43:10 2017 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java | 4 ----
 1 file changed, 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/21dcef20/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
index 6f9b401..b94b464 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
@@ -110,11 +110,8 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePar
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheRendezvousAffinityClientSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheStoreUpdateTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridPartitionedBackupLoadSelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridNearOffheapCacheStoreUpdateTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridPartitionedBackupLoadSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.NearCacheSyncUpdateTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.NoneRebalanceModeSelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedEvictionSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedJobExecutionTest;
 import org.apache.ignite.internal.processors.cache.local.GridCacheLocalAtomicBasicStoreSelfTest;
 import org.apache.ignite.internal.processors.cache.local.GridCacheLocalAtomicGetAndTransformStoreSelfTest;
@@ -178,7 +175,6 @@ public class IgniteCacheTestSuite2 extends TestSuite {
         suite.addTest(new TestSuite(RendezvousAffinityFunctionExcludeNeighborsSelfTest.class));
         suite.addTest(new TestSuite(RendezvousAffinityFunctionFastPowerOfTwoHashSelfTest.class));
         suite.addTest(new TestSuite(RendezvousAffinityFunctionStandardHashSelfTest.class));
-        suite.addTest(new TestSuite(FairAffinityFunctionExcludeNeighborsSelfTest.class));
         suite.addTest(new TestSuite(GridCacheRendezvousAffinityClientSelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedProjectionAffinitySelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedBasicOpSelfTest.class));