下面列出了怎么用org.apache.hadoop.hbase.TableNotEnabledException的API类实例代码及写法,或者点击链接到github查看源代码。
public static void deleteTable(HBaseTestingUtility testUtil, Admin admin, TableName tableName)
throws Exception {
// NOTE: We need a latch because admin is not sync,
// so the postOp coprocessor method may be called after the admin operation returned.
MasterSyncObserver observer = testUtil.getHBaseCluster().getMaster()
.getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class);
observer.tableDeletionLatch = new CountDownLatch(1);
try {
admin.disableTable(tableName);
} catch (TableNotEnabledException e) {
LOG.debug("Table: " + tableName + " already disabled, so just deleting it.");
}
admin.deleteTable(tableName);
observer.tableDeletionLatch.await();
observer.tableDeletionLatch = null;
}
/**
* Checks if the output table exists and is enabled.
*
* @param context The current context.
* @throws IOException When the check fails.
* @throws InterruptedException When the job is aborted.
* @see OutputFormat#checkOutputSpecs(JobContext)
*/
@Override
public void checkOutputSpecs(JobContext context) throws IOException,
InterruptedException {
Configuration hConf = getConf();
if (hConf == null) {
hConf = context.getConfiguration();
}
try (Admin admin = ConnectionFactory.createConnection(hConf).getAdmin()) {
TableName tableName = TableName.valueOf(hConf.get(OUTPUT_TABLE));
if (!admin.tableExists(tableName)) {
throw new TableNotFoundException("Can't write, table does not exist:" +
tableName.getNameAsString());
}
if (!admin.isTableEnabled(tableName)) {
throw new TableNotEnabledException("Can't write, table is not enabled: " +
tableName.getNameAsString());
}
}
}
private boolean causeIsPleaseHold(Throwable e) {
if (e instanceof PleaseHoldException)
return true;
if (e instanceof TableNotEnabledException)
return true;
if (e instanceof RegionOfflineException)
return true;
if (e instanceof RetriesExhaustedException || e instanceof SocketTimeoutException) {
if (e.getCause() instanceof RemoteException) {
RemoteException re = (RemoteException) e.getCause();
if (PleaseHoldException.class.getName().equals(re.getClassName()))
return true;
} else if (e.getCause() instanceof MasterNotRunningException) {
return true;
}
return (e.getCause() instanceof IOException && e.getCause().getCause() instanceof CallTimeoutException) ||
(e.getCause() instanceof RemoteWithExtrasException && e.getMessage().equals(
"Table Namespace Manager not fully initialized, try again later"));
}
return false;
}
public void dropTable(String table) throws IOException {
TableName tableName = TableName.valueOf(this.namespace, table);
try (Admin admin = this.hbase.getAdmin()) {
try {
admin.disableTable(tableName);
} catch (TableNotEnabledException ignored) {
// pass
}
admin.deleteTable(tableName);
}
}
/**
* Method to disable a table, if not already disabled. This method suppresses
* {@link TableNotEnabledException}, if thrown while disabling the table.
* @param conn connection to re-use
* @param tableName table name which has moved into space quota violation
*/
public static void disableTableIfNotDisabled(Connection conn, TableName tableName)
throws IOException {
try {
conn.getAdmin().disableTable(tableName);
} catch (TableNotEnabledException | TableNotFoundException e) {
// ignore
}
}
/**
* Check that cluster is up and master is running. Check table is modifiable.
* If <code>enabled</code>, check table is enabled else check it is disabled.
* Call in Procedure constructor so can pass any exception to caller.
* @param enabled If true, check table is enabled and throw exception if not. If false, do the
* inverse. If null, do no table checks.
*/
protected void preflightChecks(MasterProcedureEnv env, Boolean enabled) throws HBaseIOException {
MasterServices master = env.getMasterServices();
if (!master.isClusterUp()) {
throw new HBaseIOException("Cluster not up!");
}
if (master.isStopping() || master.isStopped()) {
throw new HBaseIOException("Master stopping=" + master.isStopping() +
", stopped=" + master.isStopped());
}
if (enabled == null) {
// Don't do any table checks.
return;
}
try {
// Checks table exists and is modifiable.
checkTableModifiable(env);
TableName tn = getTableName();
TableStateManager tsm = master.getTableStateManager();
TableState ts = tsm.getTableState(tn);
if (enabled) {
if (!ts.isEnabledOrEnabling()) {
throw new TableNotEnabledException(tn);
}
} else {
if (!ts.isDisabledOrDisabling()) {
throw new TableNotDisabledException(tn);
}
}
} catch (IOException ioe) {
if (ioe instanceof HBaseIOException) {
throw (HBaseIOException)ioe;
}
throw new HBaseIOException(ioe);
}
}
/**
* Action before any real action of disabling table. Set the exception in the procedure instead
* of throwing it. This approach is to deal with backward compatible with 1.0.
* @param env MasterProcedureEnv
*/
private boolean prepareDisable(final MasterProcedureEnv env) throws IOException {
boolean canTableBeDisabled = true;
if (tableName.equals(TableName.META_TABLE_NAME)) {
setFailure("master-disable-table",
new ConstraintException("Cannot disable " + this.tableName));
canTableBeDisabled = false;
} else if (!MetaTableAccessor.tableExists(env.getMasterServices().getConnection(), tableName)) {
setFailure("master-disable-table", new TableNotFoundException(tableName));
canTableBeDisabled = false;
} else if (!skipTableStateCheck) {
// There could be multiple client requests trying to disable or enable
// the table at the same time. Ensure only the first request is honored
// After that, no other requests can be accepted until the table reaches
// DISABLED or ENABLED.
//
// Note: in 1.0 release, we called TableStateManager.setTableStateIfInStates() to set
// the state to DISABLING from ENABLED. The implementation was done before table lock
// was implemented. With table lock, there is no need to set the state here (it will
// set the state later on). A quick state check should be enough for us to move forward.
TableStateManager tsm = env.getMasterServices().getTableStateManager();
TableState ts = tsm.getTableState(tableName);
if (!ts.isEnabled()) {
LOG.info("Not ENABLED, state={}, skipping disable; {}", ts.getState(), this);
setFailure("master-disable-table", new TableNotEnabledException(ts.toString()));
canTableBeDisabled = false;
}
}
// We are done the check. Future actions in this procedure could be done asynchronously.
releaseSyncLatch();
return canTableBeDisabled;
}
@Test
public void testDisabled() throws InterruptedException, ExecutionException {
ASYNC_CONN.getAdmin().disableTable(TABLE_NAME).get();
try {
getTable.get().get(new Get(row)).get();
fail("Should fail since table has been disabled");
} catch (ExecutionException e) {
Throwable cause = e.getCause();
assertThat(cause, instanceOf(TableNotEnabledException.class));
assertThat(cause.getMessage(), containsString(TABLE_NAME.getNameAsString()));
}
}
/**
* Can't disable a table if the table isn't in enabled state
*/
@Test (expected=TableNotEnabledException.class)
public void testTableNotEnabledExceptionWithATable() throws IOException {
final TableName name = TableName.valueOf(this.name.getMethodName());
TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
ADMIN.disableTable(name);
ADMIN.disableTable(name);
}
/**
* Take a snapshot of the specified table and verify the given families.
* Note that this will leave the table disabled in the case of an offline snapshot.
*/
public static void createSnapshotAndValidate(Admin admin,
TableName tableName, List<byte[]> nonEmptyFamilyNames, List<byte[]> emptyFamilyNames,
String snapshotNameString, Path rootDir, FileSystem fs, boolean onlineSnapshot)
throws Exception {
if (!onlineSnapshot) {
try {
LOG.info("prepping for offline snapshot.");
admin.disableTable(tableName);
} catch (TableNotEnabledException tne) {
LOG.info("In attempting to disable " + tableName + " it turns out that the this table is " +
"already disabled.");
}
}
LOG.info("taking snapshot.");
admin.snapshot(snapshotNameString, tableName);
LOG.info("Confirming snapshot exists.");
List<SnapshotDescription> snapshots =
SnapshotTestingUtils.assertExistsMatchingSnapshot(admin, snapshotNameString, tableName);
if (snapshots == null || snapshots.size() != 1) {
Assert.fail("Incorrect number of snapshots for table " + tableName);
}
LOG.info("validating snapshot.");
SnapshotTestingUtils.confirmSnapshotValid(
ProtobufUtil.createHBaseProtosSnapshotDesc(snapshots.get(0)), tableName, nonEmptyFamilyNames,
emptyFamilyNames, rootDir, admin, fs);
}
@Test(expected = TableNotEnabledException.class)
public void testWritingToDisabledTable() throws IOException {
try (Admin admin = UTIL.getConnection().getAdmin();
Table table = UTIL.getConnection().getTable(TABLE_FOR_NEGATIVE_TESTS)) {
admin.disableTable(table.getName());
runTestOnTable(table);
fail("Should not have reached here, should have thrown an exception");
}
}
@Override
public CompletableFuture<Void> flush(TableName tableName) {
CompletableFuture<Void> future = new CompletableFuture<>();
addListener(tableExists(tableName), (exists, err) -> {
if (err != null) {
future.completeExceptionally(err);
} else if (!exists) {
future.completeExceptionally(new TableNotFoundException(tableName));
} else {
addListener(isTableEnabled(tableName), (tableEnabled, err2) -> {
if (err2 != null) {
future.completeExceptionally(err2);
} else if (!tableEnabled) {
future.completeExceptionally(new TableNotEnabledException(tableName));
} else {
addListener(execProcedure(FLUSH_TABLE_PROCEDURE_SIGNATURE, tableName.getNameAsString(),
new HashMap<>()), (ret, err3) -> {
if (err3 != null) {
future.completeExceptionally(err3);
} else {
future.complete(ret);
}
});
}
});
}
});
return future;
}
/**
* Verifies that the given policy on the given table has been violated
*/
void verifyViolation(SpaceViolationPolicy policyToViolate, TableName tn, Mutation m)
throws Exception {
// But let's try a few times to get the exception before failing
boolean sawError = false;
String msg = "";
for (int i = 0; i < NUM_RETRIES && !sawError; i++) {
try (Table table = testUtil.getConnection().getTable(tn)) {
if (m instanceof Put) {
table.put((Put) m);
} else if (m instanceof Delete) {
table.delete((Delete) m);
} else if (m instanceof Append) {
table.append((Append) m);
} else if (m instanceof Increment) {
table.increment((Increment) m);
} else {
fail(
"Failed to apply " + m.getClass().getSimpleName() +
" to the table. Programming error");
}
LOG.info("Did not reject the " + m.getClass().getSimpleName() + ", will sleep and retry");
Thread.sleep(2000);
} catch (Exception e) {
msg = StringUtils.stringifyException(e);
if ((policyToViolate.equals(SpaceViolationPolicy.DISABLE)
&& e instanceof TableNotEnabledException) || msg.contains(policyToViolate.name())) {
LOG.info("Got the expected exception={}", msg);
sawError = true;
break;
} else {
LOG.warn("Did not get the expected exception, will sleep and retry", e);
Thread.sleep(2000);
}
}
}
if (!sawError) {
try (Table quotaTable = testUtil.getConnection().getTable(QuotaUtil.QUOTA_TABLE_NAME)) {
ResultScanner scanner = quotaTable.getScanner(new Scan());
Result result = null;
LOG.info("Dumping contents of hbase:quota table");
while ((result = scanner.next()) != null) {
LOG.info(Bytes.toString(result.getRow()) + " => " + result.toString());
}
scanner.close();
}
} else {
if (policyToViolate.equals(SpaceViolationPolicy.DISABLE)) {
assertTrue(
msg.contains("TableNotEnabledException") || msg.contains(policyToViolate.name()));
} else {
assertTrue("Expected exception message to contain the word '" + policyToViolate.name()
+ "', but was " + msg,
msg.contains(policyToViolate.name()));
}
}
assertTrue(
"Expected to see an exception writing data to a table exceeding its quota", sawError);
}
protected final void onError(Throwable t, Supplier<String> errMsg,
Consumer<Throwable> updateCachedLocation) {
if (future.isDone()) {
// Give up if the future is already done, this is possible if user has already canceled the
// future. And for timeline consistent read, we will also cancel some requests if we have
// already get one of the responses.
LOG.debug("The future is already done, canceled={}, give up retrying", future.isCancelled());
return;
}
Throwable error = translateException(t);
// We use this retrying caller to open a scanner, as it is idempotent, but we may throw
// ScannerResetException, which is a DoNotRetryIOException when opening a scanner as now we will
// also fetch data when opening a scanner. The intention here is that if we hit a
// ScannerResetException when scanning then we should try to open a new scanner, instead of
// retrying on the old one, so it is declared as a DoNotRetryIOException. But here we are
// exactly trying to open a new scanner, so we should retry on ScannerResetException.
if (error instanceof DoNotRetryIOException && !(error instanceof ScannerResetException)) {
future.completeExceptionally(error);
return;
}
if (tries > startLogErrorsCnt) {
LOG.warn(errMsg.get() + ", tries = " + tries + ", maxAttempts = " + maxAttempts +
", timeout = " + TimeUnit.NANOSECONDS.toMillis(operationTimeoutNs) +
" ms, time elapsed = " + elapsedMs() + " ms", error);
}
updateCachedLocation.accept(error);
RetriesExhaustedException.ThrowableWithExtraContext qt =
new RetriesExhaustedException.ThrowableWithExtraContext(error,
EnvironmentEdgeManager.currentTime(), "");
exceptions.add(qt);
if (tries >= maxAttempts) {
completeExceptionally();
return;
}
// check whether the table has been disabled, notice that the check will introduce a request to
// meta, so here we only check for disabled for some specific exception types.
if (error instanceof NotServingRegionException || error instanceof RegionOfflineException) {
Optional<TableName> tableName = getTableName();
if (tableName.isPresent()) {
FutureUtils.addListener(conn.getAdmin().isTableDisabled(tableName.get()), (disabled, e) -> {
if (e != null) {
if (e instanceof TableNotFoundException) {
future.completeExceptionally(e);
} else {
// failed to test whether the table is disabled, not a big deal, continue retrying
tryScheduleRetry(error);
}
return;
}
if (disabled) {
future.completeExceptionally(new TableNotEnabledException(tableName.get()));
} else {
tryScheduleRetry(error);
}
});
} else {
tryScheduleRetry(error);
}
} else {
tryScheduleRetry(error);
}
}