001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.net; 019 020import org.apache.commons.lang3.StringUtils; 021import org.apache.yetus.audience.InterfaceAudience; 022 023import org.apache.hbase.thirdparty.com.google.common.net.HostAndPort; 024 025/** 026 * An immutable type to hold a hostname and port combo, like an Endpoint 027 * or java.net.InetSocketAddress (but without danger of our calling 028 * resolve -- we do NOT want a resolve happening every time we want 029 * to hold a hostname and port combo). This class is also <<Comparable>>. 030 * <p>In implementation this class is a facade over Guava's {@link HostAndPort}. 031 * We cannot have Guava classes in our API hence this Type. 032 */ 033@InterfaceAudience.Public 034public class Address implements Comparable<Address> { 035 private HostAndPort hostAndPort; 036 037 private Address(HostAndPort hostAndPort) { 038 this.hostAndPort = hostAndPort; 039 } 040 041 public static Address fromParts(String hostname, int port) { 042 return new Address(HostAndPort.fromParts(hostname, port)); 043 } 044 045 public static Address fromString(String hostnameAndPort) { 046 return new Address(HostAndPort.fromString(hostnameAndPort)); 047 } 048 049 public String getHostname() { 050 return this.hostAndPort.getHost(); 051 } 052 053 public int getPort() { 054 return this.hostAndPort.getPort(); 055 } 056 057 @Override 058 public String toString() { 059 return this.hostAndPort.toString(); 060 } 061 062 /** 063 * If hostname is a.b.c and the port is 123, return a:123 instead of a.b.c:123. 064 * @return if host looks like it is resolved -- not an IP -- then strip the domain portion 065 * otherwise returns same as {@link #toString()}} 066 */ 067 public String toStringWithoutDomain() { 068 String hostname = getHostname(); 069 String [] parts = hostname.split("\\."); 070 if (parts.length > 1) { 071 for (String part: parts) { 072 if (!StringUtils.isNumeric(part)) { 073 return Address.fromParts(parts[0], getPort()).toString(); 074 } 075 } 076 } 077 return toString(); 078 } 079 080 @Override 081 // Don't use HostAndPort equals... It is wonky including 082 // ipv6 brackets 083 public boolean equals(Object other) { 084 if (this == other) { 085 return true; 086 } 087 if (other instanceof Address) { 088 Address that = (Address)other; 089 return this.getHostname().equals(that.getHostname()) && 090 this.getPort() == that.getPort(); 091 } 092 return false; 093 } 094 095 @Override 096 public int hashCode() { 097 return this.getHostname().hashCode() ^ getPort(); 098 } 099 100 @Override 101 public int compareTo(Address that) { 102 int compare = this.getHostname().compareTo(that.getHostname()); 103 if (compare != 0) return compare; 104 return this.getPort() - that.getPort(); 105 } 106}