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 or 027 * java.net.InetSocketAddress (but without danger of our calling resolve -- we do NOT want a resolve 028 * happening every time we want to hold a hostname and port combo). This class is also 029 * {@link Comparable} 030 * <p> 031 * In implementation this class is a facade over Guava's {@link HostAndPort}. We cannot have Guava 032 * classes in our API hence this Type. 033 */ 034@InterfaceAudience.Public 035public class Address implements Comparable<Address> { 036 private HostAndPort hostAndPort; 037 038 private Address(HostAndPort hostAndPort) { 039 this.hostAndPort = hostAndPort; 040 } 041 042 public static Address fromParts(String hostname, int port) { 043 return new Address(HostAndPort.fromParts(hostname, port)); 044 } 045 046 public static Address fromString(String hostnameAndPort) { 047 return new Address(HostAndPort.fromString(hostnameAndPort)); 048 } 049 050 public String getHostname() { 051 return this.hostAndPort.getHost(); 052 } 053 054 public int getPort() { 055 return this.hostAndPort.getPort(); 056 } 057 058 @Override 059 public String toString() { 060 return this.hostAndPort.toString(); 061 } 062 063 /** 064 * If hostname is a.b.c and the port is 123, return a:123 instead of a.b.c:123. 065 * @return if host looks like it is resolved -- not an IP -- then strip the domain portion 066 * otherwise returns same as {@link #toString()}} 067 */ 068 public String toStringWithoutDomain() { 069 String hostname = getHostname(); 070 String[] parts = hostname.split("\\."); 071 if (parts.length > 1) { 072 for (String part : parts) { 073 if (!StringUtils.isNumeric(part)) { 074 return Address.fromParts(parts[0], getPort()).toString(); 075 } 076 } 077 } 078 return toString(); 079 } 080 081 @Override 082 // Don't use HostAndPort equals... It is wonky including 083 // ipv6 brackets 084 public boolean equals(Object other) { 085 if (this == other) { 086 return true; 087 } 088 if (other instanceof Address) { 089 Address that = (Address) other; 090 return this.getHostname().equals(that.getHostname()) && 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) { 104 return compare; 105 } 106 107 return this.getPort() - that.getPort(); 108 } 109}