/** * Parse ZK-related fields from request. */ @Override public OpenRegionCoordination.OpenRegionDetails parseFromProtoRequest( AdminProtos.OpenRegionRequest.RegionOpenInfo regionOpenInfo) { ZkOpenRegionCoordination.ZkOpenRegionDetails zkCrd = new ZkOpenRegionCoordination.ZkOpenRegionDetails(); int versionOfOfflineNode = -1; if (regionOpenInfo.hasVersionOfOfflineNode()) { versionOfOfflineNode = regionOpenInfo.getVersionOfOfflineNode(); } zkCrd.setVersionOfOfflineNode(versionOfOfflineNode); zkCrd.setServerName(coordination.getServer().getServerName()); return zkCrd; }
private void replayToServer(HRegionInfo regionInfo, List<Entry> entries) throws IOException, ServiceException { if (entries.isEmpty()) return; Entry[] entriesArray = new Entry[entries.size()]; entriesArray = entries.toArray(entriesArray); AdminService.BlockingInterface remoteSvr = conn.getAdmin(getLocation().getServerName()); Pair<AdminProtos.ReplicateWALEntryRequest, CellScanner> p = ReplicationProtbufUtil.buildReplicateWALEntryRequest(entriesArray); PayloadCarryingRpcController controller = rpcControllerFactory.newController(p.getSecond()); try { remoteSvr.replay(controller, p.getFirst()); } catch (ServiceException se) { throw ProtobufUtil.getRemoteException(se); } }
/** * Test get of meta region fails properly if nothing to connect to. * @throws IOException * @throws InterruptedException * @throws KeeperException * @throws ServiceException */ @Test public void testVerifyMetaRegionLocationFails() throws IOException, InterruptedException, KeeperException, ServiceException { ClusterConnection connection = Mockito.mock(ClusterConnection.class); ServiceException connectException = new ServiceException(new ConnectException("Connection refused")); final AdminProtos.AdminService.BlockingInterface implementation = Mockito.mock(AdminProtos.AdminService.BlockingInterface.class); Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(), (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException); Mockito.when(connection.getAdmin(Mockito.any(ServerName.class))). thenReturn(implementation); RpcControllerFactory controllerFactory = Mockito.mock(RpcControllerFactory.class); Mockito.when(controllerFactory.newController()).thenReturn( Mockito.mock(PayloadCarryingRpcController.class)); Mockito.when(connection.getRpcControllerFactory()).thenReturn(controllerFactory); ServerName sn = ServerName.valueOf("example.com", 1234, System.currentTimeMillis()); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPENING); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPEN); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); }
private void performMultiplePutAndFlush(HBaseAdmin admin, HTable table, byte[] row, byte[] family, int nFlushes, int nPuts) throws Exception { // connection needed for poll-wait HRegionLocation loc = table.getRegionLocation(row, true); AdminProtos.AdminService.BlockingInterface server = admin.getConnection().getAdmin(loc.getServerName()); byte[] regName = loc.getRegionInfo().getRegionName(); for (int i = 0; i < nFlushes; i++) { randomCFPuts(table, row, family, nPuts); List<String> sf = ProtobufUtil.getStoreFiles(server, regName, FAMILY); int sfCount = sf.size(); // TODO: replace this api with a synchronous flush after HBASE-2949 admin.flush(table.getTableName()); // synchronously poll wait for a new storefile to appear (flush happened) while (ProtobufUtil.getStoreFiles( server, regName, FAMILY).size() == sfCount) { Thread.sleep(40); } } }
/** * Get region info from local cluster. */ Map<ServerName, List<String>> getDeployedHRIs(final HBaseAdmin admin) throws IOException { ClusterStatus status = admin.getClusterStatus(); Collection<ServerName> regionServers = status.getServers(); Map<ServerName, List<String>> mm = new HashMap<ServerName, List<String>>(); for (ServerName hsi : regionServers) { AdminProtos.AdminService.BlockingInterface server = ((HConnection) connection).getAdmin(hsi); // list all online regions from this region server List<HRegionInfo> regions = ProtobufUtil.getOnlineRegions(server); List<String> regionNames = new ArrayList<String>(); for (HRegionInfo hri : regions) { regionNames.add(hri.getRegionNameAsString()); } mm.put(hsi, regionNames); } return mm; }
@Test(timeout = 60000) public void testCloseByMasterWithoutZNode() throws Exception { // Transition in ZK on. This should fail, as there is no znode AdminProtos.CloseRegionRequest crr = RequestConverter.buildCloseRegionRequest( getRS().getServerName(), regionName, true); AdminProtos.CloseRegionResponse responseClose = getRS().rpcServices.closeRegion(null, crr); Assert.assertTrue(responseClose.getClosed()); // now waiting. After a while, the transition should be done while (!getRS().getRegionsInTransitionInRS().isEmpty()) { Thread.sleep(1); } // the region is still available, the close got rejected at the end Assert.assertTrue("The close should have failed", getRS().getRegion(regionName).isAvailable()); }
@Test(timeout = 60000) public void testOpenCloseByMasterWithZNode() throws Exception { ZKAssign.createNodeClosing(HTU.getZooKeeperWatcher(), hri, getRS().getServerName()); AdminProtos.CloseRegionRequest crr = RequestConverter.buildCloseRegionRequest( getRS().getServerName(), regionName, true); AdminProtos.CloseRegionResponse responseClose = getRS().rpcServices.closeRegion(null, crr); Assert.assertTrue(responseClose.getClosed()); checkRegionIsClosed(HTU, getRS(), hri); ZKAssign.deleteClosedNode(HTU.getZooKeeperWatcher(), hri.getEncodedName(), getRS().getServerName()); openRegion(HTU, getRS(), hri); }
@Test public void testOpenClosingRegion() throws Exception { Assert.assertTrue(getRS().getRegion(regionName).isAvailable()); try { // we re-opened meta so some of its data is lost ServerName sn = getRS().getServerName(); MetaTableAccessor.updateRegionLocation(getRS().getConnection(), hri, sn, getRS().getRegion(regionName).getOpenSeqNum(), -1); // fake region to be closing now, need to clear state afterwards getRS().regionsInTransitionInRS.put(hri.getEncodedNameAsBytes(), Boolean.FALSE); AdminProtos.OpenRegionRequest orr = RequestConverter.buildOpenRegionRequest(sn, hri, 0, null, null); getRS().rpcServices.openRegion(null, orr); Assert.fail("The closing region should not be opened"); } catch (ServiceException se) { Assert.assertTrue("The region should be already in transition", se.getCause() instanceof RegionAlreadyInTransitionException); } finally { getRS().regionsInTransitionInRS.remove(hri.getEncodedNameAsBytes()); } }
@Override public ServerName getServerHoldingRegion(TableName tn, byte[] regionName) throws IOException { HRegionLocation regionLoc = null; try (RegionLocator locator = connection.getRegionLocator(tn)) { regionLoc = locator.getRegionLocation(regionName); } if (regionLoc == null) { LOG.warn("Cannot find region server holding region " + Bytes.toString(regionName) + ", start key [" + Bytes.toString(HRegionInfo.getStartKey(regionName)) + "]"); return null; } AdminProtos.AdminService.BlockingInterface client = ((ClusterConnection)this.connection).getAdmin(regionLoc.getServerName()); ServerInfo info = ProtobufUtil.getServerInfo(null, client); return ProtobufUtil.toServerName(info.getServerName()); }
/** * Test get of meta region fails properly if nothing to connect to. * @throws IOException * @throws InterruptedException * @throws KeeperException * @throws ServiceException */ @Test public void testVerifyMetaRegionLocationFails() throws IOException, InterruptedException, KeeperException, ServiceException { ClusterConnection connection = Mockito.mock(ClusterConnection.class); ServiceException connectException = new ServiceException(new ConnectException("Connection refused")); final AdminProtos.AdminService.BlockingInterface implementation = Mockito.mock(AdminProtos.AdminService.BlockingInterface.class); Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(), (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException); Mockito.when(connection.getAdmin(Mockito.any(ServerName.class))). thenReturn(implementation); ServerName sn = ServerName.valueOf("example.com", 1234, System.currentTimeMillis()); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPENING); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPEN); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); }
@Test(timeout = 60000) public void testOpenCloseByMasterWithZNode() throws Exception { ZKAssign.createNodeClosing(HTU.getZooKeeperWatcher(), hri, getRS().getServerName()); AdminProtos.CloseRegionRequest crr = RequestConverter.buildCloseRegionRequest( getRS().getServerName(), regionName, true); AdminProtos.CloseRegionResponse responseClose = getRS().rpcServices.closeRegion(null, crr); Assert.assertTrue(responseClose.getClosed()); checkRegionIsClosed(); ZKAssign.deleteClosedNode(HTU.getZooKeeperWatcher(), hri.getEncodedName(), getRS().getServerName()); reopenRegion(); }
@Test public void testOpenClosingRegion() throws Exception { Assert.assertTrue(getRS().getRegion(regionName).isAvailable()); try { // we re-opened meta so some of its data is lost ServerName sn = getRS().getServerName(); MetaTableAccessor.updateRegionLocation(getRS().getConnection(), hri, sn, getRS().getRegion(regionName).getOpenSeqNum()); // fake region to be closing now, need to clear state afterwards getRS().regionsInTransitionInRS.put(hri.getEncodedNameAsBytes(), Boolean.FALSE); AdminProtos.OpenRegionRequest orr = RequestConverter.buildOpenRegionRequest(sn, hri, 0, null, null); getRS().rpcServices.openRegion(null, orr); Assert.fail("The closing region should not be opened"); } catch (ServiceException se) { Assert.assertTrue("The region should be already in transition", se.getCause() instanceof RegionAlreadyInTransitionException); } finally { getRS().regionsInTransitionInRS.remove(hri.getEncodedNameAsBytes()); } }
private void replayToServer(HRegionInfo regionInfo, List<HLog.Entry> entries) throws IOException, ServiceException { if (entries.isEmpty()) return; HLog.Entry[] entriesArray = new HLog.Entry[entries.size()]; entriesArray = entries.toArray(entriesArray); AdminService.BlockingInterface remoteSvr = conn.getAdmin(getLocation().getServerName()); Pair<AdminProtos.ReplicateWALEntryRequest, CellScanner> p = ReplicationProtbufUtil.buildReplicateWALEntryRequest(entriesArray); try { PayloadCarryingRpcController controller = new PayloadCarryingRpcController(p.getSecond()); remoteSvr.replay(controller, p.getFirst()); } catch (ServiceException se) { throw ProtobufUtil.getRemoteException(se); } }
/** * Test get of meta region fails properly if nothing to connect to. * @throws IOException * @throws InterruptedException * @throws KeeperException * @throws ServiceException */ @Test public void testVerifyMetaRegionLocationFails() throws IOException, InterruptedException, KeeperException, ServiceException { HConnection connection = Mockito.mock(HConnection.class); ServiceException connectException = new ServiceException(new ConnectException("Connection refused")); final AdminProtos.AdminService.BlockingInterface implementation = Mockito.mock(AdminProtos.AdminService.BlockingInterface.class); Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(), (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException); Mockito.when(connection.getAdmin(Mockito.any(ServerName.class), Mockito.anyBoolean())). thenReturn(implementation); final CatalogTracker ct = constructAndStartCatalogTracker(connection); MetaRegionTracker.setMetaLocation(this.watcher, ServerName.valueOf("example.com", 1234, System.currentTimeMillis())); Assert.assertFalse(ct.verifyMetaRegionLocation(100)); }
private void performMultiplePutAndFlush(HBaseAdmin admin, HTable table, byte[] row, byte[] family, int nFlushes, int nPuts) throws Exception { // connection needed for poll-wait HConnection conn = HConnectionManager.getConnection(TEST_UTIL .getConfiguration()); HRegionLocation loc = table.getRegionLocation(row, true); AdminProtos.AdminService.BlockingInterface server = conn.getAdmin(loc.getServerName()); byte[] regName = loc.getRegionInfo().getRegionName(); for (int i = 0; i < nFlushes; i++) { randomCFPuts(table, row, family, nPuts); List<String> sf = ProtobufUtil.getStoreFiles(server, regName, FAMILY); int sfCount = sf.size(); // TODO: replace this api with a synchronous flush after HBASE-2949 admin.flush(table.getTableName()); // synchronously poll wait for a new storefile to appear (flush happened) while (ProtobufUtil.getStoreFiles( server, regName, FAMILY).size() == sfCount) { Thread.sleep(40); } } }
/** * Get region info from local cluster. */ Map<ServerName, List<String>> getDeployedHRIs( final HBaseAdmin admin) throws IOException { ClusterStatus status = admin.getClusterStatus(); Collection<ServerName> regionServers = status.getServers(); Map<ServerName, List<String>> mm = new HashMap<ServerName, List<String>>(); HConnection connection = admin.getConnection(); for (ServerName hsi : regionServers) { AdminProtos.AdminService.BlockingInterface server = connection.getAdmin(hsi); // list all online regions from this region server List<HRegionInfo> regions = ProtobufUtil.getOnlineRegions(server); List<String> regionNames = new ArrayList<String>(); for (HRegionInfo hri : regions) { regionNames.add(hri.getRegionNameAsString()); } mm.put(hsi, regionNames); } return mm; }
@Test(timeout = 60000) public void testCloseByMasterWithoutZNode() throws Exception { // Transition in ZK on. This should fail, as there is no znode AdminProtos.CloseRegionRequest crr = RequestConverter.buildCloseRegionRequest( getRS().getServerName(), regionName, true); AdminProtos.CloseRegionResponse responseClose = getRS().closeRegion(null, crr); Assert.assertTrue(responseClose.getClosed()); // now waiting. After a while, the transition should be done while (!getRS().getRegionsInTransitionInRS().isEmpty()) { Thread.sleep(1); } // the region is still available, the close got rejected at the end Assert.assertTrue("The close should have failed", getRS().getRegion(regionName).isAvailable()); }
@Test(timeout = 60000) public void testOpenCloseByMasterWithZNode() throws Exception { ZKAssign.createNodeClosing(HTU.getZooKeeperWatcher(), hri, getRS().getServerName()); AdminProtos.CloseRegionRequest crr = RequestConverter.buildCloseRegionRequest( getRS().getServerName(), regionName, true); AdminProtos.CloseRegionResponse responseClose = getRS().closeRegion(null, crr); Assert.assertTrue(responseClose.getClosed()); checkRegionIsClosed(); ZKAssign.deleteClosedNode(HTU.getZooKeeperWatcher(), hri.getEncodedName(), getRS().getServerName()); reopenRegion(); }
/** * Test that we can send multiple openRegion to the region server. * This is used when: * - there is a SocketTimeout: in this case, the master does not know if the region server * received the request before the timeout. * - We have a socket error during the operation: same stuff: we don't know * - a master failover: if we find a znode in thz M_ZK_REGION_OFFLINE, we don't know if * the region server has received the query or not. Only solution to be efficient: re-ask * immediately. */ @Test(timeout = 60000) public void testMultipleOpen() throws Exception { // We close closeNoZK(); checkRegionIsClosed(); // We reopen. We need a ZK node here, as a open is always triggered by a master. ZKAssign.createNodeOffline(HTU.getZooKeeperWatcher(), hri, getRS().getServerName()); // We're sending multiple requests in a row. The region server must handle this nicely. for (int i = 0; i < 10; i++) { AdminProtos.OpenRegionRequest orr = RequestConverter.buildOpenRegionRequest(getRS().getServerName(), hri, 0, null); AdminProtos.OpenRegionResponse responseOpen = getRS().openRegion(null, orr); Assert.assertTrue(responseOpen.getOpeningStateCount() == 1); AdminProtos.OpenRegionResponse.RegionOpeningState ors = responseOpen.getOpeningState(0); Assert.assertTrue("request " + i + " failed", ors.equals(AdminProtos.OpenRegionResponse.RegionOpeningState.OPENED) || ors.equals(AdminProtos.OpenRegionResponse.RegionOpeningState.ALREADY_OPENED) ); } checkRegionIsOpened(); }
@Test public void testOpenClosingRegion() throws Exception { Assert.assertTrue(getRS().getRegion(regionName).isAvailable()); try { // fake region to be closing now, need to clear state afterwards getRS().regionsInTransitionInRS.put(hri.getEncodedNameAsBytes(), Boolean.FALSE); AdminProtos.OpenRegionRequest orr = RequestConverter.buildOpenRegionRequest(getRS().getServerName(), hri, 0, null); getRS().openRegion(null, orr); Assert.fail("The closing region should not be opened"); } catch (ServiceException se) { Assert.assertTrue("The region should be already in transition", se.getCause() instanceof RegionAlreadyInTransitionException); } finally { getRS().regionsInTransitionInRS.remove(hri.getEncodedNameAsBytes()); } }
@Override public ServerName getServerHoldingRegion(byte[] regionName) throws IOException { HConnection connection = admin.getConnection(); HRegionLocation regionLoc = connection.locateRegion(regionName); if (regionLoc == null) { LOG.warn("Cannot find region server holding region " + Bytes.toString(regionName) + " for table " + HRegionInfo.getTableName(regionName) + ", start key [" + Bytes.toString(HRegionInfo.getStartKey(regionName)) + "]"); return null; } AdminProtos.AdminService.BlockingInterface client = connection.getAdmin(regionLoc.getServerName()); ServerInfo info = ProtobufUtil.getServerInfo(client); return ProtobufUtil.toServerName(info.getServerName()); }
private void replayToServer(HRegionInfo regionInfo, List<HLog.Entry> entries) throws IOException, ServiceException { if (entries.isEmpty()) return; HLog.Entry[] entriesArray = new HLog.Entry[entries.size()]; entriesArray = entries.toArray(entriesArray); AdminService.BlockingInterface remoteSvr = conn.getAdmin(getLocation().getServerName()); Pair<AdminProtos.ReplicateWALEntryRequest, CellScanner> p = ReplicationProtbufUtil.buildReplicateWALEntryRequest(entriesArray); PayloadCarryingRpcController controller = rpcControllerFactory.newController(p.getSecond()); try { remoteSvr.replay(controller, p.getFirst()); } catch (ServiceException se) { throw ProtobufUtil.getRemoteException(se); } }
/** * Test that we can send multiple openRegion to the region server. * This is used when: * - there is a SocketTimeout: in this case, the master does not know if the region server * received the request before the timeout. * - We have a socket error during the operation: same stuff: we don't know * - a master failover: if we find a znode in thz M_ZK_REGION_OFFLINE, we don't know if * the region server has received the query or not. Only solution to be efficient: re-ask * immediately. */ @Test(timeout = 60000) public void testMultipleOpen() throws Exception { // We close closeNoZK(); checkRegionIsClosed(); // We reopen. We need a ZK node here, as a open is always triggered by a master. ZKAssign.createNodeOffline(HTU.getZooKeeperWatcher(), hri, getRS().getServerName()); // We're sending multiple requests in a row. The region server must handle this nicely. for (int i = 0; i < 10; i++) { AdminProtos.OpenRegionRequest orr = RequestConverter.buildOpenRegionRequest(getRS().getServerName(), hri, 0, null); AdminProtos.OpenRegionResponse responseOpen = getRS().rpcServices.openRegion(null, orr); Assert.assertTrue(responseOpen.getOpeningStateCount() == 1); AdminProtos.OpenRegionResponse.RegionOpeningState ors = responseOpen.getOpeningState(0); Assert.assertTrue("request " + i + " failed", ors.equals(AdminProtos.OpenRegionResponse.RegionOpeningState.OPENED) || ors.equals(AdminProtos.OpenRegionResponse.RegionOpeningState.ALREADY_OPENED) ); } checkRegionIsOpened(); }
@Test public void testOpenClosingRegion() throws Exception { Assert.assertTrue(getRS().getRegion(regionName).isAvailable()); try { // we re-opened meta so some of its data is lost ServerName sn = getRS().getServerName(); MetaEditor.updateRegionLocation(getRS().catalogTracker, hri, sn, getRS().getRegion(regionName).getOpenSeqNum()); // fake region to be closing now, need to clear state afterwards getRS().regionsInTransitionInRS.put(hri.getEncodedNameAsBytes(), Boolean.FALSE); AdminProtos.OpenRegionRequest orr = RequestConverter.buildOpenRegionRequest(sn, hri, 0, null); getRS().rpcServices.openRegion(null, orr); Assert.fail("The closing region should not be opened"); } catch (ServiceException se) { Assert.assertTrue("The region should be already in transition", se.getCause() instanceof RegionAlreadyInTransitionException); } finally { getRS().regionsInTransitionInRS.remove(hri.getEncodedNameAsBytes()); } }
@Test(timeout = 60000) public void testCloseByMasterWithoutZNode() throws Exception { // Transition in ZK on. This should fail, as there is no znode AdminProtos.CloseRegionRequest crr = RequestConverter.buildCloseRegionRequest( regionName, true); AdminProtos.CloseRegionResponse responseClose = getRS().closeRegion(null, crr); Assert.assertTrue(responseClose.getClosed()); // now waiting. After a while, the transition should be done while (!getRS().getRegionsInTransitionInRS().isEmpty()) { Thread.sleep(1); } // the region is still available, the close got rejected at the end Assert.assertTrue("The close should have failed", getRS().getRegion(regionName).isAvailable()); }