ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [06/31] incubator-ignite git commit: #ignite-128: WIP.
Date Tue, 03 Feb 2015 14:18:33 GMT
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java
new file mode 100644
index 0000000..4970610
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterClientImpl.java
@@ -0,0 +1,200 @@
+/*
+ * 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.router.impl;
+
+import org.apache.ignite.client.impl.*;
+import org.apache.ignite.client.impl.connection.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.client.router.*;
+import org.jdk8.backport.*;
+import org.jetbrains.annotations.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import static org.apache.ignite.internal.client.util.GridClientUtils.*;
+
+/**
+ * A {@link GridClient} router implementation.
+ */
+class GridRouterClientImpl implements GridClient {
+    /** Decorated client implementation. */
+    private final GridClientImpl clientImpl;
+
+    /** Client configuration. */
+    private final GridClientConfiguration cliCfg;
+
+    /** TCP connection managers. */
+    private final ConcurrentMap<Byte, GridClientConnectionManager> connMgrMap = new ConcurrentHashMap8<>();
+
+    /**
+     * Creates a new TCP client based on the given configuration.
+     *
+     * @param id Client identifier.
+     * @param routerCfg Router configuration.
+     * @throws GridClientException If client configuration is incorrect.
+     * @throws GridServerUnreachableException If none of the servers
+     *     specified in configuration can be reached.
+     */
+    GridRouterClientImpl(UUID id, GridTcpRouterConfiguration routerCfg) throws GridClientException {
+        GridClientConfiguration cliCfg = new GridClientConfiguration();
+
+        cliCfg.setServers(routerCfg.getServers());
+        cliCfg.setSslContextFactory(routerCfg.getSslContextFactory());
+        cliCfg.setSecurityCredentialsProvider(routerCfg.getSecurityCredentialsProvider());
+
+        this.cliCfg = cliCfg;
+
+        clientImpl = new GridClientImpl(id, cliCfg);
+
+        if (cliCfg.getProtocol() != GridClientProtocol.TCP)
+            throw new AssertionError("Unknown protocol: " + cliCfg.getProtocol());
+    }
+
+    /**
+     * Send a raw packet "as is" directly to the given node.
+     * The exact types of acceptable arguments and return values depends on underlying connections.
+     *
+     * @param msg Raw message to send.
+     * @param destId Id of node to send message to. If {@code null} than node will be chosen
+     *     from the topology randomly.
+     * @return Future, representing forwarded message.
+     * @throws GridServerUnreachableException If destination node can't be reached.
+     * @throws GridClientClosedException If client is closed.
+     * @throws GridClientException If any other client-related error occurs.
+     * @throws InterruptedException If router was interrupted while trying.
+     *     to establish connection with destination node.
+     */
+    GridClientFutureAdapter<?> forwardMessage(Object msg, @Nullable UUID destId, byte marshId)
+        throws GridClientException, InterruptedException {
+        GridClientTopology top = clientImpl.topology();
+
+        GridClientNode dest = destId != null ?
+            top.node(destId) : cliCfg.getBalancer().balancedNode(
+                applyFilter(top.nodes(), new GridClientPredicate<GridClientNodeImpl>() {
+                    @Override public boolean apply(GridClientNodeImpl e) {
+                        return restAvailable(e, cliCfg.getProtocol());
+                    }
+                }));
+
+        if (dest == null)
+            throw new GridServerUnreachableException("Failed to resolve node for specified destination ID: " + destId);
+
+        GridClientConnectionManager connMgr = connectionManager(marshId);
+
+        GridClientConnection conn = null;
+
+        // No reconnection handling there. Let client to do it if needed.
+        GridClientException cause;
+
+        try {
+            conn = connMgr.connection(dest);
+
+            return conn.forwardMessage(msg);
+        }
+        catch (GridClientConnectionResetException e) {
+            if (destId != null)
+                connMgr.terminateConnection(conn, top.node(destId), e);
+            else
+                connMgr.terminateConnection(conn, null, e);
+
+            cause = e;
+        }
+        catch (GridClientException e) {
+            cause = e;
+        }
+
+        GridClientFutureAdapter<Object> fail = new GridClientFutureAdapter<>();
+
+        fail.onDone(cause);
+
+        return fail;
+    }
+
+    /**
+     * @param marshId Marshaller ID.
+     * @return Connection manager.
+     * @throws GridClientException In case of error.
+     */
+    private GridClientConnectionManager connectionManager(byte marshId) throws GridClientException {
+        GridClientConnectionManager mgr = connMgrMap.get(marshId);
+
+        if (mgr == null) {
+            GridClientConnectionManager old = connMgrMap.putIfAbsent(marshId, mgr =
+                clientImpl.newConnectionManager(marshId));
+
+            if (old != null)
+                mgr = old;
+        }
+
+        return mgr;
+    }
+
+    /**
+     * Closes client.
+     * @param wait If {@code true} will wait for all pending requests to be proceeded.
+     */
+    public void stop(boolean wait) {
+        clientImpl.stop(wait);
+    }
+
+    /** {@inheritDoc} */
+    @Override public UUID id() {
+        return clientImpl.id();
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridClientData data() throws GridClientException {
+        return clientImpl.data();
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridClientData data(String cacheName) throws GridClientException {
+        return clientImpl.data(cacheName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridClientCompute compute() {
+        return clientImpl.compute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void addTopologyListener(GridClientTopologyListener lsnr) {
+        clientImpl.addTopologyListener(lsnr);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void removeTopologyListener(GridClientTopologyListener lsnr) {
+        clientImpl.removeTopologyListener(lsnr);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<GridClientTopologyListener> topologyListeners() {
+        return clientImpl.topologyListeners();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean connected() {
+        return clientImpl.connected();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void close() {
+        clientImpl.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterCommandLineStartup.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterCommandLineStartup.java b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterCommandLineStartup.java
new file mode 100644
index 0000000..c6b4cad
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridRouterCommandLineStartup.java
@@ -0,0 +1,164 @@
+/*
+ * 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.router.impl;
+
+import org.apache.ignite.*;
+import org.apache.ignite.internal.client.router.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.lifecycle.*;
+import org.apache.ignite.internal.processors.spring.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+
+import java.net.*;
+import java.util.*;
+import java.util.logging.*;
+
+import static org.apache.ignite.internal.IgniteComponentType.*;
+import static org.apache.ignite.internal.GridProductImpl.*;
+
+/**
+ * Loader class for router.
+ */
+public class GridRouterCommandLineStartup {
+    /** Logger. */
+    @SuppressWarnings("FieldCanBeLocal")
+    private IgniteLogger log;
+
+    /** TCP router. */
+    private LifecycleAware tcpRouter;
+
+    /**
+     * Search given context for required configuration and starts router.
+     *
+     * @param beans Beans loaded from spring configuration file.
+     */
+    public void start(Map<Class<?>, Object> beans) {
+        log = (IgniteLogger)beans.get(IgniteLogger.class);
+
+        if (log == null) {
+            U.error(log, "Failed to find logger definition in application context. Stopping the router.");
+
+            return;
+        }
+
+        GridTcpRouterConfiguration tcpCfg = (GridTcpRouterConfiguration)beans.get(GridTcpRouterConfiguration.class);
+
+        if (tcpCfg == null)
+            U.warn(log, "TCP router startup skipped (configuration not found).");
+        else {
+            tcpRouter = new GridTcpRouterImpl(tcpCfg);
+
+            if (tcpRouter != null) {
+                try {
+                    tcpRouter.start();
+                }
+                catch (IgniteCheckedException e) {
+                    U.error(log, "Failed to start TCP router on port " + tcpCfg.getPort() + ": " + e.getMessage(), e);
+
+                    tcpRouter = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * Stops router.
+     */
+    public void stop() {
+        if (tcpRouter != null) {
+            try {
+                tcpRouter.stop();
+            }
+            catch (IgniteCheckedException e) {
+                U.error(log, "Error while stopping the router.", e);
+            }
+        }
+    }
+
+    /**
+     * Wrapper method to run router from command-line.
+     *
+     * @param args Command-line arguments.
+     * @throws IgniteCheckedException If failed.
+     */
+    public static void main(String[] args) throws IgniteCheckedException {
+        X.println(
+            "   __________  ________________ ",
+            "  /  _/ ___/ |/ /  _/_  __/ __/ ",
+            " _/ // (_ /    // /  / / / _/   ",
+            "/___/\\___/_/|_/___/ /_/ /___/  ",
+            " ",
+            "Ignite Router Command Line Loader",
+            "ver. " + ACK_VER,
+            COPYRIGHT,
+            " "
+        );
+
+        IgniteSpringProcessor spring = SPRING.create(false);
+
+        if (args.length < 1) {
+            X.error("Missing XML configuration path.");
+
+            System.exit(1);
+        }
+
+        String cfgPath = args[0];
+
+        URL cfgUrl = U.resolveGridGainUrl(cfgPath);
+
+        if (cfgUrl == null) {
+            X.error("Spring XML file not found (is IGNITE_HOME set?): " + cfgPath);
+
+            System.exit(1);
+        }
+
+        boolean isLog4jUsed = U.gridClassLoader().getResource("org/apache/log4j/Appender.class") != null;
+
+        IgniteBiTuple<Object, Object> t = null;
+        Collection<Handler> savedHnds = null;
+
+        if (isLog4jUsed)
+            t = U.addLog4jNoOpLogger();
+        else
+            savedHnds = U.addJavaNoOpLogger();
+
+        Map<Class<?>, Object> beans;
+
+        try {
+            beans = spring.loadBeans(cfgUrl, IgniteLogger.class, GridTcpRouterConfiguration.class);
+        }
+        finally {
+            if (isLog4jUsed && t != null)
+                U.removeLog4jNoOpLogger(t);
+
+            if (!isLog4jUsed)
+                U.removeJavaNoOpLogger(savedHnds);
+        }
+
+        final GridRouterCommandLineStartup routerStartup = new GridRouterCommandLineStartup();
+
+        routerStartup.start(beans);
+
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override public void run() {
+                routerStartup.stop();
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterImpl.java
new file mode 100644
index 0000000..a5ebc2c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterImpl.java
@@ -0,0 +1,348 @@
+/*
+ * 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.router.impl;
+
+import org.apache.ignite.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.client.router.*;
+import org.apache.ignite.internal.client.ssl.*;
+import org.apache.ignite.lifecycle.*;
+import org.apache.ignite.logger.java.*;
+import org.apache.ignite.internal.processors.rest.client.message.*;
+import org.apache.ignite.internal.util.nio.*;
+import org.apache.ignite.internal.util.nio.ssl.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.jetbrains.annotations.*;
+
+import javax.management.*;
+import javax.net.ssl.*;
+import java.lang.management.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.nio.*;
+import java.util.*;
+
+/**
+ * Wrapper class for router process.
+ */
+public class GridTcpRouterImpl implements GridTcpRouter, GridTcpRouterMBean, LifecycleAware {
+    /** */
+    private static final String ENT_NIO_LSNR_CLS = "org.gridgain.client.router.impl.GridTcpRouterNioListenerEntImpl";
+
+    /** Id. */
+    private final UUID id = UUID.randomUUID();
+
+    /** Configuration. */
+    private final GridTcpRouterConfiguration cfg;
+
+    /** Logger. */
+    private final IgniteLogger log;
+
+    /** Server. */
+    private GridNioServer<GridClientMessage> srv;
+
+    /** Client. */
+    private GridRouterClientImpl client;
+
+    /** MBean name. */
+    private ObjectName mbeanName;
+
+    /** NIO parser. */
+    private volatile GridTcpRouterNioParser parser;
+
+    /** Host where server was actually bound. */
+    private volatile String bindHost;
+
+    /** Port where server was actually bound. */
+    private volatile int bindPort;
+
+    /**
+     * Creates new router instance.
+     *
+     * @param cfg Router configuration.
+     */
+    public GridTcpRouterImpl(GridTcpRouterConfiguration cfg) {
+        this.cfg = cfg;
+
+        log = cfg.getLogger() != null ?
+            cfg.getLogger().getLogger(getClass()) : new IgniteJavaLogger().getLogger(getClass());
+    }
+
+    /**
+     * Starts router.
+     *
+     * @throws IgniteCheckedException If failed.
+     */
+    @Override public void start() throws IgniteCheckedException {
+        try {
+            client = createClient(cfg);
+        }
+        catch (GridClientException e) {
+            throw new IgniteCheckedException("Failed to initialise embedded client.", e);
+        }
+
+        GridNioServerListener<GridClientMessage> lsnr;
+
+        try {
+            Class<?> cls = Class.forName(ENT_NIO_LSNR_CLS);
+
+            Constructor<?> cons = cls.getDeclaredConstructor(IgniteLogger.class, GridRouterClientImpl.class);
+
+            cons.setAccessible(true);
+
+            lsnr = (GridNioServerListener<GridClientMessage>)cons.newInstance(log, client);
+        }
+        catch (ClassNotFoundException ignored) {
+            lsnr = new GridTcpRouterNioListenerOsImpl(log, client);
+        }
+        catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
+            throw new IgniteCheckedException("Failed to create NIO listener.", e);
+        }
+
+        parser = new GridTcpRouterNioParser();
+
+        final InetAddress hostAddr;
+
+        try {
+            hostAddr = InetAddress.getByName(cfg.getHost());
+        }
+        catch (UnknownHostException e) {
+            throw new IgniteCheckedException("Failed to resolve grid address for configured host: " + cfg.getHost(), e);
+        }
+
+        SSLContext sslCtx;
+
+        try {
+            GridSslContextFactory sslCtxFactory = cfg.getSslContextFactory();
+
+            sslCtx = sslCtxFactory == null ? null : sslCtxFactory.createSslContext();
+        }
+        catch (SSLException e) {
+            throw new IgniteCheckedException("Failed to create SSL context.", e);
+        }
+
+        for (int port = cfg.getPort(), last = port + cfg.getPortRange(); port <= last; port++) {
+            if (startTcpServer(hostAddr, port, lsnr, parser, cfg.isNoDelay(), sslCtx, cfg.isSslClientAuth(),
+                cfg.isSslClientAuth())) {
+                if (log.isInfoEnabled())
+                    log.info("TCP router successfully started for endpoint: " + hostAddr.getHostAddress() + ":" + port);
+
+                bindPort = port;
+                bindHost = hostAddr.getHostName();
+
+                break;
+            }
+            else
+                U.warn(log, "TCP REST router failed to start on endpoint: " + hostAddr.getHostAddress() + ":" + port +
+                    ". Will try next port within allowed port range.");
+        }
+
+        if (bindPort == 0)
+            throw new IgniteCheckedException("Failed to bind TCP router server (possibly all ports in range " +
+                "are in use) [firstPort=" + cfg.getPort() + ", lastPort=" + (cfg.getPort() + cfg.getPortRange()) +
+                ", addr=" + hostAddr + ']');
+
+        try {
+            ObjectName objName = U.registerMBean(
+                ManagementFactory.getPlatformMBeanServer(),
+                "Router",
+                "TCP Router " + id,
+                getClass().getSimpleName(),
+                this,
+                GridTcpRouterMBean.class);
+
+            if (log.isDebugEnabled())
+                log.debug("Registered MBean: " + objName);
+
+            mbeanName = objName;
+        }
+        catch (JMException e) {
+            U.error(log, "Failed to register MBean.", e);
+        }
+    }
+
+    /**
+     * Stops this router.
+     */
+    @Override public void stop() {
+        if (srv != null)
+            srv.stop();
+
+        if (client != null)
+            client.stop(true);
+
+        if (mbeanName != null)
+            try {
+                ManagementFactory.getPlatformMBeanServer().unregisterMBean(mbeanName);
+
+                if (log.isDebugEnabled())
+                    log.debug("Unregistered MBean: " + mbeanName);
+            }
+            catch (JMException e) {
+                U.error(log, "Failed to unregister MBean.", e);
+            }
+
+        if (log.isInfoEnabled())
+            log.info("TCP router successfully stopped.");
+    }
+
+    /**
+     * Tries to start server with given parameters.
+     *
+     * @param hostAddr Host on which server should be bound.
+     * @param port Port on which server should be bound.
+     * @param lsnr Server message listener.
+     * @param parser Server message parser.
+     * @param tcpNoDelay Flag indicating whether TCP_NODELAY flag should be set for accepted connections.
+     * @param sslCtx SSL context in case if SSL is enabled.
+     * @param wantClientAuth Whether client will be requested for authentication.
+     * @param needClientAuth Whether client is required to be authenticated.
+     * @return {@code True} if server successfully started, {@code false} if port is used and
+     *      server was unable to start.
+     */
+    private boolean startTcpServer(InetAddress hostAddr, int port, GridNioServerListener<GridClientMessage> lsnr,
+        GridNioParser parser, boolean tcpNoDelay, @Nullable SSLContext sslCtx, boolean wantClientAuth,
+        boolean needClientAuth) {
+        try {
+            GridNioFilter codec = new GridNioCodecFilter(parser, log, false);
+
+            // This name is required to be unique in order to avoid collisions with
+            // ThreadWorkerGroups running in the same JVM by other routers/nodes.
+            String gridName = "router-" + id;
+
+            GridNioFilter[] filters;
+
+            if (sslCtx != null) {
+                GridNioSslFilter sslFilter = new GridNioSslFilter(sslCtx, log);
+
+                sslFilter.wantClientAuth(wantClientAuth);
+
+                sslFilter.needClientAuth(needClientAuth);
+
+                filters = new GridNioFilter[] { codec, sslFilter };
+            }
+            else
+                filters = new GridNioFilter[] { codec };
+
+            srv = GridNioServer.<GridClientMessage>builder()
+                .address(hostAddr)
+                .port(port)
+                .listener(lsnr)
+                .logger(log)
+                .selectorCount(Runtime.getRuntime().availableProcessors())
+                .gridName(gridName)
+                .tcpNoDelay(tcpNoDelay)
+                .directBuffer(false)
+                .byteOrder(ByteOrder.nativeOrder())
+                .socketSendBufferSize(0)
+                .socketReceiveBufferSize(0)
+                .sendQueueLimit(0)
+                .filters(filters)
+                .idleTimeout(cfg.getIdleTimeout())
+                .build();
+
+            srv.start();
+
+            return true;
+        }
+        catch (IgniteCheckedException e) {
+            if (log.isDebugEnabled())
+                log.debug("Failed to start TCP router protocol on port " + port + ": " + e.getMessage());
+
+            srv = null;
+
+            return false;
+        }
+    }
+
+    /**
+     * Creates a client for forwarding messages to the grid.
+     *
+     * @param routerCfg Router configuration.
+     * @return Client instance.
+     * @throws GridClientException If client creation failed.
+     */
+    private GridRouterClientImpl createClient(GridTcpRouterConfiguration routerCfg) throws GridClientException {
+        UUID clientId = UUID.randomUUID();
+
+        return new GridRouterClientImpl(clientId, routerCfg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getHost() {
+        return bindHost;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getPort() {
+        return bindPort;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSslEnabled() {
+        return cfg.getSslContextFactory() != null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSslClientAuth() {
+        return cfg.isSslClientAuth();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<String> getServers() {
+        return cfg.getServers();
+    }
+
+    /** {@inheritDoc} */
+    @Override public UUID id() {
+        return id;
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridTcpRouterConfiguration configuration() {
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getReceivedCount() {
+        return parser != null ? parser.getReceivedCount() : 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getSendCount() {
+        return parser != null ? parser.getSendCount() : 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        return id.hashCode();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (o == this)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        GridTcpRouterImpl that = (GridTcpRouterImpl)o;
+
+        return id.equals(that.id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerAdapter.java
new file mode 100644
index 0000000..a5dc2d1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerAdapter.java
@@ -0,0 +1,203 @@
+/*
+ * 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.router.impl;
+
+import org.apache.ignite.*;
+import org.apache.ignite.client.marshaller.*;
+import org.apache.ignite.client.marshaller.jdk.*;
+import org.apache.ignite.client.marshaller.optimized.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.processors.rest.client.message.*;
+import org.apache.ignite.internal.util.nio.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.jetbrains.annotations.*;
+
+import java.util.*;
+
+import static org.apache.ignite.internal.util.nio.GridNioSessionMetaKey.*;
+
+/**
+ * Nio listener for the router. Extracts necessary meta information from messages
+ * and delegates their delivery to underlying client.
+ */
+abstract class GridTcpRouterNioListenerAdapter implements GridNioServerListener<GridClientMessage> {
+    /** Supported protocol versions. */
+    private static final Collection<Short> SUPP_VERS = new HashSet<>();
+
+    /**
+     */
+    static {
+        SUPP_VERS.add((short)1);
+    }
+
+    /** Logger. */
+    private final IgniteLogger log;
+
+    /** Client for grid access. */
+    private final GridRouterClientImpl client;
+
+    /** Marshallers map. */
+    protected final Map<Byte, GridClientMarshaller> marshMap;
+
+    /**
+     * @param log Logger.
+     * @param client Client for grid access.
+     */
+    @SuppressWarnings({"AbstractMethodCallInConstructor", "OverriddenMethodCallDuringObjectConstruction"})
+    GridTcpRouterNioListenerAdapter(IgniteLogger log, GridRouterClientImpl client) {
+        this.log = log;
+        this.client = client;
+
+        marshMap = new HashMap<>();
+
+        marshMap.put(GridClientOptimizedMarshaller.ID, new GridClientOptimizedMarshaller());
+        marshMap.put(GridClientJdkMarshaller.ID, new GridClientJdkMarshaller());
+
+        init();
+    }
+
+    /**
+     */
+    protected abstract void init();
+
+    /** {@inheritDoc} */
+    @Override public void onConnected(GridNioSession ses) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onDisconnected(GridNioSession ses, @Nullable Exception e) {
+        if (e != null) {
+            if (e instanceof RuntimeException)
+                U.error(log, "Failed to process request from remote client: " + ses, e);
+            else
+                U.warn(log, "Closed client session due to exception [ses=" + ses + ", err=" + e.getMessage() + ']');
+        }
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("TypeMayBeWeakened")
+    @Override public void onMessage(final GridNioSession ses, final GridClientMessage msg) {
+        if (msg instanceof GridRouterRequest) {
+            GridRouterRequest routerMsg = (GridRouterRequest)msg;
+
+            final UUID clientId = routerMsg.clientId();
+            final long reqId = routerMsg.requestId();
+
+            try {
+                client.forwardMessage(routerMsg, routerMsg.destinationId(), ses.<Byte>meta(MARSHALLER_ID.ordinal()))
+                    .listenAsync(new GridClientFutureListener() {
+                        @Override public void onDone(GridClientFuture fut) {
+                            try {
+                                GridRouterResponse res = (GridRouterResponse)fut.get();
+                                // Restoring original request id, because it was overwritten by the client.
+                                res.requestId(reqId);
+
+                                ses.send(res);
+                            }
+                            catch (GridClientException e) {
+                                ses.send(makeFailureResponse(e, clientId, reqId));
+                            }
+                        }
+                    });
+            }
+            catch (GridClientException e) {
+                ses.send(makeFailureResponse(e, clientId, reqId));
+            }
+            catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+
+                U.warn(
+                    log,
+                    "Message forwarding was interrupted (will ignore last message): " + e.getMessage(),
+                    "Message forwarding was interrupted.");
+            }
+        }
+        else if (msg instanceof GridClientHandshakeRequest) {
+            GridClientHandshakeRequest hs = (GridClientHandshakeRequest)msg;
+
+            short ver = hs.version();
+
+            if (!SUPP_VERS.contains(ver)) {
+                U.error(log, "Client protocol version is not supported [ses=" + ses +
+                    ", ver=" + ver +
+                    ", supported=" + SUPP_VERS + ']');
+
+                ses.close();
+            }
+            else {
+                byte marshId = hs.marshallerId();
+
+                GridClientMarshaller marsh = marshMap.get(marshId);
+
+                if (marsh == null) {
+                    U.error(log, "Client marshaller ID is invalid. Note that .NET and C++ clients " +
+                        "are supported only in enterprise edition [ses=" + ses + ", marshId=" + marshId + ']');
+
+                    ses.close();
+                }
+                else {
+                    ses.addMeta(MARSHALLER_ID.ordinal(), marshId);
+                    ses.addMeta(MARSHALLER.ordinal(), marsh);
+
+                    ses.send(GridClientHandshakeResponse.OK);
+                }
+            }
+        }
+        else if (msg instanceof GridClientPingPacket)
+            ses.send(GridClientPingPacket.PING_MESSAGE);
+        else
+            throw new IllegalArgumentException("Unsupported input message: " + msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onSessionWriteTimeout(GridNioSession ses) {
+        U.warn(log, "Closing NIO session because of write timeout.");
+
+        ses.close();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onSessionIdleTimeout(GridNioSession ses) {
+        U.warn(log, "Closing NIO session because of idle.");
+
+        ses.close();
+    }
+
+    /**
+     * Creates a failure response, based on the given exception.
+     *
+     * @param e Exception to extract failure report from.
+     * @param clientId Client id.
+     * @param reqId Request id.
+     * @return Failure response.
+     */
+    private GridClientResponse makeFailureResponse(GridClientException e, UUID clientId, Long reqId) {
+        U.error(log, "Failed to process message on router.", e);
+
+        GridClientResponse res = new GridClientResponse();
+
+        res.clientId(clientId);
+        res.requestId(reqId);
+        res.successStatus(GridClientResponse.STATUS_FAILED);
+        res.errorMessage("Failed to process message on router " +
+            "[exception=" + e.getClass().getSimpleName() + ", message=" + e.getMessage() + ']');
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerOsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerOsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerOsImpl.java
new file mode 100644
index 0000000..61e6bd6
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioListenerOsImpl.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router.impl;
+
+import org.apache.ignite.*;
+
+/**
+ * Router NIO listener.
+ */
+class GridTcpRouterNioListenerOsImpl extends GridTcpRouterNioListenerAdapter {
+    /**
+     * @param log Logger.
+     * @param client Client for grid access.
+     */
+    GridTcpRouterNioListenerOsImpl(IgniteLogger log, GridRouterClientImpl client) {
+        super(log, client);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void init() {
+        // No-op.
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioParser.java b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioParser.java
new file mode 100644
index 0000000..23f5aa3
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/router/impl/GridTcpRouterNioParser.java
@@ -0,0 +1,109 @@
+/*
+ * 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.router.impl;
+
+import org.apache.ignite.*;
+import org.apache.ignite.client.marshaller.*;
+import org.apache.ignite.internal.processors.rest.client.message.*;
+import org.apache.ignite.internal.processors.rest.protocols.tcp.*;
+import org.apache.ignite.internal.util.nio.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+
+import java.io.*;
+import java.nio.*;
+
+import static org.apache.ignite.internal.processors.rest.protocols.tcp.GridMemcachedMessage.*;
+
+/**
+ *
+ */
+class GridTcpRouterNioParser extends GridTcpRestParser {
+    /** Number of received messages. */
+    private volatile long rcvCnt;
+
+    /** Number of sent messages. */
+    private volatile long sndCnt;
+
+    /** {@inheritDoc} */
+    @Override protected GridClientMessage parseClientMessage(GridNioSession ses, ParserState state) {
+        rcvCnt++;
+
+        return new GridRouterRequest(
+            state.buffer().toByteArray(),
+            state.header().reqId(),
+            state.header().clientId(),
+            state.header().destinationId());
+    }
+
+    /** {@inheritDoc} */
+    @Override public ByteBuffer encode(GridNioSession ses, Object msg) throws IOException, IgniteCheckedException {
+        sndCnt++;
+
+        if (msg instanceof GridRouterResponse) {
+            GridRouterResponse resp = (GridRouterResponse)msg;
+
+            ByteBuffer res = ByteBuffer.allocate(resp.body().length + 45);
+
+            res.put(IGNITE_REQ_FLAG);
+            res.putInt(resp.body().length + 40);
+            res.putLong(resp.requestId());
+            res.put(U.uuidToBytes(resp.clientId()));
+            res.put(U.uuidToBytes(resp.destinationId()));
+            res.put(resp.body());
+
+            res.flip();
+
+            return res;
+        }
+        else if (msg instanceof GridClientResponse) {
+            GridClientMarshaller marsh = marshaller(ses);
+
+            GridClientMessage clientMsg = (GridClientMessage)msg;
+
+            ByteBuffer res = marsh.marshal(msg, 45);
+
+            ByteBuffer slice = res.slice();
+
+            slice.put(IGNITE_REQ_FLAG);
+            slice.putInt(res.remaining() - 5);
+            slice.putLong(clientMsg.requestId());
+            slice.put(U.uuidToBytes(clientMsg.clientId()));
+            slice.put(U.uuidToBytes(clientMsg.destinationId()));
+
+            return res;
+        }
+        else if (msg instanceof GridClientPingPacket || msg instanceof GridClientHandshakeResponse)
+            return super.encode(ses, msg);
+        else
+            throw new IgniteCheckedException("Unsupported message: " + msg);
+    }
+
+    /**
+     * @return Number of received messages.
+     */
+    public long getReceivedCount() {
+        return rcvCnt;
+    }
+
+    /**
+     * @return Number of sent messages.
+     */
+    public long getSendCount() {
+        return sndCnt;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
new file mode 100644
index 0000000..92c34e0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
@@ -0,0 +1,438 @@
+/*
+ * 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.ssl;
+
+import org.apache.ignite.internal.util.typedef.internal.*;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import java.util.*;
+
+/**
+ * Basic ssl context factory that provides ssl context configuration with specified key
+ * and trust stores.
+ * <p>
+ * In some cases it is useful to disable certificate validation of client side (e.g. when connecting
+ * to a server with self-signed certificate). This can be achieved by setting a disabled trust manager
+ * to this factory, which can be obtained by {@link #getDisabledTrustManager()} method:
+ * <pre>
+ *     GridSslBasicContextFactory factory = new GridSslBasicContextFactory();
+ *     factory.setTrustManagers(GridSslBasicContextFactory.getDisabledTrustManager());
+ *     // Rest of initialization.
+ * </pre>
+ */
+public class GridSslBasicContextFactory implements GridSslContextFactory {
+    /** Default key store type. */
+    public static final String DFLT_STORE_TYPE = "JKS";
+
+    /** Default SSL protocol. */
+    public static final String DFLT_SSL_PROTOCOL = "TLS";
+
+    /** Default key manager algorithm. */
+    public static final String DFLT_KEY_ALGORITHM = "SunX509";
+
+    /** SSL protocol. */
+    private String proto = DFLT_SSL_PROTOCOL;
+
+    /** Key manager algorithm. */
+    private String keyAlgorithm = DFLT_KEY_ALGORITHM;
+
+    /** Key store type. */
+    private String keyStoreType = DFLT_STORE_TYPE;
+
+    /** Path to key store file */
+    private String keyStoreFilePath;
+
+    /** Key store password */
+    private char[] keyStorePwd;
+
+    /** Trust store type. */
+    private String trustStoreType = DFLT_STORE_TYPE;
+
+    /** Path to trust store. */
+    private String trustStoreFilePath;
+
+    /** Trust store password */
+    private char[] trustStorePwd;
+
+    /** Trust managers. */
+    private TrustManager[] trustMgrs;
+
+    /**
+     * Gets key store type used for context creation.
+     *
+     * @return Key store type.
+     */
+    public String getKeyStoreType() {
+        return keyStoreType;
+    }
+
+    /**
+     * Sets key store type used in context initialization. If not provided, {@link #DFLT_STORE_TYPE} will
+     * be used.
+     *
+     * @param keyStoreType Key store type.
+     */
+    public void setKeyStoreType(String keyStoreType) {
+        A.notNull(keyStoreType, "keyStoreType");
+
+        this.keyStoreType = keyStoreType;
+    }
+
+    /**
+     * Gets trust store type used for context creation.
+     *
+     * @return trust store type.
+     */
+    public String getTrustStoreType() {
+        return trustStoreType;
+    }
+
+    /**
+     * Sets trust store type used in context initialization. If not provided, {@link #DFLT_STORE_TYPE} will
+     * be used.
+     *
+     * @param trustStoreType Trust store type.
+     */
+    public void setTrustStoreType(String trustStoreType) {
+        A.notNull(trustStoreType, "trustStoreType");
+
+        this.trustStoreType = trustStoreType;
+    }
+
+    /**
+     * Gets protocol for secure transport.
+     *
+     * @return SSL protocol name.
+     */
+    public String getProtocol() {
+        return proto;
+    }
+
+    /**
+     * Sets protocol for secure transport. If not specified, {@link #DFLT_SSL_PROTOCOL} will be used.
+     *
+     * @param proto SSL protocol name.
+     */
+    public void setProtocol(String proto) {
+        A.notNull(proto, "proto");
+
+        this.proto = proto;
+    }
+
+    /**
+     * Gets algorithm that will be used to create a key manager. If not specified, {@link #DFLT_KEY_ALGORITHM}
+     * will be used.
+     *
+     * @return Key manager algorithm.
+     */
+    public String getKeyAlgorithm() {
+        return keyAlgorithm;
+    }
+
+    /**
+     * Sets key manager algorithm that will be used to create a key manager. Notice that in most cased default value
+     * suites well, however, on Android platform this value need to be set to <tt>X509<tt/>.
+     *
+     * @param keyAlgorithm Key algorithm name.
+     */
+    public void setKeyAlgorithm(String keyAlgorithm) {
+        A.notNull(keyAlgorithm, "keyAlgorithm");
+
+        this.keyAlgorithm = keyAlgorithm;
+    }
+
+    /**
+     * Gets path to the key store file.
+     *
+     * @return Path to key store file.
+     */
+    public String getKeyStoreFilePath() {
+        return keyStoreFilePath;
+    }
+
+    /**
+     * Sets path to the key store file. This is a mandatory parameter since
+     * ssl context could not be initialized without key manager.
+     *
+     * @param keyStoreFilePath Path to key store file.
+     */
+    public void setKeyStoreFilePath(String keyStoreFilePath) {
+        A.notNull(keyStoreFilePath, "keyStoreFilePath");
+
+        this.keyStoreFilePath = keyStoreFilePath;
+    }
+
+    /**
+     * Gets key store password.
+     *
+     * @return Key store password.
+     */
+    public char[] getKeyStorePassword() {
+        return keyStorePwd;
+    }
+
+    /**
+     * Sets key store password.
+     *
+     * @param keyStorePwd Key store password.
+     */
+    public void setKeyStorePassword(char[] keyStorePwd) {
+        A.notNull(keyStorePwd, "keyStorePwd");
+
+        this.keyStorePwd = keyStorePwd;
+    }
+
+    /**
+     * Gets path to the trust store file.
+     *
+     * @return Path to the trust store file.
+     */
+    public String getTrustStoreFilePath() {
+        return trustStoreFilePath;
+    }
+
+    /**
+     * Sets path to the trust store file. This is an optional parameter,
+     * however one of the {@code setTrustStoreFilePath(String)}, {@link #setTrustManagers(TrustManager[])}
+     * properties must be set.
+     *
+     * @param trustStoreFilePath Path to the trust store file.
+     */
+    public void setTrustStoreFilePath(String trustStoreFilePath) {
+        this.trustStoreFilePath = trustStoreFilePath;
+    }
+
+    /**
+     * Gets trust store password.
+     *
+     * @return Trust store password.
+     */
+    public char[] getTrustStorePassword() {
+        return trustStorePwd;
+    }
+
+    /**
+     * Sets trust store password.
+     *
+     * @param trustStorePwd Trust store password.
+     */
+    public void setTrustStorePassword(char[] trustStorePwd) {
+        this.trustStorePwd = trustStorePwd;
+    }
+
+    /**
+     * Gets pre-configured trust managers.
+     *
+     * @return Trust managers.
+     */
+    public TrustManager[] getTrustManagers() {
+        return trustMgrs;
+    }
+
+    /**
+     * Sets pre-configured trust managers. This is an optional parameter,
+     * however one of the {@link #setTrustStoreFilePath(String)}, {@code #setTrustManagers(TrustManager[])}
+     *
+     * @param trustMgrs Pre-configured trust managers.
+     */
+    public void setTrustManagers(TrustManager... trustMgrs) {
+        this.trustMgrs = trustMgrs;
+    }
+
+    /**
+     * Returns an instance of trust manager that will always succeed regardless of certificate provided.
+     *
+     * @return Trust manager instance.
+     */
+    public static TrustManager getDisabledTrustManager() {
+        return new DisabledX509TrustManager();
+    }
+
+    /** {@inheritDoc} */
+    @Override public SSLContext createSslContext() throws SSLException {
+        checkParameters();
+
+        try {
+            KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance(keyAlgorithm);
+
+            KeyStore keyStore = loadKeyStore(keyStoreType, keyStoreFilePath, keyStorePwd);
+
+            keyMgrFactory.init(keyStore, keyStorePwd);
+
+            TrustManager[] mgrs = trustMgrs;
+
+            if (mgrs == null) {
+                TrustManagerFactory trustMgrFactory = TrustManagerFactory.getInstance(keyAlgorithm);
+
+                KeyStore trustStore = loadKeyStore(trustStoreType, trustStoreFilePath, trustStorePwd);
+
+                trustMgrFactory.init(trustStore);
+
+                mgrs = trustMgrFactory.getTrustManagers();
+            }
+
+            SSLContext ctx = SSLContext.getInstance(proto);
+
+            ctx.init(keyMgrFactory.getKeyManagers(), mgrs, null);
+
+            return ctx;
+        }
+        catch (GeneralSecurityException e) {
+            throw new SSLException("Failed to initialize SSL context " + parameters(), e);
+        }
+    }
+
+    /**
+     * Builds human-readable string with factory parameters.
+     *
+     * @return Parameters string.
+     */
+    private String parameters() {
+        StringBuilder buf = new StringBuilder("[keyStoreType=").append(keyStoreType);
+
+        buf.append(", proto=").append(proto).append(", keyStoreFile=").append(keyStoreFilePath);
+
+        if (trustMgrs != null)
+            buf.append(", trustMgrs=").append(Arrays.toString(trustMgrs));
+        else
+            buf.append(", trustStoreFile=").append(trustStoreFilePath);
+
+        buf.append(']');
+
+        return buf.toString();
+    }
+
+    /**
+     * Checks that all required parameters are set.
+     *
+     * @throws SSLException If any of required parameters is missing.
+     */
+    private void checkParameters() throws SSLException {
+        assert keyStoreType != null;
+        assert proto != null;
+
+        checkNullParameter(keyStoreFilePath, "keyStoreFilePath");
+        checkNullParameter(keyStorePwd, "keyStorePwd");
+
+        if (trustMgrs == null) {
+            if (trustStoreFilePath == null)
+                throw new SSLException("Failed to initialize SSL context (either trustStoreFilePath or " +
+                    "trustManagers must be provided)");
+            else
+                checkNullParameter(trustStorePwd, "trustStorePwd");
+        }
+    }
+
+    /**
+     * @param param Value.
+     * @param name Name.
+     * @throws SSLException If {@code null}.
+     */
+    private void checkNullParameter(Object param, String name) throws SSLException {
+        if (param == null)
+            throw new SSLException("Failed to initialize SSL context (parameter cannot be null): " + name);
+    }
+
+    /**
+     * By default, this method simply opens a raw file input stream. Subclasses may override this method
+     * if some specific location should be handled (this may be a case for Android users).
+     *
+     * @param filePath Path to the file.
+     * @return Opened input stream.
+     * @throws IOException If stream could not be opened.
+     */
+    protected InputStream openFileInputStream(String filePath) throws IOException {
+        return new FileInputStream(filePath);
+    }
+
+    /**
+     * Loads key store with configured parameters.
+     *
+     * @param keyStoreType Type of key store.
+     * @param storeFilePath Path to key store file.
+     * @param keyStorePwd Store password.
+     * @return Initialized key store.
+     * @throws SSLException If key store could not be initialized.
+     */
+    private KeyStore loadKeyStore(String keyStoreType, String storeFilePath, char[] keyStorePwd) throws SSLException {
+        InputStream input = null;
+
+        try {
+            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+
+            input = openFileInputStream(storeFilePath);
+
+            keyStore.load(input, keyStorePwd);
+
+            return keyStore;
+        }
+        catch (GeneralSecurityException e) {
+            throw new SSLException("Failed to initialize key store (security exception occurred) [type=" +
+                keyStoreType + ", keyStorePath=" + storeFilePath + ']', e);
+        }
+        catch (FileNotFoundException e) {
+            throw new SSLException("Failed to initialize key store (key store file was not found): [path=" +
+                storeFilePath + ", msg=" + e.getMessage() + ']');
+        }
+        catch (IOException e) {
+            throw new SSLException("Failed to initialize key store (I/O error occurred): " + storeFilePath, e);
+        }
+        finally {
+            if (input != null) {
+                try {
+                    input.close();
+                }
+                catch (IOException ignored) {
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        return getClass().getSimpleName() + parameters();
+    }
+
+    /**
+     * Disabled trust manager, will skip all certificate checks.
+     */
+    private static class DisabledX509TrustManager implements X509TrustManager {
+        /** Empty certificate array. */
+        private static final X509Certificate[] CERTS = new X509Certificate[0];
+
+        /** {@inheritDoc} */
+        @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
+            throws CertificateException {
+            // No-op, all clients are trusted.
+        }
+
+        /** {@inheritDoc} */
+        @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
+            throws CertificateException {
+            // No-op, all servers are trusted.
+        }
+
+        /** {@inheritDoc} */
+        @Override public X509Certificate[] getAcceptedIssuers() {
+            return CERTS;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslContextFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslContextFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslContextFactory.java
new file mode 100644
index 0000000..8a9cd13
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslContextFactory.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.internal.client.ssl;
+
+import javax.net.ssl.*;
+
+/**
+ * This interface provides creation of SSL context both for server and client use.
+ * <p>
+ * Usually, it is enough to configure context from a particular key and trust stores, this functionality is provided
+ * in {@link org.apache.ignite.internal.client.ssl.GridSslBasicContextFactory}.
+ */
+public interface GridSslContextFactory {
+    /**
+     * Creates SSL context based on factory settings.
+     *
+     * @return Initialized SSL context.
+     * @throws SSLException If SSL context could not be created.
+     */
+    public SSLContext createSslContext() throws SSLException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientConsistentHash.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientConsistentHash.java b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientConsistentHash.java
new file mode 100644
index 0000000..6e2b73b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientConsistentHash.java
@@ -0,0 +1,440 @@
+/*
+ * 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.util;
+
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.jetbrains.annotations.*;
+
+import java.util.*;
+import java.util.concurrent.locks.*;
+
+/**
+ * Controls key to node affinity using consistent hash algorithm. This class is thread-safe
+ * and does not have to be externally synchronized.
+ * <p>
+ * For a good explanation of what consistent hashing is, you can refer to
+ * <a href="http://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html">Tom White's Blog</a>.
+ */
+@SuppressWarnings("NullableProblems")
+public class GridClientConsistentHash<N> {
+    /** Prime number. */
+    private static final int PRIME = 15485857;
+
+    /** Random generator. */
+    private static final Random RAND = new Random();
+
+    /** Affinity seed. */
+    private final Object affSeed;
+
+    /** Map of hash assignments. */
+    private final NavigableMap<Integer, SortedSet<N>> circle = new TreeMap<>();
+
+    /** Read/write lock. */
+    private final ReadWriteLock rw = new ReentrantReadWriteLock();
+
+    /** Distinct nodes in the hash. */
+    private Collection<N> nodes = new HashSet<>();
+
+    /** Nodes comparator to resolve hash codes collisions. */
+    private Comparator<N> nodesComp;
+
+    /**
+     * Constructs consistent hash using empty affinity seed and {@code MD5} hasher function.
+     */
+    public GridClientConsistentHash() {
+        this(null, null);
+    }
+
+    /**
+     * Constructs consistent hash using given affinity seed and {@code MD5} hasher function.
+     *
+     * @param affSeed Affinity seed (will be used as key prefix for hashing).
+     */
+    public GridClientConsistentHash(Object affSeed) {
+        this(null, affSeed);
+    }
+
+    /**
+     * Constructs consistent hash using given affinity seed and hasher function.
+     *
+     * @param nodesComp Nodes comparator to resolve hash codes collisions.
+     *  If {@code null} natural order will be used.
+     * @param affSeed Affinity seed (will be used as key prefix for hashing).
+     */
+    public GridClientConsistentHash(Comparator<N> nodesComp, Object affSeed) {
+        this.nodesComp = nodesComp;
+        this.affSeed = affSeed == null ? new Integer(PRIME) : affSeed;
+    }
+
+    /**
+     * Adds nodes to consistent hash algorithm (if nodes are {@code null} or empty, then no-op).
+     *
+     * @param nodes Nodes to add.
+     * @param replicas Number of replicas for every node.
+     */
+    public void addNodes(Collection<N> nodes, int replicas) {
+        if (nodes == null || nodes.isEmpty())
+            return;
+
+        rw.writeLock().lock();
+
+        try {
+            for (N node : nodes)
+                addNode(node, replicas);
+        }
+        finally {
+            rw.writeLock().unlock();
+        }
+    }
+
+    /**
+     * Adds a node to consistent hash algorithm.
+     *
+     * @param node New node (if {@code null} then no-op).
+     * @param replicas Number of replicas for the node.
+     * @return {@code True} if node was added, {@code false} if it is {@code null} or
+     *      is already contained in the hash.
+     */
+    public boolean addNode(N node, int replicas) {
+        if (node == null)
+            return false;
+
+        long seed = affSeed.hashCode() * 31 + hash(node);
+
+        rw.writeLock().lock();
+
+        try {
+            if (!nodes.add(node))
+                return false;
+
+            int hash = hash(seed);
+
+            SortedSet<N> set = circle.get(hash);
+
+            if (set == null)
+                circle.put(hash, set = new TreeSet<>(nodesComp));
+
+            set.add(node);
+
+            for (int i = 1; i <= replicas; i++) {
+                seed = seed * affSeed.hashCode() + i;
+
+                hash = hash(seed);
+
+                set = circle.get(hash);
+
+                if (set == null)
+                    circle.put(hash, set = new TreeSet<>(nodesComp));
+
+                set.add(node);
+            }
+
+            return true;
+        }
+        finally {
+            rw.writeLock().unlock();
+        }
+    }
+
+    /**
+     * Removes a node and all of its replicas.
+     *
+     * @param node Node to remove (if {@code null}, then no-op).
+     * @return {@code True} if node was removed, {@code false} if node is {@code null} or
+     *      not present in hash.
+     */
+    public boolean removeNode(N node) {
+        if (node == null)
+            return false;
+
+        rw.writeLock().lock();
+
+        try {
+            if (!nodes.remove(node))
+                return false;
+
+            for (Iterator<SortedSet<N>> it = circle.values().iterator(); it.hasNext();) {
+                SortedSet<N> set = it.next();
+
+                if (!set.remove(node))
+                    continue;
+
+                if (set.isEmpty())
+                    it.remove();
+            }
+
+            return true;
+        }
+        finally {
+            rw.writeLock().unlock();
+        }
+    }
+
+    /**
+     * Gets number of distinct nodes, excluding replicas, in consistent hash.
+     *
+     * @return Number of distinct nodes, excluding replicas, in consistent hash.
+     */
+    public int count() {
+        rw.readLock().lock();
+
+        try {
+            return nodes.size();
+        }
+        finally {
+            rw.readLock().unlock();
+        }
+    }
+
+    /**
+     * Gets size of all nodes (including replicas) in consistent hash.
+     *
+     * @return Size of all nodes (including replicas) in consistent hash.
+     */
+    public int size() {
+        rw.readLock().lock();
+
+        try {
+            int size = 0;
+
+            for (SortedSet<N> set : circle.values())
+                size += set.size();
+
+            return size;
+        }
+        finally {
+            rw.readLock().unlock();
+        }
+    }
+
+    /**
+     * Checks if consistent hash has nodes added to it.
+     *
+     * @return {@code True} if consistent hash is empty, {@code false} otherwise.
+     */
+    public boolean isEmpty() {
+        return count() == 0;
+    }
+
+    /**
+     * Gets set of all distinct nodes in the consistent hash (in no particular order).
+     *
+     * @return Set of all distinct nodes in the consistent hash.
+     */
+    public Set<N> nodes() {
+        rw.readLock().lock();
+
+        try {
+            return new HashSet<>(nodes);
+        }
+        finally {
+            rw.readLock().unlock();
+        }
+    }
+
+    /**
+     * Picks a random node from consistent hash.
+     *
+     * @return Random node from consistent hash or {@code null} if there are no nodes.
+     */
+    public N random() {
+        return node(RAND.nextLong());
+    }
+
+    /**
+     * Gets node for a key.
+     *
+     * @param key Key.
+     * @return Node.
+     */
+    public N node(Object key) {
+        int hash = hash(key);
+
+        rw.readLock().lock();
+
+        try {
+            Map.Entry<Integer, SortedSet<N>> firstEntry = circle.firstEntry();
+
+            if (firstEntry == null)
+                return null;
+
+            Map.Entry<Integer, SortedSet<N>> tailEntry = circle.tailMap(hash, true).firstEntry();
+
+            // Get first node hash in the circle clock-wise.
+            return circle.get(tailEntry == null ? firstEntry.getKey() : tailEntry.getKey()).first();
+        }
+        finally {
+            rw.readLock().unlock();
+        }
+    }
+
+    /**
+     * Gets node for a given key.
+     *
+     * @param key Key to get node for.
+     * @param inc Optional inclusion set. Only nodes contained in this set may be returned.
+     *      If {@code null}, then all nodes may be included.
+     * @return Node for key, or {@code null} if node was not found.
+     */
+    public N node(Object key, Collection<N> inc) {
+        return node(key, inc, null);
+    }
+
+    /**
+     * Gets node for a given key.
+     *
+     * @param key Key to get node for.
+     * @param inc Optional inclusion set. Only nodes contained in this set may be returned.
+     *      If {@code null}, then all nodes may be included.
+     * @param exc Optional exclusion set. Only nodes not contained in this set may be returned.
+     *      If {@code null}, then all nodes may be returned.
+     * @return Node for key, or {@code null} if node was not found.
+     */
+    public N node(Object key, @Nullable final Collection<N> inc, @Nullable final Collection<N> exc) {
+        if (inc == null && exc == null)
+            return node(key);
+
+        return node(key, new GridClientPredicate<N>() {
+            @Override public boolean apply(N n) {
+                return (inc == null || inc.contains(n)) && (exc == null || !exc.contains(n));
+            }
+        });
+    }
+
+    /**
+     * Gets node for a given key.
+     *
+     * @param key Key to get node for.
+     * @param p Optional predicate for node filtering.
+     * @return Node for key, or {@code null} if node was not found.
+     */
+    public N node(Object key, GridClientPredicate<N>... p) {
+        if (p == null || p.length == 0)
+            return node(key);
+
+        int hash = hash(key);
+
+        rw.readLock().lock();
+
+        try {
+            final int size = nodes.size();
+
+            if (size == 0)
+                return null;
+
+            Set<N> failed = null;
+
+            // Move clock-wise starting from selected position 'hash'.
+            for (SortedSet<N> set : circle.tailMap(hash, true).values()) {
+                for (N n : set) {
+                    if (failed != null && failed.contains(n))
+                        continue;
+
+                    if (apply(p, n))
+                        return n;
+
+                    if (failed == null)
+                        failed = new HashSet<>();
+
+                    failed.add(n);
+
+                    if (failed.size() == size)
+                        return null;
+                }
+            }
+
+            //
+            // Copy-paste is used to escape several new objects creation.
+            //
+
+            // Wrap around moving clock-wise from the circle start.
+            for (SortedSet<N> set : circle.headMap(hash, false).values()) { // Circle head.
+                for (N n : set) {
+                    if (failed != null && failed.contains(n))
+                        continue;
+
+                    if (apply(p, n))
+                        return n;
+
+                    if (failed == null)
+                        failed = U.newHashSet(size);
+
+                    failed.add(n);
+
+                    if (failed.size() == size)
+                        return null;
+                }
+            }
+
+            return null;
+        }
+        finally {
+            rw.readLock().unlock();
+        }
+    }
+
+    /**
+     * Apply predicate to the node.
+     *
+     * @param p Predicate.
+     * @param n Node.
+     * @return {@code True} if filter passed or empty.
+     */
+    private boolean apply(GridClientPredicate<N>[] p, N n) {
+        if (p != null) {
+            for (GridClientPredicate<? super N> r : p) {
+                if (r != null && !r.apply(n))
+                    return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Gets hash code for a given object.
+     *
+     * @param o Object to get hash code for.
+     * @return Hash code.
+     */
+    public static int hash(Object o) {
+        int h = o == null ? 0 : o instanceof byte[] ? Arrays.hashCode((byte[])o) : o.hashCode();
+
+        // Spread bits to hash code.
+        h += (h <<  15) ^ 0xffffcd7d;
+        h ^= (h >>> 10);
+        h += (h <<   3);
+        h ^= (h >>>  6);
+        h += (h <<   2) + (h << 14);
+
+        return h ^ (h >>> 16);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        StringBuilder sb = new StringBuilder(getClass().getSimpleName());
+
+        sb.append(" [affSeed=").append(affSeed).
+            append(", circle=").append(circle).
+            append(", nodesComp=").append(nodesComp).
+            append(", nodes=").append(nodes).append("]");
+
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientStripedLock.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientStripedLock.java b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientStripedLock.java
new file mode 100644
index 0000000..30a4baa
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientStripedLock.java
@@ -0,0 +1,135 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.locks.*;
+
+/**
+ * This is an utility class for 'splitting' locking of some
+ * {@code int}- or {@code long}-keyed resources.
+ *
+ * Map {@code int} and {@code long} values to some number of locks,
+ * and supply convenience methods to obtain and release these locks using key values.
+ */
+public class GridClientStripedLock {
+    /** Array of underlying locks. */
+    private final Lock[] locks;
+
+    /**
+     * Creates new instance with the given concurrency level (number of locks).
+     *
+     * @param concurrencyLevel Concurrency level.
+     */
+    public GridClientStripedLock(int concurrencyLevel) {
+        locks = new Lock[concurrencyLevel];
+
+        for (int i = 0; i < concurrencyLevel; i++)
+            locks[i] = new ReentrantLock();
+    }
+
+    /**
+     * Gets concurrency level.
+     *
+     * @return Concurrency level.
+     */
+    public int concurrencyLevel() {
+        return locks.length;
+    }
+
+    /**
+     * Returns {@link Lock} object for the given key.
+     * @param key Key.
+     * @return Lock.
+     */
+    public Lock getLock(int key) {
+        return locks[GridClientUtils.safeAbs(key) % locks.length];
+    }
+
+    /**
+     * Returns {@link Lock} object for the given key.
+     * @param key Key.
+     * @return Lock.
+     */
+    public Lock getLock(long key) {
+        return locks[GridClientUtils.safeAbs((int)(key % locks.length))];
+    }
+
+    /**
+     * Returns lock for object.
+     *
+     * @param o Object.
+     * @return Lock.
+     */
+    public Lock getLock(Object o) {
+        return o == null ? locks[0] : getLock(o.hashCode());
+    }
+
+    /**
+     * Locks given key.
+     *
+     * @param key Key.
+     */
+    public void lock(int key) {
+        getLock(key).lock();
+    }
+
+    /**
+     * Unlocks given key.
+     *
+     * @param key Key.
+     */
+    public void unlock(int key) {
+        getLock(key).unlock();
+    }
+
+    /**
+     * Locks given key.
+     *
+     * @param key Key.
+     */
+    public void lock(long key) {
+        getLock(key).lock();
+    }
+
+    /**
+     * Unlocks given key.
+     *
+     * @param key Key.
+     */
+    public void unlock(long key) {
+        getLock(key).unlock();
+    }
+
+    /**
+     * Locks an object.
+     *
+     * @param o Object.
+     */
+    public void lock(Object o) {
+        getLock(o).lock();
+    }
+
+    /**
+     * Unlocks an object.
+     *
+     * @param o Object.
+     */
+    public void unlock(Object o) {
+        getLock(o).unlock();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientUtils.java
new file mode 100644
index 0000000..237959e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridClientUtils.java
@@ -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.
+ */
+
+package org.apache.ignite.internal.client.util;
+
+import org.apache.ignite.internal.client.*;
+import org.jetbrains.annotations.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.logging.*;
+
+/**
+ * Java client utils.
+ */
+public abstract class GridClientUtils {
+    /**
+     * Closes resource without reporting any error.
+     *
+     * @param closeable Resource to close.
+     */
+    public static void closeQuiet(@Nullable Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            }
+            catch (IOException ignored) {
+                // No-op.
+            }
+        }
+    }
+
+    /**
+     * Creates a predicates that checks if given value is contained in collection c.
+     *
+     * @param c Collection to check.
+     * @param <T> Type of elements in collection.
+     * @return Predicate.
+     */
+    public static <T> GridClientPredicate<T> contains(final Collection<T> c) {
+        return new GridClientPredicate<T>() {
+            @Override public boolean apply(T t) {
+                return (!(c == null || c.isEmpty())) && c.contains(t);
+            }
+        };
+    }
+
+    /**
+     * Gets first element from given collection or returns {@code null} if the collection is empty.
+     *
+     * @param c A collection.
+     * @param <T> Type of the collection.
+     * @return Collections' first element or {@code null} in case if the collection is empty.
+     */
+    @Nullable public static <T> T first(@Nullable Iterable<? extends T> c) {
+        if (c == null)
+            return null;
+
+        Iterator<? extends T> it = c.iterator();
+
+        return it.hasNext() ? it.next() : null;
+    }
+
+    /**
+     * Applies filter and returns filtered collection of nodes.
+     *
+     * @param elements Nodes to be filtered.
+     * @param filters Filters to apply. Elements of this array are allowed to be {@code null}.
+     * @return Filtered collection.
+     */
+    public static <T> Collection<T> applyFilter(Iterable<? extends T> elements,
+        GridClientPredicate<? super T>... filters) {
+        assert filters != null;
+
+        Collection<T> res = new LinkedList<>();
+
+        for (T e : elements) {
+            boolean add = true;
+
+            for (GridClientPredicate<? super T> filter : filters)
+                if (filter != null && !filter.apply(e)) {
+                    add = false;
+
+                    break;
+                }
+
+            if (add)
+                res.add(e);
+        }
+
+        return res;
+    }
+
+    /**
+     * Checks if given REST protocol available for given node.
+     *
+     * @param node Node.
+     * @param p Protocol.
+     * @return {@code true} if protocol {@code p} available for {@code node},
+     *  {@code false} otherwise.
+     */
+    public static boolean restAvailable(GridClientNode node, GridClientProtocol p) {
+        return !node.availableAddresses(p, false).isEmpty();
+    }
+
+    /**
+     * Shutdowns given {@code ExecutorService} and wait for executor service to stop.
+     *
+     * @param owner The ExecutorService owner.
+     * @param exec ExecutorService to shutdown.
+     * @param log The logger to possible exceptions and warnings.
+     */
+    public static void shutdownNow(Class<?> owner, ExecutorService exec, Logger log) {
+        if (exec != null) {
+            List<Runnable> tasks = exec.shutdownNow();
+
+            if (!tasks.isEmpty())
+                log.warning("Runnable tasks outlived thread pool executor service [owner=" + getSimpleName(owner) +
+                    ", tasks=" + tasks + ']');
+
+            try {
+                exec.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+            }
+            catch (InterruptedException ignored) {
+                log.warning("Got interrupted while waiting for executor service to stop.");
+
+                exec.shutdownNow();
+
+                // Preserve interrupt status.
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    /**
+     * Gets simple class name taking care of empty names.
+     *
+     * @param cls Class to get the name for.
+     * @return Simple class name.
+     */
+    public static String getSimpleName(Class<?> cls) {
+        return cls.getSimpleName().isEmpty() ? cls.getName() : cls.getSimpleName();
+    }
+
+    /**
+     * Gets absolute value for integer. If integer is {@link Integer#MIN_VALUE}, then {@code 0} is returned.
+     *
+     * @param i Integer.
+     * @return Absolute value.
+     */
+    public static int safeAbs(int i) {
+        i = Math.abs(i);
+
+        return i < 0 ? 0 : i;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridConcurrentHashSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridConcurrentHashSet.java b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridConcurrentHashSet.java
new file mode 100644
index 0000000..1840786
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/util/GridConcurrentHashSet.java
@@ -0,0 +1,113 @@
+/*
+ * 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.util;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+/**
+ * Wrapper around concurrent map.
+ */
+public class GridConcurrentHashSet<E> extends AbstractSet<E> {
+    /** Dummy value. */
+    protected static final Object VAL = Boolean.TRUE;
+
+    /** Base map. */
+    protected ConcurrentMap<E, Object> map;
+
+    /**
+     * Creates new set based on {@link ConcurrentHashMap}.
+     */
+    public GridConcurrentHashSet() {
+        this(new ConcurrentHashMap<E, Object>());
+    }
+
+    /**
+     * Creates new set based on the given map.
+     *
+     * @param map Map to be used for set implementation.
+     */
+    @SuppressWarnings({"unchecked"})
+    public GridConcurrentHashSet(ConcurrentMap<E, ?> map) {
+        this.map = (ConcurrentMap<E, Object>)map;
+    }
+
+    /**
+     * Gets wrapped map.
+     *
+     * @return Wrapped map.
+     */
+    @SuppressWarnings({"unchecked"})
+    protected final <T extends Map<E, Object>> T  map() {
+        return (T)map;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public boolean add(E e) {
+        return map.put(e, VAL) == null;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public Iterator<E> iterator() {
+        return map.keySet().iterator();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return map.size();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings({"SuspiciousMethodCalls"})
+    @Override public boolean contains(Object o) {
+        return map.containsKey(o);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object[] toArray() {
+        return map.keySet().toArray();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings({"SuspiciousToArrayCall"})
+    @Override public <T> T[] toArray(T[] a) {
+        return map.keySet().toArray(a);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean remove(Object o) {
+        return map.remove(o) != null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clear() {
+        map.clear();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return map.keySet().toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
index a4f6488..bb52163 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
@@ -20,13 +20,13 @@ package org.apache.ignite.internal.processors.rest.protocols.tcp;
 import org.apache.ignite.*;
 import org.apache.ignite.configuration.*;
 import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.client.ssl.*;
 import org.apache.ignite.marshaller.*;
 import org.apache.ignite.marshaller.jdk.*;
 import org.apache.ignite.spi.*;
 import org.apache.ignite.client.marshaller.*;
 import org.apache.ignite.client.marshaller.jdk.*;
 import org.apache.ignite.client.marshaller.optimized.*;
-import org.apache.ignite.client.ssl.*;
 import org.apache.ignite.internal.processors.rest.*;
 import org.apache.ignite.internal.processors.rest.client.message.*;
 import org.apache.ignite.internal.processors.rest.protocols.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/test/java/org/apache/ignite/internal/GridLifecycleAwareSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridLifecycleAwareSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridLifecycleAwareSelfTest.java
index 5f6487f..63b3a0f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/GridLifecycleAwareSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/GridLifecycleAwareSelfTest.java
@@ -19,11 +19,11 @@ package org.apache.ignite.internal;
 
 import org.apache.ignite.*;
 import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.client.ssl.*;
 import org.apache.ignite.lifecycle.*;
 import org.apache.ignite.logger.java.*;
 import org.apache.ignite.marshaller.optimized.*;
 import org.apache.ignite.plugin.segmentation.*;
-import org.apache.ignite.client.ssl.*;
 import org.apache.ignite.testframework.junits.common.*;
 import org.jetbrains.annotations.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b88a1012/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
index f4895b9..c1dd3ff 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
@@ -23,10 +23,10 @@ import org.apache.ignite.cache.*;
 import org.apache.ignite.cache.affinity.consistenthash.*;
 import org.apache.ignite.cluster.*;
 import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.client.ssl.*;
 import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.util.*;
 import org.apache.ignite.lang.*;
-import org.apache.ignite.client.ssl.*;
 import org.apache.ignite.internal.processors.cache.distributed.dht.*;
 import org.apache.ignite.internal.processors.cache.distributed.near.*;
 import org.apache.ignite.internal.util.future.*;


Mime
View raw message