下面列出了怎么用org.apache.hadoop.hbase.NotServingRegionException的API类实例代码及写法,或者点击链接到github查看源代码。
private HRegion getRegionByEncodedName(byte[] regionName, String encodedRegionName)
throws NotServingRegionException {
HRegion region = this.onlineRegions.get(encodedRegionName);
if (region == null) {
MovedRegionInfo moveInfo = getMovedRegion(encodedRegionName);
if (moveInfo != null) {
throw new RegionMovedException(moveInfo.getServerName(), moveInfo.getSeqNum());
}
Boolean isOpening = this.regionsInTransitionInRS.get(Bytes.toBytes(encodedRegionName));
String regionNameStr = regionName == null?
encodedRegionName: Bytes.toStringBinary(regionName);
if (isOpening != null && isOpening) {
throw new RegionOpeningException("Region " + regionNameStr +
" is opening on " + this.serverName);
}
throw new NotServingRegionException("" + regionNameStr +
" is not online on " + this.serverName);
}
return region;
}
/**
* Cleanup after Throwable caught invoking method. Converts <code>t</code> to
* IOE if it isn't already.
*
* @param t Throwable
* @param msg Message to log in error. Can be null.
* @return Throwable converted to an IOE; methods can only let out IOEs.
*/
private Throwable cleanup(final Throwable t, final String msg) {
// Don't log as error if NSRE; NSRE is 'normal' operation.
if (t instanceof NotServingRegionException) {
LOG.debug("NotServingRegionException; " + t.getMessage());
return t;
}
Throwable e = t instanceof RemoteException ? ((RemoteException) t).unwrapRemoteException() : t;
if (msg == null) {
LOG.error("", e);
} else {
LOG.error(msg, e);
}
if (!rpcServices.checkOOME(t)) {
checkFileSystem();
}
return t;
}
/**
* Throw some exceptions. Mostly throw exceptions which do not clear meta cache.
* Periodically throw NotSevingRegionException which clears the meta cache.
* @throws ServiceException
*/
private void throwSomeExceptions(FakeRSRpcServices rpcServices,
HBaseProtos.RegionSpecifier regionSpec)
throws ServiceException {
if (!isTestTable(rpcServices, regionSpec)) {
return;
}
numReqs++;
// Succeed every 5 request, throw cache clearing exceptions twice every 5 requests and throw
// meta cache preserving exceptions otherwise.
if (numReqs % 5 ==0) {
return;
} else if (numReqs % 5 == 1 || numReqs % 5 == 2) {
throw new ServiceException(new NotServingRegionException());
}
// Round robin between different special exceptions.
// This is not ideal since exception types are not tied to the operation performed here,
// But, we don't really care here if we throw MultiActionTooLargeException while doing
// single Gets.
expCount++;
Throwable t = metaCachePreservingExceptions.get(
expCount % metaCachePreservingExceptions.size());
throw new ServiceException(t);
}
/**
* Wrapper for {@link #postScannerOpen(ObserverContext, Scan, RegionScanner)} that ensures no non IOException is thrown,
* to prevent the coprocessor from becoming blacklisted.
*
*/
@Override
public final RegionScanner postScannerOpen(
final ObserverContext<RegionCoprocessorEnvironment> c, final Scan scan,
final RegionScanner s) throws IOException {
try {
if (!isRegionObserverFor(scan)) {
return s;
}
return new RegionScannerHolder(c, scan, s);
} catch (Throwable t) {
// If the exception is NotServingRegionException then throw it as
// StaleRegionBoundaryCacheException to handle it by phoenix client other wise hbase
// client may recreate scans with wrong region boundaries.
if(t instanceof NotServingRegionException) {
Exception cause = new StaleRegionBoundaryCacheException(c.getEnvironment().getRegion().getRegionInfo().getTable().getNameAsString());
throw new DoNotRetryIOException(cause.getMessage(), cause);
}
ServerUtil.throwIOException(c.getEnvironment().getRegion().getRegionInfo().getRegionNameAsString(), t);
return null; // impossible
}
}
@Override
public DataResult getFkCounter(byte[] key,DataResult previous) throws IOException{
Get g=new Get(key);
g.addColumn(SIConstants.DEFAULT_FAMILY_BYTES,SIConstants.FK_COUNTER_COLUMN_BYTES);
try{
Result r=region.get(g);
if(previous==null)
previous=new HResult(r);
else{
((HResult)previous).set(r);
}
return previous;
}catch(NotServingRegionException | ConnectionClosingException nsre){
throw new HNotServingRegion(nsre.getMessage());
}catch(WrongRegionException wre){
throw new HWrongRegion(wre.getMessage());
}
}
@Override
public DataResult getLatest(byte[] key,DataResult previous) throws IOException{
Get g=new Get(key);
g.setMaxVersions(1);
try{
Result result=region.get(g);
if(previous==null)
previous=new HResult(result);
else{
((HResult)previous).set(result);
}
return previous;
}catch(NotServingRegionException | ConnectionClosingException | AssertionError | NullPointerException nsre){
throw new HNotServingRegion(nsre.getMessage());
}catch(WrongRegionException wre){
throw new HWrongRegion(wre.getMessage());
}
}
@Override
public DataResult getLatest(byte[] rowKey,byte[] family,DataResult previous) throws IOException{
Get g=new Get(rowKey);
g.setMaxVersions(1);
g.addFamily(family);
try{
Result result=region.get(g);
if(previous==null)
previous=new HResult(result);
else{
((HResult)previous).set(result);
}
return previous;
}catch(NotServingRegionException| ConnectionClosingException nsre){
throw new HNotServingRegion(nsre.getMessage());
}catch(WrongRegionException wre){
throw new HWrongRegion(wre.getMessage());
}
}
@Override
public void batchMutate(List<DataMutation> mutations) throws IOException{
try{
Mutation[] ms = new Mutation[mutations.size()];
int i = 0;
for (DataMutation dm : mutations) {
if(dm instanceof HPut)
ms[i++] = ((HPut)dm).unwrapDelegate();
else
ms[i++] = ((HDelete)dm).unwrapDelegate();
}
region.batchMutate(ms);
}catch(NotServingRegionException | ConnectionClosingException nsre){
throw new HNotServingRegion(nsre.getMessage());
}catch(WrongRegionException wre){
throw new HWrongRegion(wre.getMessage());
}
}
private boolean clearCacheIfNeeded(Throwable e) throws IOException{
if (e==null ||
e instanceof WrongPartitionException ||
e instanceof NotServingRegionException ||
e instanceof NotServingPartitionException ||
e instanceof ConnectException ||
e instanceof ConnectionClosingException ||
e instanceof NoServerForRegionException ||
isFailedServerException(e)) {
/*
* We sent it to the wrong place, so we need to resubmit it. But since we
* pulled it from the cache, we first invalidate that cache
*/
partitionInfoCache.invalidate(this.tableName);
partitionInfoCache.invalidateAdapter(this.tableName);
return true;
}
return false;
}
private void mc(boolean tableLevel, Set<byte[]> targets) throws InterruptedException, IOException {
int i = 1;
for (byte[] tableOrRegion : targets) {
if (args.has(Args.OPTION_CF)) {
String cf = (String) args.valueOf(Args.OPTION_CF);
try {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on " + cf + " CF of " +
(tableLevel ? "table " : "region ") + Bytes.toStringBinary(tableOrRegion) +
(tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
admin.majorCompact(tableOrRegion, cf.getBytes());
mcCounter.getAndIncrement();
} catch (IOException e) {
String message = "column family " + cf + " does not exist";
if (e.getMessage().contains(message)) {
System.out.println("WARNING - " + message + " on " + Bytes.toStringBinary(tableOrRegion));
} else {
throw e;
}
}
} else {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on "
+ (tableLevel ? "table " : "region ")
+ Bytes.toStringBinary(tableOrRegion) + (tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
try {
admin.majorCompact(tableOrRegion);
} catch (NotServingRegionException ignore) {
}
mcCounter.getAndIncrement();
}
}
}
private void mc(boolean tableLevel, Set<byte[]> targets) throws InterruptedException, IOException {
int i = 1;
for (byte[] tableOrRegion : targets) {
if (args.has(Args.OPTION_CF)) {
String cf = (String) args.valueOf(Args.OPTION_CF);
try {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on " + cf + " CF of " +
(tableLevel ? "table " : "region ") + Bytes.toStringBinary(tableOrRegion) +
(tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
admin.majorCompact(tableOrRegion, cf.getBytes());
mcCounter.getAndIncrement();
} catch (IOException e) {
String message = "column family " + cf + " does not exist";
if (e.getMessage().contains(message)) {
System.out.println("WARNING - " + message + " on " + Bytes.toStringBinary(tableOrRegion));
} else {
throw e;
}
}
} else {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on "
+ (tableLevel ? "table " : "region ")
+ Bytes.toStringBinary(tableOrRegion) + (tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
try {
admin.majorCompact(tableOrRegion);
} catch (NotServingRegionException ignore) {
}
mcCounter.getAndIncrement();
}
}
}
private void mc(boolean tableLevel, Set<byte[]> targets) throws InterruptedException, IOException {
int i = 1;
for (byte[] tableOrRegion : targets) {
if (args.has(Args.OPTION_CF)) {
String cf = (String) args.valueOf(Args.OPTION_CF);
try {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on " + cf + " CF of " +
(tableLevel ? "table " : "region ") + Bytes.toStringBinary(tableOrRegion) +
(tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
admin.majorCompact(tableOrRegion, cf.getBytes());
mcCounter.getAndIncrement();
} catch (IOException e) {
String message = "column family " + cf + " does not exist";
if (e.getMessage().contains(message)) {
System.out.println("WARNING - " + message + " on " + Bytes.toStringBinary(tableOrRegion));
} else {
throw e;
}
}
} else {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on "
+ (tableLevel ? "table " : "region ")
+ Bytes.toStringBinary(tableOrRegion) + (tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
try {
admin.majorCompact(tableOrRegion);
} catch (NotServingRegionException ignore) {
}
mcCounter.getAndIncrement();
}
}
}
private void mc(boolean tableLevel, Set<byte[]> targets) throws InterruptedException, IOException {
int i = 1;
for (byte[] tableOrRegion : targets) {
if (args.has(Args.OPTION_CF)) {
String cf = (String) args.valueOf(Args.OPTION_CF);
try {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on " + cf + " CF of " +
(tableLevel ? "table " : "region ") + Bytes.toStringBinary(tableOrRegion) +
(tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
admin.majorCompact(tableOrRegion, cf.getBytes());
mcCounter.getAndIncrement();
} catch (IOException e) {
String message = "column family " + cf + " does not exist";
if (e.getMessage().contains(message)) {
System.out.println("WARNING - " + message + " on " + Bytes.toStringBinary(tableOrRegion));
} else {
throw e;
}
}
} else {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on "
+ (tableLevel ? "table " : "region ")
+ Bytes.toStringBinary(tableOrRegion) + (tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
try {
admin.majorCompact(tableOrRegion);
} catch (NotServingRegionException ignore) {
}
mcCounter.getAndIncrement();
}
}
}
private void mc(boolean tableLevel, Set<byte[]> targets) throws InterruptedException, IOException {
int i = 1;
for (byte[] tableOrRegion : targets) {
if (args.has(Args.OPTION_CF)) {
String cf = (String) args.valueOf(Args.OPTION_CF);
try {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on " + cf + " CF of " +
(tableLevel ? "table " : "region ") + Bytes.toStringBinary(tableOrRegion) +
(tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
admin.majorCompact(tableOrRegion, cf.getBytes());
mcCounter.getAndIncrement();
} catch (IOException e) {
String message = "column family " + cf + " does not exist";
if (e.getMessage().contains(message)) {
System.out.println("WARNING - " + message + " on " + Bytes.toStringBinary(tableOrRegion));
} else {
throw e;
}
}
} else {
System.out.print(i++ + "/" + targets.size() + " - Major compaction on "
+ (tableLevel ? "table " : "region ")
+ Bytes.toStringBinary(tableOrRegion) + (tableLevel ? "" : " - " + getRegionInfo(tableOrRegion)));
if (!Util.askProceedInteractively(args, true)) continue;
try {
admin.majorCompact(tableOrRegion);
} catch (NotServingRegionException ignore) {
}
mcCounter.getAndIncrement();
}
}
}
/**
* Increment the count for a specific exception type. This is called for each exception type
* that is returned to the thrift handler.
* @param rawThrowable type of exception
*/
public void exception(Throwable rawThrowable) {
source.exception();
Throwable throwable = unwrap(rawThrowable);
/**
* Keep some metrics for commonly seen exceptions
*
* Try and put the most common types first.
* Place child types before the parent type that they extend.
*
* If this gets much larger we might have to go to a hashmap
*/
if (throwable != null) {
if (throwable instanceof OutOfOrderScannerNextException) {
source.outOfOrderException();
} else if (throwable instanceof RegionTooBusyException) {
source.tooBusyException();
} else if (throwable instanceof UnknownScannerException) {
source.unknownScannerException();
} else if (throwable instanceof ScannerResetException) {
source.scannerResetException();
} else if (throwable instanceof RegionMovedException) {
source.movedRegionException();
} else if (throwable instanceof NotServingRegionException) {
source.notServingRegionException();
} else if (throwable instanceof FailedSanityCheckException) {
source.failedSanityException();
} else if (throwable instanceof MultiActionResultTooLarge) {
source.multiActionTooLargeException();
} else if (throwable instanceof CallQueueTooBigException) {
source.callQueueTooBigException();
}
}
}
@Override
public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> e,
Get get, List<Cell> results) throws IOException {
byte[] errorType = get.getAttribute(SHOULD_ERROR_ATTRIBUTE);
if (errorType != null) {
ErrorType type = ErrorType.valueOf(Bytes.toString(errorType));
switch (type) {
case CALL_QUEUE_TOO_BIG:
throw new CallQueueTooBigException("Failing for test");
case MULTI_ACTION_RESULT_TOO_LARGE:
throw new MultiActionResultTooLarge("Failing for test");
case FAILED_SANITY_CHECK:
throw new FailedSanityCheckException("Failing for test");
case NOT_SERVING_REGION:
throw new NotServingRegionException("Failing for test");
case REGION_MOVED:
throw new RegionMovedException(e.getEnvironment().getServerName(), 1);
case SCANNER_RESET:
throw new ScannerResetException("Failing for test");
case UNKNOWN_SCANNER:
throw new UnknownScannerException("Failing for test");
case REGION_TOO_BUSY:
throw new RegionTooBusyException("Failing for test");
case OUT_OF_ORDER_SCANNER_NEXT:
throw new OutOfOrderScannerNextException("Failing for test");
default:
throw new DoNotRetryIOException("Failing for test");
}
}
}
/**
* Contacts a region server and waits up to timeout ms
* to close the region. This bypasses the active hmaster.
* Pass -1 as timeout if you do not want to wait on result.
*/
public static void closeRegionSilentlyAndWait(AsyncClusterConnection connection,
ServerName server, RegionInfo region, long timeout) throws IOException, InterruptedException {
AsyncRegionServerAdmin admin = connection.getRegionServerAdmin(server);
try {
FutureUtils.get(
admin.closeRegion(ProtobufUtil.buildCloseRegionRequest(server, region.getRegionName())));
} catch (IOException e) {
LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e);
}
if (timeout < 0) {
return;
}
long expiration = timeout + System.currentTimeMillis();
while (System.currentTimeMillis() < expiration) {
try {
RegionInfo rsRegion = ProtobufUtil.toRegionInfo(FutureUtils
.get(
admin.getRegionInfo(RequestConverter.buildGetRegionInfoRequest(region.getRegionName())))
.getRegionInfo());
if (rsRegion == null) {
return;
}
} catch (IOException ioe) {
if (ioe instanceof NotServingRegionException) {
// no need to retry again
return;
}
LOG.warn("Exception when retrieving regioninfo from: " + region.getRegionNameAsString(),
ioe);
}
Thread.sleep(1000);
}
throw new IOException("Region " + region + " failed to close within" + " timeout " + timeout);
}
/**
* Find the List of HRegions based on a list of region specifiers
*
* @param regionSpecifiers the list of region specifiers
* @return the corresponding list of regions
* @throws IOException if any of the specifiers is not null,
* but failed to find the region
*/
private List<HRegion> getRegions(final List<RegionSpecifier> regionSpecifiers,
final CacheEvictionStatsBuilder stats) {
List<HRegion> regions = Lists.newArrayListWithCapacity(regionSpecifiers.size());
for (RegionSpecifier regionSpecifier: regionSpecifiers) {
try {
regions.add(regionServer.getRegion(regionSpecifier.getValue().toByteArray()));
} catch (NotServingRegionException e) {
stats.addException(regionSpecifier.getValue().toByteArray(), e);
}
}
return regions;
}
public void exception(Throwable throwable) {
source.exception();
/**
* Keep some metrics for commonly seen exceptions
*
* Try and put the most common types first.
* Place child types before the parent type that they extend.
*
* If this gets much larger we might have to go to a hashmap
*/
if (throwable != null) {
if (throwable instanceof OutOfOrderScannerNextException) {
source.outOfOrderException();
} else if (throwable instanceof RegionTooBusyException) {
source.tooBusyException();
} else if (throwable instanceof UnknownScannerException) {
source.unknownScannerException();
} else if (throwable instanceof ScannerResetException) {
source.scannerResetException();
} else if (throwable instanceof RegionMovedException) {
source.movedRegionException();
} else if (throwable instanceof NotServingRegionException) {
source.notServingRegionException();
} else if (throwable instanceof FailedSanityCheckException) {
source.failedSanityException();
} else if (throwable instanceof MultiActionResultTooLarge) {
source.multiActionTooLargeException();
} else if (throwable instanceof CallQueueTooBigException) {
source.callQueueTooBigException();
}
}
}
@Test
public void testRegionMove() throws IOException, InterruptedException, ExecutionException {
createSingleRegionTable();
ServerName serverName = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME).getServerName();
HRegionLocation loc =
getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get();
assertLocEquals(EMPTY_START_ROW, EMPTY_END_ROW, serverName, loc);
ServerName newServerName = TEST_UTIL.getHBaseCluster().getRegionServerThreads().stream()
.map(t -> t.getRegionServer().getServerName()).filter(sn -> !sn.equals(serverName)).findAny()
.get();
TEST_UTIL.getAdmin().move(Bytes.toBytes(loc.getRegion().getEncodedName()), newServerName);
while (!TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME).getServerName()
.equals(newServerName)) {
Thread.sleep(100);
}
// Should be same as it is in cache
assertSame(loc,
getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get());
LOCATOR.updateCachedLocationOnError(loc, null);
// null error will not trigger a cache cleanup
assertSame(loc,
getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get());
LOCATOR.updateCachedLocationOnError(loc, new NotServingRegionException());
assertLocEquals(EMPTY_START_ROW, EMPTY_END_ROW, newServerName,
getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get());
}
@Test
public void testConcurrentUpdateCachedLocationOnError() throws Exception {
createSingleRegionTable();
HRegionLocation loc =
getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false)
.get();
IntStream.range(0, 100).parallel()
.forEach(i -> LOCATOR.updateCachedLocationOnError(loc, new NotServingRegionException()));
}
private void checkRegionIsClosed(String encodedRegionName) throws Exception {
while (!getRS().getRegionsInTransitionInRS().isEmpty()) {
Thread.sleep(1);
}
try {
Assert.assertFalse(getRS().getRegionByEncodedName(encodedRegionName).isAvailable());
} catch (NotServingRegionException expected) {
// That's how it work: if the region is closed we have an exception.
}
// We don't delete the znode here, because there is not always a znode.
}
@Override
protected CloseRegionResponse execCloseRegion(ServerName server, byte[] regionName)
throws IOException {
switch (this.invocations++) {
case 0:
throw new NotServingRegionException("Fake");
case 1:
executor.schedule(new Runnable() {
@Override
public void run() {
LOG.info("Sending in CRASH of " + server);
doCrash(server);
}
}, 1, TimeUnit.SECONDS);
throw new RegionServerAbortedException("Fake!");
case 2:
executor.schedule(new Runnable() {
@Override
public void run() {
LOG.info("Sending in CRASH of " + server);
doCrash(server);
}
}, 1, TimeUnit.SECONDS);
throw new RegionServerStoppedException("Fake!");
case 3:
throw new ServerNotRunningYetException("Fake!");
case 4:
LOG.info("Returned null from serverName={}; means STUCK...TODO timeout", server);
executor.schedule(new Runnable() {
@Override
public void run() {
LOG.info("Sending in CRASH of " + server);
doCrash(server);
}
}, 1, TimeUnit.SECONDS);
return null;
default:
return super.execCloseRegion(server, regionName);
}
}
public static void checkRegionIsClosed(HBaseTestingUtility HTU, HRegionServer rs,
RegionInfo hri) throws Exception {
while (!rs.getRegionsInTransitionInRS().isEmpty()) {
Thread.sleep(1);
}
try {
Assert.assertFalse(rs.getRegion(hri.getRegionName()).isAvailable());
} catch (NotServingRegionException expected) {
// That's how it work: if the region is closed we have an exception.
}
}
/**
* Create a table that throws a DoNoRetryIOException on first scanner next
* call
*
* @throws IOException
*/
static Table createDNRIOEScannerTable(byte[] name, final int failCnt)
throws IOException {
// build up a mock scanner stuff to fail the first time
Answer<ResultScanner> a = new Answer<ResultScanner>() {
int cnt = 0;
@Override
public ResultScanner answer(InvocationOnMock invocation) throws Throwable {
// first invocation return the busted mock scanner
if (cnt++ < failCnt) {
// create mock ResultScanner that always fails.
Scan scan = mock(Scan.class);
doReturn(Bytes.toBytes("bogus")).when(scan).getStartRow(); // avoid npe
ResultScanner scanner = mock(ResultScanner.class);
invocation.callRealMethod(); // simulate NotServingRegionException
doThrow(
new NotServingRegionException("Injected simulated TimeoutException"))
.when(scanner).next();
return scanner;
}
// otherwise return the real scanner.
return (ResultScanner) invocation.callRealMethod();
}
};
Table htable = spy(createTable(name));
doAnswer(a).when(htable).getScanner((Scan) anyObject());
return htable;
}
/**
* Create a table that throws a NotServingRegionException on first scanner
* next call
*
* @throws IOException
*/
static Table createDNRIOEScannerTable(byte[] name, final int failCnt)
throws IOException {
// build up a mock scanner stuff to fail the first time
Answer<ResultScanner> a = new Answer<ResultScanner>() {
int cnt = 0;
@Override
public ResultScanner answer(InvocationOnMock invocation) throws Throwable {
// first invocation return the busted mock scanner
if (cnt++ < failCnt) {
// create mock ResultScanner that always fails.
Scan scan = mock(Scan.class);
doReturn(Bytes.toBytes("bogus")).when(scan).getStartRow(); // avoid npe
ResultScanner scanner = mock(ResultScanner.class);
invocation.callRealMethod(); // simulate NotServingRegionException
doThrow(
new NotServingRegionException("Injected simulated TimeoutException"))
.when(scanner).next();
return scanner;
}
// otherwise return the real scanner.
return (ResultScanner) invocation.callRealMethod();
}
};
Table htable = spy(createTable(name));
doAnswer(a).when(htable).getScanner((Scan) anyObject());
return htable;
}
/**
* Run test assuming NotServingRegionException using newer mapreduce api
*
* @throws InterruptedException
* @throws org.apache.hadoop.hbase.NotServingRegionException
*/
@Test(expected = org.apache.hadoop.hbase.NotServingRegionException.class)
public void testTableRecordReaderScannerTimeoutMapreduceTwice()
throws IOException, InterruptedException {
Table htable = createDNRIOEScannerTable(Bytes.toBytes("table5-mr"), 2);
runTestMapreduce(htable);
}
public static boolean isMetaClearingException(Throwable cur) {
cur = findException(cur);
if (cur == null) {
return true;
}
return !isSpecialException(cur) || (cur instanceof RegionMovedException)
|| cur instanceof NotServingRegionException;
}
public static boolean isSpecialException(Throwable cur) {
return (cur instanceof RegionMovedException || cur instanceof RegionOpeningException
|| cur instanceof RegionTooBusyException || cur instanceof RpcThrottlingException
|| cur instanceof MultiActionResultTooLarge || cur instanceof RetryImmediatelyException
|| cur instanceof CallQueueTooBigException || cur instanceof CallDroppedException
|| cur instanceof NotServingRegionException || cur instanceof RequestTooBigException);
}
/**
* Return the first SQLException in the exception chain, otherwise parse it.
* When we're receiving an exception locally, there's no need to string parse,
* as the SQLException will already be part of the chain.
* @param t
* @return the SQLException, or null if none found
*/
public static SQLException parseLocalOrRemoteServerException(Throwable t) {
while (t.getCause() != null) {
if (t instanceof NotServingRegionException) {
return parseRemoteException(new StaleRegionBoundaryCacheException());
} else if (t instanceof SQLException) {
return (SQLException) t;
}
t = t.getCause();
}
return parseRemoteException(t);
}