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; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertNotNull; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023import static org.junit.jupiter.api.Assertions.fail; 024 025import java.io.IOException; 026import java.security.PrivilegedAction; 027import java.util.EnumSet; 028import java.util.List; 029import java.util.Map; 030import java.util.Optional; 031import java.util.concurrent.CompletableFuture; 032import java.util.concurrent.atomic.AtomicInteger; 033import org.apache.hadoop.conf.Configuration; 034import org.apache.hadoop.hbase.ClusterMetrics.Option; 035import org.apache.hadoop.hbase.Waiter.Predicate; 036import org.apache.hadoop.hbase.client.Admin; 037import org.apache.hadoop.hbase.client.AsyncAdmin; 038import org.apache.hadoop.hbase.client.AsyncConnection; 039import org.apache.hadoop.hbase.client.ClusterConnectionFactory; 040import org.apache.hadoop.hbase.client.Connection; 041import org.apache.hadoop.hbase.client.ConnectionFactory; 042import org.apache.hadoop.hbase.client.Get; 043import org.apache.hadoop.hbase.client.Put; 044import org.apache.hadoop.hbase.client.RegionInfoBuilder; 045import org.apache.hadoop.hbase.client.RegionStatesCount; 046import org.apache.hadoop.hbase.client.Result; 047import org.apache.hadoop.hbase.client.Scan; 048import org.apache.hadoop.hbase.client.Table; 049import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; 050import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor; 051import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; 052import org.apache.hadoop.hbase.coprocessor.MasterObserver; 053import org.apache.hadoop.hbase.coprocessor.ObserverContext; 054import org.apache.hadoop.hbase.filter.FilterAllFilter; 055import org.apache.hadoop.hbase.master.HMaster; 056import org.apache.hadoop.hbase.monitoring.TaskMonitor; 057import org.apache.hadoop.hbase.regionserver.HRegionServer; 058import org.apache.hadoop.hbase.regionserver.MetricsUserAggregateFactory; 059import org.apache.hadoop.hbase.security.User; 060import org.apache.hadoop.hbase.security.UserProvider; 061import org.apache.hadoop.hbase.testclassification.MediumTests; 062import org.apache.hadoop.hbase.util.Bytes; 063import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 064import org.apache.hadoop.hbase.util.JVMClusterUtil.MasterThread; 065import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; 066import org.junit.jupiter.api.AfterAll; 067import org.junit.jupiter.api.BeforeAll; 068import org.junit.jupiter.api.Tag; 069import org.junit.jupiter.api.Test; 070 071@Tag(MediumTests.TAG) 072public class TestClientClusterMetrics { 073 074 private static HBaseTestingUtil UTIL; 075 private static Admin ADMIN; 076 private final static int SLAVES = 5; 077 private final static int MASTERS = 3; 078 private static SingleProcessHBaseCluster CLUSTER; 079 private static HRegionServer DEAD; 080 private static final TableName TABLE_NAME = TableName.valueOf("test"); 081 private static final byte[] CF = Bytes.toBytes("cf"); 082 083 // We need to promote the visibility of tryRegionServerReport for this test 084 public static class MyRegionServer 085 extends SingleProcessHBaseCluster.MiniHBaseClusterRegionServer { 086 public MyRegionServer(Configuration conf) throws IOException, InterruptedException { 087 super(conf); 088 } 089 090 @Override 091 public void tryRegionServerReport(long reportStartTime, long reportEndTime) throws IOException { 092 super.tryRegionServerReport(reportStartTime, reportEndTime); 093 } 094 } 095 096 @BeforeAll 097 public static void setUpBeforeClass() throws Exception { 098 Configuration conf = HBaseConfiguration.create(); 099 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, MyObserver.class.getName()); 100 UTIL = new HBaseTestingUtil(conf); 101 StartTestingClusterOption option = 102 StartTestingClusterOption.builder().rsClass(TestClientClusterMetrics.MyRegionServer.class) 103 .numMasters(MASTERS).numRegionServers(SLAVES).numDataNodes(SLAVES).build(); 104 UTIL.startMiniCluster(option); 105 CLUSTER = UTIL.getHBaseCluster(); 106 CLUSTER.waitForActiveAndReadyMaster(); 107 ADMIN = UTIL.getAdmin(); 108 // Kill one region server 109 List<RegionServerThread> rsts = CLUSTER.getLiveRegionServerThreads(); 110 RegionServerThread rst = rsts.get(rsts.size() - 1); 111 DEAD = rst.getRegionServer(); 112 DEAD.stop("Test dead servers metrics"); 113 while (rst.isAlive()) { 114 Thread.sleep(500); 115 } 116 } 117 118 @Test 119 public void testDefaults() throws Exception { 120 ClusterMetrics origin = ADMIN.getClusterMetrics(); 121 ClusterMetrics defaults = ADMIN.getClusterMetrics(EnumSet.allOf(Option.class)); 122 assertEquals(origin.getHBaseVersion(), defaults.getHBaseVersion()); 123 assertEquals(origin.getClusterId(), defaults.getClusterId()); 124 assertEquals(origin.getAverageLoad(), defaults.getAverageLoad(), 0); 125 assertEquals(origin.getBackupMasterNames().size(), defaults.getBackupMasterNames().size()); 126 assertEquals(origin.getDeadServerNames().size(), defaults.getDeadServerNames().size()); 127 assertEquals(origin.getRegionCount(), defaults.getRegionCount()); 128 assertEquals(origin.getLiveServerMetrics().size(), defaults.getLiveServerMetrics().size()); 129 assertEquals(origin.getMasterInfoPort(), defaults.getMasterInfoPort()); 130 assertEquals(origin.getServersName().size(), defaults.getServersName().size()); 131 assertEquals(ADMIN.getRegionServers().size(), defaults.getServersName().size()); 132 // We decommission the first online region server and verify the metrics. 133 List<ServerName> serverNames = origin.getServersName().subList(0, 1); 134 ADMIN.decommissionRegionServers(serverNames, false); 135 assertEquals(1, ADMIN.getClusterMetrics().getDecommissionedServerNames().size()); 136 assertEquals(ADMIN.getClusterMetrics().getDecommissionedServerNames().get(0), 137 serverNames.get(0)); 138 } 139 140 @Test 141 public void testAsyncClient() throws Exception { 142 try (AsyncConnection asyncConnect = 143 ConnectionFactory.createAsyncConnection(UTIL.getConfiguration()).get()) { 144 AsyncAdmin asyncAdmin = asyncConnect.getAdmin(); 145 CompletableFuture<ClusterMetrics> originFuture = asyncAdmin.getClusterMetrics(); 146 CompletableFuture<ClusterMetrics> defaultsFuture = 147 asyncAdmin.getClusterMetrics(EnumSet.allOf(Option.class)); 148 ClusterMetrics origin = originFuture.get(); 149 ClusterMetrics defaults = defaultsFuture.get(); 150 assertEquals(origin.getHBaseVersion(), defaults.getHBaseVersion()); 151 assertEquals(origin.getClusterId(), defaults.getClusterId()); 152 assertEquals(origin.getHBaseVersion(), defaults.getHBaseVersion()); 153 assertEquals(origin.getClusterId(), defaults.getClusterId()); 154 assertEquals(origin.getAverageLoad(), defaults.getAverageLoad(), 0); 155 assertEquals(origin.getBackupMasterNames().size(), defaults.getBackupMasterNames().size()); 156 assertEquals(origin.getDeadServerNames().size(), defaults.getDeadServerNames().size()); 157 assertEquals(origin.getRegionCount(), defaults.getRegionCount()); 158 assertEquals(origin.getLiveServerMetrics().size(), defaults.getLiveServerMetrics().size()); 159 assertEquals(origin.getMasterInfoPort(), defaults.getMasterInfoPort()); 160 assertEquals(origin.getServersName().size(), defaults.getServersName().size()); 161 origin.getTableRegionStatesCount().forEach(((tableName, regionStatesCount) -> { 162 RegionStatesCount defaultRegionStatesCount = 163 defaults.getTableRegionStatesCount().get(tableName); 164 assertEquals(defaultRegionStatesCount, regionStatesCount); 165 })); 166 } 167 } 168 169 @Test 170 public void testLiveAndDeadServersStatus() throws Exception { 171 // Count the number of live regionservers 172 List<RegionServerThread> regionserverThreads = CLUSTER.getLiveRegionServerThreads(); 173 int numRs = 0; 174 int len = regionserverThreads.size(); 175 for (int i = 0; i < len; i++) { 176 if (regionserverThreads.get(i).isAlive()) { 177 numRs++; 178 } 179 } 180 // Depending on the (random) order of unit execution we may run this unit before the 181 // minicluster is fully up and recovered from the RS shutdown done during test init. 182 Waiter.waitFor(CLUSTER.getConfiguration(), 10 * 1000, 100, new Predicate<Exception>() { 183 @Override 184 public boolean evaluate() throws Exception { 185 ClusterMetrics metrics = ADMIN.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS)); 186 assertNotNull(metrics); 187 return metrics.getRegionCount() > 0; 188 } 189 }); 190 // Retrieve live servers and dead servers info. 191 EnumSet<Option> options = 192 EnumSet.of(Option.LIVE_SERVERS, Option.DEAD_SERVERS, Option.SERVERS_NAME); 193 ClusterMetrics metrics = ADMIN.getClusterMetrics(options); 194 assertNotNull(metrics); 195 // exclude a dead region server 196 assertEquals(SLAVES - 1, numRs); 197 // live servers = nums of regionservers 198 // By default, HMaster don't carry any regions so it won't report its load. 199 // Hence, it won't be in the server list. 200 assertEquals(numRs, metrics.getLiveServerMetrics().size()); 201 assertTrue(metrics.getRegionCount() > 0); 202 assertNotNull(metrics.getDeadServerNames()); 203 assertEquals(1, metrics.getDeadServerNames().size()); 204 ServerName deadServerName = metrics.getDeadServerNames().iterator().next(); 205 assertEquals(DEAD.getServerName(), deadServerName); 206 assertNotNull(metrics.getServersName()); 207 assertEquals(numRs, metrics.getServersName().size()); 208 } 209 210 @Test 211 public void testRegionStatesCount() throws Exception { 212 Table table = UTIL.createTable(TABLE_NAME, CF); 213 table.put(new Put(Bytes.toBytes("k1")).addColumn(CF, Bytes.toBytes("q1"), Bytes.toBytes("v1"))); 214 table.put(new Put(Bytes.toBytes("k2")).addColumn(CF, Bytes.toBytes("q2"), Bytes.toBytes("v2"))); 215 table.put(new Put(Bytes.toBytes("k3")).addColumn(CF, Bytes.toBytes("q3"), Bytes.toBytes("v3"))); 216 217 ClusterMetrics metrics = ADMIN.getClusterMetrics(); 218 assertEquals(metrics.getTableRegionStatesCount().size(), 2); 219 assertEquals( 220 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getRegionsInTransition(), 221 0); 222 assertEquals( 223 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getOpenRegions(), 1); 224 assertEquals( 225 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getTotalRegions(), 1); 226 assertEquals( 227 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getClosedRegions(), 0); 228 assertEquals( 229 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getSplitRegions(), 0); 230 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getRegionsInTransition(), 0); 231 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getOpenRegions(), 1); 232 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getTotalRegions(), 1); 233 234 UTIL.deleteTable(TABLE_NAME); 235 } 236 237 @Test 238 public void testRegionStatesWithSplit() throws Exception { 239 int startRowNum = 20; 240 int rowCount = 80; 241 Table table = UTIL.createTable(TABLE_NAME, CF); 242 table.put(new Put(Bytes.toBytes("k1")).addColumn(CF, Bytes.toBytes("q1"), Bytes.toBytes("v1"))); 243 table.put(new Put(Bytes.toBytes("k2")).addColumn(CF, Bytes.toBytes("q2"), Bytes.toBytes("v2"))); 244 245 insertData(TABLE_NAME, startRowNum, rowCount); 246 247 ClusterMetrics metrics = ADMIN.getClusterMetrics(); 248 assertEquals(metrics.getTableRegionStatesCount().size(), 2); 249 assertEquals( 250 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getRegionsInTransition(), 251 0); 252 assertEquals( 253 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getOpenRegions(), 1); 254 assertEquals( 255 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getTotalRegions(), 1); 256 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getRegionsInTransition(), 0); 257 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getOpenRegions(), 1); 258 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getTotalRegions(), 1); 259 260 int splitRowNum = startRowNum + rowCount / 2; 261 byte[] splitKey = Bytes.toBytes("" + splitRowNum); 262 263 // Split region of the table 264 ADMIN.split(TABLE_NAME, splitKey); 265 266 metrics = ADMIN.getClusterMetrics(); 267 assertEquals(metrics.getTableRegionStatesCount().size(), 2); 268 assertEquals( 269 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getRegionsInTransition(), 270 0); 271 assertEquals( 272 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getOpenRegions(), 1); 273 assertEquals( 274 metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME).getTotalRegions(), 1); 275 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getRegionsInTransition(), 0); 276 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getOpenRegions(), 2); 277 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getTotalRegions(), 3); 278 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getSplitRegions(), 1); 279 assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME).getClosedRegions(), 0); 280 281 UTIL.deleteTable(TABLE_NAME); 282 } 283 284 @Test 285 public void testMasterAndBackupMastersStatus() throws Exception { 286 // get all the master threads 287 List<MasterThread> masterThreads = CLUSTER.getMasterThreads(); 288 int numActive = 0; 289 int activeIndex = 0; 290 ServerName activeName = null; 291 HMaster active = null; 292 for (int i = 0; i < masterThreads.size(); i++) { 293 if (masterThreads.get(i).getMaster().isActiveMaster()) { 294 numActive++; 295 activeIndex = i; 296 active = masterThreads.get(activeIndex).getMaster(); 297 activeName = active.getServerName(); 298 } 299 } 300 assertNotNull(active); 301 assertEquals(1, numActive); 302 assertEquals(MASTERS, masterThreads.size()); 303 // Retrieve master and backup masters infos only. 304 EnumSet<Option> options = EnumSet.of(Option.MASTER, Option.BACKUP_MASTERS); 305 ClusterMetrics metrics = ADMIN.getClusterMetrics(options); 306 assertTrue(metrics.getMasterName().equals(activeName)); 307 assertEquals(MASTERS - 1, metrics.getBackupMasterNames().size()); 308 } 309 310 @Test 311 public void testUserMetrics() throws Exception { 312 Configuration conf = UTIL.getConfiguration(); 313 // If metrics for users is not enabled, this test doesn't make sense. 314 if ( 315 !conf.getBoolean(MetricsUserAggregateFactory.METRIC_USER_ENABLED_CONF, 316 MetricsUserAggregateFactory.DEFAULT_METRIC_USER_ENABLED_CONF) 317 ) { 318 return; 319 } 320 User userFoo = User.createUserForTesting(conf, "FOO_USER_METRIC_TEST", new String[0]); 321 User userBar = User.createUserForTesting(conf, "BAR_USER_METRIC_TEST", new String[0]); 322 User userTest = User.createUserForTesting(conf, "TEST_USER_METRIC_TEST", new String[0]); 323 UTIL.createTable(TABLE_NAME, CF); 324 waitForUsersMetrics(0); 325 long writeMetaMetricBeforeNextuser = getMetaMetrics().getWriteRequestCount(); 326 userFoo.runAs(new PrivilegedAction<Void>() { 327 @Override 328 public Void run() { 329 try { 330 doPut(); 331 } catch (IOException e) { 332 fail("Exception:" + e.getMessage()); 333 } 334 return null; 335 } 336 }); 337 waitForUsersMetrics(1); 338 long writeMetaMetricForUserFoo = 339 getMetaMetrics().getWriteRequestCount() - writeMetaMetricBeforeNextuser; 340 long readMetaMetricBeforeNextuser = getMetaMetrics().getReadRequestCount(); 341 userBar.runAs(new PrivilegedAction<Void>() { 342 @Override 343 public Void run() { 344 try { 345 doGet(); 346 } catch (IOException e) { 347 fail("Exception:" + e.getMessage()); 348 } 349 return null; 350 } 351 }); 352 waitForUsersMetrics(2); 353 long readMetaMetricForUserBar = 354 getMetaMetrics().getReadRequestCount() - readMetaMetricBeforeNextuser; 355 long filteredMetaReqeust = getMetaMetrics().getFilteredReadRequestCount(); 356 userTest.runAs(new PrivilegedAction<Void>() { 357 @Override 358 public Void run() { 359 try { 360 Table table = createConnection(UTIL.getConfiguration()).getTable(TABLE_NAME); 361 for (Result result : table.getScanner(new Scan().setFilter(new FilterAllFilter()))) { 362 fail("Should have filtered all rows"); 363 } 364 } catch (IOException e) { 365 fail("Exception:" + e.getMessage()); 366 } 367 return null; 368 } 369 }); 370 waitForUsersMetrics(3); 371 long filteredMetaReqeustForTestUser = 372 getMetaMetrics().getFilteredReadRequestCount() - filteredMetaReqeust; 373 Map<byte[], UserMetrics> userMap = ADMIN.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS)) 374 .getLiveServerMetrics().values().iterator().next().getUserMetrics(); 375 for (byte[] user : userMap.keySet()) { 376 switch (Bytes.toString(user)) { 377 case "FOO_USER_METRIC_TEST": 378 assertEquals(1, userMap.get(user).getWriteRequestCount() - writeMetaMetricForUserFoo); 379 break; 380 case "BAR_USER_METRIC_TEST": 381 assertEquals(1, userMap.get(user).getReadRequestCount() - readMetaMetricForUserBar); 382 assertEquals(0, userMap.get(user).getWriteRequestCount()); 383 break; 384 case "TEST_USER_METRIC_TEST": 385 assertEquals(1, 386 userMap.get(user).getFilteredReadRequests() - filteredMetaReqeustForTestUser); 387 assertEquals(0, userMap.get(user).getWriteRequestCount()); 388 break; 389 default: 390 // current user 391 assertEquals(UserProvider.instantiate(conf).getCurrent().getName(), Bytes.toString(user)); 392 // Read/write count because of Meta operations 393 assertTrue(userMap.get(user).getReadRequestCount() > 1); 394 break; 395 } 396 } 397 UTIL.deleteTable(TABLE_NAME); 398 } 399 400 @Test 401 public void testServerTasks() throws Exception { 402 // TaskMonitor is a singleton per VM, so will be shared among all minicluster "servers", 403 // so we only need to look at the first live server's results to find it. 404 final String testTaskName = "TEST TASK"; 405 TaskMonitor.get().createStatus(testTaskName).setStatus("Testing 1... 2... 3..."); 406 // Of course, first we must trigger regionserver reports. 407 final long now = EnvironmentEdgeManager.currentTime(); 408 final long last = now - 1000; // fake a period, or someone might div by zero 409 for (RegionServerThread rs : CLUSTER.getRegionServerThreads()) { 410 ((MyRegionServer) rs.getRegionServer()).tryRegionServerReport(last, now); 411 } 412 // Get status now 413 ClusterMetrics clusterMetrics = ADMIN.getClusterMetrics(EnumSet.of(Option.TASKS)); 414 // The test task will be in the master metrics list 415 boolean found = false; 416 for (ServerTask task : clusterMetrics.getMasterTasks()) { 417 if (testTaskName.equals(task.getDescription())) { 418 // Found it 419 found = true; 420 break; 421 } 422 } 423 assertTrue(found, "Expected task not found in master task list"); 424 // Get the tasks information (carried in server metrics) 425 found = false; 426 for (ServerMetrics serverMetrics : clusterMetrics.getLiveServerMetrics().values()) { 427 if (serverMetrics.getTasks() != null) { 428 for (ServerTask task : serverMetrics.getTasks()) { 429 if (testTaskName.equals(task.getDescription())) { 430 // Found it 431 found = true; 432 break; 433 } 434 } 435 } 436 } 437 // We will fall through here if getClusterMetrics(TASKS) did not correctly process the 438 // task list. 439 assertTrue(found, "Expected task not found in server load"); 440 } 441 442 private RegionMetrics getMetaMetrics() throws IOException { 443 for (ServerMetrics serverMetrics : ADMIN.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS)) 444 .getLiveServerMetrics().values()) { 445 RegionMetrics metaMetrics = serverMetrics.getRegionMetrics() 446 .get(RegionInfoBuilder.FIRST_META_REGIONINFO.getRegionName()); 447 if (metaMetrics != null) { 448 return metaMetrics; 449 } 450 } 451 fail("Should have find meta metrics"); 452 return null; 453 } 454 455 private void waitForUsersMetrics(int noOfUsers) throws Exception { 456 // Sleep for metrics to get updated on master 457 Thread.sleep(5000); 458 Waiter.waitFor(CLUSTER.getConfiguration(), 10 * 1000, 100, new Predicate<Exception>() { 459 @Override 460 public boolean evaluate() throws Exception { 461 Map<byte[], UserMetrics> metrics = ADMIN.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS)) 462 .getLiveServerMetrics().values().iterator().next().getUserMetrics(); 463 assertNotNull(metrics); 464 // including current user + noOfUsers 465 return metrics.keySet().size() > noOfUsers; 466 } 467 }); 468 } 469 470 private void doPut() throws IOException { 471 Table table = createConnection(UTIL.getConfiguration()).getTable(TABLE_NAME); 472 table.put(new Put(Bytes.toBytes("a")).addColumn(CF, Bytes.toBytes("col1"), Bytes.toBytes("1"))); 473 474 } 475 476 private void doGet() throws IOException { 477 Table table = createConnection(UTIL.getConfiguration()).getTable(TABLE_NAME); 478 table.get(new Get(Bytes.toBytes("a")).addColumn(CF, Bytes.toBytes("col1"))); 479 480 } 481 482 private Connection createConnection(Configuration conf) throws IOException { 483 User user = UserProvider.instantiate(conf).getCurrent(); 484 return ClusterConnectionFactory.createAsyncClusterConnection(conf, null, user).toConnection(); 485 } 486 487 @Test 488 public void testOtherStatusInfos() throws Exception { 489 EnumSet<Option> options = EnumSet.of(Option.MASTER_COPROCESSORS, Option.HBASE_VERSION, 490 Option.CLUSTER_ID, Option.BALANCER_ON); 491 ClusterMetrics metrics = ADMIN.getClusterMetrics(options); 492 assertEquals(1, metrics.getMasterCoprocessorNames().size()); 493 assertNotNull(metrics.getHBaseVersion()); 494 assertNotNull(metrics.getClusterId()); 495 assertTrue(metrics.getAverageLoad() == 0.0); 496 assertNotNull(metrics.getBalancerOn()); 497 } 498 499 @AfterAll 500 public static void tearDownAfterClass() throws Exception { 501 if (ADMIN != null) { 502 ADMIN.close(); 503 } 504 UTIL.shutdownMiniCluster(); 505 } 506 507 @Test 508 public void testObserver() throws IOException { 509 int preCount = MyObserver.PRE_COUNT.get(); 510 int postCount = MyObserver.POST_COUNT.get(); 511 assertTrue(ADMIN.getClusterMetrics().getMasterCoprocessorNames().stream() 512 .anyMatch(s -> s.equals(MyObserver.class.getSimpleName()))); 513 assertEquals(preCount + 1, MyObserver.PRE_COUNT.get()); 514 assertEquals(postCount + 1, MyObserver.POST_COUNT.get()); 515 } 516 517 private static void insertData(final TableName tableName, int startRow, int rowCount) 518 throws IOException { 519 Table t = UTIL.getConnection().getTable(tableName); 520 Put p; 521 for (int i = 0; i < rowCount; i++) { 522 p = new Put(Bytes.toBytes("" + (startRow + i))); 523 p.addColumn(CF, Bytes.toBytes("val1"), Bytes.toBytes(i)); 524 t.put(p); 525 } 526 } 527 528 public static class MyObserver implements MasterCoprocessor, MasterObserver { 529 private static final AtomicInteger PRE_COUNT = new AtomicInteger(0); 530 private static final AtomicInteger POST_COUNT = new AtomicInteger(0); 531 532 @Override 533 public Optional<MasterObserver> getMasterObserver() { 534 return Optional.of(this); 535 } 536 537 @Override 538 public void preGetClusterMetrics(ObserverContext<MasterCoprocessorEnvironment> ctx) 539 throws IOException { 540 PRE_COUNT.incrementAndGet(); 541 } 542 543 @Override 544 public void postGetClusterMetrics(ObserverContext<MasterCoprocessorEnvironment> ctx, 545 ClusterMetrics metrics) throws IOException { 546 POST_COUNT.incrementAndGet(); 547 } 548 } 549}