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.thrift2; 019 020import static org.apache.hadoop.hbase.HConstants.DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD; 021import static org.apache.hadoop.hbase.HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD; 022import static org.apache.hadoop.hbase.thrift.Constants.THRIFT_READONLY_ENABLED; 023import static org.apache.hadoop.hbase.thrift.Constants.THRIFT_READONLY_ENABLED_DEFAULT; 024import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.appendFromThrift; 025import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.columnFamilyDescriptorFromThrift; 026import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.compareOpFromThrift; 027import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.deleteFromThrift; 028import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.deletesFromThrift; 029import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.getFromThrift; 030import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.getsFromThrift; 031import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.incrementFromThrift; 032import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.namespaceDescriptorFromHBase; 033import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.namespaceDescriptorFromThrift; 034import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.namespaceDescriptorsFromHBase; 035import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.putFromThrift; 036import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.putsFromThrift; 037import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.resultFromHBase; 038import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.resultsFromHBase; 039import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.rowMutationsFromThrift; 040import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.scanFromThrift; 041import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.splitKeyFromThrift; 042import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.tableDescriptorFromHBase; 043import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.tableDescriptorFromThrift; 044import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.tableDescriptorsFromHBase; 045import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.tableNameFromThrift; 046import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.tableNamesFromHBase; 047import static org.apache.thrift.TBaseHelper.byteBufferToByteArray; 048 049import java.io.IOException; 050import java.nio.ByteBuffer; 051import java.util.ArrayList; 052import java.util.Collections; 053import java.util.List; 054import java.util.Set; 055import java.util.concurrent.TimeUnit; 056import java.util.concurrent.atomic.AtomicInteger; 057import java.util.regex.Pattern; 058import org.apache.hadoop.conf.Configuration; 059import org.apache.hadoop.hbase.DoNotRetryIOException; 060import org.apache.hadoop.hbase.HRegionLocation; 061import org.apache.hadoop.hbase.NamespaceDescriptor; 062import org.apache.hadoop.hbase.ServerName; 063import org.apache.hadoop.hbase.TableName; 064import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 065import org.apache.hadoop.hbase.client.LogQueryFilter; 066import org.apache.hadoop.hbase.client.OnlineLogRecord; 067import org.apache.hadoop.hbase.client.RegionLocator; 068import org.apache.hadoop.hbase.client.ResultScanner; 069import org.apache.hadoop.hbase.client.Table; 070import org.apache.hadoop.hbase.client.TableDescriptor; 071import org.apache.hadoop.hbase.security.UserProvider; 072import org.apache.hadoop.hbase.security.access.AccessControlClient; 073import org.apache.hadoop.hbase.security.access.Permission; 074import org.apache.hadoop.hbase.thrift.HBaseServiceHandler; 075import org.apache.hadoop.hbase.thrift2.generated.TAccessControlEntity; 076import org.apache.hadoop.hbase.thrift2.generated.TAppend; 077import org.apache.hadoop.hbase.thrift2.generated.TColumnFamilyDescriptor; 078import org.apache.hadoop.hbase.thrift2.generated.TCompareOperator; 079import org.apache.hadoop.hbase.thrift2.generated.TDelete; 080import org.apache.hadoop.hbase.thrift2.generated.TGet; 081import org.apache.hadoop.hbase.thrift2.generated.THBaseService; 082import org.apache.hadoop.hbase.thrift2.generated.THRegionLocation; 083import org.apache.hadoop.hbase.thrift2.generated.TIOError; 084import org.apache.hadoop.hbase.thrift2.generated.TIllegalArgument; 085import org.apache.hadoop.hbase.thrift2.generated.TIncrement; 086import org.apache.hadoop.hbase.thrift2.generated.TLogQueryFilter; 087import org.apache.hadoop.hbase.thrift2.generated.TNamespaceDescriptor; 088import org.apache.hadoop.hbase.thrift2.generated.TOnlineLogRecord; 089import org.apache.hadoop.hbase.thrift2.generated.TPermissionScope; 090import org.apache.hadoop.hbase.thrift2.generated.TPut; 091import org.apache.hadoop.hbase.thrift2.generated.TResult; 092import org.apache.hadoop.hbase.thrift2.generated.TRowMutations; 093import org.apache.hadoop.hbase.thrift2.generated.TScan; 094import org.apache.hadoop.hbase.thrift2.generated.TServerName; 095import org.apache.hadoop.hbase.thrift2.generated.TTableDescriptor; 096import org.apache.hadoop.hbase.thrift2.generated.TTableName; 097import org.apache.hadoop.hbase.thrift2.generated.TThriftServerType; 098import org.apache.hadoop.hbase.util.Bytes; 099import org.apache.thrift.TException; 100import org.apache.yetus.audience.InterfaceAudience; 101import org.slf4j.Logger; 102import org.slf4j.LoggerFactory; 103 104import org.apache.hbase.thirdparty.com.google.common.cache.Cache; 105import org.apache.hbase.thirdparty.com.google.common.cache.CacheBuilder; 106import org.apache.hbase.thirdparty.com.google.common.cache.RemovalListener; 107 108/** 109 * This class is a glue object that connects Thrift RPC calls to the HBase client API primarily 110 * defined in the Table interface. 111 */ 112@InterfaceAudience.Private 113@SuppressWarnings("deprecation") 114public class ThriftHBaseServiceHandler extends HBaseServiceHandler implements THBaseService.Iface { 115 116 // TODO: Size of pool configuraple 117 private static final Logger LOG = LoggerFactory.getLogger(ThriftHBaseServiceHandler.class); 118 119 // nextScannerId and scannerMap are used to manage scanner state 120 private final AtomicInteger nextScannerId = new AtomicInteger(0); 121 private final Cache<Integer, ResultScanner> scannerMap; 122 123 private static final IOException ioe = 124 new DoNotRetryIOException("Thrift Server is in Read-only mode."); 125 private boolean isReadOnly; 126 127 private static class TIOErrorWithCause extends TIOError { 128 private Throwable cause; 129 130 public TIOErrorWithCause(Throwable cause) { 131 super(); 132 this.cause = cause; 133 } 134 135 @Override 136 public synchronized Throwable getCause() { 137 return cause; 138 } 139 140 @Override 141 public boolean equals(Object other) { 142 if (super.equals(other) && other instanceof TIOErrorWithCause) { 143 Throwable otherCause = ((TIOErrorWithCause) other).getCause(); 144 if (this.getCause() != null) { 145 return otherCause != null && this.getCause().equals(otherCause); 146 } else { 147 return otherCause == null; 148 } 149 } 150 return false; 151 } 152 153 @Override 154 public int hashCode() { 155 int result = super.hashCode(); 156 result = 31 * result + (cause != null ? cause.hashCode() : 0); 157 return result; 158 } 159 } 160 161 public ThriftHBaseServiceHandler(final Configuration conf, final UserProvider userProvider) 162 throws IOException { 163 super(conf, userProvider); 164 long cacheTimeout = conf.getLong(HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, 165 DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD); 166 isReadOnly = conf.getBoolean(THRIFT_READONLY_ENABLED, THRIFT_READONLY_ENABLED_DEFAULT); 167 scannerMap = CacheBuilder.newBuilder().expireAfterAccess(cacheTimeout, TimeUnit.MILLISECONDS) 168 .removalListener((RemovalListener<Integer, 169 ResultScanner>) removalNotification -> removalNotification.getValue().close()) 170 .build(); 171 } 172 173 @Override 174 protected Table getTable(ByteBuffer tableName) { 175 try { 176 return connectionCache.getTable(Bytes.toString(byteBufferToByteArray(tableName))); 177 } catch (IOException ie) { 178 throw new RuntimeException(ie); 179 } 180 } 181 182 private RegionLocator getLocator(ByteBuffer tableName) { 183 try { 184 return connectionCache.getRegionLocator(byteBufferToByteArray(tableName)); 185 } catch (IOException ie) { 186 throw new RuntimeException(ie); 187 } 188 } 189 190 private void closeTable(Table table) throws TIOError { 191 try { 192 table.close(); 193 } catch (IOException e) { 194 throw getTIOError(e); 195 } 196 } 197 198 private TIOError getTIOError(IOException e) { 199 TIOError err = new TIOErrorWithCause(e); 200 err.setCanRetry(!(e instanceof DoNotRetryIOException)); 201 err.setMessage(e.getMessage()); 202 return err; 203 } 204 205 /** 206 * Assigns a unique ID to the scanner and adds the mapping to an internal HashMap. 207 * @param scanner to add 208 * @return Id for this Scanner 209 */ 210 private int addScanner(ResultScanner scanner) { 211 int id = nextScannerId.getAndIncrement(); 212 scannerMap.put(id, scanner); 213 return id; 214 } 215 216 /** 217 * Returns the Scanner associated with the specified Id. 218 * @param id of the Scanner to get 219 * @return a Scanner, or null if the Id is invalid 220 */ 221 private ResultScanner getScanner(int id) { 222 return scannerMap.getIfPresent(id); 223 } 224 225 /** 226 * Removes the scanner associated with the specified ID from the internal HashMap. 227 * @param id of the Scanner to remove 228 */ 229 protected void removeScanner(int id) { 230 scannerMap.invalidate(id); 231 } 232 233 @Override 234 public boolean exists(ByteBuffer table, TGet get) throws TIOError, TException { 235 Table htable = getTable(table); 236 try { 237 return htable.exists(getFromThrift(get)); 238 } catch (IOException e) { 239 throw getTIOError(e); 240 } finally { 241 closeTable(htable); 242 } 243 } 244 245 @Override 246 public List<Boolean> existsAll(ByteBuffer table, List<TGet> gets) throws TIOError, TException { 247 Table htable = getTable(table); 248 try { 249 boolean[] exists = htable.exists(getsFromThrift(gets)); 250 List<Boolean> result = new ArrayList<>(exists.length); 251 for (boolean exist : exists) { 252 result.add(exist); 253 } 254 return result; 255 } catch (IOException e) { 256 throw getTIOError(e); 257 } finally { 258 closeTable(htable); 259 } 260 } 261 262 @Override 263 public TResult get(ByteBuffer table, TGet get) throws TIOError, TException { 264 Table htable = getTable(table); 265 try { 266 return resultFromHBase(htable.get(getFromThrift(get))); 267 } catch (IOException e) { 268 throw getTIOError(e); 269 } finally { 270 closeTable(htable); 271 } 272 } 273 274 @Override 275 public List<TResult> getMultiple(ByteBuffer table, List<TGet> gets) throws TIOError, TException { 276 Table htable = getTable(table); 277 try { 278 return resultsFromHBase(htable.get(getsFromThrift(gets))); 279 } catch (IOException e) { 280 throw getTIOError(e); 281 } finally { 282 closeTable(htable); 283 } 284 } 285 286 @Override 287 public void put(ByteBuffer table, TPut put) throws TIOError, TException { 288 checkReadOnlyMode(); 289 Table htable = getTable(table); 290 try { 291 htable.put(putFromThrift(put)); 292 } catch (IOException e) { 293 throw getTIOError(e); 294 } finally { 295 closeTable(htable); 296 } 297 } 298 299 @Override 300 public boolean checkAndPut(ByteBuffer table, ByteBuffer row, ByteBuffer family, 301 ByteBuffer qualifier, ByteBuffer value, TPut put) throws TIOError, TException { 302 checkReadOnlyMode(); 303 Table htable = getTable(table); 304 try { 305 Table.CheckAndMutateBuilder builder = 306 htable.checkAndMutate(byteBufferToByteArray(row), byteBufferToByteArray(family)) 307 .qualifier(byteBufferToByteArray(qualifier)); 308 if (value == null) { 309 return builder.ifNotExists().thenPut(putFromThrift(put)); 310 } else { 311 return builder.ifEquals(byteBufferToByteArray(value)).thenPut(putFromThrift(put)); 312 } 313 } catch (IOException e) { 314 throw getTIOError(e); 315 } finally { 316 closeTable(htable); 317 } 318 } 319 320 @Override 321 public void putMultiple(ByteBuffer table, List<TPut> puts) throws TIOError, TException { 322 checkReadOnlyMode(); 323 Table htable = getTable(table); 324 try { 325 htable.put(putsFromThrift(puts)); 326 } catch (IOException e) { 327 throw getTIOError(e); 328 } finally { 329 closeTable(htable); 330 } 331 } 332 333 @Override 334 public void deleteSingle(ByteBuffer table, TDelete deleteSingle) throws TIOError, TException { 335 checkReadOnlyMode(); 336 Table htable = getTable(table); 337 try { 338 htable.delete(deleteFromThrift(deleteSingle)); 339 } catch (IOException e) { 340 throw getTIOError(e); 341 } finally { 342 closeTable(htable); 343 } 344 } 345 346 @Override 347 public List<TDelete> deleteMultiple(ByteBuffer table, List<TDelete> deletes) 348 throws TIOError, TException { 349 checkReadOnlyMode(); 350 Table htable = getTable(table); 351 try { 352 htable.delete(deletesFromThrift(deletes)); 353 } catch (IOException e) { 354 throw getTIOError(e); 355 } finally { 356 closeTable(htable); 357 } 358 return Collections.emptyList(); 359 } 360 361 @Override 362 public boolean checkAndMutate(ByteBuffer table, ByteBuffer row, ByteBuffer family, 363 ByteBuffer qualifier, TCompareOperator compareOp, ByteBuffer value, TRowMutations rowMutations) 364 throws TIOError, TException { 365 checkReadOnlyMode(); 366 try (final Table htable = getTable(table)) { 367 return htable.checkAndMutate(byteBufferToByteArray(row), byteBufferToByteArray(family)) 368 .qualifier(byteBufferToByteArray(qualifier)) 369 .ifMatches(compareOpFromThrift(compareOp), byteBufferToByteArray(value)) 370 .thenMutate(rowMutationsFromThrift(rowMutations)); 371 } catch (IOException e) { 372 throw getTIOError(e); 373 } 374 } 375 376 @Override 377 public boolean checkAndDelete(ByteBuffer table, ByteBuffer row, ByteBuffer family, 378 ByteBuffer qualifier, ByteBuffer value, TDelete deleteSingle) throws TIOError, TException { 379 checkReadOnlyMode(); 380 Table htable = getTable(table); 381 try { 382 Table.CheckAndMutateBuilder mutateBuilder = 383 htable.checkAndMutate(byteBufferToByteArray(row), byteBufferToByteArray(family)) 384 .qualifier(byteBufferToByteArray(qualifier)); 385 if (value == null) { 386 return mutateBuilder.ifNotExists().thenDelete(deleteFromThrift(deleteSingle)); 387 } else { 388 return mutateBuilder.ifEquals(byteBufferToByteArray(value)) 389 .thenDelete(deleteFromThrift(deleteSingle)); 390 } 391 } catch (IOException e) { 392 throw getTIOError(e); 393 } finally { 394 closeTable(htable); 395 } 396 } 397 398 @Override 399 public TResult increment(ByteBuffer table, TIncrement increment) throws TIOError, TException { 400 checkReadOnlyMode(); 401 Table htable = getTable(table); 402 try { 403 return resultFromHBase(htable.increment(incrementFromThrift(increment))); 404 } catch (IOException e) { 405 throw getTIOError(e); 406 } finally { 407 closeTable(htable); 408 } 409 } 410 411 @Override 412 public TResult append(ByteBuffer table, TAppend append) throws TIOError, TException { 413 checkReadOnlyMode(); 414 Table htable = getTable(table); 415 try { 416 return resultFromHBase(htable.append(appendFromThrift(append))); 417 } catch (IOException e) { 418 throw getTIOError(e); 419 } finally { 420 closeTable(htable); 421 } 422 } 423 424 @Override 425 public int openScanner(ByteBuffer table, TScan scan) throws TIOError, TException { 426 Table htable = getTable(table); 427 ResultScanner resultScanner = null; 428 try { 429 resultScanner = htable.getScanner(scanFromThrift(scan)); 430 } catch (IOException e) { 431 throw getTIOError(e); 432 } finally { 433 closeTable(htable); 434 } 435 return addScanner(resultScanner); 436 } 437 438 @Override 439 public List<TResult> getScannerRows(int scannerId, int numRows) 440 throws TIOError, TIllegalArgument, TException { 441 ResultScanner scanner = getScanner(scannerId); 442 if (scanner == null) { 443 TIllegalArgument ex = new TIllegalArgument(); 444 ex.setMessage("Invalid scanner Id"); 445 throw ex; 446 } 447 try { 448 connectionCache.updateConnectionAccessTime(); 449 return resultsFromHBase(scanner.next(numRows)); 450 } catch (IOException e) { 451 throw getTIOError(e); 452 } 453 } 454 455 @Override 456 public List<TResult> getScannerResults(ByteBuffer table, TScan scan, int numRows) 457 throws TIOError, TException { 458 Table htable = getTable(table); 459 List<TResult> results = null; 460 ResultScanner scanner = null; 461 try { 462 scanner = htable.getScanner(scanFromThrift(scan)); 463 results = resultsFromHBase(scanner.next(numRows)); 464 } catch (IOException e) { 465 throw getTIOError(e); 466 } finally { 467 if (scanner != null) { 468 scanner.close(); 469 } 470 closeTable(htable); 471 } 472 return results; 473 } 474 475 @Override 476 public void closeScanner(int scannerId) throws TIOError, TIllegalArgument, TException { 477 LOG.debug("scannerClose: id=" + scannerId); 478 ResultScanner scanner = getScanner(scannerId); 479 if (scanner == null) { 480 LOG.warn("scanner ID: " + scannerId + "is invalid"); 481 // While the scanner could be already expired, 482 // we should not throw exception here. Just log and return. 483 return; 484 } 485 scanner.close(); 486 removeScanner(scannerId); 487 } 488 489 @Override 490 public void mutateRow(ByteBuffer table, TRowMutations rowMutations) throws TIOError, TException { 491 checkReadOnlyMode(); 492 Table htable = getTable(table); 493 try { 494 htable.mutateRow(rowMutationsFromThrift(rowMutations)); 495 } catch (IOException e) { 496 throw getTIOError(e); 497 } finally { 498 closeTable(htable); 499 } 500 } 501 502 @Override 503 public List<THRegionLocation> getAllRegionLocations(ByteBuffer table) 504 throws TIOError, TException { 505 RegionLocator locator = null; 506 try { 507 locator = getLocator(table); 508 return ThriftUtilities.regionLocationsFromHBase(locator.getAllRegionLocations()); 509 510 } catch (IOException e) { 511 throw getTIOError(e); 512 } finally { 513 if (locator != null) { 514 try { 515 locator.close(); 516 } catch (IOException e) { 517 LOG.warn("Couldn't close the locator.", e); 518 } 519 } 520 } 521 } 522 523 @Override 524 public THRegionLocation getRegionLocation(ByteBuffer table, ByteBuffer row, boolean reload) 525 throws TIOError, TException { 526 527 RegionLocator locator = null; 528 try { 529 locator = getLocator(table); 530 byte[] rowBytes = byteBufferToByteArray(row); 531 HRegionLocation hrl = locator.getRegionLocation(rowBytes, reload); 532 return ThriftUtilities.regionLocationFromHBase(hrl); 533 534 } catch (IOException e) { 535 throw getTIOError(e); 536 } finally { 537 if (locator != null) { 538 try { 539 locator.close(); 540 } catch (IOException e) { 541 LOG.warn("Couldn't close the locator.", e); 542 } 543 } 544 } 545 } 546 547 private void checkReadOnlyMode() throws TIOError { 548 if (isReadOnly()) { 549 throw getTIOError(ioe); 550 } 551 } 552 553 private boolean isReadOnly() { 554 return isReadOnly; 555 } 556 557 @Override 558 public TTableDescriptor getTableDescriptor(TTableName table) throws TIOError, TException { 559 try { 560 TableName tableName = ThriftUtilities.tableNameFromThrift(table); 561 TableDescriptor tableDescriptor = connectionCache.getAdmin().getDescriptor(tableName); 562 return tableDescriptorFromHBase(tableDescriptor); 563 } catch (IOException e) { 564 throw getTIOError(e); 565 } 566 } 567 568 @Override 569 public List<TTableDescriptor> getTableDescriptors(List<TTableName> tables) 570 throws TIOError, TException { 571 try { 572 List<TableName> tableNames = ThriftUtilities.tableNamesFromThrift(tables); 573 List<TableDescriptor> tableDescriptors = 574 connectionCache.getAdmin().listTableDescriptors(tableNames); 575 return tableDescriptorsFromHBase(tableDescriptors); 576 } catch (IOException e) { 577 throw getTIOError(e); 578 } 579 } 580 581 @Override 582 public boolean tableExists(TTableName tTableName) throws TIOError, TException { 583 try { 584 TableName tableName = tableNameFromThrift(tTableName); 585 return connectionCache.getAdmin().tableExists(tableName); 586 } catch (IOException e) { 587 throw getTIOError(e); 588 } 589 } 590 591 @Override 592 public List<TTableDescriptor> getTableDescriptorsByPattern(String regex, boolean includeSysTables) 593 throws TIOError, TException { 594 try { 595 Pattern pattern = (regex == null ? null : Pattern.compile(regex)); 596 List<TableDescriptor> tableDescriptors = 597 connectionCache.getAdmin().listTableDescriptors(pattern, includeSysTables); 598 return tableDescriptorsFromHBase(tableDescriptors); 599 } catch (IOException e) { 600 throw getTIOError(e); 601 } 602 } 603 604 @Override 605 public List<TTableDescriptor> getTableDescriptorsByNamespace(String name) 606 throws TIOError, TException { 607 try { 608 List<TableDescriptor> descriptors = 609 connectionCache.getAdmin().listTableDescriptorsByNamespace(Bytes.toBytes(name)); 610 return tableDescriptorsFromHBase(descriptors); 611 } catch (IOException e) { 612 throw getTIOError(e); 613 } 614 } 615 616 @Override 617 public List<TTableName> getTableNamesByPattern(String regex, boolean includeSysTables) 618 throws TIOError, TException { 619 try { 620 Pattern pattern = (regex == null ? null : Pattern.compile(regex)); 621 TableName[] tableNames = connectionCache.getAdmin().listTableNames(pattern, includeSysTables); 622 return tableNamesFromHBase(tableNames); 623 } catch (IOException e) { 624 throw getTIOError(e); 625 } 626 } 627 628 @Override 629 public List<TTableName> getTableNamesByNamespace(String name) throws TIOError, TException { 630 try { 631 TableName[] tableNames = connectionCache.getAdmin().listTableNamesByNamespace(name); 632 return tableNamesFromHBase(tableNames); 633 } catch (IOException e) { 634 throw getTIOError(e); 635 } 636 } 637 638 @Override 639 public void createTable(TTableDescriptor desc, List<ByteBuffer> splitKeys) 640 throws TIOError, TException { 641 try { 642 TableDescriptor descriptor = tableDescriptorFromThrift(desc); 643 byte[][] split = splitKeyFromThrift(splitKeys); 644 if (split != null) { 645 connectionCache.getAdmin().createTable(descriptor, split); 646 } else { 647 connectionCache.getAdmin().createTable(descriptor); 648 } 649 } catch (IOException e) { 650 throw getTIOError(e); 651 } 652 } 653 654 @Override 655 public void deleteTable(TTableName tableName) throws TIOError, TException { 656 try { 657 TableName table = tableNameFromThrift(tableName); 658 connectionCache.getAdmin().deleteTable(table); 659 } catch (IOException e) { 660 throw getTIOError(e); 661 } 662 } 663 664 @Override 665 public void truncateTable(TTableName tableName, boolean preserveSplits) 666 throws TIOError, TException { 667 try { 668 TableName table = tableNameFromThrift(tableName); 669 connectionCache.getAdmin().truncateTable(table, preserveSplits); 670 } catch (IOException e) { 671 throw getTIOError(e); 672 } 673 } 674 675 @Override 676 public void enableTable(TTableName tableName) throws TIOError, TException { 677 try { 678 TableName table = tableNameFromThrift(tableName); 679 connectionCache.getAdmin().enableTable(table); 680 } catch (IOException e) { 681 throw getTIOError(e); 682 } 683 } 684 685 @Override 686 public void disableTable(TTableName tableName) throws TIOError, TException { 687 try { 688 TableName table = tableNameFromThrift(tableName); 689 connectionCache.getAdmin().disableTable(table); 690 } catch (IOException e) { 691 throw getTIOError(e); 692 } 693 } 694 695 @Override 696 public boolean isTableEnabled(TTableName tableName) throws TIOError, TException { 697 try { 698 TableName table = tableNameFromThrift(tableName); 699 return connectionCache.getAdmin().isTableEnabled(table); 700 } catch (IOException e) { 701 throw getTIOError(e); 702 } 703 } 704 705 @Override 706 public boolean isTableDisabled(TTableName tableName) throws TIOError, TException { 707 try { 708 TableName table = tableNameFromThrift(tableName); 709 return connectionCache.getAdmin().isTableDisabled(table); 710 } catch (IOException e) { 711 throw getTIOError(e); 712 } 713 } 714 715 @Override 716 public boolean isTableAvailable(TTableName tableName) throws TIOError, TException { 717 try { 718 TableName table = tableNameFromThrift(tableName); 719 return connectionCache.getAdmin().isTableAvailable(table); 720 } catch (IOException e) { 721 throw getTIOError(e); 722 } 723 } 724 725 @Override 726 public void addColumnFamily(TTableName tableName, TColumnFamilyDescriptor column) 727 throws TIOError, TException { 728 try { 729 TableName table = tableNameFromThrift(tableName); 730 ColumnFamilyDescriptor columnFamilyDescriptor = columnFamilyDescriptorFromThrift(column); 731 connectionCache.getAdmin().addColumnFamily(table, columnFamilyDescriptor); 732 } catch (IOException e) { 733 throw getTIOError(e); 734 } 735 } 736 737 @Override 738 public void deleteColumnFamily(TTableName tableName, ByteBuffer column) 739 throws TIOError, TException { 740 try { 741 TableName table = tableNameFromThrift(tableName); 742 connectionCache.getAdmin().deleteColumnFamily(table, column.array()); 743 } catch (IOException e) { 744 throw getTIOError(e); 745 } 746 } 747 748 @Override 749 public void modifyColumnFamily(TTableName tableName, TColumnFamilyDescriptor column) 750 throws TIOError, TException { 751 try { 752 TableName table = tableNameFromThrift(tableName); 753 ColumnFamilyDescriptor columnFamilyDescriptor = columnFamilyDescriptorFromThrift(column); 754 connectionCache.getAdmin().modifyColumnFamily(table, columnFamilyDescriptor); 755 } catch (IOException e) { 756 throw getTIOError(e); 757 } 758 } 759 760 @Override 761 public void modifyTable(TTableDescriptor desc) throws TIOError, TException { 762 try { 763 TableDescriptor descriptor = tableDescriptorFromThrift(desc); 764 connectionCache.getAdmin().modifyTable(descriptor); 765 } catch (IOException e) { 766 throw getTIOError(e); 767 } 768 } 769 770 @Override 771 public void createNamespace(TNamespaceDescriptor namespaceDesc) throws TIOError, TException { 772 try { 773 NamespaceDescriptor descriptor = namespaceDescriptorFromThrift(namespaceDesc); 774 connectionCache.getAdmin().createNamespace(descriptor); 775 } catch (IOException e) { 776 throw getTIOError(e); 777 } 778 } 779 780 @Override 781 public void modifyNamespace(TNamespaceDescriptor namespaceDesc) throws TIOError, TException { 782 try { 783 NamespaceDescriptor descriptor = namespaceDescriptorFromThrift(namespaceDesc); 784 connectionCache.getAdmin().modifyNamespace(descriptor); 785 } catch (IOException e) { 786 throw getTIOError(e); 787 } 788 } 789 790 @Override 791 public void deleteNamespace(String name) throws TIOError, TException { 792 try { 793 connectionCache.getAdmin().deleteNamespace(name); 794 } catch (IOException e) { 795 throw getTIOError(e); 796 } 797 } 798 799 @Override 800 public TNamespaceDescriptor getNamespaceDescriptor(String name) throws TIOError, TException { 801 try { 802 NamespaceDescriptor descriptor = connectionCache.getAdmin().getNamespaceDescriptor(name); 803 return namespaceDescriptorFromHBase(descriptor); 804 } catch (IOException e) { 805 throw getTIOError(e); 806 } 807 } 808 809 @Override 810 public List<String> listNamespaces() throws TIOError, TException { 811 try { 812 String[] namespaces = connectionCache.getAdmin().listNamespaces(); 813 List<String> result = new ArrayList<>(namespaces.length); 814 for (String ns : namespaces) { 815 result.add(ns); 816 } 817 return result; 818 } catch (IOException e) { 819 throw getTIOError(e); 820 } 821 } 822 823 @Override 824 public TThriftServerType getThriftServerType() { 825 return TThriftServerType.TWO; 826 } 827 828 @Override 829 public String getClusterId() throws TException { 830 return connectionCache.getClusterId(); 831 } 832 833 @Override 834 public List<TOnlineLogRecord> getSlowLogResponses(Set<TServerName> tServerNames, 835 TLogQueryFilter tLogQueryFilter) throws TIOError, TException { 836 try { 837 Set<ServerName> serverNames = ThriftUtilities.getServerNamesFromThrift(tServerNames); 838 LogQueryFilter logQueryFilter = ThriftUtilities.getSlowLogQueryFromThrift(tLogQueryFilter); 839 List<OnlineLogRecord> onlineLogRecords = 840 connectionCache.getAdmin().getSlowLogResponses(serverNames, logQueryFilter); 841 return ThriftUtilities.getSlowLogRecordsFromHBase(onlineLogRecords); 842 } catch (IOException e) { 843 throw getTIOError(e); 844 } 845 } 846 847 @Override 848 public List<Boolean> clearSlowLogResponses(Set<TServerName> tServerNames) 849 throws TIOError, TException { 850 Set<ServerName> serverNames = ThriftUtilities.getServerNamesFromThrift(tServerNames); 851 try { 852 return connectionCache.getAdmin().clearSlowLogResponses(serverNames); 853 } catch (IOException e) { 854 throw getTIOError(e); 855 } 856 } 857 858 @Override 859 public boolean grant(TAccessControlEntity info) throws TIOError, TException { 860 Permission.Action[] actions = ThriftUtilities.permissionActionsFromString(info.actions); 861 try { 862 if (info.scope == TPermissionScope.NAMESPACE) { 863 AccessControlClient.grant(connectionCache.getAdmin().getConnection(), info.getNsName(), 864 info.getUsername(), actions); 865 } else if (info.scope == TPermissionScope.TABLE) { 866 TableName tableName = TableName.valueOf(info.getTableName()); 867 AccessControlClient.grant(connectionCache.getAdmin().getConnection(), tableName, 868 info.getUsername(), null, null, actions); 869 } 870 } catch (Throwable t) { 871 if (t instanceof IOException) { 872 throw getTIOError((IOException) t); 873 } else { 874 throw getTIOError(new DoNotRetryIOException(t.getMessage())); 875 } 876 } 877 return true; 878 } 879 880 @Override 881 public boolean revoke(TAccessControlEntity info) throws TIOError, TException { 882 Permission.Action[] actions = ThriftUtilities.permissionActionsFromString(info.actions); 883 try { 884 if (info.scope == TPermissionScope.NAMESPACE) { 885 AccessControlClient.revoke(connectionCache.getAdmin().getConnection(), info.getNsName(), 886 info.getUsername(), actions); 887 } else if (info.scope == TPermissionScope.TABLE) { 888 TableName tableName = TableName.valueOf(info.getTableName()); 889 AccessControlClient.revoke(connectionCache.getAdmin().getConnection(), tableName, 890 info.getUsername(), null, null, actions); 891 } 892 } catch (Throwable t) { 893 if (t instanceof IOException) { 894 throw getTIOError((IOException) t); 895 } else { 896 throw getTIOError(new DoNotRetryIOException(t.getMessage())); 897 } 898 } 899 return true; 900 } 901 902 @Override 903 public List<TNamespaceDescriptor> listNamespaceDescriptors() throws TIOError, TException { 904 try { 905 NamespaceDescriptor[] descriptors = connectionCache.getAdmin().listNamespaceDescriptors(); 906 return namespaceDescriptorsFromHBase(descriptors); 907 } catch (IOException e) { 908 throw getTIOError(e); 909 } 910 } 911}