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