ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [4/4] ignite git commit: IGNITE-7421: Java thin client.
Date Thu, 29 Mar 2018 10:21:43 GMT
IGNITE-7421: Java thin client.


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

Branch: refs/heads/master
Commit: ed03b931819bbb8f0ff3c22e203201c7d75cd56c
Parents: bdf86e9
Author: Alexey Kukushkin <alexeykukushkin@yahoo.com>
Authored: Thu Mar 29 13:21:36 2018 +0300
Committer: devozerov <ppozerov@gmail.com>
Committed: Thu Mar 29 13:21:36 2018 +0300

----------------------------------------------------------------------
 .../examples/client/ClientPutGetExample.java    |  69 ++
 .../main/java/org/apache/ignite/Ignition.java   |  19 +
 .../ignite/binary/BinaryTypeConfiguration.java  |   6 +-
 .../client/ClientAuthenticationException.java   |  45 ++
 .../org/apache/ignite/client/ClientCache.java   | 356 ++++++++++
 .../ignite/client/ClientCacheConfiguration.java | 656 +++++++++++++++++++
 .../client/ClientConfigurationException.java    |  51 ++
 .../client/ClientConnectionException.java       |  45 ++
 .../apache/ignite/client/ClientException.java   |  77 +++
 .../org/apache/ignite/client/IgniteClient.java  |  91 +++
 .../java/org/apache/ignite/client/SslMode.java  |  26 +
 .../org/apache/ignite/client/SslProtocol.java   |  28 +
 .../configuration/BinaryConfiguration.java      |   6 +-
 .../configuration/ClientConfiguration.java      | 400 +++++++++++
 .../binary/BinaryCachingMetadataHandler.java    |  11 +-
 .../internal/binary/BinaryClassDescriptor.java  |  12 +
 .../ignite/internal/binary/BinaryContext.java   |  17 +
 .../internal/binary/BinaryMetadataHandler.java  |   8 +
 .../binary/BinaryNoopMetadataHandler.java       |   6 +
 .../internal/client/thin/ClientBinary.java      | 167 +++++
 .../client/thin/ClientBinaryMarshaller.java     | 112 ++++
 .../internal/client/thin/ClientCacheEntry.java  |  62 ++
 .../internal/client/thin/ClientChannel.java     |  45 ++
 .../client/thin/ClientChannelConfiguration.java | 242 +++++++
 .../internal/client/thin/ClientError.java       |  71 ++
 .../client/thin/ClientFieldsQueryCursor.java    |  40 ++
 .../client/thin/ClientFieldsQueryPager.java     |  81 +++
 .../internal/client/thin/ClientOperation.java   |  72 ++
 .../client/thin/ClientProtocolError.java        |  40 ++
 .../internal/client/thin/ClientQueryCursor.java |  94 +++
 .../internal/client/thin/ClientQueryPager.java  |  60 ++
 .../internal/client/thin/ClientServerError.java |  47 ++
 .../internal/client/thin/ClientUtils.java       | 602 +++++++++++++++++
 .../internal/client/thin/FieldsQueryPager.java  |  30 +
 .../internal/client/thin/GenericQueryPager.java | 139 ++++
 .../internal/client/thin/ProtocolVersion.java   | 100 +++
 .../ignite/internal/client/thin/QueryPager.java |  36 +
 .../internal/client/thin/ReliableChannel.java   | 208 ++++++
 .../ignite/internal/client/thin/Result.java     |  60 ++
 .../internal/client/thin/TcpClientCache.java    | 504 ++++++++++++++
 .../internal/client/thin/TcpClientChannel.java  | 559 ++++++++++++++++
 .../internal/client/thin/TcpIgniteClient.java   | 412 ++++++++++++
 .../binary/CacheObjectBinaryProcessorImpl.java  |   4 +
 .../odbc/ClientListenerNioListener.java         |  19 +
 .../platform/client/ClientResourceRegistry.java |  10 +-
 .../platform/client/ClientStatus.java           |   3 +
 .../client/ClientCacheConfigurationTest.java    | 100 +++
 .../ignite/client/ClientConfigurationTest.java  |  69 ++
 .../org/apache/ignite/client/Comparers.java     | 112 ++++
 .../java/org/apache/ignite/client/Config.java   |  61 ++
 .../apache/ignite/client/FunctionalTest.java    | 390 +++++++++++
 .../apache/ignite/client/IgniteBinaryTest.java  | 221 +++++++
 .../java/org/apache/ignite/client/LoadTest.java | 133 ++++
 .../ignite/client/LocalIgniteCluster.java       | 193 ++++++
 .../java/org/apache/ignite/client/Person.java   |  65 ++
 .../apache/ignite/client/ReliabilityTest.java   | 186 ++++++
 .../org/apache/ignite/client/SecurityTest.java  | 158 +++++
 .../binary/TestCachingMetadataHandler.java      |   9 +-
 modules/core/src/test/resources/client.jks      | Bin 0 -> 3232 bytes
 modules/core/src/test/resources/server.jks      | Bin 0 -> 3230 bytes
 modules/core/src/test/resources/trust.jks       | Bin 0 -> 2432 bytes
 .../apache/ignite/client/ClientTestSuite.java   |  40 ++
 .../ignite/client/FunctionalQueryTest.java      | 169 +++++
 .../ignite/client/IgniteBinaryQueryTest.java    | 130 ++++
 parent/pom.xml                                  |   1 +
 65 files changed, 7776 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/examples/src/main/java/org/apache/ignite/examples/client/ClientPutGetExample.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/client/ClientPutGetExample.java b/examples/src/main/java/org/apache/ignite/examples/client/ClientPutGetExample.java
new file mode 100644
index 0000000..c84a800
--- /dev/null
+++ b/examples/src/main/java/org/apache/ignite/examples/client/ClientPutGetExample.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.client;
+
+import org.apache.ignite.Ignition;
+import org.apache.ignite.examples.model.Address;
+import org.apache.ignite.client.ClientCache;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.client.ClientException;
+
+/**
+ * Demonstrates how to use Ignite thin client for basic put/get cache operations.
+ * <p>
+ * Prerequisites:
+ * <ul>
+ * <li>An Ignite server node must be running on local host.</li>
+ * </ul>
+ * </p>
+ */
+public class ClientPutGetExample {
+    /** Entry point. */
+    public static void main(String[] args) {
+        ClientConfiguration cfg = new ClientConfiguration().setAddresses("127.0.0.1:10800");
+
+        try (IgniteClient igniteClient = Ignition.startClient(cfg)) {
+            System.out.println();
+            System.out.println(">>> Thin client put-get example started.");
+
+            final String CACHE_NAME = "put-get-example";
+
+            ClientCache<Integer, Address> cache = igniteClient.getOrCreateCache(CACHE_NAME);
+
+            System.out.format(">>> Created cache [%s].\n", CACHE_NAME);
+
+            Integer key = 1;
+            Address val = new Address("1545 Jackson Street", 94612);
+
+            cache.put(key, val);
+
+            System.out.format(">>> Saved [%s] in the cache.\n", val);
+
+            Address cachedVal = cache.get(key);
+
+            System.out.format(">>> Loaded [%s] from the cache.\n", cachedVal);
+        }
+        catch (ClientException e) {
+            System.err.println(e.getMessage());
+        }
+        catch (Exception e) {
+            System.err.format("Unexpected failure: %s\n", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/Ignition.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/Ignition.java b/modules/core/src/main/java/org/apache/ignite/Ignition.java
index 1bdd58d..229dbdb 100644
--- a/modules/core/src/main/java/org/apache/ignite/Ignition.java
+++ b/modules/core/src/main/java/org/apache/ignite/Ignition.java
@@ -20,12 +20,17 @@ package org.apache.ignite;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.List;
+import java.util.Objects;
 import java.util.UUID;
+import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgnitionEx;
+import org.apache.ignite.internal.client.thin.TcpIgniteClient;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.spi.discovery.DiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.client.ClientConfigurationException;
+import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.thread.IgniteThread;
 import org.jetbrains.annotations.Nullable;
 
@@ -570,4 +575,18 @@ public class Ignition {
     public static boolean removeListener(IgnitionListener lsnr) {
         return IgnitionEx.removeListener(lsnr);
     }
+
+    /**
+     * Initializes new instance of {@link IgniteClient}.
+     * <p>
+     * Server connection will be lazily initialized when first required.
+     *
+     * @param cfg Thin client configuration.
+     * @return Successfully opened thin client connection.
+     */
+    public static IgniteClient startClient(ClientConfiguration cfg) throws ClientConfigurationException {
+        Objects.requireNonNull(cfg, "cfg");
+
+        return TcpIgniteClient.start(cfg);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
index 2d00bd2..84cefed 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.binary;
 
+import java.io.Serializable;
 import org.apache.ignite.configuration.BinaryConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.util.typedef.internal.A;
@@ -33,7 +34,10 @@ import java.util.Map;
  * However, this class allows you to change configuration properties for a specific
  * binary type without affecting configuration for other binary types.
  */
-public class BinaryTypeConfiguration {
+public class BinaryTypeConfiguration implements Serializable {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
     /** Class name. */
     private String typeName;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/ClientAuthenticationException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientAuthenticationException.java b/modules/core/src/main/java/org/apache/ignite/client/ClientAuthenticationException.java
new file mode 100644
index 0000000..dc39c7a
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/ClientAuthenticationException.java
@@ -0,0 +1,45 @@
+/*
+ * 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.client;
+
+/**
+ * Indicates Ignite server the client is connected to closed the connection and no longer available.
+ */
+public class ClientAuthenticationException extends ClientException {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** Message. */
+    private static final String MSG = "Invalid user name or password";
+
+    /**
+     * Default constructor.
+     */
+    public ClientAuthenticationException() {
+        super(MSG);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause.
+     *
+     * @param cause the cause.
+     */
+    public ClientAuthenticationException(Throwable cause) {
+        super(MSG, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/ClientCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientCache.java b/modules/core/src/main/java/org/apache/ignite/client/ClientCache.java
new file mode 100644
index 0000000..168b30b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/ClientCache.java
@@ -0,0 +1,356 @@
+/*
+ * 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.client;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
+import org.apache.ignite.cache.query.Query;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.ScanQuery;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.SqlQuery;
+
+/**
+ * Thin client cache.
+ */
+public interface ClientCache<K, V> {
+    /**
+     * Gets an entry from the cache.
+     *
+     * @param key the key whose associated value is to be returned
+     * @return the element, or null, if it does not exist.
+     * @throws NullPointerException if the key is null.
+     */
+    public V get(K key) throws ClientException;
+
+    /**
+     * Associates the specified value with the specified key in the cache.
+     * <p>
+     * If the {@link ClientCache} previously contained a mapping for the key, the old
+     * value is replaced by the specified value.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param val value to be associated with the specified key.
+     * @throws NullPointerException if key is null or if value is null.
+     */
+    public void put(K key, V val) throws ClientException;
+
+    /**
+     * Determines if the {@link ClientCache} contains an entry for the specified key.
+     * <p>
+     * More formally, returns <tt>true</tt> if and only if this cache contains a
+     * mapping for a key <tt>k</tt> such that <tt>key.equals(k)</tt>.
+     * (There can be at most one such mapping)
+     *
+     * @param key key whose presence in this cache is to be tested.
+     * @return <tt>true</tt> if this map contains a mapping for the specified key.
+     */
+    public boolean containsKey(K key) throws ClientException;
+
+    /**
+     * @return The name of the cache.
+     */
+    public String getName();
+
+    /**
+     * @return The cache configuration.
+     */
+    public ClientCacheConfiguration getConfiguration() throws ClientException;
+
+    /**
+     * Gets the number of all entries cached across all nodes. By default, if {@code peekModes} value isn't provided,
+     * only size of primary copies across all nodes will be returned. This behavior is identical to calling
+     * this method with {@link CachePeekMode#PRIMARY} peek mode.
+     * <p>
+     * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
+     *
+     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
+     */
+    public int size(CachePeekMode... peekModes) throws ClientException;
+
+    /**
+     * Gets a collection of entries from the {@link ClientCache}, returning them as
+     * {@link Map} of the values associated with the set of keys requested.
+     *
+     * @param keys The keys whose associated values are to be returned.
+     * @return A map of entries that were found for the given keys. Keys not found
+     * in the cache are not in the returned map.
+     */
+    public Map<K, V> getAll(Set<? extends K> keys) throws ClientException;
+
+    /**
+     * Copies all of the entries from the specified map to the {@link ClientCache}.
+     * <p>
+     * The effect of this call is equivalent to that of calling
+     * {@link #put(Object, Object) put(k, v)} on this cache once for each mapping
+     * from key <tt>k</tt> to value <tt>v</tt> in the specified map.
+     * <p>
+     * The order in which the individual puts occur is undefined.
+     * <p>
+     * The behavior of this operation is undefined if entries in the cache
+     * corresponding to entries in the map are modified or removed while this
+     * operation is in progress. or if map is modified while the operation is in
+     * progress.
+     * <p>
+     *
+     * @param map Mappings to be stored in this cache.
+     */
+    public void putAll(Map<? extends K, ? extends V> map) throws ClientException;
+
+    /**
+     * Atomically replaces the entry for a key only if currently mapped to a given value.
+     * <p>
+     * This is equivalent to:
+     * <pre><code>
+     * if (cache.containsKey(key) &amp;&amp; equals(cache.get(key), oldValue)) {
+     *  cache.put(key, newValue);
+     * return true;
+     * } else {
+     *  return false;
+     * }
+     * </code></pre>
+     * except that the action is performed atomically.
+     *
+     * @param key Key with which the specified value is associated.
+     * @param oldVal Value expected to be associated with the specified key.
+     * @param newVal Value to be associated with the specified key.
+     * @return <tt>true</tt> if the value was replaced
+     */
+    public boolean replace(K key, V oldVal, V newVal) throws ClientException;
+
+    /**
+     * Atomically replaces the entry for a key only if currently mapped to some
+     * value.
+     * <p>
+     * This is equivalent to
+     * <pre><code>
+     * if (cache.containsKey(key)) {
+     *   cache.put(key, value);
+     *   return true;
+     * } else {
+     *   return false;
+     * }</code></pre>
+     * except that the action is performed atomically.
+     *
+     * @param key The key with which the specified value is associated.
+     * @param val The value to be associated with the specified key.
+     * @return <tt>true</tt> if the value was replaced.
+     */
+    public boolean replace(K key, V val) throws ClientException;
+
+    /**
+     * Removes the mapping for a key from this cache if it is present.
+     * <p>
+     * More formally, if this cache contains a mapping from key <tt>k</tt> to value <tt>v</tt> such that
+     * <code>(key==null ?  k==null : key.equals(k))</code>, that mapping is removed.
+     * (The cache can contain at most one such mapping.)
+     *
+     * <p>Returns <tt>true</tt> if this cache previously associated the key, or <tt>false</tt> if the cache
+     * contained no mapping for the key.
+     * <p>
+     * The cache will not contain a mapping for the specified key once the
+     * call returns.
+     *
+     * @param key Key whose mapping is to be removed from the cache.
+     * @return <tt>false</tt> if there was no matching key.
+     */
+    public boolean remove(K key) throws ClientException;
+
+    /**
+     * Atomically removes the mapping for a key only if currently mapped to the given value.
+     * <p>
+     * This is equivalent to:
+     * <pre><code>
+     * if (cache.containsKey(key) &amp;&amp; equals(cache.get(key), oldValue) {
+     *   cache.remove(key);
+     *   return true;
+     * } else {
+     *   return false;
+     * }
+     * </code></pre>
+     * except that the action is performed atomically.
+     *
+     * @param key Key whose mapping is to be removed from the cache.
+     * @param oldVal Value expected to be associated with the specified key.
+     * @return <tt>false</tt> if there was no matching key.
+     */
+    public boolean remove(K key, V oldVal) throws ClientException;
+
+    /**
+     * Removes entries for the specified keys.
+     * <p>
+     * The order in which the individual entries are removed is undefined.
+     *
+     * @param keys The keys to remove.
+     */
+    public void removeAll(Set<? extends K> keys) throws ClientException;
+
+    /**
+     * Removes all of the mappings from this cache.
+     * <p>
+     * The order that the individual entries are removed is undefined.
+     */
+    public void removeAll() throws ClientException;
+
+    /**
+     * Associates the specified value with the specified key in this cache, returning an existing value if one existed.
+     * <p>
+     * If the cache previously contained a mapping for
+     * the key, the old value is replaced by the specified value.  (A cache
+     * <tt>c</tt> is said to contain a mapping for a key <tt>k</tt> if and only
+     * if {@link #containsKey(Object) c.containsKey(k)} would return
+     * <tt>true</tt>.)
+     * <p>
+     * The previous value is returned, or null if there was no value associated
+     * with the key previously.
+     *
+     * @param key Key with which the specified value is to be associated.
+     * @param val Value to be associated with the specified key.
+     * @return The value associated with the key at the start of the operation or
+     * null if none was associated.
+     */
+    public V getAndPut(K key, V val) throws ClientException;
+
+    /**
+     * Atomically removes the entry for a key only if currently mapped to some value.
+     * <p>
+     * This is equivalent to:
+     * <pre><code>
+     * if (cache.containsKey(key)) {
+     *   V oldValue = cache.get(key);
+     *   cache.remove(key);
+     *   return oldValue;
+     * } else {
+     *   return null;
+     * }
+     * </code></pre>
+     * except that the action is performed atomically.
+     *
+     * @param key Key with which the specified value is associated.
+     * @return The value if one existed or null if no mapping existed for this key.
+     */
+    public V getAndRemove(K key) throws ClientException;
+
+    /**
+     * Atomically replaces the value for a given key if and only if there is a value currently mapped by the key.
+     * <p>
+     * This is equivalent to
+     * <pre><code>
+     * if (cache.containsKey(key)) {
+     *   V oldValue = cache.get(key);
+     *   cache.put(key, value);
+     *   return oldValue;
+     * } else {
+     *   return null;
+     * }
+     * </code></pre>
+     * except that the action is performed atomically.
+     *
+     * @param key Key with which the specified value is associated.
+     * @param val Value to be associated with the specified key.
+     * @return The previous value associated with the specified key, or
+     * <tt>null</tt> if there was no mapping for the key.
+     */
+    public V getAndReplace(K key, V val) throws ClientException;
+
+    /**
+     * Atomically associates the specified key with the given value if it is not already associated with a value.
+     * <p>
+     * This is equivalent to:
+     * <pre><code>
+     * if (!cache.containsKey(key)) {}
+     *   cache.put(key, value);
+     *   return true;
+     * } else {
+     *   return false;
+     * }
+     * </code></pre>
+     * except that the action is performed atomically.
+     *
+     * @param key Key with which the specified value is to be associated.
+     * @param val Value to be associated with the specified key.
+     * @return <tt>true</tt> if a value was set.
+     */
+    public boolean putIfAbsent(K key, V val) throws ClientException;
+
+    /**
+     * Clears the contents of the cache.
+     */
+    public void clear() throws ClientException;
+
+    /**
+     * Returns cache that will operate with binary objects.
+     * <p>
+     * Cache returned by this method will not be forced to deserialize binary objects,
+     * so keys and values will be returned from cache API methods without changes. Therefore,
+     * signature of the cache can contain only following types:
+     * <ul>
+     *     <li><code>org.apache.ignite.binary.BinaryObject</code> for binary classes</li>
+     *     <li>All primitives (byte, int, ...) and there boxed versions (Byte, Integer, ...)</li>
+     *     <li>Arrays of primitives (byte[], int[], ...)</li>
+     *     <li>{@link String} and array of {@link String}s</li>
+     *     <li>{@link UUID} and array of {@link UUID}s</li>
+     *     <li>{@link Date} and array of {@link Date}s</li>
+     *     <li>{@link java.sql.Timestamp} and array of {@link java.sql.Timestamp}s</li>
+     *     <li>Enums and array of enums</li>
+     *     <li>
+     *         Maps, collections and array of objects (but objects inside
+     *         them will still be converted if they are binary)
+     *     </li>
+     * </ul>
+     * <p>
+     * For example, if you use {@link Integer} as a key and {@code Value} class as a value
+     * (which will be stored in binary format), you should acquire following projection
+     * to avoid deserialization:
+     * <pre>
+     * CacheClient<Integer, BinaryObject> prj = cache.withKeepBinary();
+     *
+     * // Value is not deserialized and returned in binary format.
+     * BinaryObject po = prj.get(1);
+     * </pre>
+     * <p>
+     * Note that this method makes sense only if cache is working in binary mode
+     * if default marshaller is used.
+     * If not, this method is no-op and will return current cache.
+     *
+     * @return New cache instance for binary objects.
+     */
+    public <K1, V1> ClientCache<K1, V1> withKeepBinary();
+
+    /**
+     * Queries cache. Supports {@link ScanQuery}, {@link SqlQuery} and {@link SqlFieldsQuery}.
+     *
+     * @param qry Query.
+     * @return Cursor.
+     *
+     */
+    public <R> QueryCursor<R> query(Query<R> qry);
+
+    /**
+     * Convenience method to execute {@link SqlFieldsQuery}.
+     *
+     * @param qry Query.
+     * @return Cursor.
+     */
+    public FieldsQueryCursor<List<?>> query(SqlFieldsQuery qry);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/ClientCacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientCacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/client/ClientCacheConfiguration.java
new file mode 100644
index 0000000..b51dcaa
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/ClientCacheConfiguration.java
@@ -0,0 +1,656 @@
+/*
+ * 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.client;
+
+import java.io.Serializable;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheKeyConfiguration;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.PartitionLossPolicy;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/** Cache configuration. */
+public final class ClientCacheConfiguration implements Serializable {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** @serial Cache name. */
+    private String name;
+
+    /** @serial Atomicity mode. */
+    private CacheAtomicityMode atomicityMode = CacheConfiguration.DFLT_CACHE_ATOMICITY_MODE;
+
+    /** @serial Backups. */
+    private int backups = CacheConfiguration.DFLT_BACKUPS;
+
+    /** @serial Cache mode. */
+    private CacheMode cacheMode = CacheConfiguration.DFLT_CACHE_MODE;
+
+    /** @serial Eager TTL flag. */
+    private boolean eagerTtl = CacheConfiguration.DFLT_EAGER_TTL;
+
+    /** @serial Group name. */
+    private String grpName = null;
+
+    /** @serial Default lock timeout. */
+    private long dfltLockTimeout = CacheConfiguration.DFLT_LOCK_TIMEOUT;
+
+    /** @serial Partition loss policy. */
+    private PartitionLossPolicy partLossPlc = CacheConfiguration.DFLT_PARTITION_LOSS_POLICY;
+
+    /** @serial Read from backup. */
+    private boolean readFromBackup = CacheConfiguration.DFLT_READ_FROM_BACKUP;
+
+    /** @serial Rebalance batch size. */
+    private int rebalanceBatchSize = CacheConfiguration.DFLT_REBALANCE_BATCH_SIZE;
+
+    /** @serial Rebalance batches prefetch count. */
+    private long rebalanceBatchesPrefetchCnt = CacheConfiguration.DFLT_REBALANCE_BATCHES_PREFETCH_COUNT;
+
+    /** @serial Rebalance delay. */
+    private long rebalanceDelay = 0;
+
+    /** @serial Rebalance mode. */
+    private CacheRebalanceMode rebalanceMode = CacheConfiguration.DFLT_REBALANCE_MODE;
+
+    /** @serial Rebalance order. */
+    private int rebalanceOrder = 0;
+
+    /** @serial Rebalance throttle. */
+    private long rebalanceThrottle = CacheConfiguration.DFLT_REBALANCE_THROTTLE;
+
+    /** @serial @serial Rebalance timeout. */
+    private long rebalanceTimeout = CacheConfiguration.DFLT_REBALANCE_TIMEOUT;
+
+    /** @serial Write synchronization mode. */
+    private CacheWriteSynchronizationMode writeSynchronizationMode = CacheWriteSynchronizationMode.PRIMARY_SYNC;
+
+    /** @serial Copy on read. */
+    private boolean cpOnRead = CacheConfiguration.DFLT_COPY_ON_READ;
+
+    /** @serial Data region name. */
+    private String dataRegionName = null;
+
+    /** @serial Statistics enabled. */
+    private boolean statisticsEnabled = false;
+
+    /** @serial Max concurrent async operations. */
+    private int maxConcurrentAsyncOperations = CacheConfiguration.DFLT_MAX_CONCURRENT_ASYNC_OPS;
+
+    /** @serial Max query iterators count. */
+    private int maxQryIteratorsCnt = CacheConfiguration.DFLT_MAX_QUERY_ITERATOR_CNT;
+
+    /** @serial Onheap cache enabled. */
+    private boolean onheapCacheEnabled = false;
+
+    /** @serial Query detail metrics size. */
+    private int qryDetailMetricsSize = CacheConfiguration.DFLT_QRY_DETAIL_METRICS_SIZE;
+
+    /** @serial Query parallelism. */
+    private int qryParallelism = CacheConfiguration.DFLT_QUERY_PARALLELISM;
+
+    /** @serial Sql escape all. */
+    private boolean sqlEscapeAll = false;
+
+    /** @serial Sql index max inline size. */
+    private int sqlIdxMaxInlineSize = CacheConfiguration.DFLT_SQL_INDEX_MAX_INLINE_SIZE;
+
+    /** @serial Sql schema. */
+    private String sqlSchema = null;
+
+    /** @serial Key config. */
+    private CacheKeyConfiguration[] keyCfg = null;
+
+    /** @serial Query entities. */
+    private QueryEntity[] qryEntities = null;
+
+    /**
+     * @return Cache name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name New cache name.
+     */
+    public ClientCacheConfiguration setName(String name) {
+        this.name = name;
+
+        return this;
+    }
+
+    /**
+     * @return Cache atomicity mode.
+     */
+    public CacheAtomicityMode getAtomicityMode() {
+        return atomicityMode;
+    }
+
+    /**
+     * @param atomicityMode New Atomicity mode.
+     */
+    public ClientCacheConfiguration setAtomicityMode(CacheAtomicityMode atomicityMode) {
+        this.atomicityMode = atomicityMode;
+
+        return this;
+    }
+
+    /**
+     * @return Number of backups.
+     */
+    public int getBackups() {
+        return backups;
+    }
+
+    /**
+     * @param backups New number of backups.
+     */
+    public ClientCacheConfiguration setBackups(int backups) {
+        this.backups = backups;
+
+        return this;
+    }
+
+    /**
+     * @return Cache mode.
+     */
+    public CacheMode getCacheMode() {
+        return cacheMode;
+    }
+
+    /**
+     * @param cacheMode New cache mode.
+     */
+    public ClientCacheConfiguration setCacheMode(CacheMode cacheMode) {
+        this.cacheMode = cacheMode;
+
+        return this;
+    }
+
+    /**
+     * Gets flag indicating whether expired cache entries will be eagerly removed from cache.
+     * If there is at least one cache configured with this flag set to {@code true}, Ignite
+     * will create a single thread to clean up expired entries in background. When flag is
+     * set to {@code false}, expired entries will be removed on next entry access.
+     *
+     * @return Flag indicating whether Ignite will eagerly remove expired entries.
+     */
+    public boolean isEagerTtl() {
+        return eagerTtl;
+    }
+
+    /**
+     * @param eagerTtl {@code True} if Ignite should eagerly remove expired cache entries.
+     */
+    public ClientCacheConfiguration setEagerTtl(boolean eagerTtl) {
+        this.eagerTtl = eagerTtl;
+
+        return this;
+    }
+
+    /**
+     * Gets the cache group name.
+     * <p>
+     * Caches with the same group name share single underlying 'physical' cache (partition set),
+     * but are logically isolated. Grouping caches reduces overall overhead, since internal data structures are shared.
+     * </p>
+     */
+    public String getGroupName() {
+        return grpName;
+    }
+
+    /**
+     * @param newVal Group name.
+     */
+    public ClientCacheConfiguration setGroupName(String newVal) {
+        grpName = newVal;
+
+        return this;
+    }
+
+    /**
+     * Gets default lock acquisition timeout. {@code 0} and means that lock acquisition will never timeout.
+     */
+    public long getDefaultLockTimeout() {
+        return dfltLockTimeout;
+    }
+
+    /**
+     * @param dfltLockTimeout Default lock timeout.
+     */
+    public ClientCacheConfiguration setDefaultLockTimeout(long dfltLockTimeout) {
+        this.dfltLockTimeout = dfltLockTimeout;
+
+        return this;
+    }
+
+    /**
+     * Gets partition loss policy. This policy defines how Ignite will react to a situation when all nodes for
+     * some partition leave the cluster.
+     */
+    public PartitionLossPolicy getPartitionLossPolicy() {
+        return partLossPlc;
+    }
+
+    /**
+     * @param newVal Partition loss policy.
+     */
+    public ClientCacheConfiguration setPartitionLossPolicy(PartitionLossPolicy newVal) {
+        partLossPlc = newVal;
+
+        return this;
+    }
+
+    /**
+     * Gets flag indicating whether data can be read from backup.
+     * If {@code false} always get data from primary node (never from backup).
+     */
+    public boolean isReadFromBackup() {
+        return readFromBackup;
+    }
+
+    /**
+     * @param readFromBackup Read from backup.
+     */
+    public ClientCacheConfiguration setReadFromBackup(boolean readFromBackup) {
+        this.readFromBackup = readFromBackup;
+
+        return this;
+    }
+
+    /**
+     * Gets size (in number bytes) to be loaded within a single rebalance message.
+     * Rebalancing algorithm will split total data set on every node into multiple
+     * batches prior to sending data.
+     */
+    public int getRebalanceBatchSize() {
+        return rebalanceBatchSize;
+    }
+
+    /**
+     * @param rebalanceBatchSize Rebalance batch size.
+     */
+    public ClientCacheConfiguration setRebalanceBatchSize(int rebalanceBatchSize) {
+        this.rebalanceBatchSize = rebalanceBatchSize;
+
+        return this;
+    }
+
+    /**
+     * To gain better rebalancing performance supplier node can provide more than one batch at rebalancing start and
+     * provide one new to each next demand request.
+     *
+     * Gets number of batches generated by supply node at rebalancing start.
+     * Minimum is 1.
+     */
+    public long getRebalanceBatchesPrefetchCount() {
+        return rebalanceBatchesPrefetchCnt;
+    }
+
+    /**
+     * @param rebalanceBatchesPrefetchCnt Rebalance batches prefetch count.
+     */
+    public ClientCacheConfiguration setRebalanceBatchesPrefetchCount(long rebalanceBatchesPrefetchCnt) {
+        this.rebalanceBatchesPrefetchCnt = rebalanceBatchesPrefetchCnt;
+
+        return this;
+    }
+
+    /**
+     * Gets delay in milliseconds upon a node joining or leaving topology (or crash) after which rebalancing
+     * should be started automatically. Rebalancing should be delayed if you plan to restart nodes
+     * after they leave topology, or if you plan to start multiple nodes at once or one after another
+     * and don't want to repartition and rebalance until all nodes are started.
+     * <p>
+     * Default value is {@code 0} which means that repartitioning and rebalancing will start
+     * immediately upon node leaving topology. If {@code -1} is returned, then rebalancing
+     * will only be started manually.
+     * </p>
+     */
+    public long getRebalanceDelay() {
+        return rebalanceDelay;
+    }
+
+    /**
+     * @param rebalanceDelay Rebalance delay.
+     */
+    public ClientCacheConfiguration setRebalanceDelay(long rebalanceDelay) {
+        this.rebalanceDelay = rebalanceDelay;
+
+        return this;
+    }
+
+    /**
+     * Gets rebalance mode.
+     */
+    public CacheRebalanceMode getRebalanceMode() {
+        return rebalanceMode;
+    }
+
+    /**
+     * @param rebalanceMode Rebalance mode.
+     */
+    public ClientCacheConfiguration setRebalanceMode(CacheRebalanceMode rebalanceMode) {
+        this.rebalanceMode = rebalanceMode;
+
+        return this;
+    }
+
+    /**
+     * Gets cache rebalance order. Rebalance order can be set to non-zero value for caches with
+     * {@link CacheRebalanceMode#SYNC SYNC} or {@link CacheRebalanceMode#ASYNC ASYNC} rebalance modes only.
+     * <p/>
+     * If cache rebalance order is positive, rebalancing for this cache will be started only when rebalancing for
+     * all caches with smaller rebalance order will be completed.
+     * <p/>
+     * Note that cache with order {@code 0} does not participate in ordering. This means that cache with
+     * rebalance order {@code 0} will never wait for any other caches. All caches with order {@code 0} will
+     * be rebalanced right away concurrently with each other and ordered rebalance processes.
+     * <p/>
+     * If not set, cache order is 0, i.e. rebalancing is not ordered.
+     */
+    public int getRebalanceOrder() {
+        return rebalanceOrder;
+    }
+
+    /**
+     * @param rebalanceOrder Rebalance order.
+     */
+    public ClientCacheConfiguration setRebalanceOrder(int rebalanceOrder) {
+        this.rebalanceOrder = rebalanceOrder;
+
+        return this;
+    }
+
+    /**
+     * Time in milliseconds to wait between rebalance messages to avoid overloading of CPU or network.
+     * When rebalancing large data sets, the CPU or network can get over-consumed with rebalancing messages,
+     * which consecutively may slow down the application performance. This parameter helps tune
+     * the amount of time to wait between rebalance messages to make sure that rebalancing process
+     * does not have any negative performance impact. Note that application will continue to work
+     * properly while rebalancing is still in progress.
+     * <p>
+     * Default value of {@code 0} means that throttling is disabled.
+     * </p>
+     */
+    public long getRebalanceThrottle() {
+        return rebalanceThrottle;
+    }
+
+    /**
+     * @param newVal Rebalance throttle.
+     */
+    public ClientCacheConfiguration setRebalanceThrottle(long newVal) {
+        rebalanceThrottle = newVal;
+
+        return this;
+    }
+
+    /**
+     * Gets rebalance timeout (ms).
+     */
+    public long getRebalanceTimeout() {
+        return rebalanceTimeout;
+    }
+
+    /**
+     * @param newVal Rebalance timeout.
+     */
+    public ClientCacheConfiguration setRebalanceTimeout(long newVal) {
+        rebalanceTimeout = newVal;
+
+        return this;
+    }
+
+    /**
+     * Gets write synchronization mode. This mode controls whether the main caller should wait for update on other
+     * nodes to complete or not.
+     */
+    public CacheWriteSynchronizationMode getWriteSynchronizationMode() {
+        return writeSynchronizationMode;
+    }
+
+    /**
+     * @param newVal Write synchronization mode.
+     */
+    public ClientCacheConfiguration setWriteSynchronizationMode(CacheWriteSynchronizationMode newVal) {
+        writeSynchronizationMode = newVal;
+
+        return this;
+    }
+
+
+    /**
+     * @return Copy on read.
+     */
+    public boolean isCopyOnRead() {
+        return cpOnRead;
+    }
+
+    /**
+     * @param newVal Copy on read.
+     */
+    public ClientCacheConfiguration setCopyOnRead(boolean newVal) {
+        cpOnRead = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Max concurrent async operations.
+     */
+    public int getMaxConcurrentAsyncOperations() {
+        return maxConcurrentAsyncOperations;
+    }
+
+    /**
+     * @param newVal Max concurrent async operations.
+     */
+    public ClientCacheConfiguration setMaxConcurrentAsyncOperations(int newVal) {
+        maxConcurrentAsyncOperations = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Data region name.
+     */
+    public String getDataRegionName() {
+        return dataRegionName;
+    }
+
+    /**
+     * @param newVal Data region name.
+     */
+    public ClientCacheConfiguration setDataRegionName(String newVal) {
+        dataRegionName = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Statistics enabled.
+     */
+    public boolean isStatisticsEnabled() {
+        return statisticsEnabled;
+    }
+
+    /**
+     * @param newVal Statistics enabled.
+     */
+    public ClientCacheConfiguration setStatisticsEnabled(boolean newVal) {
+        statisticsEnabled = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Max query iterators count.
+     */
+    public int getMaxQueryIteratorsCount() {
+        return maxQryIteratorsCnt;
+    }
+
+    /**
+     * @param newVal Max query iterators count.
+     */
+    public ClientCacheConfiguration setMaxQueryIteratorsCount(int newVal) {
+        maxQryIteratorsCnt = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Onheap cache enabled.
+     */
+    public boolean isOnheapCacheEnabled() {
+        return onheapCacheEnabled;
+    }
+
+    /**
+     * @param newVal Onheap cache enabled.
+     */
+    public ClientCacheConfiguration setOnheapCacheEnabled(boolean newVal) {
+        onheapCacheEnabled = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Query detail metrics size.
+     */
+    public int getQueryDetailMetricsSize() {
+        return qryDetailMetricsSize;
+    }
+
+    /**
+     * @param newVal Query detail metrics size.
+     */
+    public ClientCacheConfiguration setQueryDetailMetricsSize(int newVal) {
+        qryDetailMetricsSize = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Query parallelism.
+     */
+    public int getQueryParallelism() {
+        return qryParallelism;
+    }
+
+    /**
+     * @param newVal Query parallelism.
+     */
+    public ClientCacheConfiguration setQueryParallelism(int newVal) {
+        qryParallelism = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Sql escape all.
+     */
+    public boolean isSqlEscapeAll() {
+        return sqlEscapeAll;
+    }
+
+    /**
+     * @param newVal Sql escape all.
+     */
+    public ClientCacheConfiguration setSqlEscapeAll(boolean newVal) {
+        sqlEscapeAll = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Sql index max inline size.
+     */
+    public int getSqlIndexMaxInlineSize() {
+        return sqlIdxMaxInlineSize;
+    }
+
+    /**
+     * @param newVal Sql index max inline size.
+     */
+    public ClientCacheConfiguration setSqlIndexMaxInlineSize(int newVal) {
+        sqlIdxMaxInlineSize = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Sql schema.
+     */
+    public String getSqlSchema() {
+        return sqlSchema;
+    }
+
+    /**
+     * @param newVal Sql schema.
+     */
+    public ClientCacheConfiguration setSqlSchema(String newVal) {
+        sqlSchema = newVal;
+
+        return this;
+    }
+
+
+    /**
+     * @return Cache key configuration.
+     */
+    public CacheKeyConfiguration[] getKeyConfiguration() {
+        return keyCfg;
+    }
+
+    /**
+     * @param newVal Cache key configuration.
+     */
+    public ClientCacheConfiguration setKeyConfiguration(CacheKeyConfiguration... newVal) {
+        this.keyCfg = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Query entities configurations.
+     */
+    public QueryEntity[] getQueryEntities() {
+        return qryEntities;
+    }
+
+    /**
+     * @param newVal Query entities configurations.
+     */
+    public ClientCacheConfiguration setQueryEntities(QueryEntity... newVal) {
+        qryEntities = newVal;
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(ClientCacheConfiguration.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/ClientConfigurationException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientConfigurationException.java b/modules/core/src/main/java/org/apache/ignite/client/ClientConfigurationException.java
new file mode 100644
index 0000000..aac37eb
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/ClientConfigurationException.java
@@ -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.
+ */
+
+package org.apache.ignite.client;
+
+/**
+ * Indicates Ignite client configuration error.
+ */
+public class ClientConfigurationException extends ClientException {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /**
+     * Default constructor.
+     */
+    public ClientConfigurationException() {
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     *
+     * @param msg the detail message.
+     */
+    public ClientConfigurationException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt>.
+     *
+     * @param cause the cause.
+     */
+    public ClientConfigurationException(Throwable cause) {
+        super(cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/ClientConnectionException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientConnectionException.java b/modules/core/src/main/java/org/apache/ignite/client/ClientConnectionException.java
new file mode 100644
index 0000000..1ec096c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/ClientConnectionException.java
@@ -0,0 +1,45 @@
+/*
+ * 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.client;
+
+/**
+ * Indicates all the Ignite servers specified in the client configuration are no longer available.
+ */
+public class ClientConnectionException extends ClientException {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** Message. */
+    private static final String MSG = "Ignite cluster is unavailable";
+
+    /**
+     * Default constructor.
+     */
+    public ClientConnectionException() {
+        super(MSG);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause.
+     *
+     * @param cause the cause.
+     */
+    public ClientConnectionException(Throwable cause) {
+        super(MSG, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/ClientException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientException.java b/modules/core/src/main/java/org/apache/ignite/client/ClientException.java
new file mode 100644
index 0000000..0555635
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/ClientException.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.client;
+
+/**
+ * Common thin client checked exception.
+ */
+public class ClientException extends Exception {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /**
+     * Constructs a new exception with {@code null} as its detail message.
+     */
+    public ClientException() {
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     *
+     * @param msg the detail message.
+     */
+    public ClientException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt>.
+     *
+     * @param cause the cause.
+     */
+    public ClientException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and cause.
+     *
+     * @param msg the detail message.
+     * @param cause the cause.
+     */
+    public ClientException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message,
+     * cause, suppression enabled or disabled, and writable stack
+     * trace enabled or disabled.
+     *
+     * @param msg the detail message.
+     * @param cause the cause.
+     * @param enableSuppression whether or not suppression is enabled
+     *                          or disabled
+     * @param writableStackTrace whether or not the stack trace should
+     *                           be writable
+     */
+    public ClientException(String msg, Throwable cause,  boolean enableSuppression, boolean writableStackTrace) {
+        super(msg, cause, enableSuppression, writableStackTrace);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/IgniteClient.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/IgniteClient.java b/modules/core/src/main/java/org/apache/ignite/client/IgniteClient.java
new file mode 100644
index 0000000..85ceeb4
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/IgniteClient.java
@@ -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.
+ */
+
+package org.apache.ignite.client;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.ignite.IgniteBinary;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+
+/**
+ * Ignite thin client.
+ * <p>
+ * Unlike Ignite client nodes, thin clients do not start Ignite infrastructure and communicate with Ignite cluster
+ * over a fast and lightweight protocol.
+ * </p>
+ */
+public interface IgniteClient extends AutoCloseable {
+    /**
+     * Get existing cache or create the cache if it does not exist.
+     *
+     * @param name Cache name.
+     */
+    public <K, V> ClientCache<K, V> getOrCreateCache(String name) throws ClientException;
+
+    /**
+     * Get existing cache or create the cache if it does not exist.
+     *
+     * @param cfg Cache configuration.
+     */
+    public <K, V> ClientCache<K, V> getOrCreateCache(ClientCacheConfiguration cfg) throws ClientException;
+
+    /**
+     * Get existing cache.
+     *
+     * @param name Cache name.
+     */
+    public <K, V> ClientCache<K, V> cache(String name);
+
+    /**
+     * @return Collection of names of currently available caches or an empty collection if no caches are available.
+     */
+    public Collection<String> cacheNames() throws ClientException;
+
+    /**
+     * Destroy cache.
+     */
+    public void destroyCache(String name) throws ClientException;
+
+    /**
+     * Create cache.
+     *
+     * @param name Cache name.
+     */
+    public <K, V> ClientCache<K, V> createCache(String name) throws ClientException;
+
+    /**
+     * Create cache.
+     *
+     * @param cfg Cache configuration.
+     */
+    public <K, V> ClientCache<K, V> createCache(ClientCacheConfiguration cfg) throws ClientException;
+
+    /**
+     * @return Instance of {@link IgniteBinary} interface.
+     */
+    public IgniteBinary binary();
+
+    /**
+     * Execute SQL query and get cursor to iterate over results.
+     *
+     * @param qry SQL query.
+     * @return Cursor.
+     */
+    public FieldsQueryCursor<List<?>> query(SqlFieldsQuery qry);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/SslMode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/SslMode.java b/modules/core/src/main/java/org/apache/ignite/client/SslMode.java
new file mode 100644
index 0000000..837f289
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/SslMode.java
@@ -0,0 +1,26 @@
+/*
+ * 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.client;
+
+/**
+ * SSL/TLS modes.
+ */
+public enum SslMode {
+    /** Disabled. */DISABLED,
+    /** Required. */REQUIRED
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/client/SslProtocol.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/client/SslProtocol.java b/modules/core/src/main/java/org/apache/ignite/client/SslProtocol.java
new file mode 100644
index 0000000..06dfac9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/client/SslProtocol.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.client;
+
+/**
+ * SSL Protocol.
+ */
+public enum SslProtocol {
+    /** Supports some version of TLS; may support other versions. */TLS,
+    /** Supports RFC 2246: TLS version 1.0 ; may support other versions. */TLSv1,
+    /** Supports RFC 4346: TLS version 1.1 ; may support other versions. */TLSv1_1,
+    /** Supports RFC 5246: TLS version 1.2 ; may support other versions. */TLSv1_2
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java
index 54bfc40..eabfe6a 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.configuration;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import org.apache.ignite.binary.BinaryIdMapper;
@@ -29,7 +30,10 @@ import org.apache.ignite.internal.util.typedef.internal.S;
  * Configuration object for Ignite Binary Objects.
  * @see org.apache.ignite.IgniteBinary
  */
-public class BinaryConfiguration {
+public class BinaryConfiguration implements Serializable {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
     /** Default compact footer flag setting. */
     public static final boolean DFLT_COMPACT_FOOTER = true;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/configuration/ClientConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/ClientConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/ClientConfiguration.java
new file mode 100644
index 0000000..426b686
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/ClientConfiguration.java
@@ -0,0 +1,400 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.configuration;
+
+import java.io.Serializable;
+import javax.cache.configuration.Factory;
+import javax.net.ssl.SSLContext;
+import org.apache.ignite.client.SslMode;
+import org.apache.ignite.client.SslProtocol;
+import org.apache.ignite.internal.client.thin.TcpIgniteClient;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * {@link TcpIgniteClient} configuration.
+ */
+public final class ClientConfiguration implements Serializable {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** @serial Server addresses. */
+    private String[] addrs = null;
+
+    /** @serial Tcp no delay. */
+    private boolean tcpNoDelay = true;
+
+    /** @serial Timeout. 0 means infinite. */
+    private int timeout = 0;
+
+    /** @serial Send buffer size. 0 means system default. */
+    private int sndBufSize = 32 * 1024;
+
+    /** @serial Receive buffer size. 0 means system default. */
+    private int rcvBufSize = 32 * 1024;
+
+    /** @serial Configuration for Ignite binary objects. */
+    private BinaryConfiguration binaryCfg;
+
+    /** @serial Ssl mode. */
+    private SslMode sslMode = SslMode.DISABLED;
+
+    /** @serial Ssl client certificate key store path. */
+    private String sslClientCertKeyStorePath;
+
+    /** @serial Ssl client certificate key store password. */
+    private String sslClientCertKeyStorePwd;
+
+    /** @serial Ssl trust certificate key store path. */
+    private String sslTrustCertKeyStorePath;
+
+    /** @serial Ssl trust certificate key store password. */
+    private String sslTrustCertKeyStorePwd;
+
+    /** @serial Ssl client certificate key store type. */
+    private String sslClientCertKeyStoreType;
+
+    /** @serial Ssl trust certificate key store type. */
+    private String sslTrustCertKeyStoreType;
+
+    /** @serial Ssl key algorithm. */
+    private String sslKeyAlgorithm;
+
+    /** @serial Flag indicating if certificate validation errors should be ignored. */
+    private boolean sslTrustAll;
+
+    /** @serial Ssl protocol. */
+    private SslProtocol sslProto = SslProtocol.TLS;
+
+    /** @serial Ssl context factory. */
+    private Factory<SSLContext> sslCtxFactory;
+
+    /** @serial User name. */
+    private String userName;
+
+    /** @serial User password. */
+    private String userPwd;
+
+    /**
+     * @return Host addresses.
+     */
+    public String[] getAddresses() {
+        return addrs;
+    }
+
+    /**
+     * @param addrs Host addresses.
+     */
+    public ClientConfiguration setAddresses(String... addrs) {
+        this.addrs = addrs;
+
+        return this;
+    }
+
+    /**
+     * @return Whether Nagle's algorithm is enabled.
+     */
+    public boolean isTcpNoDelay() {
+        return tcpNoDelay;
+    }
+
+    /**
+     * @param tcpNoDelay whether Nagle's algorithm is enabled.
+     */
+    public ClientConfiguration setTcpNoDelay(boolean tcpNoDelay) {
+        this.tcpNoDelay = tcpNoDelay;
+
+        return this;
+    }
+
+    /**
+     * @return Send/receive timeout in milliseconds.
+     */
+    public int getTimeout() {
+        return timeout;
+    }
+
+    /**
+     * @param timeout Send/receive timeout in milliseconds.
+     */
+    public ClientConfiguration setTimeout(int timeout) {
+        this.timeout = timeout;
+
+        return this;
+    }
+
+    /**
+     * @return Send buffer size.
+     */
+    public int getSendBufferSize() {
+        return sndBufSize;
+    }
+
+    /**
+     * @param sndBufSize Send buffer size.
+     */
+    public ClientConfiguration setSendBufferSize(int sndBufSize) {
+        this.sndBufSize = sndBufSize;
+
+        return this;
+    }
+
+    /**
+     * @return Send buffer size.
+     */
+    public int getReceiveBufferSize() {
+        return rcvBufSize;
+    }
+
+    /**
+     * @param rcvBufSize Send buffer size.
+     */
+    public ClientConfiguration setReceiveBufferSize(int rcvBufSize) {
+        this.rcvBufSize = rcvBufSize;
+
+        return this;
+    }
+
+    /**
+     * @return Configuration for Ignite Binary objects.
+     */
+    public BinaryConfiguration getBinaryConfiguration() {
+        return binaryCfg;
+    }
+
+    /**
+     * @param binaryCfg Configuration for Ignite Binary objects.
+     */
+    public ClientConfiguration setBinaryConfiguration(BinaryConfiguration binaryCfg) {
+        this.binaryCfg = binaryCfg;
+
+        return this;
+    }
+
+    /**
+     * @return SSL mode.
+     */
+    public SslMode getSslMode() {
+        return sslMode;
+    }
+
+    /**
+     * @param sslMode SSL mode.
+     */
+    public ClientConfiguration setSslMode(SslMode sslMode) {
+        this.sslMode = sslMode;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl client certificate key store path.
+     */
+    public String getSslClientCertificateKeyStorePath() {
+        return sslClientCertKeyStorePath;
+    }
+
+    /**
+     * @param newVal Ssl client certificate key store path.
+     */
+    public ClientConfiguration setSslClientCertificateKeyStorePath(String newVal) {
+        sslClientCertKeyStorePath = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl client certificate key store password.
+     */
+    public String getSslClientCertificateKeyStorePassword() {
+        return sslClientCertKeyStorePwd;
+    }
+
+    /**
+     * @param newVal Ssl client certificate key store password.
+     */
+    public ClientConfiguration setSslClientCertificateKeyStorePassword(String newVal) {
+        sslClientCertKeyStorePwd = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl client certificate key store type.
+     */
+    public String getSslClientCertificateKeyStoreType() {
+        return sslClientCertKeyStoreType;
+    }
+
+    /**
+     * @param newVal Ssl client certificate key store type.
+     */
+    public ClientConfiguration setSslClientCertificateKeyStoreType(String newVal) {
+        sslClientCertKeyStoreType = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl trust certificate key store path.
+     */
+    public String getSslTrustCertificateKeyStorePath() {
+        return sslTrustCertKeyStorePath;
+    }
+
+    /**
+     * @param newVal Ssl trust certificate key store path.
+     */
+    public ClientConfiguration setSslTrustCertificateKeyStorePath(String newVal) {
+        sslTrustCertKeyStorePath = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl trust certificate key store password.
+     */
+    public String getSslTrustCertificateKeyStorePassword() {
+        return sslTrustCertKeyStorePwd;
+    }
+
+    /**
+     * @param newVal Ssl trust certificate key store password.
+     */
+    public ClientConfiguration setSslTrustCertificateKeyStorePassword(String newVal) {
+        sslTrustCertKeyStorePwd = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl trust certificate key store type.
+     */
+    public String getSslTrustCertificateKeyStoreType() {
+        return sslTrustCertKeyStoreType;
+    }
+
+    /**
+     * @param newVal Ssl trust certificate key store type.
+     */
+    public ClientConfiguration setSslTrustCertificateKeyStoreType(String newVal) {
+        sslTrustCertKeyStoreType = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl key algorithm.
+     */
+    public String getSslKeyAlgorithm() {
+        return sslKeyAlgorithm;
+    }
+
+    /**
+     * @param newVal Ssl key algorithm.
+     */
+    public ClientConfiguration setSslKeyAlgorithm(String newVal) {
+        sslKeyAlgorithm = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Flag indicating if certificate validation errors should be ignored.
+     */
+    public boolean isSslTrustAll() {
+        return sslTrustAll;
+    }
+
+    /**
+     * @param newVal Flag indicating if certificate validation errors should be ignored.
+     */
+    public ClientConfiguration setSslTrustAll(boolean newVal) {
+        sslTrustAll = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return Ssl protocol.
+     */
+    public SslProtocol getSslProtocol() {
+        return sslProto;
+    }
+
+    /**
+     * @param newVal Ssl protocol.
+     */
+    public ClientConfiguration setSslProtocol(SslProtocol newVal) {
+        sslProto = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return User name.
+     */
+    public String getUserName() {
+        return userName;
+    }
+
+    /**
+     * @param newVal User name.
+     */
+    public ClientConfiguration setUserName(String newVal) {
+        userName = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return User password.
+     */
+    public String getUserPassword() {
+        return userPwd;
+    }
+
+    /**
+     * @param newVal User password.
+     */
+    public ClientConfiguration setUserPassword(String newVal) {
+        userPwd = newVal;
+
+        return this;
+    }
+
+    /**
+     * @return SSL Context Factory.
+     */
+    public Factory<SSLContext> getSslContextFactory() {
+        return sslCtxFactory;
+    }
+
+    /**
+     * @param newVal SSL Context Factory.
+     */
+    public ClientConfiguration setSslContextFactory(Factory<SSLContext> newVal) {
+        this.sslCtxFactory = newVal;
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(ClientConfiguration.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
index 26dc4c4..535249c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
@@ -17,11 +17,11 @@
 
 package org.apache.ignite.internal.binary;
 
+import java.util.Collection;
+import java.util.HashMap;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryType;
 
-import java.util.HashMap;
-
 /**
  * Simple caching metadata handler. Used mainly in tests.
  */
@@ -78,6 +78,11 @@ public class BinaryCachingMetadataHandler implements BinaryMetadataHandler {
     /** {@inheritDoc} */
     @Override public synchronized BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
         BinaryTypeImpl type = (BinaryTypeImpl) metas.get(typeId);
-        return type.metadata().hasSchema(schemaId) ? type : null;
+        return type != null && type.metadata().hasSchema(schemaId) ? type : null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<BinaryType> metadata() throws BinaryObjectException {
+        return metas.values();
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index bac5d40..106d238 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -517,6 +517,18 @@ public class BinaryClassDescriptor {
     }
 
     /**
+     * Register current stable schema if applicable.
+     */
+    public void registerStableSchema() {
+        if (schemaReg != null && stableSchema != null) {
+            int schemaId = stableSchema.schemaId();
+
+            if (schemaReg.schema(schemaId) == null)
+                schemaReg.addSchema(stableSchema.schemaId(), stableSchema);
+        }
+    }
+
+    /**
      * @return binaryReadResolve() method
      */
     @SuppressWarnings("UnusedDeclaration")

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
index 8f85947..2337696 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
@@ -1164,6 +1164,16 @@ public class BinaryContext {
     }
 
     /**
+     * Register user types schemas.
+     */
+    public void registerUserTypesSchema() {
+        for (BinaryClassDescriptor desc : predefinedTypes.values()) {
+            if (desc.userType())
+                desc.registerStableSchema();
+        }
+    }
+
+    /**
      * Register "type ID to class name" mapping on all nodes to allow for mapping requests resolution form client.
      * Other {@link BinaryContext}'s "register" methods and method
      * {@link BinaryContext#descriptorForClass(Class, boolean)} already call this functionality so use this method
@@ -1257,6 +1267,13 @@ public class BinaryContext {
     }
 
     /**
+     * @return All metadata known to this node.
+     */
+    public Collection<BinaryType> metadata() throws BinaryObjectException {
+        return metaHnd != null ? metaHnd.metadata() : Collections.emptyList();
+    }
+
+    /**
      * @param typeId Type ID.
      * @param schemaId Schema ID.
      * @return Meta data.

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
index e565338..5df32e7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.binary;
 
+import java.util.Collection;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryType;
 
@@ -60,4 +61,11 @@ public interface BinaryMetadataHandler {
      * @throws BinaryObjectException In case of error.
      */
     public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException;
+
+    /**
+     * Gets all metadata known to the node.
+     * @return Metadata collection
+     * @throws BinaryObjectException If failed.
+     */
+    public Collection<BinaryType> metadata() throws BinaryObjectException;
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
index 39c942a..bbd9311 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.binary;
 
+import java.util.Collection;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryType;
 
@@ -60,4 +61,9 @@ public class BinaryNoopMetadataHandler implements BinaryMetadataHandler {
     @Override public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
         return null;
     }
+
+    /** {@inheritDoc} */
+    @Override public Collection<BinaryType> metadata() throws BinaryObjectException {
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ed03b931/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientBinary.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientBinary.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientBinary.java
new file mode 100644
index 0000000..8525f5e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientBinary.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.thin;
+
+import java.util.Collection;
+import java.util.Map;
+import org.apache.ignite.IgniteBinary;
+import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.binary.BinaryObjectBuilder;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryType;
+import org.apache.ignite.internal.binary.BinaryContext;
+import org.apache.ignite.internal.binary.BinaryEnumObjectImpl;
+import org.apache.ignite.internal.binary.BinaryMetadata;
+import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl;
+import org.apache.ignite.internal.binary.streams.BinaryHeapInputStream;
+
+/**
+ * Thin client implementation of {@link IgniteBinary}.
+ */
+class ClientBinary implements IgniteBinary {
+    /** Marshaller. */
+    private final ClientBinaryMarshaller marsh;
+
+    /**
+     * Constructor.
+     */
+    ClientBinary(ClientBinaryMarshaller marsh) {
+        this.marsh = marsh;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int typeId(String typeName) {
+        return marsh.context().typeId(typeName);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public <T> T toBinary(Object obj) {
+        if (obj == null)
+            return null;
+
+        if (obj instanceof IgniteBinary)
+            return (T)obj;
+
+        byte[] objBytes = marsh.marshal(obj);
+
+        return (T)marsh.unmarshal(new BinaryHeapInputStream(objBytes));
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryObjectBuilder builder(String typeName) {
+        if (typeName == null || typeName.length() == 0)
+            throw new IllegalArgumentException("typeName");
+
+        return new BinaryObjectBuilderImpl(marsh.context(), typeName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryObjectBuilder builder(BinaryObject binaryObj) {
+        if (binaryObj == null)
+            throw new NullPointerException("binaryObj");
+
+        return BinaryObjectBuilderImpl.wrap(binaryObj);
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryType type(Class<?> cls) throws BinaryObjectException {
+        if (cls == null)
+            throw new NullPointerException("cls");
+
+        return type(cls.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryType type(String typeName) {
+        if (typeName == null || typeName.length() == 0)
+            throw new IllegalArgumentException("typeName");
+
+        int typeId = marsh.context().typeId(typeName);
+
+        return type(typeId);
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryType type(int typeId) {
+        return marsh.context().metadata(typeId);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<BinaryType> types() {
+        return marsh.context().metadata();
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, int ord) {
+        if (typeName == null || typeName.length() == 0)
+            throw new IllegalArgumentException("typeName");
+
+        BinaryContext ctx = marsh.context();
+
+        int typeId = ctx.typeId(typeName);
+
+        return new BinaryEnumObjectImpl(ctx, typeId, null, ord);
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, String name) {
+        if (typeName == null || typeName.length() == 0)
+            throw new IllegalArgumentException("typeName");
+
+        if (name == null || name.length() == 0)
+            throw new IllegalArgumentException("name");
+
+        BinaryContext ctx = marsh.context();
+
+        int typeId = ctx.typeId(typeName);
+
+        BinaryMetadata metadata = ctx.metadata0(typeId);
+
+        if (metadata == null)
+            throw new BinaryObjectException(
+                String.format("Failed to get metadata for type [typeId=%s, typeName='%s']", typeId, typeName)
+            );
+
+        Integer ordinal = metadata.getEnumOrdinalByName(name);
+
+        if (ordinal == null)
+            throw new BinaryObjectException(String.format(
+                "Failed to resolve enum ordinal by name [typeId=%s, typeName='%s', name='%s']",
+                typeId,
+                typeName,
+                name
+            ));
+
+        return new BinaryEnumObjectImpl(ctx, typeId, null, ordinal);
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryType registerEnum(String typeName, Map<String, Integer> vals) {
+        if (typeName == null || typeName.length() == 0)
+            throw new IllegalArgumentException("typeName");
+
+        BinaryContext ctx = marsh.context();
+
+        int typeId = ctx.typeId(typeName);
+
+        ctx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, null, null, null, true, vals));
+
+        return ctx.metadata(typeId);
+    }
+}


Mime
View raw message