use of org.apache.hadoop.hbase.ipc.HBaseRpcController in project hbase by apache.
the class TestMetaTableAccessorNoCluster method testRideOverServerNotRunning.
/**
* Test that MetaTableAccessor will ride over server throwing
* "Server not running" IOEs.
* @see @link {https://issues.apache.org/jira/browse/HBASE-3446}
* @throws IOException
* @throws InterruptedException
*/
@Test
public void testRideOverServerNotRunning() throws IOException, InterruptedException, ServiceException {
// Need a zk watcher.
ZooKeeperWatcher zkw = new ZooKeeperWatcher(UTIL.getConfiguration(), this.getClass().getSimpleName(), ABORTABLE, true);
// This is a servername we use in a few places below.
ServerName sn = ServerName.valueOf("example.com", 1234, System.currentTimeMillis());
ClusterConnection connection = null;
try {
// Mock an ClientProtocol. Our mock implementation will fail a few
// times when we go to open a scanner.
final ClientProtos.ClientService.BlockingInterface implementation = Mockito.mock(ClientProtos.ClientService.BlockingInterface.class);
// When scan called throw IOE 'Server not running' a few times
// before we return a scanner id. Whats WEIRD is that these
// exceptions do not show in the log because they are caught and only
// printed if we FAIL. We eventually succeed after retry so these don't
// show. We will know if they happened or not because we will ask
// mockito at the end of this test to verify that scan was indeed
// called the wanted number of times.
List<Cell> kvs = new ArrayList<>();
final byte[] rowToVerify = Bytes.toBytes("rowToVerify");
kvs.add(new KeyValue(rowToVerify, HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, HRegionInfo.FIRST_META_REGIONINFO.toByteArray()));
kvs.add(new KeyValue(rowToVerify, HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER, Bytes.toBytes(sn.getHostAndPort())));
kvs.add(new KeyValue(rowToVerify, HConstants.CATALOG_FAMILY, HConstants.STARTCODE_QUALIFIER, Bytes.toBytes(sn.getStartcode())));
final List<CellScannable> cellScannables = new ArrayList<>(1);
cellScannables.add(Result.create(kvs));
final ScanResponse.Builder builder = ScanResponse.newBuilder();
for (CellScannable result : cellScannables) {
builder.addCellsPerResult(((Result) result).size());
}
Mockito.when(implementation.scan((RpcController) Mockito.any(), (ScanRequest) Mockito.any())).thenThrow(new ServiceException("Server not running (1 of 3)")).thenThrow(new ServiceException("Server not running (2 of 3)")).thenThrow(new ServiceException("Server not running (3 of 3)")).thenAnswer(new Answer<ScanResponse>() {
public ScanResponse answer(InvocationOnMock invocation) throws Throwable {
((HBaseRpcController) invocation.getArguments()[0]).setCellScanner(CellUtil.createCellScanner(cellScannables));
return builder.setScannerId(1234567890L).setMoreResults(false).build();
}
});
// Associate a spied-upon Connection with UTIL.getConfiguration. Need
// to shove this in here first so it gets picked up all over; e.g. by
// HTable.
connection = HConnectionTestingUtility.getSpiedConnection(UTIL.getConfiguration());
// Fix the location lookup so it 'works' though no network. First
// make an 'any location' object.
final HRegionLocation anyLocation = new HRegionLocation(HRegionInfo.FIRST_META_REGIONINFO, sn);
final RegionLocations rl = new RegionLocations(anyLocation);
// Return the RegionLocations object when locateRegion
// The ugly format below comes of 'Important gotcha on spying real objects!' from
// http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html
Mockito.doReturn(rl).when(connection).locateRegion((TableName) Mockito.any(), (byte[]) Mockito.any(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyInt());
// Now shove our HRI implementation into the spied-upon connection.
Mockito.doReturn(implementation).when(connection).getClient(Mockito.any(ServerName.class));
// Scan meta for user tables and verify we got back expected answer.
NavigableMap<HRegionInfo, Result> hris = MetaTableAccessor.getServerUserRegions(connection, sn);
assertEquals(1, hris.size());
assertTrue(hris.firstEntry().getKey().equals(HRegionInfo.FIRST_META_REGIONINFO));
assertTrue(Bytes.equals(rowToVerify, hris.firstEntry().getValue().getRow()));
// Finally verify that scan was called four times -- three times
// with exception and then on 4th attempt we succeed
Mockito.verify(implementation, Mockito.times(4)).scan((RpcController) Mockito.any(), (ScanRequest) Mockito.any());
} finally {
if (connection != null && !connection.isClosed())
connection.close();
zkw.close();
}
}
use of org.apache.hadoop.hbase.ipc.HBaseRpcController in project hbase by apache.
the class RegionServerCallable method call.
/**
* Override that changes call Exception from {@link Exception} to {@link IOException}.
* Also does set up of the rpcController.
*/
public T call(int callTimeout) throws IOException {
try {
// com.google.protobuf.RpcController or null -- will just skip over this config.
if (getRpcController() != null) {
RpcController shadedRpcController = (RpcController) getRpcController();
// Do a reset to clear previous states, such as CellScanner.
shadedRpcController.reset();
if (shadedRpcController instanceof HBaseRpcController) {
HBaseRpcController hrc = (HBaseRpcController) getRpcController();
// If it is an instance of HBaseRpcController, we can set priority on the controller based
// off the tableName. Set call timeout too.
hrc.setPriority(tableName);
hrc.setCallTimeout(callTimeout);
}
}
return rpcCall();
} catch (Exception e) {
throw ProtobufUtil.handleRemoteException(e);
}
}
use of org.apache.hadoop.hbase.ipc.HBaseRpcController in project hbase by apache.
the class MockRegionServer method scan.
@Override
public ScanResponse scan(RpcController controller, ScanRequest request) throws ServiceException {
ScanResponse.Builder builder = ScanResponse.newBuilder();
try {
if (request.hasScan()) {
byte[] regionName = request.getRegion().getValue().toByteArray();
builder.setScannerId(openScanner(regionName, null));
builder.setMoreResults(true);
} else {
long scannerId = request.getScannerId();
Result result = next(scannerId);
if (result != null) {
builder.addCellsPerResult(result.size());
List<CellScannable> results = new ArrayList<>(1);
results.add(result);
((HBaseRpcController) controller).setCellScanner(CellUtil.createCellScanner(results));
builder.setMoreResults(true);
} else {
builder.setMoreResults(false);
close(scannerId);
}
}
} catch (IOException ie) {
throw new ServiceException(ie);
}
return builder.build();
}
use of org.apache.hadoop.hbase.ipc.HBaseRpcController in project hbase by apache.
the class ServerManager method closeRegionSilentlyAndWait.
/**
* Contacts a region server and waits up to timeout ms
* to close the region. This bypasses the active hmaster.
*/
public static void closeRegionSilentlyAndWait(ClusterConnection connection, ServerName server, HRegionInfo region, long timeout) throws IOException, InterruptedException {
AdminService.BlockingInterface rs = connection.getAdmin(server);
HBaseRpcController controller = connection.getRpcControllerFactory().newController();
try {
ProtobufUtil.closeRegion(controller, rs, server, region.getRegionName());
} catch (IOException e) {
LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e);
}
long expiration = timeout + System.currentTimeMillis();
while (System.currentTimeMillis() < expiration) {
controller.reset();
try {
HRegionInfo rsRegion = ProtobufUtil.getRegionInfo(controller, rs, region.getRegionName());
if (rsRegion == null)
return;
} catch (IOException ioe) {
if (// no need to retry again
ioe instanceof NotServingRegionException)
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);
}
use of org.apache.hadoop.hbase.ipc.HBaseRpcController in project hbase by apache.
the class ServerManager method sendRegionCloseForSplitOrMerge.
/**
* Sends an CLOSE RPC to the specified server to close the specified region for SPLIT.
* <p>
* A region server could reject the close request because it either does not
* have the specified region or the region is being split.
* @param server server to close a region
* @param regionToClose the info of the region(s) to close
* @throws IOException
*/
public boolean sendRegionCloseForSplitOrMerge(final ServerName server, final HRegionInfo... regionToClose) throws IOException {
if (server == null) {
throw new NullPointerException("Passed server is null");
}
AdminService.BlockingInterface admin = getRsAdmin(server);
if (admin == null) {
throw new IOException("Attempting to send CLOSE For Split or Merge RPC to server " + server.toString() + " failed because no RPC connection found to this server.");
}
HBaseRpcController controller = newRpcController();
return ProtobufUtil.closeRegionForSplitOrMerge(controller, admin, server, regionToClose);
}
Aggregations