View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.util;
20  
21  import java.net.Inet4Address;
22  import java.net.Inet6Address;
23  import java.net.InetAddress;
24  import java.net.InetSocketAddress;
25  import java.net.NetworkInterface;
26  import java.net.SocketException;
27  import java.util.Enumeration;
28  
29  import org.apache.hadoop.hbase.classification.InterfaceAudience;
30  
31  /**
32   * Utility for network addresses, resolving and naming.
33   */
34  @InterfaceAudience.Private
35  public class Addressing {
36    public static final String VALID_PORT_REGEX = "[\\d]+";
37    public static final String HOSTNAME_PORT_SEPARATOR = ":";
38  
39    /**
40     * @param hostAndPort Formatted as <code>&lt;hostname> ':' &lt;port></code>
41     * @return An InetSocketInstance
42     */
43    public static InetSocketAddress createInetSocketAddressFromHostAndPortStr(
44        final String hostAndPort) {
45      return new InetSocketAddress(parseHostname(hostAndPort), parsePort(hostAndPort));
46    }
47  
48    /**
49     * @param hostname Server hostname
50     * @param port Server port
51     * @return Returns a concatenation of <code>hostname</code> and
52     * <code>port</code> in following
53     * form: <code>&lt;hostname> ':' &lt;port></code>.  For example, if hostname
54     * is <code>example.org</code> and port is 1234, this method will return
55     * <code>example.org:1234</code>
56     */
57    public static String createHostAndPortStr(final String hostname, final int port) {
58      return hostname + HOSTNAME_PORT_SEPARATOR + port;
59    }
60  
61    /**
62     * @param hostAndPort Formatted as <code>&lt;hostname> ':' &lt;port></code>
63     * @return The hostname portion of <code>hostAndPort</code>
64     */
65    public static String parseHostname(final String hostAndPort) {
66      int colonIndex = hostAndPort.lastIndexOf(HOSTNAME_PORT_SEPARATOR);
67      if (colonIndex < 0) {
68        throw new IllegalArgumentException("Not a host:port pair: " + hostAndPort);
69      }
70      return hostAndPort.substring(0, colonIndex);
71    }
72  
73    /**
74     * @param hostAndPort Formatted as <code>&lt;hostname> ':' &lt;port></code>
75     * @return The port portion of <code>hostAndPort</code>
76     */
77    public static int parsePort(final String hostAndPort) {
78      int colonIndex = hostAndPort.lastIndexOf(HOSTNAME_PORT_SEPARATOR);
79      if (colonIndex < 0) {
80        throw new IllegalArgumentException("Not a host:port pair: " + hostAndPort);
81      }
82      return Integer.parseInt(hostAndPort.substring(colonIndex + 1));
83    }
84  
85    public static InetAddress getIpAddress() throws SocketException {
86      // Before we connect somewhere, we cannot be sure about what we'd be bound to; however,
87      // we only connect when the message where client ID is, is long constructed. Thus,
88      // just use whichever IP address we can find.
89      Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
90      while (interfaces.hasMoreElements()) {
91        NetworkInterface current = interfaces.nextElement();
92        if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue;
93        Enumeration<InetAddress> addresses = current.getInetAddresses();
94        while (addresses.hasMoreElements()) {
95          InetAddress addr = addresses.nextElement();
96          if (addr.isLoopbackAddress()) continue;
97          if (addr instanceof Inet4Address || addr instanceof Inet6Address) {
98            return addr;
99          }
100       }
101     }
102 
103     throw new SocketException("Can't get our ip address, interfaces are: " + interfaces);
104   }
105 
106   /**
107    * Given an InetAddress, checks to see if the address is a local address, by comparing the address
108    * with all the interfaces on the node.
109    * @param addr address to check if it is local node's address
110    * @return true if the address corresponds to the local node
111    */
112   public static boolean isLocalAddress(InetAddress addr) {
113     // Check if the address is any local or loop back
114     boolean local = addr.isAnyLocalAddress() || addr.isLoopbackAddress();
115 
116     // Check if the address is defined on any interface
117     if (!local) {
118       try {
119         local = NetworkInterface.getByInetAddress(addr) != null;
120       } catch (SocketException e) {
121         local = false;
122       }
123     }
124     return local;
125   }
126 }