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.coprocessor; 019 020import static org.junit.Assert.assertFalse; 021import static org.junit.Assert.assertNotNull; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import java.util.Arrays; 026import java.util.Collection; 027import java.util.List; 028import java.util.Optional; 029import java.util.Set; 030import java.util.concurrent.CountDownLatch; 031import org.apache.hadoop.conf.Configuration; 032import org.apache.hadoop.hbase.CoprocessorEnvironment; 033import org.apache.hadoop.hbase.HBaseClassTestRule; 034import org.apache.hadoop.hbase.HBaseTestingUtility; 035import org.apache.hadoop.hbase.HColumnDescriptor; 036import org.apache.hadoop.hbase.HRegionLocation; 037import org.apache.hadoop.hbase.HTableDescriptor; 038import org.apache.hadoop.hbase.MiniHBaseCluster; 039import org.apache.hadoop.hbase.NamespaceDescriptor; 040import org.apache.hadoop.hbase.ServerName; 041import org.apache.hadoop.hbase.TableName; 042import org.apache.hadoop.hbase.client.Admin; 043import org.apache.hadoop.hbase.client.Connection; 044import org.apache.hadoop.hbase.client.ConnectionFactory; 045import org.apache.hadoop.hbase.client.MasterSwitchType; 046import org.apache.hadoop.hbase.client.Mutation; 047import org.apache.hadoop.hbase.client.RegionInfo; 048import org.apache.hadoop.hbase.client.RegionLocator; 049import org.apache.hadoop.hbase.client.SnapshotDescription; 050import org.apache.hadoop.hbase.client.Table; 051import org.apache.hadoop.hbase.client.TableDescriptor; 052import org.apache.hadoop.hbase.master.HMaster; 053import org.apache.hadoop.hbase.master.MasterCoprocessorHost; 054import org.apache.hadoop.hbase.master.RegionPlan; 055import org.apache.hadoop.hbase.net.Address; 056import org.apache.hadoop.hbase.procedure2.LockType; 057import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility; 058import org.apache.hadoop.hbase.quotas.GlobalQuotaSettings; 059import org.apache.hadoop.hbase.regionserver.HRegionServer; 060import org.apache.hadoop.hbase.testclassification.CoprocessorTests; 061import org.apache.hadoop.hbase.testclassification.MediumTests; 062import org.apache.hadoop.hbase.util.Bytes; 063import org.apache.hadoop.hbase.util.Threads; 064import org.junit.AfterClass; 065import org.junit.BeforeClass; 066import org.junit.ClassRule; 067import org.junit.Rule; 068import org.junit.Test; 069import org.junit.experimental.categories.Category; 070import org.junit.rules.TestName; 071import org.slf4j.Logger; 072import org.slf4j.LoggerFactory; 073 074import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 075import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter; 076import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsRequest; 077import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableNamesRequest; 078 079/** 080 * Tests invocation of the {@link org.apache.hadoop.hbase.coprocessor.MasterObserver} 081 * interface hooks at all appropriate times during normal HMaster operations. 082 */ 083@Category({CoprocessorTests.class, MediumTests.class}) 084public class TestMasterObserver { 085 086 @ClassRule 087 public static final HBaseClassTestRule CLASS_RULE = 088 HBaseClassTestRule.forClass(TestMasterObserver.class); 089 090 private static final Logger LOG = LoggerFactory.getLogger(TestMasterObserver.class); 091 092 public static CountDownLatch tableCreationLatch = new CountDownLatch(1); 093 public static CountDownLatch tableDeletionLatch = new CountDownLatch(1); 094 095 public static class CPMasterObserver implements MasterCoprocessor, MasterObserver { 096 097 private boolean preCreateTableCalled; 098 private boolean postCreateTableCalled; 099 private boolean preDeleteTableCalled; 100 private boolean postDeleteTableCalled; 101 private boolean preTruncateTableCalled; 102 private boolean postTruncateTableCalled; 103 private boolean preModifyTableCalled; 104 private boolean postModifyTableCalled; 105 private boolean preCreateNamespaceCalled; 106 private boolean postCreateNamespaceCalled; 107 private boolean preDeleteNamespaceCalled; 108 private boolean postDeleteNamespaceCalled; 109 private boolean preModifyNamespaceCalled; 110 private boolean postModifyNamespaceCalled; 111 private boolean preGetNamespaceDescriptorCalled; 112 private boolean postGetNamespaceDescriptorCalled; 113 private boolean preListNamespaceDescriptorsCalled; 114 private boolean postListNamespaceDescriptorsCalled; 115 private boolean preAddColumnCalled; 116 private boolean postAddColumnCalled; 117 private boolean preModifyColumnCalled; 118 private boolean postModifyColumnCalled; 119 private boolean preDeleteColumnCalled; 120 private boolean postDeleteColumnCalled; 121 private boolean preEnableTableCalled; 122 private boolean postEnableTableCalled; 123 private boolean preDisableTableCalled; 124 private boolean postDisableTableCalled; 125 private boolean preAbortProcedureCalled; 126 private boolean postAbortProcedureCalled; 127 private boolean preGetProceduresCalled; 128 private boolean postGetProceduresCalled; 129 private boolean preGetLocksCalled; 130 private boolean postGetLocksCalled; 131 private boolean preMoveCalled; 132 private boolean postMoveCalled; 133 private boolean preAssignCalled; 134 private boolean postAssignCalled; 135 private boolean preUnassignCalled; 136 private boolean postUnassignCalled; 137 private boolean preRegionOfflineCalled; 138 private boolean postRegionOfflineCalled; 139 private boolean preBalanceCalled; 140 private boolean postBalanceCalled; 141 private boolean preBalanceSwitchCalled; 142 private boolean postBalanceSwitchCalled; 143 private boolean preShutdownCalled; 144 private boolean preStopMasterCalled; 145 private boolean preMasterInitializationCalled; 146 private boolean postStartMasterCalled; 147 private boolean startCalled; 148 private boolean stopCalled; 149 private boolean preSnapshotCalled; 150 private boolean postSnapshotCalled; 151 private boolean preListSnapshotCalled; 152 private boolean postListSnapshotCalled; 153 private boolean preCloneSnapshotCalled; 154 private boolean postCloneSnapshotCalled; 155 private boolean preRestoreSnapshotCalled; 156 private boolean postRestoreSnapshotCalled; 157 private boolean preDeleteSnapshotCalled; 158 private boolean postDeleteSnapshotCalled; 159 private boolean preCreateTableActionCalled; 160 private boolean postCompletedCreateTableActionCalled; 161 private boolean preDeleteTableActionCalled; 162 private boolean postCompletedDeleteTableActionCalled; 163 private boolean preTruncateTableActionCalled; 164 private boolean postCompletedTruncateTableActionCalled; 165 private boolean preAddColumnFamilyActionCalled; 166 private boolean postCompletedAddColumnFamilyActionCalled; 167 private boolean preModifyColumnFamilyActionCalled; 168 private boolean postCompletedModifyColumnFamilyActionCalled; 169 private boolean preDeleteColumnFamilyActionCalled; 170 private boolean postCompletedDeleteColumnFamilyActionCalled; 171 private boolean preEnableTableActionCalled; 172 private boolean postCompletedEnableTableActionCalled; 173 private boolean preDisableTableActionCalled; 174 private boolean postCompletedDisableTableActionCalled; 175 private boolean preModifyTableActionCalled; 176 private boolean postCompletedModifyTableActionCalled; 177 private boolean preGetTableDescriptorsCalled; 178 private boolean postGetTableDescriptorsCalled; 179 private boolean postGetTableNamesCalled; 180 private boolean preGetTableNamesCalled; 181 private boolean preMergeRegionsCalled; 182 private boolean postMergeRegionsCalled; 183 private boolean preRequestLockCalled; 184 private boolean postRequestLockCalled; 185 private boolean preLockHeartbeatCalled; 186 private boolean postLockHeartbeatCalled; 187 188 public void resetStates() { 189 preCreateTableCalled = false; 190 postCreateTableCalled = false; 191 preDeleteTableCalled = false; 192 postDeleteTableCalled = false; 193 preTruncateTableCalled = false; 194 postTruncateTableCalled = false; 195 preModifyTableCalled = false; 196 postModifyTableCalled = false; 197 preCreateNamespaceCalled = false; 198 postCreateNamespaceCalled = false; 199 preDeleteNamespaceCalled = false; 200 postDeleteNamespaceCalled = false; 201 preModifyNamespaceCalled = false; 202 postModifyNamespaceCalled = false; 203 preGetNamespaceDescriptorCalled = false; 204 postGetNamespaceDescriptorCalled = false; 205 preListNamespaceDescriptorsCalled = false; 206 postListNamespaceDescriptorsCalled = false; 207 preAddColumnCalled = false; 208 postAddColumnCalled = false; 209 preModifyColumnCalled = false; 210 postModifyColumnCalled = false; 211 preDeleteColumnCalled = false; 212 postDeleteColumnCalled = false; 213 preEnableTableCalled = false; 214 postEnableTableCalled = false; 215 preDisableTableCalled = false; 216 postDisableTableCalled = false; 217 preAbortProcedureCalled = false; 218 postAbortProcedureCalled = false; 219 preGetProceduresCalled = false; 220 postGetProceduresCalled = false; 221 preGetLocksCalled = false; 222 postGetLocksCalled = false; 223 preMoveCalled= false; 224 postMoveCalled = false; 225 preAssignCalled = false; 226 postAssignCalled = false; 227 preUnassignCalled = false; 228 postUnassignCalled = false; 229 preRegionOfflineCalled = false; 230 postRegionOfflineCalled = false; 231 preBalanceCalled = false; 232 postBalanceCalled = false; 233 preBalanceSwitchCalled = false; 234 postBalanceSwitchCalled = false; 235 preShutdownCalled = false; 236 preStopMasterCalled = false; 237 preSnapshotCalled = false; 238 postSnapshotCalled = false; 239 preListSnapshotCalled = false; 240 postListSnapshotCalled = false; 241 preCloneSnapshotCalled = false; 242 postCloneSnapshotCalled = false; 243 preRestoreSnapshotCalled = false; 244 postRestoreSnapshotCalled = false; 245 preDeleteSnapshotCalled = false; 246 postDeleteSnapshotCalled = false; 247 preCreateTableActionCalled = false; 248 postCompletedCreateTableActionCalled = false; 249 preDeleteTableActionCalled = false; 250 postCompletedDeleteTableActionCalled = false; 251 preTruncateTableActionCalled = false; 252 postCompletedTruncateTableActionCalled = false; 253 preModifyTableActionCalled = false; 254 postCompletedModifyTableActionCalled = false; 255 preAddColumnFamilyActionCalled = false; 256 postCompletedAddColumnFamilyActionCalled = false; 257 preModifyColumnFamilyActionCalled = false; 258 postCompletedModifyColumnFamilyActionCalled = false; 259 preDeleteColumnFamilyActionCalled = false; 260 postCompletedDeleteColumnFamilyActionCalled = false; 261 preEnableTableActionCalled = false; 262 postCompletedEnableTableActionCalled = false; 263 preDisableTableActionCalled = false; 264 postCompletedDisableTableActionCalled = false; 265 preGetTableDescriptorsCalled = false; 266 postGetTableDescriptorsCalled = false; 267 postGetTableNamesCalled = false; 268 preGetTableNamesCalled = false; 269 preMergeRegionsCalled = false; 270 postMergeRegionsCalled = false; 271 preRequestLockCalled = false; 272 postRequestLockCalled = false; 273 preLockHeartbeatCalled = false; 274 postLockHeartbeatCalled = false; 275 } 276 277 @Override 278 public Optional<MasterObserver> getMasterObserver() { 279 return Optional.of(this); 280 } 281 282 @Override 283 public void preMergeRegions( 284 final ObserverContext<MasterCoprocessorEnvironment> ctx, 285 final RegionInfo[] regionsToMerge) throws IOException { 286 preMergeRegionsCalled = true; 287 } 288 289 @Override 290 public void postMergeRegions( 291 final ObserverContext<MasterCoprocessorEnvironment> ctx, 292 final RegionInfo[] regionsToMerge) throws IOException { 293 postMergeRegionsCalled = true; 294 } 295 296 public boolean wasMergeRegionsCalled() { 297 return preMergeRegionsCalled && postMergeRegionsCalled; 298 } 299 300 @Override 301 public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> env, 302 TableDescriptor desc, RegionInfo[] regions) throws IOException { 303 preCreateTableCalled = true; 304 } 305 306 @Override 307 public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> env, 308 TableDescriptor desc, RegionInfo[] regions) throws IOException { 309 postCreateTableCalled = true; 310 } 311 312 public boolean wasCreateTableCalled() { 313 return preCreateTableCalled && postCreateTableCalled; 314 } 315 316 public boolean preCreateTableCalledOnly() { 317 return preCreateTableCalled && !postCreateTableCalled; 318 } 319 320 @Override 321 public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> env, 322 TableName tableName) throws IOException { 323 preDeleteTableCalled = true; 324 } 325 326 @Override 327 public void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> env, 328 TableName tableName) throws IOException { 329 postDeleteTableCalled = true; 330 } 331 332 public boolean wasDeleteTableCalled() { 333 return preDeleteTableCalled && postDeleteTableCalled; 334 } 335 336 public boolean preDeleteTableCalledOnly() { 337 return preDeleteTableCalled && !postDeleteTableCalled; 338 } 339 340 @Override 341 public void preTruncateTable(ObserverContext<MasterCoprocessorEnvironment> env, 342 TableName tableName) throws IOException { 343 preTruncateTableCalled = true; 344 } 345 346 @Override 347 public void postTruncateTable(ObserverContext<MasterCoprocessorEnvironment> env, 348 TableName tableName) throws IOException { 349 postTruncateTableCalled = true; 350 } 351 352 public boolean wasTruncateTableCalled() { 353 return preTruncateTableCalled && postTruncateTableCalled; 354 } 355 356 public boolean preTruncateTableCalledOnly() { 357 return preTruncateTableCalled && !postTruncateTableCalled; 358 } 359 360 @Override 361 public void postSetSplitOrMergeEnabled(final ObserverContext<MasterCoprocessorEnvironment> ctx, 362 final boolean newValue, final MasterSwitchType switchType) throws IOException { 363 } 364 365 @Override 366 public void preModifyTable(ObserverContext<MasterCoprocessorEnvironment> env, 367 TableName tableName, TableDescriptor htd) throws IOException { 368 preModifyTableCalled = true; 369 } 370 371 @Override 372 public void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> env, 373 TableName tableName, TableDescriptor htd) throws IOException { 374 postModifyTableCalled = true; 375 } 376 377 public boolean wasModifyTableCalled() { 378 return preModifyTableCalled && postModifyTableCalled; 379 } 380 381 public boolean preModifyTableCalledOnly() { 382 return preModifyTableCalled && !postModifyTableCalled; 383 } 384 385 @Override 386 public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env, 387 NamespaceDescriptor ns) throws IOException { 388 preCreateNamespaceCalled = true; 389 } 390 391 @Override 392 public void postCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env, 393 NamespaceDescriptor ns) throws IOException { 394 postCreateNamespaceCalled = true; 395 } 396 397 public boolean wasCreateNamespaceCalled() { 398 return preCreateNamespaceCalled && postCreateNamespaceCalled; 399 } 400 401 public boolean preCreateNamespaceCalledOnly() { 402 return preCreateNamespaceCalled && !postCreateNamespaceCalled; 403 } 404 405 @Override 406 public void preDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env, 407 String name) throws IOException { 408 preDeleteNamespaceCalled = true; 409 } 410 411 @Override 412 public void postDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env, 413 String name) throws IOException { 414 postDeleteNamespaceCalled = true; 415 } 416 417 public boolean wasDeleteNamespaceCalled() { 418 return preDeleteNamespaceCalled && postDeleteNamespaceCalled; 419 } 420 421 public boolean preDeleteNamespaceCalledOnly() { 422 return preDeleteNamespaceCalled && !postDeleteNamespaceCalled; 423 } 424 425 @Override 426 public void preModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env, 427 NamespaceDescriptor ns) throws IOException { 428 preModifyNamespaceCalled = true; 429 } 430 431 @Override 432 public void postModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env, 433 NamespaceDescriptor ns) throws IOException { 434 postModifyNamespaceCalled = true; 435 } 436 437 public boolean wasModifyNamespaceCalled() { 438 return preModifyNamespaceCalled && postModifyNamespaceCalled; 439 } 440 441 public boolean preModifyNamespaceCalledOnly() { 442 return preModifyNamespaceCalled && !postModifyNamespaceCalled; 443 } 444 445 446 @Override 447 public void preGetNamespaceDescriptor(ObserverContext<MasterCoprocessorEnvironment> ctx, 448 String namespace) throws IOException { 449 preGetNamespaceDescriptorCalled = true; 450 } 451 452 @Override 453 public void postGetNamespaceDescriptor(ObserverContext<MasterCoprocessorEnvironment> ctx, 454 NamespaceDescriptor ns) throws IOException { 455 postGetNamespaceDescriptorCalled = true; 456 } 457 458 public boolean wasGetNamespaceDescriptorCalled() { 459 return preGetNamespaceDescriptorCalled && postGetNamespaceDescriptorCalled; 460 } 461 462 @Override 463 public void preListNamespaceDescriptors(ObserverContext<MasterCoprocessorEnvironment> env, 464 List<NamespaceDescriptor> descriptors) throws IOException { 465 preListNamespaceDescriptorsCalled = true; 466 } 467 468 @Override 469 public void postListNamespaceDescriptors(ObserverContext<MasterCoprocessorEnvironment> env, 470 List<NamespaceDescriptor> descriptors) throws IOException { 471 postListNamespaceDescriptorsCalled = true; 472 } 473 474 public boolean wasListNamespaceDescriptorsCalled() { 475 return preListNamespaceDescriptorsCalled && postListNamespaceDescriptorsCalled; 476 } 477 478 public boolean preListNamespaceDescriptorsCalledOnly() { 479 return preListNamespaceDescriptorsCalled && !postListNamespaceDescriptorsCalled; 480 } 481 482 @Override 483 public void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> env, 484 TableName tableName) throws IOException { 485 preEnableTableCalled = true; 486 } 487 488 @Override 489 public void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> env, 490 TableName tableName) throws IOException { 491 postEnableTableCalled = true; 492 } 493 494 public boolean wasEnableTableCalled() { 495 return preEnableTableCalled && postEnableTableCalled; 496 } 497 498 public boolean preEnableTableCalledOnly() { 499 return preEnableTableCalled && !postEnableTableCalled; 500 } 501 502 @Override 503 public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> env, 504 TableName tableName) throws IOException { 505 preDisableTableCalled = true; 506 } 507 508 @Override 509 public void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> env, 510 TableName tableName) throws IOException { 511 postDisableTableCalled = true; 512 } 513 514 public boolean wasDisableTableCalled() { 515 return preDisableTableCalled && postDisableTableCalled; 516 } 517 518 public boolean preDisableTableCalledOnly() { 519 return preDisableTableCalled && !postDisableTableCalled; 520 } 521 522 @Override 523 public void preAbortProcedure( 524 ObserverContext<MasterCoprocessorEnvironment> ctx, final long procId) throws IOException { 525 preAbortProcedureCalled = true; 526 } 527 528 @Override 529 public void postAbortProcedure( 530 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { 531 postAbortProcedureCalled = true; 532 } 533 534 public boolean wasAbortProcedureCalled() { 535 return preAbortProcedureCalled && postAbortProcedureCalled; 536 } 537 538 public boolean wasPreAbortProcedureCalledOnly() { 539 return preAbortProcedureCalled && !postAbortProcedureCalled; 540 } 541 542 @Override 543 public void preGetProcedures( 544 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { 545 preGetProceduresCalled = true; 546 } 547 548 @Override 549 public void postGetProcedures( 550 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { 551 postGetProceduresCalled = true; 552 } 553 554 public boolean wasGetProceduresCalled() { 555 return preGetProceduresCalled && postGetProceduresCalled; 556 } 557 558 public boolean wasPreGetProceduresCalledOnly() { 559 return preGetProceduresCalled && !postGetProceduresCalled; 560 } 561 562 @Override 563 public void preGetLocks(ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { 564 preGetLocksCalled = true; 565 } 566 567 @Override 568 public void postGetLocks(ObserverContext<MasterCoprocessorEnvironment> ctx) 569 throws IOException { 570 postGetLocksCalled = true; 571 } 572 573 public boolean wasGetLocksCalled() { 574 return preGetLocksCalled && postGetLocksCalled; 575 } 576 577 public boolean wasPreGetLocksCalledOnly() { 578 return preGetLocksCalled && !postGetLocksCalled; 579 } 580 581 @Override 582 public void preMove(ObserverContext<MasterCoprocessorEnvironment> env, 583 RegionInfo region, ServerName srcServer, ServerName destServer) 584 throws IOException { 585 preMoveCalled = true; 586 } 587 588 @Override 589 public void postMove(ObserverContext<MasterCoprocessorEnvironment> env, RegionInfo region, 590 ServerName srcServer, ServerName destServer) 591 throws IOException { 592 postMoveCalled = true; 593 } 594 595 public boolean wasMoveCalled() { 596 return preMoveCalled && postMoveCalled; 597 } 598 599 public boolean preMoveCalledOnly() { 600 return preMoveCalled && !postMoveCalled; 601 } 602 603 @Override 604 public void preAssign(ObserverContext<MasterCoprocessorEnvironment> env, 605 final RegionInfo regionInfo) throws IOException { 606 preAssignCalled = true; 607 } 608 609 @Override 610 public void postAssign(ObserverContext<MasterCoprocessorEnvironment> env, 611 final RegionInfo regionInfo) throws IOException { 612 postAssignCalled = true; 613 } 614 615 public boolean wasAssignCalled() { 616 return preAssignCalled && postAssignCalled; 617 } 618 619 public boolean preAssignCalledOnly() { 620 return preAssignCalled && !postAssignCalled; 621 } 622 623 @Override 624 public void preUnassign(ObserverContext<MasterCoprocessorEnvironment> env, 625 final RegionInfo regionInfo, final boolean force) throws IOException { 626 preUnassignCalled = true; 627 } 628 629 @Override 630 public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> env, 631 final RegionInfo regionInfo, final boolean force) throws IOException { 632 postUnassignCalled = true; 633 } 634 635 public boolean wasUnassignCalled() { 636 return preUnassignCalled && postUnassignCalled; 637 } 638 639 public boolean preUnassignCalledOnly() { 640 return preUnassignCalled && !postUnassignCalled; 641 } 642 643 @Override 644 public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env, 645 final RegionInfo regionInfo) throws IOException { 646 preRegionOfflineCalled = true; 647 } 648 649 @Override 650 public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env, 651 final RegionInfo regionInfo) throws IOException { 652 postRegionOfflineCalled = true; 653 } 654 655 public boolean wasRegionOfflineCalled() { 656 return preRegionOfflineCalled && postRegionOfflineCalled; 657 } 658 659 public boolean preRegionOfflineCalledOnly() { 660 return preRegionOfflineCalled && !postRegionOfflineCalled; 661 } 662 663 @Override 664 public void preBalance(ObserverContext<MasterCoprocessorEnvironment> env) 665 throws IOException { 666 preBalanceCalled = true; 667 } 668 669 @Override 670 public void postBalance(ObserverContext<MasterCoprocessorEnvironment> env, 671 List<RegionPlan> plans) throws IOException { 672 postBalanceCalled = true; 673 } 674 675 public boolean wasBalanceCalled() { 676 return preBalanceCalled && postBalanceCalled; 677 } 678 679 public boolean preBalanceCalledOnly() { 680 return preBalanceCalled && !postBalanceCalled; 681 } 682 683 @Override 684 public void preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env, boolean b) 685 throws IOException { 686 preBalanceSwitchCalled = true; 687 } 688 689 @Override 690 public void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env, 691 boolean oldValue, boolean newValue) throws IOException { 692 postBalanceSwitchCalled = true; 693 } 694 695 public boolean wasBalanceSwitchCalled() { 696 return preBalanceSwitchCalled && postBalanceSwitchCalled; 697 } 698 699 public boolean preBalanceSwitchCalledOnly() { 700 return preBalanceSwitchCalled && !postBalanceSwitchCalled; 701 } 702 703 @Override 704 public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> env) 705 throws IOException { 706 preShutdownCalled = true; 707 } 708 709 public boolean wasShutdownCalled() { 710 return preShutdownCalled; 711 } 712 713 @Override 714 public void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> env) 715 throws IOException { 716 preStopMasterCalled = true; 717 } 718 719 public boolean wasStopMasterCalled() { 720 return preStopMasterCalled; 721 } 722 723 @Override 724 public void preMasterInitialization( 725 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { 726 preMasterInitializationCalled = true; 727 } 728 729 public boolean wasMasterInitializationCalled(){ 730 return preMasterInitializationCalled; 731 } 732 733 @Override 734 public void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx) 735 throws IOException { 736 postStartMasterCalled = true; 737 } 738 739 public boolean wasStartMasterCalled() { 740 return postStartMasterCalled; 741 } 742 743 @Override 744 public void start(CoprocessorEnvironment env) throws IOException { 745 startCalled = true; 746 } 747 748 @Override 749 public void stop(CoprocessorEnvironment env) throws IOException { 750 stopCalled = true; 751 } 752 753 public boolean wasStarted() { return startCalled; } 754 755 public boolean wasStopped() { return stopCalled; } 756 757 @Override 758 public void preSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 759 final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor) 760 throws IOException { 761 preSnapshotCalled = true; 762 } 763 764 @Override 765 public void postSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 766 final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor) 767 throws IOException { 768 postSnapshotCalled = true; 769 } 770 771 public boolean wasSnapshotCalled() { 772 return preSnapshotCalled && postSnapshotCalled; 773 } 774 775 @Override 776 public void preListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 777 final SnapshotDescription snapshot) throws IOException { 778 preListSnapshotCalled = true; 779 } 780 781 @Override 782 public void postListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 783 final SnapshotDescription snapshot) throws IOException { 784 postListSnapshotCalled = true; 785 } 786 787 public boolean wasListSnapshotCalled() { 788 return preListSnapshotCalled && postListSnapshotCalled; 789 } 790 791 @Override 792 public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 793 final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor) 794 throws IOException { 795 preCloneSnapshotCalled = true; 796 } 797 798 @Override 799 public void postCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 800 final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor) 801 throws IOException { 802 postCloneSnapshotCalled = true; 803 } 804 805 public boolean wasCloneSnapshotCalled() { 806 return preCloneSnapshotCalled && postCloneSnapshotCalled; 807 } 808 809 @Override 810 public void preRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 811 final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor) 812 throws IOException { 813 preRestoreSnapshotCalled = true; 814 } 815 816 @Override 817 public void postRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 818 final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor) 819 throws IOException { 820 postRestoreSnapshotCalled = true; 821 } 822 823 public boolean wasRestoreSnapshotCalled() { 824 return preRestoreSnapshotCalled && postRestoreSnapshotCalled; 825 } 826 827 @Override 828 public void preDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 829 final SnapshotDescription snapshot) throws IOException { 830 preDeleteSnapshotCalled = true; 831 } 832 833 @Override 834 public void postDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx, 835 final SnapshotDescription snapshot) throws IOException { 836 postDeleteSnapshotCalled = true; 837 } 838 839 public boolean wasDeleteSnapshotCalled() { 840 return preDeleteSnapshotCalled && postDeleteSnapshotCalled; 841 } 842 843 @Override 844 public void preCreateTableAction( 845 final ObserverContext<MasterCoprocessorEnvironment> env, 846 final TableDescriptor desc, 847 final RegionInfo[] regions) throws IOException { 848 preCreateTableActionCalled = true; 849 } 850 851 @Override 852 public void postCompletedCreateTableAction( 853 final ObserverContext<MasterCoprocessorEnvironment> ctx, 854 final TableDescriptor desc, 855 final RegionInfo[] regions) throws IOException { 856 postCompletedCreateTableActionCalled = true; 857 tableCreationLatch.countDown(); 858 } 859 860 public boolean wasPreCreateTableActionCalled(){ 861 return preCreateTableActionCalled; 862 } 863 public boolean wasCreateTableActionCalled() { 864 return preCreateTableActionCalled && postCompletedCreateTableActionCalled; 865 } 866 867 public boolean wasCreateTableActionCalledOnly() { 868 return preCreateTableActionCalled && !postCompletedCreateTableActionCalled; 869 } 870 871 @Override 872 public void preDeleteTableAction( 873 final ObserverContext<MasterCoprocessorEnvironment> env, final TableName tableName) 874 throws IOException { 875 preDeleteTableActionCalled = true; 876 } 877 878 @Override 879 public void postCompletedDeleteTableAction( 880 final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) 881 throws IOException { 882 postCompletedDeleteTableActionCalled = true; 883 tableDeletionLatch.countDown(); 884 } 885 886 public boolean wasDeleteTableActionCalled() { 887 return preDeleteTableActionCalled && postCompletedDeleteTableActionCalled; 888 } 889 890 public boolean wasDeleteTableActionCalledOnly() { 891 return preDeleteTableActionCalled && !postCompletedDeleteTableActionCalled; 892 } 893 894 @Override 895 public void preTruncateTableAction( 896 final ObserverContext<MasterCoprocessorEnvironment> env, final TableName tableName) 897 throws IOException { 898 preTruncateTableActionCalled = true; 899 } 900 901 @Override 902 public void postCompletedTruncateTableAction( 903 final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) 904 throws IOException { 905 postCompletedTruncateTableActionCalled = true; 906 } 907 908 public boolean wasTruncateTableActionCalled() { 909 return preTruncateTableActionCalled && postCompletedTruncateTableActionCalled; 910 } 911 912 public boolean wasTruncateTableActionCalledOnly() { 913 return preTruncateTableActionCalled && !postCompletedTruncateTableActionCalled; 914 } 915 916 @Override 917 public void preModifyTableAction( 918 final ObserverContext<MasterCoprocessorEnvironment> env, 919 final TableName tableName, 920 final TableDescriptor htd) throws IOException { 921 preModifyTableActionCalled = true; 922 } 923 924 @Override 925 public void postCompletedModifyTableAction( 926 final ObserverContext<MasterCoprocessorEnvironment> env, 927 final TableName tableName, 928 final TableDescriptor htd) throws IOException { 929 postCompletedModifyTableActionCalled = true; 930 } 931 932 public boolean wasModifyTableActionCalled() { 933 return preModifyTableActionCalled && postCompletedModifyTableActionCalled; 934 } 935 936 public boolean wasModifyTableActionCalledOnly() { 937 return preModifyTableActionCalled && !postCompletedModifyTableActionCalled; 938 } 939 940 @Override 941 public void preEnableTableAction( 942 final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) 943 throws IOException { 944 preEnableTableActionCalled = true; 945 } 946 947 @Override 948 public void postCompletedEnableTableAction( 949 final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) 950 throws IOException { 951 postCompletedEnableTableActionCalled = true; 952 } 953 954 public boolean wasEnableTableActionCalled() { 955 return preEnableTableActionCalled && postCompletedEnableTableActionCalled; 956 } 957 958 public boolean preEnableTableActionCalledOnly() { 959 return preEnableTableActionCalled && !postCompletedEnableTableActionCalled; 960 } 961 962 @Override 963 public void preDisableTableAction( 964 final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) 965 throws IOException { 966 preDisableTableActionCalled = true; 967 } 968 969 @Override 970 public void postCompletedDisableTableAction( 971 final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) 972 throws IOException { 973 postCompletedDisableTableActionCalled = true; 974 } 975 976 public boolean wasDisableTableActionCalled() { 977 return preDisableTableActionCalled && postCompletedDisableTableActionCalled; 978 } 979 980 public boolean preDisableTableActionCalledOnly() { 981 return preDisableTableActionCalled && !postCompletedDisableTableActionCalled; 982 } 983 984 @Override 985 public void preGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx, 986 List<TableName> tableNamesList, List<TableDescriptor> descriptors, String regex) 987 throws IOException { 988 preGetTableDescriptorsCalled = true; 989 } 990 991 @Override 992 public void postGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx, 993 List<TableName> tableNamesList, List<TableDescriptor> descriptors, 994 String regex) throws IOException { 995 postGetTableDescriptorsCalled = true; 996 } 997 998 public boolean wasGetTableDescriptorsCalled() { 999 return preGetTableDescriptorsCalled && postGetTableDescriptorsCalled; 1000 } 1001 1002 @Override 1003 public void preGetTableNames(ObserverContext<MasterCoprocessorEnvironment> ctx, 1004 List<TableDescriptor> descriptors, String regex) throws IOException { 1005 preGetTableNamesCalled = true; 1006 } 1007 1008 @Override 1009 public void postGetTableNames(ObserverContext<MasterCoprocessorEnvironment> ctx, 1010 List<TableDescriptor> descriptors, String regex) throws IOException { 1011 postGetTableNamesCalled = true; 1012 } 1013 1014 public boolean wasGetTableNamesCalled() { 1015 return preGetTableNamesCalled && postGetTableNamesCalled; 1016 } 1017 1018 @Override 1019 public void preTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx, 1020 TableName tableName) throws IOException { 1021 } 1022 1023 @Override 1024 public void postTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx, 1025 TableName tableName) throws IOException { 1026 } 1027 1028 @Override 1029 public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1030 final String userName, final GlobalQuotaSettings quotas) throws IOException { 1031 } 1032 1033 @Override 1034 public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1035 final String userName, final GlobalQuotaSettings quotas) throws IOException { 1036 } 1037 1038 @Override 1039 public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1040 final String userName, final TableName tableName, final GlobalQuotaSettings quotas) 1041 throws IOException { 1042 } 1043 1044 @Override 1045 public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1046 final String userName, final TableName tableName, final GlobalQuotaSettings quotas) 1047 throws IOException { 1048 } 1049 1050 @Override 1051 public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1052 final String userName, final String namespace, final GlobalQuotaSettings quotas) 1053 throws IOException { 1054 } 1055 1056 @Override 1057 public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1058 final String userName, final String namespace, final GlobalQuotaSettings quotas) 1059 throws IOException { 1060 } 1061 1062 @Override 1063 public void preSetTableQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1064 final TableName tableName, final GlobalQuotaSettings quotas) throws IOException { 1065 } 1066 1067 @Override 1068 public void postSetTableQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1069 final TableName tableName, final GlobalQuotaSettings quotas) throws IOException { 1070 } 1071 1072 @Override 1073 public void preSetNamespaceQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1074 final String namespace, final GlobalQuotaSettings quotas) throws IOException { 1075 } 1076 1077 @Override 1078 public void postSetNamespaceQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx, 1079 final String namespace, final GlobalQuotaSettings quotas) throws IOException { 1080 } 1081 1082 @Override 1083 public void preMoveServersAndTables(ObserverContext<MasterCoprocessorEnvironment> ctx, 1084 Set<Address> servers, Set<TableName> tables, String targetGroup) throws IOException { 1085 } 1086 1087 @Override 1088 public void postMoveServersAndTables(ObserverContext<MasterCoprocessorEnvironment> ctx, 1089 Set<Address> servers, Set<TableName> tables,String targetGroup) throws IOException { 1090 } 1091 1092 @Override 1093 public void preMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx, 1094 Set<Address> servers, String targetGroup) throws IOException { 1095 } 1096 1097 @Override 1098 public void postMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx, 1099 Set<Address> servers, String targetGroup) throws IOException { 1100 } 1101 1102 @Override 1103 public void preMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx, 1104 Set<TableName> tables, String targetGroupGroup) throws IOException { 1105 } 1106 1107 @Override 1108 public void postMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx, 1109 Set<TableName> tables, String targetGroup) throws IOException { 1110 } 1111 1112 @Override 1113 public void preAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, 1114 String name) throws IOException { 1115 } 1116 1117 @Override 1118 public void postAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, 1119 String name) throws IOException { 1120 } 1121 1122 @Override 1123 public void preRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, 1124 String name) throws IOException { 1125 } 1126 1127 @Override 1128 public void postRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, 1129 String name) throws IOException { 1130 } 1131 1132 @Override 1133 public void preBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, 1134 String groupName) throws IOException { 1135 } 1136 1137 @Override 1138 public void postBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, 1139 String groupName, boolean balancerRan) throws IOException { 1140 } 1141 1142 @Override 1143 public void preRequestLock(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace, 1144 TableName tableName, RegionInfo[] regionInfos, String description) throws IOException { 1145 preRequestLockCalled = true; 1146 } 1147 1148 @Override 1149 public void postRequestLock(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace, 1150 TableName tableName, RegionInfo[] regionInfos, String description) throws IOException { 1151 postRequestLockCalled = true; 1152 } 1153 1154 @Override 1155 public void preLockHeartbeat(ObserverContext<MasterCoprocessorEnvironment> ctx, 1156 TableName tn, String description) throws IOException { 1157 preLockHeartbeatCalled = true; 1158 } 1159 1160 @Override 1161 public void postLockHeartbeat(ObserverContext<MasterCoprocessorEnvironment> ctx) 1162 throws IOException { 1163 postLockHeartbeatCalled = true; 1164 } 1165 1166 public boolean preAndPostForQueueLockAndHeartbeatLockCalled() { 1167 return preRequestLockCalled && postRequestLockCalled && preLockHeartbeatCalled && 1168 postLockHeartbeatCalled; 1169 } 1170 1171 @Override 1172 public void preSplitRegion( 1173 final ObserverContext<MasterCoprocessorEnvironment> c, 1174 final TableName tableName, 1175 final byte[] splitRow) throws IOException { 1176 } 1177 1178 @Override 1179 public void preSplitRegionAction( 1180 final ObserverContext<MasterCoprocessorEnvironment> c, 1181 final TableName tableName, 1182 final byte[] splitRow) throws IOException { 1183 } 1184 1185 @Override 1186 public void postCompletedSplitRegionAction( 1187 final ObserverContext<MasterCoprocessorEnvironment> c, 1188 final RegionInfo regionInfoA, 1189 final RegionInfo regionInfoB) throws IOException { 1190 } 1191 1192 @Override 1193 public void preSplitRegionBeforeMETAAction( 1194 final ObserverContext<MasterCoprocessorEnvironment> ctx, 1195 final byte[] splitKey, 1196 final List<Mutation> metaEntries) throws IOException { 1197 } 1198 1199 @Override 1200 public void preSplitRegionAfterMETAAction( 1201 final ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { 1202 } 1203 1204 @Override 1205 public void postRollBackSplitRegionAction( 1206 final ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { 1207 } 1208 1209 @Override 1210 public void preMergeRegionsAction( 1211 final ObserverContext<MasterCoprocessorEnvironment> ctx, 1212 final RegionInfo[] regionsToMerge) throws IOException { 1213 } 1214 1215 @Override 1216 public void postCompletedMergeRegionsAction( 1217 final ObserverContext<MasterCoprocessorEnvironment> c, 1218 final RegionInfo[] regionsToMerge, 1219 final RegionInfo mergedRegion) throws IOException { 1220 } 1221 1222 @Override 1223 public void preMergeRegionsCommitAction( 1224 final ObserverContext<MasterCoprocessorEnvironment> ctx, 1225 final RegionInfo[] regionsToMerge, 1226 final List<Mutation> metaEntries) throws IOException { 1227 } 1228 1229 @Override 1230 public void postMergeRegionsCommitAction( 1231 final ObserverContext<MasterCoprocessorEnvironment> ctx, 1232 final RegionInfo[] regionsToMerge, 1233 final RegionInfo mergedRegion) throws IOException { 1234 } 1235 1236 @Override 1237 public void postRollBackMergeRegionsAction( 1238 final ObserverContext<MasterCoprocessorEnvironment> ctx, 1239 final RegionInfo[] regionsToMerge) throws IOException { 1240 } 1241 } 1242 1243 private static HBaseTestingUtility UTIL = new HBaseTestingUtility(); 1244 private static byte[] TEST_SNAPSHOT = Bytes.toBytes("observed_snapshot"); 1245 private static TableName TEST_CLONE = TableName.valueOf("observed_clone"); 1246 private static byte[] TEST_FAMILY = Bytes.toBytes("fam1"); 1247 private static byte[] TEST_FAMILY2 = Bytes.toBytes("fam2"); 1248 @Rule public TestName name = new TestName(); 1249 1250 @BeforeClass 1251 public static void setupBeforeClass() throws Exception { 1252 Configuration conf = UTIL.getConfiguration(); 1253 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, 1254 CPMasterObserver.class.getName()); 1255 // We need more than one data server on this test 1256 UTIL.startMiniCluster(2); 1257 } 1258 1259 @AfterClass 1260 public static void tearDownAfterClass() throws Exception { 1261 UTIL.shutdownMiniCluster(); 1262 } 1263 1264 @Test 1265 public void testStarted() throws Exception { 1266 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1267 1268 HMaster master = cluster.getMaster(); 1269 assertTrue("Master should be active", master.isActiveMaster()); 1270 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1271 assertNotNull("CoprocessorHost should not be null", host); 1272 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1273 assertNotNull("CPMasterObserver coprocessor not found or not installed!", cp); 1274 1275 // check basic lifecycle 1276 assertTrue("MasterObserver should have been started", cp.wasStarted()); 1277 assertTrue("preMasterInitialization() hook should have been called", 1278 cp.wasMasterInitializationCalled()); 1279 assertTrue("postStartMaster() hook should have been called", 1280 cp.wasStartMasterCalled()); 1281 } 1282 1283 @Test 1284 public void testTableOperations() throws Exception { 1285 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1286 final TableName tableName = TableName.valueOf(name.getMethodName()); 1287 HMaster master = cluster.getMaster(); 1288 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1289 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1290 cp.resetStates(); 1291 assertFalse("No table created yet", cp.wasCreateTableCalled()); 1292 1293 // create a table 1294 HTableDescriptor htd = new HTableDescriptor(tableName); 1295 htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); 1296 try(Connection connection = ConnectionFactory.createConnection(UTIL.getConfiguration()); 1297 Admin admin = connection.getAdmin()) { 1298 tableCreationLatch = new CountDownLatch(1); 1299 admin.createTable(htd, Arrays.copyOfRange(HBaseTestingUtility.KEYS, 1300 1, HBaseTestingUtility.KEYS.length)); 1301 1302 assertTrue("Test table should be created", cp.wasCreateTableCalled()); 1303 tableCreationLatch.await(); 1304 assertTrue("Table pre create handler called.", cp 1305 .wasPreCreateTableActionCalled()); 1306 assertTrue("Table create handler should be called.", 1307 cp.wasCreateTableActionCalled()); 1308 1309 RegionLocator regionLocator = connection.getRegionLocator(htd.getTableName()); 1310 List<HRegionLocation> regions = regionLocator.getAllRegionLocations(); 1311 1312 admin.mergeRegionsAsync(regions.get(0).getRegionInfo().getEncodedNameAsBytes(), 1313 regions.get(1).getRegionInfo().getEncodedNameAsBytes(), true); 1314 assertTrue("Coprocessor should have been called on region merge", 1315 cp.wasMergeRegionsCalled()); 1316 1317 tableCreationLatch = new CountDownLatch(1); 1318 admin.disableTable(tableName); 1319 assertTrue(admin.isTableDisabled(tableName)); 1320 assertTrue("Coprocessor should have been called on table disable", 1321 cp.wasDisableTableCalled()); 1322 assertTrue("Disable table handler should be called.", 1323 cp.wasDisableTableActionCalled()); 1324 1325 // enable 1326 assertFalse(cp.wasEnableTableCalled()); 1327 admin.enableTable(tableName); 1328 assertTrue(admin.isTableEnabled(tableName)); 1329 assertTrue("Coprocessor should have been called on table enable", 1330 cp.wasEnableTableCalled()); 1331 assertTrue("Enable table handler should be called.", 1332 cp.wasEnableTableActionCalled()); 1333 1334 admin.disableTable(tableName); 1335 assertTrue(admin.isTableDisabled(tableName)); 1336 1337 // modify table 1338 htd.setMaxFileSize(512 * 1024 * 1024); 1339 modifyTableSync(admin, tableName, htd); 1340 assertTrue("Test table should have been modified", 1341 cp.wasModifyTableCalled()); 1342 1343 // truncate table 1344 admin.truncateTable(tableName, false); 1345 1346 // delete table 1347 admin.disableTable(tableName); 1348 assertTrue(admin.isTableDisabled(tableName)); 1349 deleteTable(admin, tableName); 1350 assertFalse("Test table should have been deleted", 1351 admin.tableExists(tableName)); 1352 assertTrue("Coprocessor should have been called on table delete", 1353 cp.wasDeleteTableCalled()); 1354 assertTrue("Delete table handler should be called.", 1355 cp.wasDeleteTableActionCalled()); 1356 1357 // When bypass was supported, we'd turn off bypass and rerun tests. Leaving rerun in place. 1358 cp.resetStates(); 1359 1360 admin.createTable(htd); 1361 assertTrue("Test table should be created", cp.wasCreateTableCalled()); 1362 tableCreationLatch.await(); 1363 assertTrue("Table pre create handler called.", cp 1364 .wasPreCreateTableActionCalled()); 1365 assertTrue("Table create handler should be called.", 1366 cp.wasCreateTableActionCalled()); 1367 1368 // disable 1369 assertFalse(cp.wasDisableTableCalled()); 1370 assertFalse(cp.wasDisableTableActionCalled()); 1371 admin.disableTable(tableName); 1372 assertTrue(admin.isTableDisabled(tableName)); 1373 assertTrue("Coprocessor should have been called on table disable", 1374 cp.wasDisableTableCalled()); 1375 assertTrue("Disable table handler should be called.", 1376 cp.wasDisableTableActionCalled()); 1377 1378 // modify table 1379 htd.setMaxFileSize(512 * 1024 * 1024); 1380 modifyTableSync(admin, tableName, htd); 1381 assertTrue("Test table should have been modified", 1382 cp.wasModifyTableCalled()); 1383 1384 // enable 1385 assertFalse(cp.wasEnableTableCalled()); 1386 assertFalse(cp.wasEnableTableActionCalled()); 1387 admin.enableTable(tableName); 1388 assertTrue(admin.isTableEnabled(tableName)); 1389 assertTrue("Coprocessor should have been called on table enable", 1390 cp.wasEnableTableCalled()); 1391 assertTrue("Enable table handler should be called.", 1392 cp.wasEnableTableActionCalled()); 1393 1394 // disable again 1395 admin.disableTable(tableName); 1396 assertTrue(admin.isTableDisabled(tableName)); 1397 1398 // delete table 1399 assertFalse("No table deleted yet", cp.wasDeleteTableCalled()); 1400 assertFalse("Delete table handler should not be called.", 1401 cp.wasDeleteTableActionCalled()); 1402 deleteTable(admin, tableName); 1403 assertFalse("Test table should have been deleted", 1404 admin.tableExists(tableName)); 1405 assertTrue("Coprocessor should have been called on table delete", 1406 cp.wasDeleteTableCalled()); 1407 assertTrue("Delete table handler should be called.", 1408 cp.wasDeleteTableActionCalled()); 1409 } 1410 } 1411 1412 @Test 1413 public void testSnapshotOperations() throws Exception { 1414 final TableName tableName = TableName.valueOf(name.getMethodName()); 1415 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1416 HMaster master = cluster.getMaster(); 1417 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1418 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1419 cp.resetStates(); 1420 1421 // create a table 1422 HTableDescriptor htd = new HTableDescriptor(tableName); 1423 htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); 1424 Admin admin = UTIL.getAdmin(); 1425 1426 tableCreationLatch = new CountDownLatch(1); 1427 admin.createTable(htd); 1428 tableCreationLatch.await(); 1429 tableCreationLatch = new CountDownLatch(1); 1430 1431 admin.disableTable(tableName); 1432 assertTrue(admin.isTableDisabled(tableName)); 1433 1434 try { 1435 // Test snapshot operation 1436 assertFalse("Coprocessor should not have been called yet", 1437 cp.wasSnapshotCalled()); 1438 admin.snapshot(TEST_SNAPSHOT, tableName); 1439 assertTrue("Coprocessor should have been called on snapshot", 1440 cp.wasSnapshotCalled()); 1441 1442 //Test list operation 1443 admin.listSnapshots(); 1444 assertTrue("Coprocessor should have been called on snapshot list", 1445 cp.wasListSnapshotCalled()); 1446 1447 // Test clone operation 1448 admin.cloneSnapshot(TEST_SNAPSHOT, TEST_CLONE); 1449 assertTrue("Coprocessor should have been called on snapshot clone", 1450 cp.wasCloneSnapshotCalled()); 1451 assertFalse("Coprocessor restore should not have been called on snapshot clone", 1452 cp.wasRestoreSnapshotCalled()); 1453 admin.disableTable(TEST_CLONE); 1454 assertTrue(admin.isTableDisabled(tableName)); 1455 deleteTable(admin, TEST_CLONE); 1456 1457 // Test restore operation 1458 cp.resetStates(); 1459 admin.restoreSnapshot(TEST_SNAPSHOT); 1460 assertTrue("Coprocessor should have been called on snapshot restore", 1461 cp.wasRestoreSnapshotCalled()); 1462 assertFalse("Coprocessor clone should not have been called on snapshot restore", 1463 cp.wasCloneSnapshotCalled()); 1464 1465 admin.deleteSnapshot(TEST_SNAPSHOT); 1466 assertTrue("Coprocessor should have been called on snapshot delete", 1467 cp.wasDeleteSnapshotCalled()); 1468 } finally { 1469 deleteTable(admin, tableName); 1470 } 1471 } 1472 1473 @Test 1474 public void testNamespaceOperations() throws Exception { 1475 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1476 String testNamespace = "observed_ns"; 1477 HMaster master = cluster.getMaster(); 1478 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1479 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1480 1481 // create a table 1482 Admin admin = UTIL.getAdmin(); 1483 admin.createNamespace(NamespaceDescriptor.create(testNamespace).build()); 1484 assertTrue("Test namespace should be created", cp.wasCreateNamespaceCalled()); 1485 1486 assertNotNull(admin.getNamespaceDescriptor(testNamespace)); 1487 assertTrue("Test namespace descriptor should have been called", 1488 cp.wasGetNamespaceDescriptorCalled()); 1489 // This test used to do a bunch w/ bypass but bypass of these table and namespace stuff has 1490 // been removed so the testing code was removed. 1491 } 1492 1493 private void modifyTableSync(Admin admin, TableName tableName, HTableDescriptor htd) 1494 throws IOException { 1495 admin.modifyTable(tableName, htd); 1496 //wait until modify table finishes 1497 for (int t = 0; t < 100; t++) { //10 sec timeout 1498 HTableDescriptor td = admin.getTableDescriptor(htd.getTableName()); 1499 if (td.equals(htd)) { 1500 break; 1501 } 1502 Threads.sleep(100); 1503 } 1504 } 1505 1506 @Test 1507 public void testRegionTransitionOperations() throws Exception { 1508 final TableName tableName = TableName.valueOf(name.getMethodName()); 1509 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1510 1511 HMaster master = cluster.getMaster(); 1512 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1513 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1514 cp.resetStates(); 1515 1516 Table table = UTIL.createMultiRegionTable(tableName, TEST_FAMILY); 1517 1518 try (RegionLocator r = UTIL.getConnection().getRegionLocator(tableName)) { 1519 UTIL.waitUntilAllRegionsAssigned(tableName); 1520 1521 List<HRegionLocation> regions = r.getAllRegionLocations(); 1522 HRegionLocation firstGoodPair = null; 1523 for (HRegionLocation e: regions) { 1524 if (e.getServerName() != null) { 1525 firstGoodPair = e; 1526 break; 1527 } 1528 } 1529 assertNotNull("Found a non-null entry", firstGoodPair); 1530 LOG.info("Found " + firstGoodPair.toString()); 1531 // Try to force a move 1532 Collection<ServerName> servers = master.getClusterMetrics().getLiveServerMetrics().keySet(); 1533 String destName = null; 1534 String serverNameForFirstRegion = firstGoodPair.getServerName().toString(); 1535 LOG.info("serverNameForFirstRegion=" + serverNameForFirstRegion); 1536 ServerName masterServerName = master.getServerName(); 1537 boolean found = false; 1538 // Find server that is NOT carrying the first region 1539 for (ServerName info : servers) { 1540 LOG.info("ServerName=" + info); 1541 if (!serverNameForFirstRegion.equals(info.getServerName()) 1542 && !masterServerName.equals(info)) { 1543 destName = info.toString(); 1544 found = true; 1545 break; 1546 } 1547 } 1548 assertTrue("Found server", found); 1549 LOG.info("Found " + destName); 1550 master.getMasterRpcServices().moveRegion(null, RequestConverter.buildMoveRegionRequest( 1551 firstGoodPair.getRegionInfo().getEncodedNameAsBytes(), ServerName.valueOf(destName))); 1552 assertTrue("Coprocessor should have been called on region move", 1553 cp.wasMoveCalled()); 1554 1555 // make sure balancer is on 1556 master.balanceSwitch(true); 1557 assertTrue("Coprocessor should have been called on balance switch", 1558 cp.wasBalanceSwitchCalled()); 1559 1560 // turn balancer off 1561 master.balanceSwitch(false); 1562 1563 // wait for assignments to finish, if any 1564 UTIL.waitUntilNoRegionsInTransition(); 1565 1566 // move half the open regions from RS 0 to RS 1 1567 HRegionServer rs = cluster.getRegionServer(0); 1568 byte[] destRS = Bytes.toBytes(cluster.getRegionServer(1).getServerName().toString()); 1569 //Make sure no regions are in transition now 1570 UTIL.waitUntilNoRegionsInTransition(); 1571 List<RegionInfo> openRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()); 1572 int moveCnt = openRegions.size()/2; 1573 for (int i = 0; i < moveCnt; i++) { 1574 RegionInfo info = openRegions.get(i); 1575 if (!info.isMetaRegion()) { 1576 master.getMasterRpcServices().moveRegion(null, 1577 RequestConverter.buildMoveRegionRequest(openRegions.get(i).getEncodedNameAsBytes(), 1578 ServerName.valueOf(Bytes.toString(destRS)))); 1579 } 1580 } 1581 //Make sure no regions are in transition now 1582 UTIL.waitUntilNoRegionsInTransition(); 1583 // now trigger a balance 1584 master.balanceSwitch(true); 1585 boolean balanceRun = master.balance(); 1586 assertTrue("Coprocessor should be called on region rebalancing", 1587 cp.wasBalanceCalled()); 1588 } finally { 1589 Admin admin = UTIL.getAdmin(); 1590 admin.disableTable(tableName); 1591 deleteTable(admin, tableName); 1592 } 1593 } 1594 1595 @Test 1596 public void testTableDescriptorsEnumeration() throws Exception { 1597 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1598 1599 HMaster master = cluster.getMaster(); 1600 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1601 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1602 cp.resetStates(); 1603 1604 GetTableDescriptorsRequest req = 1605 RequestConverter.buildGetTableDescriptorsRequest((List<TableName>)null); 1606 master.getMasterRpcServices().getTableDescriptors(null, req); 1607 1608 assertTrue("Coprocessor should be called on table descriptors request", 1609 cp.wasGetTableDescriptorsCalled()); 1610 } 1611 1612 @Test 1613 public void testTableNamesEnumeration() throws Exception { 1614 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1615 1616 HMaster master = cluster.getMaster(); 1617 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1618 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1619 cp.resetStates(); 1620 1621 master.getMasterRpcServices().getTableNames(null, 1622 GetTableNamesRequest.newBuilder().build()); 1623 assertTrue("Coprocessor should be called on table names request", 1624 cp.wasGetTableNamesCalled()); 1625 } 1626 1627 @Test 1628 public void testAbortProcedureOperation() throws Exception { 1629 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1630 1631 HMaster master = cluster.getMaster(); 1632 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1633 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1634 cp.resetStates(); 1635 1636 master.abortProcedure(1, true); 1637 assertTrue( 1638 "Coprocessor should be called on abort procedure request", 1639 cp.wasAbortProcedureCalled()); 1640 } 1641 1642 @Test 1643 public void testGetProceduresOperation() throws Exception { 1644 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1645 1646 HMaster master = cluster.getMaster(); 1647 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1648 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1649 cp.resetStates(); 1650 1651 master.getProcedures(); 1652 assertTrue( 1653 "Coprocessor should be called on get procedures request", 1654 cp.wasGetProceduresCalled()); 1655 } 1656 1657 @Test 1658 public void testGetLocksOperation() throws Exception { 1659 MiniHBaseCluster cluster = UTIL.getHBaseCluster(); 1660 1661 HMaster master = cluster.getMaster(); 1662 MasterCoprocessorHost host = master.getMasterCoprocessorHost(); 1663 CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class); 1664 cp.resetStates(); 1665 1666 master.getLocks(); 1667 assertTrue( 1668 "Coprocessor should be called on get locks request", 1669 cp.wasGetLocksCalled()); 1670 } 1671 1672 private void deleteTable(Admin admin, TableName tableName) throws Exception { 1673 // NOTE: We need a latch because admin is not sync, 1674 // so the postOp coprocessor method may be called after the admin operation returned. 1675 tableDeletionLatch = new CountDownLatch(1); 1676 admin.deleteTable(tableName); 1677 tableDeletionLatch.await(); 1678 tableDeletionLatch = new CountDownLatch(1); 1679 } 1680 1681 @Test 1682 public void testQueueLockAndLockHeartbeatOperations() throws Exception { 1683 HMaster master = UTIL.getMiniHBaseCluster().getMaster(); 1684 CPMasterObserver cp = master.getMasterCoprocessorHost().findCoprocessor(CPMasterObserver.class); 1685 cp.resetStates(); 1686 1687 final TableName tableName = TableName.valueOf("testLockedTable"); 1688 long procId = master.getLockManager().remoteLocks().requestTableLock(tableName, 1689 LockType.EXCLUSIVE, "desc", null); 1690 master.getLockManager().remoteLocks().lockHeartbeat(procId, false); 1691 1692 assertTrue(cp.preAndPostForQueueLockAndHeartbeatLockCalled()); 1693 1694 ProcedureTestingUtility.waitNoProcedureRunning(master.getMasterProcedureExecutor()); 1695 ProcedureTestingUtility.assertProcNotFailed(master.getMasterProcedureExecutor(), procId); 1696 } 1697}