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