ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject ignite git commit: IGNITE-2916: Implemented port bind procedure.
Date Tue, 26 Apr 2016 11:27:59 GMT
Repository: ignite
Updated Branches:
  refs/heads/ignite-2916-1 [created] 5fe1ba8ad


IGNITE-2916: Implemented port bind procedure.


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

Branch: refs/heads/ignite-2916-1
Commit: 5fe1ba8ad283c11e90d2671cd39ac7154af977ab
Parents: 7f0737d
Author: vozerov-gridgain <vozerov@gridgain.com>
Authored: Tue Apr 26 14:27:52 2016 +0300
Committer: vozerov-gridgain <vozerov@gridgain.com>
Committed: Tue Apr 26 14:27:52 2016 +0300

----------------------------------------------------------------------
 .../ignite/configuration/OdbcConfiguration.java |  70 +++----
 .../internal/processors/odbc/OdbcProcessor.java | 102 ++++++---
 .../ignite/internal/util/HostAndPortRange.java  | 206 +++++++++++++++++++
 3 files changed, 305 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5fe1ba8a/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
b/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
index 65078c4..36d375e 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
@@ -21,17 +21,20 @@ package org.apache.ignite.configuration;
  * ODBC configuration.
  */
 public class OdbcConfiguration {
-    /** Default TCP server port. */
-    public static final int DFLT_TCP_PORT = 11443;
+    /** Default TCP host. */
+    public static final String DFLT_TCP_HOST = "0.0.0.0";
+
+    /** Default minimum TCP port range value. */
+    public static final int DFLT_TCP_PORT_FROM = 10800;
+
+    /** Default maximum TCP port range value. */
+    public static final int DFLT_TCP_PORT_TO = 10810;
 
     /** Default max number of open cursors per connection. */
     public static final int DFLT_MAX_OPEN_CURSORS = 128;
 
-    /** TCP port. */
-    private int port = DFLT_TCP_PORT;
-
-    /** TCP host. */
-    private String host;
+    /** Endpoint address. */
+    private String endpointAddr;
 
     /** Max number of opened cursors per connection. */
     private int maxOpenCursors = DFLT_MAX_OPEN_CURSORS;
@@ -52,54 +55,39 @@ public class OdbcConfiguration {
     public OdbcConfiguration(OdbcConfiguration cfg) {
         assert cfg != null;
 
-        host = cfg.getHost();
+        endpointAddr = cfg.getEndpointAddress();
         maxOpenCursors = cfg.getMaxOpenCursors();
-        port = cfg.getPort();
     }
 
     /**
-     * Gets port for TCP ODBC server.
+     * Get ODBC endpoint address. Ignite will listen for incoming TCP connections on this
address. Either single port
+     * or port range could be used. In the latter case Ignite will start listening on the
first available port
+     * form the range.
      * <p>
-     * Default is {@link #DFLT_TCP_PORT}.
-     *
-     * @return TCP port.
-     */
-    public int getPort() {
-        return port;
-    }
-
-    /**
-     * Sets port for TCP ODBC server.
-     *
-     * @param port TCP port.
-     */
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    /**
-     * Gets host for TCP ODBC server. This can be either an
-     * IP address or a domain name.
+     * The following address formats are permitted:
+     * <ul>
+     *     <li>{@code hostname} - will use provided hostname and default port range;</li>
+     *     <li>{@code hostname:port} - will use provided hostname and port;</li>
+     *     <li>{@code hostname:port_from..port_to} - will use provided hostname and
port range.</li>
+     * </ul>
      * <p>
-     * If not defined, system-wide local address will be used
-     * (see {@link IgniteConfiguration#getLocalHost()}.
+     * When set to {@code null}, ODBC processor will be bound to {@link #DFLT_TCP_HOST} host
and default port range.
      * <p>
-     * You can also use {@code 0.0.0.0} value to bind to all
-     * locally-available IP addresses.
+     * Default port range is from {@link #DFLT_TCP_PORT_FROM} to {@link #DFLT_TCP_PORT_TO}.
      *
-     * @return TCP host.
+     * @return ODBC endpoint address.
      */
-    public String getHost() {
-        return host;
+    public String getEndpointAddress() {
+        return endpointAddr;
     }
 
     /**
-     * Sets host for TCP ODBC server.
+     * Set ODBC endpoint address. See {@link #getEndpointAddress()} for more information.
      *
-     * @param host TCP host.
+     * @param addr ODBC endpoint address.
      */
-    public void setHost(String host) {
-        this.host = host;
+    public void setEndpointAddress(String addr) {
+        this.endpointAddr = addr;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/5fe1ba8a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
index 3bca056..360d1ac 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
@@ -23,9 +23,10 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
+import org.apache.ignite.internal.util.HostAndPortRange;
 import org.apache.ignite.internal.util.nio.GridNioCodecFilter;
 import org.apache.ignite.internal.util.nio.GridNioServer;
-import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.spi.IgnitePortProtocol;
 
@@ -73,37 +74,74 @@ public class OdbcProcessor extends GridProcessorAdapter {
                     throw new IgniteCheckedException("ODBC can only be used with BinaryMarshaller
(please set it " +
                         "through IgniteConfiguration.setMarshaller())");
 
-                String hostStr = odbcCfg.getHost();
-
-                if (hostStr == null)
-                    hostStr = ctx.config().getLocalHost();
-
-                InetAddress host = U.resolveLocalHost(hostStr);
-
-                int port = odbcCfg.getPort();
-
-                srv = GridNioServer.<byte[]>builder()
-                    .address(host)
-                    .port(port)
-                    .listener(new OdbcNioListener(ctx, busyLock))
-                    .logger(log)
-                    .selectorCount(DFLT_SELECTOR_CNT)
-                    .gridName(ctx.gridName())
-                    .tcpNoDelay(DFLT_TCP_NODELAY)
-                    .directBuffer(DFLT_TCP_DIRECT_BUF)
-                    .byteOrder(ByteOrder.nativeOrder())
-                    .socketSendBufferSize(DFLT_SOCK_BUF_SIZE)
-                    .socketReceiveBufferSize(DFLT_SOCK_BUF_SIZE)
-                    .filters(new GridNioCodecFilter(new OdbcBufferedParser(), log, false))
-                    .directMode(false)
-                    .idleTimeout(Long.MAX_VALUE)
-                    .build();
-
-                srv.start();
-
-                ctx.ports().registerPort(port, IgnitePortProtocol.TCP, getClass());
-
-                log.info("ODBC processor has started on TCP port " + port);
+                HostAndPortRange hostPort;
+
+                if (F.isEmpty(odbcCfg.getEndpointAddress())) {
+                    hostPort = new HostAndPortRange(OdbcConfiguration.DFLT_TCP_HOST,
+                        OdbcConfiguration.DFLT_TCP_PORT_FROM,
+                        OdbcConfiguration.DFLT_TCP_PORT_TO
+                    );
+                }
+                else {
+                    hostPort = HostAndPortRange.parse(odbcCfg.getEndpointAddress(),
+                        OdbcConfiguration.DFLT_TCP_PORT_FROM,
+                        OdbcConfiguration.DFLT_TCP_PORT_TO,
+                        "Failed to parse ODBC endpoint address"
+                    );
+                }
+
+                InetAddress host;
+
+                try {
+                    host = InetAddress.getByName(hostPort.host());
+                }
+                catch (Exception e) {
+                    throw new IgniteCheckedException("Failed to resolve ODBC host: " + hostPort.host(),
e);
+                }
+
+                Exception lastErr = null;
+
+                for (int port = hostPort.portFrom(); port <= hostPort.portTo(); port++)
{
+                    try {
+                        GridNioServer<byte[]> srv0 = GridNioServer.<byte[]>builder()
+                            .address(host)
+                            .port(port)
+                            .listener(new OdbcNioListener(ctx, busyLock))
+                            .logger(log)
+                            .selectorCount(DFLT_SELECTOR_CNT)
+                            .gridName(ctx.gridName())
+                            .tcpNoDelay(DFLT_TCP_NODELAY)
+                            .directBuffer(DFLT_TCP_DIRECT_BUF)
+                            .byteOrder(ByteOrder.nativeOrder())
+                            .socketSendBufferSize(DFLT_SOCK_BUF_SIZE)
+                            .socketReceiveBufferSize(DFLT_SOCK_BUF_SIZE)
+                            .filters(new GridNioCodecFilter(new OdbcBufferedParser(), log,
false))
+                            .directMode(false)
+                            .idleTimeout(Long.MAX_VALUE)
+                            .build();
+
+                        srv0.start();
+
+                        srv = srv0;
+
+                        ctx.ports().registerPort(port, IgnitePortProtocol.TCP, getClass());
+
+                        log.info("ODBC processor has started on TCP port " + port);
+
+                        lastErr = null;
+
+                        break;
+                    }
+                    catch (Exception e) {
+                        lastErr = e;
+                    }
+                }
+
+                assert (srv != null && lastErr == null) || (srv == null &&
lastErr != null);
+
+                if (lastErr != null)
+                    throw new IgniteCheckedException("Failed to bind to any [host:port] from
the range [" +
+                        "address=" + hostPort + ", lastErr=" + lastErr + ']');
             }
             catch (Exception e) {
                 throw new IgniteCheckedException("Failed to start ODBC processor.", e);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5fe1ba8a/modules/core/src/main/java/org/apache/ignite/internal/util/HostAndPortRange.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/HostAndPortRange.java
b/modules/core/src/main/java/org/apache/ignite/internal/util/HostAndPortRange.java
new file mode 100644
index 0000000..f85f780
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/HostAndPortRange.java
@@ -0,0 +1,206 @@
+/*
+ * 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.util;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Represents address along with port range.
+ */
+public class HostAndPortRange {
+    /** Host. */
+    private final String host;
+
+    /** Port from. */
+    private final int portFrom;
+
+    /** Port to. */
+    private final int portTo;
+
+    /**
+     * Parse string into host and port pair.
+     *
+     * @param addrStr String.
+     * @param dfltPortFrom Default port from.
+     * @param dfltPortTo Default port to.
+     * @param errMsgPrefix Error message prefix.
+     * @return Result.
+     * @throws IgniteCheckedException If failed.
+     */
+    public static HostAndPortRange parse(String addrStr, int dfltPortFrom, int dfltPortTo,
String errMsgPrefix)
+        throws IgniteCheckedException {
+        assert dfltPortFrom <= dfltPortTo;
+
+        String host;
+
+        int portFrom;
+        int portTo;
+
+        final int colIdx = addrStr.indexOf(':');
+
+        if (colIdx > 0) {
+            String portFromStr;
+            String portToStr;
+
+            host = addrStr.substring(0, colIdx);
+
+            String portStr = addrStr.substring(colIdx + 1, addrStr.length());
+
+            if (F.isEmpty(portStr))
+                throw createParseError(addrStr, errMsgPrefix, "port range is not specified");
+
+            int portRangeIdx = portStr.indexOf("..");
+
+            if (portRangeIdx >= 0) {
+                // Port range is specified.
+                portFromStr = portStr.substring(0, portRangeIdx);
+                portToStr = portStr.substring(portRangeIdx + 2, portStr.length());
+            }
+            else {
+                // Single port is specified.
+                portFromStr = portStr;
+                portToStr = portStr;
+            }
+
+            portFrom = parsePort(portFromStr, addrStr, errMsgPrefix);
+            portTo = parsePort(portToStr, addrStr, errMsgPrefix);
+
+            if (portFrom > portTo)
+                throw createParseError(addrStr, errMsgPrefix, "start port cannot be less
than end port");
+        }
+        else {
+            // Port is not specified, use defaults.
+            host = addrStr;
+
+            portFrom = dfltPortFrom;
+            portTo = dfltPortTo;
+        }
+
+        return new HostAndPortRange(host, portFrom, portTo);
+    }
+
+    /**
+     * Parse port.
+     *
+     * @param portStr Port string.
+     * @param addrStr Address string.
+     * @param errMsgPrefix Error message prefix.
+     * @return Parsed port.
+     * @throws IgniteCheckedException If failed.
+     */
+    private static int parsePort(String portStr, String addrStr, String errMsgPrefix) throws
IgniteCheckedException {
+        try {
+            int port = Integer.parseInt(portStr);
+
+            if (port < 0 || port > 65535)
+                throw createParseError(addrStr, errMsgPrefix, "port range contains invalid
port " + portStr);
+
+            return port;
+        }
+        catch (NumberFormatException e) {
+            throw createParseError(addrStr, errMsgPrefix, "port range contains invalid port
" + portStr);
+        }
+    }
+
+    /**
+     * Create parse error.
+     *
+     * @param addrStr Address string.
+     * @param errMsgPrefix Error message prefix.
+     * @param errMsg Error message.
+     * @return Exception.
+     */
+    private static IgniteCheckedException createParseError(String addrStr, String errMsgPrefix,
String errMsg) {
+        return new IgniteCheckedException(errMsgPrefix + " (" + errMsg + "): " + addrStr);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param host Host.
+     * @param port Port.
+     */
+    public HostAndPortRange(String host, int port) {
+        this(host, port, port);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param host Host.
+     * @param portFrom Port from.
+     * @param portTo Port to.
+     */
+    public HostAndPortRange(String host, int portFrom, int portTo) {
+        assert !F.isEmpty(host);
+        assert portFrom <= portTo;
+
+        this.host = host;
+        this.portFrom = portFrom;
+        this.portTo = portTo;
+    }
+
+    /**
+     * @return Host.
+     */
+    public String host() {
+        return host;
+    }
+
+    /**
+     * @return Port from.
+     */
+    public int portFrom() {
+        return portFrom;
+    }
+
+    /**
+     * @return Port to.
+     */
+    public int portTo() {
+        return portTo;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (o != null && o instanceof HostAndPortRange) {
+            HostAndPortRange other = (HostAndPortRange)o;
+
+            return F.eq(host, other.host) && portFrom == other.portFrom &&
portTo == other.portTo;
+        }
+        else
+            return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = host.hashCode();
+
+        res = 31 * res + portFrom;
+        res = 31 * res + portTo;
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return host + ":" + (portFrom == portTo ? portFrom : portFrom + ".." + portTo);
+    }
+}


Mime
View raw message