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