Returns a new client for the RS found in the root-region-server.
(final byte[] data)
| 4412 | |
| 4413 | /** Returns a new client for the RS found in the root-region-server. */ |
| 4414 | @SuppressWarnings("fallthrough") |
| 4415 | protected RegionClient handleRootZnode(final byte[] data) { |
| 4416 | // There are 3 cases. Older versions of HBase encode the location |
| 4417 | // of the root region as "host:port", 0.91 uses "host,port,startcode" |
| 4418 | // and newer versions of 0.91 use "<metadata>host,port,startcode" |
| 4419 | // where the <metadata> starts with MAGIC, then a 4 byte integer, |
| 4420 | // then that many bytes of meta data. |
| 4421 | boolean newstyle; // True if we expect a 0.91 style location. |
| 4422 | final short offset; // Bytes to skip at the beginning of data. |
| 4423 | short firstsep = -1; // Index of the first separator (':' or ','). |
| 4424 | if (data[0] == MAGIC) { |
| 4425 | newstyle = true; |
| 4426 | final int metadata_length = Bytes.getInt(data, 1); |
| 4427 | if (metadata_length < 1 || metadata_length > 65000) { |
| 4428 | LOG.error("Malformed meta-data in " + Bytes.pretty(data) |
| 4429 | + ", invalid metadata length=" + metadata_length); |
| 4430 | return null; // TODO(tsuna): Add a watch to wait until the file changes. |
| 4431 | } |
| 4432 | offset = (short) (1 + 4 + metadata_length); |
| 4433 | } else { |
| 4434 | newstyle = false; // Maybe true, the loop below will tell us. |
| 4435 | offset = 0; |
| 4436 | } |
| 4437 | final short n = (short) data.length; |
| 4438 | // Look for the first separator. Skip the offset, and skip the |
| 4439 | // first byte, because we know the separate can only come after |
| 4440 | // at least one byte. |
| 4441 | loop: for (short i = (short) (offset + 1); i < n; i++) { |
| 4442 | switch (data[i]) { |
| 4443 | case ',': |
| 4444 | newstyle = true; |
| 4445 | /* fall through */ |
| 4446 | case ':': |
| 4447 | firstsep = i; |
| 4448 | break loop; |
| 4449 | } |
| 4450 | } |
| 4451 | if (firstsep == -1) { |
| 4452 | LOG.error("-ROOT- location doesn't contain a separator" |
| 4453 | + " (':' or ','): " + Bytes.pretty(data)); |
| 4454 | return null; // TODO(tsuna): Add a watch to wait until the file changes. |
| 4455 | } |
| 4456 | final String host; |
| 4457 | final short portend; // Index past where the port number ends. |
| 4458 | if (newstyle) { |
| 4459 | host = new String(data, offset, firstsep - offset); |
| 4460 | short i; |
| 4461 | for (i = (short) (firstsep + 2); i < n; i++) { |
| 4462 | if (data[i] == ',') { |
| 4463 | break; |
| 4464 | } |
| 4465 | } |
| 4466 | portend = i; // Port ends on the comma. |
| 4467 | } else { |
| 4468 | host = new String(data, 0, firstsep); |
| 4469 | portend = n; // Port ends at the end of the array. |
| 4470 | } |
| 4471 | final int port = parsePortNumber(new String(data, firstsep + 1, |