View Javadoc

1   /**
2    * Copyright 2007 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase;
21  
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.hadoop.io.WritableComparable;
24  
25  import java.io.DataInput;
26  import java.io.DataOutput;
27  import java.io.IOException;
28  import java.net.InetSocketAddress;
29  import java.net.InetAddress;
30  
31  /**
32   * HServerAddress is a "label" for a HBase server made of host and port number.
33   */
34  public class HServerAddress implements WritableComparable<HServerAddress> {
35    private InetSocketAddress address;
36    String stringValue;
37  
38    public HServerAddress() {
39      this.address = null;
40      this.stringValue = null;
41    }
42  
43    /**
44     * Construct an instance from an {@link InetSocketAddress}.
45     * @param address InetSocketAddress of server
46     */
47    public HServerAddress(InetSocketAddress address) {
48      this.address = address;
49      this.stringValue = address.getAddress().getHostName() + ":" +
50        address.getPort();
51      checkBindAddressCanBeResolved();
52    }
53  
54    /**
55     * @param hostAndPort Hostname and port formatted as <code>&lt;hostname> ':' &lt;port></code>
56     */
57    public HServerAddress(String hostAndPort) {
58      int colonIndex = hostAndPort.lastIndexOf(':');
59      if (colonIndex < 0) {
60        throw new IllegalArgumentException("Not a host:port pair: " + hostAndPort);
61      }
62      String host = hostAndPort.substring(0, colonIndex);
63      int port = Integer.parseInt(hostAndPort.substring(colonIndex + 1));
64      this.address = getResolvedAddress(new InetSocketAddress(host, port));
65      this.stringValue = address.getHostName() + ":" + port;
66      checkBindAddressCanBeResolved();
67    }
68  
69    /**
70     * @param bindAddress Hostname
71     * @param port Port number
72     */
73    public HServerAddress(String bindAddress, int port) {
74      this.address = getResolvedAddress(new InetSocketAddress(bindAddress, port));
75      this.stringValue = address.getHostName() + ":" + port;
76      checkBindAddressCanBeResolved();
77    }
78  
79    /**
80     * Copy-constructor.
81     * @param other HServerAddress to copy from
82     */
83    public HServerAddress(HServerAddress other) {
84      this.address = getResolvedAddress(other.getInetSocketAddress());
85      stringValue = other.stringValue;
86      checkBindAddressCanBeResolved();
87    }
88  
89    /** @return Bind address */
90    public String getBindAddress() {
91      return getBindAddressInternal(address);
92    }
93    
94    private static String getBindAddressInternal(InetSocketAddress address) {
95      final InetAddress addr = address.getAddress();
96      if (addr != null) {
97        return addr.getHostAddress();
98      } else {
99        LogFactory.getLog(HServerAddress.class).error("Could not resolve the"
100           + " DNS name of " + address.getHostName());
101       return null;
102     }    
103   }
104   
105   private static InetSocketAddress getResolvedAddress(InetSocketAddress address) {
106     String bindAddress = getBindAddressInternal(address);
107     int port = address.getPort();
108     return new InetSocketAddress(bindAddress, port);    
109   }
110 
111   private void checkBindAddressCanBeResolved() {
112     if (getBindAddress() == null) {
113       throw new IllegalArgumentException("Could not resolve the"
114           + " DNS name of " + stringValue);
115     }
116   }
117 
118   /** @return Port number */
119   public int getPort() {
120     return address.getPort();
121   }
122 
123   /** @return Hostname */
124   public String getHostname() {
125     return address.getHostName();
126   }
127 
128   /** @return The InetSocketAddress */
129   public InetSocketAddress getInetSocketAddress() {
130     return address;
131   }
132 
133   /**
134    * @return String formatted as <code>&lt;bind address> ':' &lt;port></code>
135    */
136   @Override
137   public String toString() {
138     return stringValue == null ? "" : stringValue;
139   }
140 
141   @Override
142   public boolean equals(Object o) {
143     if (this == o) {
144       return true;
145     }
146     if (o == null) {
147       return false;
148     }
149     if (getClass() != o.getClass()) {
150       return false;
151     }
152     return compareTo((HServerAddress) o) == 0;
153   }
154 
155   @Override
156   public int hashCode() {
157     int result = address == null? 0: address.hashCode();
158     result ^= toString().hashCode();
159     return result;
160   }
161 
162   //
163   // Writable
164   //
165 
166   public void readFields(DataInput in) throws IOException {
167     String hostname = in.readUTF();
168     int port = in.readInt();
169 
170     if (hostname == null || hostname.length() == 0) {
171       address = null;
172       stringValue = null;
173     } else {
174       address = getResolvedAddress(new InetSocketAddress(hostname, port));
175       stringValue = hostname + ":" + port;
176       checkBindAddressCanBeResolved();
177     }
178   }
179 
180   public void write(DataOutput out) throws IOException {
181     if (address == null) {
182       out.writeUTF("");
183       out.writeInt(0);
184     } else {
185       out.writeUTF(address.getAddress().getHostName());
186       out.writeInt(address.getPort());
187     }
188   }
189 
190   //
191   // Comparable
192   //
193 
194   public int compareTo(HServerAddress o) {
195     // Addresses as Strings may not compare though address is for the one
196     // server with only difference being that one address has hostname
197     // resolved whereas other only has IP.
198     if (this.address == null) return -1;
199     if (o.address == null) return 1;
200     if (address.equals(o.address)) return 0;
201     return toString().compareTo(o.toString());
202   }  
203 }