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
73
74
75 public static final String UNKNOWN_SERVERNAME = "#unknown#";
76
77 private final String servername;
78 private final String hostname;
79 private final int port;
80 private final long startcode;
81
82
83
84
85
86 private byte [] bytes;
87
88 public ServerName(final String hostname, final int port, final long startcode) {
89 this.hostname = hostname;
90 this.port = port;
91 this.startcode = startcode;
92 this.servername = getServerName(hostname, port, startcode);
93 }
94
95 public ServerName(final String serverName) {
96 this(parseHostname(serverName), parsePort(serverName),
97 parseStartcode(serverName));
98 }
99
100 public ServerName(final String hostAndPort, final long startCode) {
101 this(Addressing.parseHostname(hostAndPort),
102 Addressing.parsePort(hostAndPort), startCode);
103 }
104
105 public static String parseHostname(final String serverName) {
106 if (serverName == null || serverName.length() <= 0) {
107 throw new IllegalArgumentException("Passed hostname is null or empty");
108 }
109 int index = serverName.indexOf(SERVERNAME_SEPARATOR);
110 return serverName.substring(0, index);
111 }
112
113 public static int parsePort(final String serverName) {
114 String [] split = serverName.split(SERVERNAME_SEPARATOR);
115 return Integer.parseInt(split[1]);
116 }
117
118 public static long parseStartcode(final String serverName) {
119 int index = serverName.lastIndexOf(SERVERNAME_SEPARATOR);
120 return Long.parseLong(serverName.substring(index + 1));
121 }
122
123 @Override
124 public String toString() {
125 return getServerName();
126 }
127
128
129
130
131
132 public synchronized byte [] getVersionedBytes() {
133 if (this.bytes == null) {
134 this.bytes = Bytes.add(VERSION_BYTES, Bytes.toBytes(getServerName()));
135 }
136 return this.bytes;
137 }
138
139 public String getServerName() {
140 return servername;
141 }
142
143 public String getHostname() {
144 return hostname;
145 }
146
147 public int getPort() {
148 return port;
149 }
150
151 public long getStartcode() {
152 return startcode;
153 }
154
155
156
157
158
159
160
161
162 public static String getServerName(String hostName, int port, long startcode) {
163 final StringBuilder name = new StringBuilder(hostName.length() + 1 + 5 + 1 + 13);
164 name.append(hostName);
165 name.append(SERVERNAME_SEPARATOR);
166 name.append(port);
167 name.append(SERVERNAME_SEPARATOR);
168 name.append(startcode);
169 return name.toString();
170 }
171
172
173
174
175
176
177
178 public static String getServerName(final String hostAndPort,
179 final long startcode) {
180 int index = hostAndPort.indexOf(":");
181 if (index <= 0) throw new IllegalArgumentException("Expected <hostname> ':' <port>");
182 return getServerName(hostAndPort.substring(0, index),
183 Integer.parseInt(hostAndPort.substring(index + 1)), startcode);
184 }
185
186
187
188
189
190 public String getHostAndPort() {
191 return Addressing.createHostAndPortStr(this.hostname, this.port);
192 }
193
194
195
196
197
198 public static long getServerStartcodeFromServerName(final String serverName) {
199 int index = serverName.lastIndexOf(SERVERNAME_SEPARATOR);
200 return Long.parseLong(serverName.substring(index + 1));
201 }
202
203
204
205
206
207
208 public static String getServerNameLessStartCode(String inServerName) {
209 if (inServerName != null && inServerName.length() > 0) {
210 int index = inServerName.lastIndexOf(SERVERNAME_SEPARATOR);
211 if (index > 0) {
212 return inServerName.substring(0, index);
213 }
214 }
215 return inServerName;
216 }
217
218 @Override
219 public int compareTo(ServerName other) {
220 int compare = this.getHostname().toLowerCase().
221 compareTo(other.getHostname().toLowerCase());
222 if (compare != 0) return compare;
223 compare = this.getPort() - other.getPort();
224 if (compare != 0) return compare;
225 return (int)(this.getStartcode() - other.getStartcode());
226 }
227
228 @Override
229 public int hashCode() {
230 return getServerName().hashCode();
231 }
232
233 @Override
234 public boolean equals(Object o) {
235 if (this == o) return true;
236 if (o == null) return false;
237 if (!(o instanceof ServerName)) return false;
238 return this.compareTo((ServerName)o) == 0;
239 }
240
241
242
243
244
245 public static ServerName findServerWithSameHostnamePort(final Collection<ServerName> names,
246 final ServerName serverName) {
247 for (ServerName sn: names) {
248 if (isSameHostnameAndPort(serverName, sn)) return sn;
249 }
250 return null;
251 }
252
253
254
255
256
257
258 public static boolean isSameHostnameAndPort(final ServerName left,
259 final ServerName right) {
260 if (left == null) return false;
261 if (right == null) return false;
262 return left.getHostname().equals(right.getHostname()) &&
263 left.getPort() == right.getPort();
264 }
265
266
267
268
269
270
271
272
273
274 public static ServerName parseVersionedServerName(final byte [] versionedBytes) {
275
276 short version = Bytes.toShort(versionedBytes);
277 if (version == VERSION) {
278 int length = versionedBytes.length - Bytes.SIZEOF_SHORT;
279 return new ServerName(Bytes.toString(versionedBytes, Bytes.SIZEOF_SHORT, length));
280 }
281
282
283 return new ServerName(Bytes.toString(versionedBytes), NON_STARTCODE);
284 }
285
286
287
288
289
290
291 public static ServerName parseServerName(final String str) {
292 return SERVERNAME_PATTERN.matcher(str).matches()? new ServerName(str):
293 new ServerName(str, NON_STARTCODE);
294 }
295 }