1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase;
21
22 import java.util.Collection;
23 import java.util.regex.Pattern;
24
25 import org.apache.hadoop.hbase.util.Addressing;
26 import org.apache.hadoop.hbase.util.Bytes;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class ServerName implements Comparable<ServerName> {
47
48
49
50
51
52
53 private static final short VERSION = 0;
54 static final byte [] VERSION_BYTES = Bytes.toBytes(VERSION);
55
56
57
58
59 public static final int NON_STARTCODE = -1;
60
61
62
63
64
65 public static final String SERVERNAME_SEPARATOR = ",";
66
67 public static Pattern SERVERNAME_PATTERN =
68 Pattern.compile("[^" + SERVERNAME_SEPARATOR + "]+" +
69 SERVERNAME_SEPARATOR + Addressing.VALID_PORT_REGEX +
70 SERVERNAME_SEPARATOR + Addressing.VALID_PORT_REGEX + "$");
71
72 private final String servername;
73 private final String hostname;
74 private final int port;
75 private final long startcode;
76
77
78
79
80
81 private byte [] bytes;
82
83 public ServerName(final String hostname, final int port, final long startcode) {
84 this.hostname = hostname;
85 this.port = port;
86 this.startcode = startcode;
87 this.servername = getServerName(hostname, port, startcode);
88 }
89
90 public ServerName(final String serverName) {
91 this(parseHostname(serverName), parsePort(serverName),
92 parseStartcode(serverName));
93 }
94
95 public ServerName(final String hostAndPort, final long startCode) {
96 this(Addressing.parseHostname(hostAndPort),
97 Addressing.parsePort(hostAndPort), startCode);
98 }
99
100 public static String parseHostname(final String serverName) {
101 if (serverName == null || serverName.length() <= 0) {
102 throw new IllegalArgumentException("Passed hostname is null or empty");
103 }
104 int index = serverName.indexOf(SERVERNAME_SEPARATOR);
105 return serverName.substring(0, index);
106 }
107
108 public static int parsePort(final String serverName) {
109 String [] split = serverName.split(SERVERNAME_SEPARATOR);
110 return Integer.parseInt(split[1]);
111 }
112
113 public static long parseStartcode(final String serverName) {
114 int index = serverName.lastIndexOf(SERVERNAME_SEPARATOR);
115 return Long.parseLong(serverName.substring(index + 1));
116 }
117
118 @Override
119 public String toString() {
120 return getServerName();
121 }
122
123
124
125
126
127 public synchronized byte [] getVersionedBytes() {
128 if (this.bytes == null) {
129 this.bytes = Bytes.add(VERSION_BYTES, Bytes.toBytes(getServerName()));
130 }
131 return this.bytes;
132 }
133
134 public String getServerName() {
135 return servername;
136 }
137
138 public String getHostname() {
139 return hostname;
140 }
141
142 public int getPort() {
143 return port;
144 }
145
146 public long getStartcode() {
147 return startcode;
148 }
149
150
151
152
153
154
155
156
157 public static String getServerName(String hostName, int port, long startcode) {
158 final StringBuilder name = new StringBuilder(hostName.length() + 1 + 5 + 1 + 13);
159 name.append(hostName);
160 name.append(SERVERNAME_SEPARATOR);
161 name.append(port);
162 name.append(SERVERNAME_SEPARATOR);
163 name.append(startcode);
164 return name.toString();
165 }
166
167
168
169
170
171
172
173 public static String getServerName(final String hostAndPort,
174 final long startcode) {
175 int index = hostAndPort.indexOf(":");
176 if (index <= 0) throw new IllegalArgumentException("Expected <hostname> ':' <port>");
177 return getServerName(hostAndPort.substring(0, index),
178 Integer.parseInt(hostAndPort.substring(index + 1)), startcode);
179 }
180
181
182
183
184
185 public String getHostAndPort() {
186 return Addressing.createHostAndPortStr(this.hostname, this.port);
187 }
188
189
190
191
192
193 public static long getServerStartcodeFromServerName(final String serverName) {
194 int index = serverName.lastIndexOf(SERVERNAME_SEPARATOR);
195 return Long.parseLong(serverName.substring(index + 1));
196 }
197
198
199
200
201
202
203 public static String getServerNameLessStartCode(String inServerName) {
204 if (inServerName != null && inServerName.length() > 0) {
205 int index = inServerName.lastIndexOf(SERVERNAME_SEPARATOR);
206 if (index > 0) {
207 return inServerName.substring(0, index);
208 }
209 }
210 return inServerName;
211 }
212
213 @Override
214 public int compareTo(ServerName other) {
215 int compare = this.getHostname().toLowerCase().
216 compareTo(other.getHostname().toLowerCase());
217 if (compare != 0) return compare;
218 compare = this.getPort() - other.getPort();
219 if (compare != 0) return compare;
220 return (int)(this.getStartcode() - other.getStartcode());
221 }
222
223 @Override
224 public int hashCode() {
225 return getServerName().hashCode();
226 }
227
228 @Override
229 public boolean equals(Object o) {
230 if (this == o) return true;
231 if (o == null) return false;
232 if (!(o instanceof ServerName)) return false;
233 return this.compareTo((ServerName)o) == 0;
234 }
235
236
237
238
239
240 public static ServerName findServerWithSameHostnamePort(final Collection<ServerName> names,
241 final ServerName serverName) {
242 for (ServerName sn: names) {
243 if (isSameHostnameAndPort(serverName, sn)) return sn;
244 }
245 return null;
246 }
247
248
249
250
251
252
253 public static boolean isSameHostnameAndPort(final ServerName left,
254 final ServerName right) {
255 if (left == null) return false;
256 if (right == null) return false;
257 return left.getHostname().equals(right.getHostname()) &&
258 left.getPort() == right.getPort();
259 }
260
261
262
263
264
265
266
267
268
269 public static ServerName parseVersionedServerName(final byte [] versionedBytes) {
270
271 short version = Bytes.toShort(versionedBytes);
272 if (version == VERSION) {
273 int length = versionedBytes.length - Bytes.SIZEOF_SHORT;
274 return new ServerName(Bytes.toString(versionedBytes, Bytes.SIZEOF_SHORT, length));
275 }
276
277
278 return new ServerName(Bytes.toString(versionedBytes), NON_STARTCODE);
279 }
280
281
282
283
284
285
286 public static ServerName parseServerName(final String str) {
287 return SERVERNAME_PATTERN.matcher(str).matches()? new ServerName(str):
288 new ServerName(str, NON_STARTCODE);
289 }
290 }