1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.coprocessor;
21
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26
27 import java.io.IOException;
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.NavigableMap;
32 import java.util.concurrent.CountDownLatch;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.hadoop.conf.Configuration;
37 import org.apache.hadoop.hbase.*;
38 import org.apache.hadoop.hbase.client.HBaseAdmin;
39 import org.apache.hadoop.hbase.client.HTable;
40 import org.apache.hadoop.hbase.master.AssignmentManager;
41 import org.apache.hadoop.hbase.master.HMaster;
42 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
43 import org.apache.hadoop.hbase.master.RegionPlan;
44 import org.apache.hadoop.hbase.master.RegionState;
45 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
46 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
47 import org.apache.hadoop.hbase.protobuf.RequestConverter;
48 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
49 import org.apache.hadoop.hbase.regionserver.HRegionServer;
50 import org.apache.hadoop.hbase.util.Bytes;
51 import org.apache.hadoop.hbase.util.Threads;
52 import org.junit.AfterClass;
53 import org.junit.BeforeClass;
54 import org.junit.Test;
55 import org.junit.experimental.categories.Category;
56
57
58
59
60
61 @Category(MediumTests.class)
62 public class TestMasterObserver {
63 private static final Log LOG = LogFactory.getLog(TestMasterObserver.class);
64
65 public static CountDownLatch tableCreationLatch = new CountDownLatch(1);
66
67 public static class CPMasterObserver implements MasterObserver {
68
69 private boolean bypass = false;
70 private boolean preCreateTableCalled;
71 private boolean postCreateTableCalled;
72 private boolean preDeleteTableCalled;
73 private boolean postDeleteTableCalled;
74 private boolean preTruncateTableCalled;
75 private boolean postTruncateTableCalled;
76 private boolean preModifyTableCalled;
77 private boolean postModifyTableCalled;
78 private boolean preCreateNamespaceCalled;
79 private boolean postCreateNamespaceCalled;
80 private boolean preDeleteNamespaceCalled;
81 private boolean postDeleteNamespaceCalled;
82 private boolean preModifyNamespaceCalled;
83 private boolean postModifyNamespaceCalled;
84 private boolean preAddColumnCalled;
85 private boolean postAddColumnCalled;
86 private boolean preModifyColumnCalled;
87 private boolean postModifyColumnCalled;
88 private boolean preDeleteColumnCalled;
89 private boolean postDeleteColumnCalled;
90 private boolean preEnableTableCalled;
91 private boolean postEnableTableCalled;
92 private boolean preDisableTableCalled;
93 private boolean postDisableTableCalled;
94 private boolean preMoveCalled;
95 private boolean postMoveCalled;
96 private boolean preAssignCalled;
97 private boolean postAssignCalled;
98 private boolean preUnassignCalled;
99 private boolean postUnassignCalled;
100 private boolean preRegionOfflineCalled;
101 private boolean postRegionOfflineCalled;
102 private boolean preBalanceCalled;
103 private boolean postBalanceCalled;
104 private boolean preBalanceSwitchCalled;
105 private boolean postBalanceSwitchCalled;
106 private boolean preShutdownCalled;
107 private boolean preStopMasterCalled;
108 private boolean preMasterInitializationCalled;
109 private boolean postStartMasterCalled;
110 private boolean startCalled;
111 private boolean stopCalled;
112 private boolean preSnapshotCalled;
113 private boolean postSnapshotCalled;
114 private boolean preCloneSnapshotCalled;
115 private boolean postCloneSnapshotCalled;
116 private boolean preRestoreSnapshotCalled;
117 private boolean postRestoreSnapshotCalled;
118 private boolean preDeleteSnapshotCalled;
119 private boolean postDeleteSnapshotCalled;
120 private boolean preCreateTableHandlerCalled;
121 private boolean postCreateTableHandlerCalled;
122 private boolean preDeleteTableHandlerCalled;
123 private boolean postDeleteTableHandlerCalled;
124 private boolean preTruncateTableHandlerCalled;
125 private boolean postTruncateTableHandlerCalled;
126 private boolean preAddColumnHandlerCalled;
127 private boolean postAddColumnHandlerCalled;
128 private boolean preModifyColumnHandlerCalled;
129 private boolean postModifyColumnHandlerCalled;
130 private boolean preDeleteColumnHandlerCalled;
131 private boolean postDeleteColumnHandlerCalled;
132 private boolean preEnableTableHandlerCalled;
133 private boolean postEnableTableHandlerCalled;
134 private boolean preDisableTableHandlerCalled;
135 private boolean postDisableTableHandlerCalled;
136 private boolean preModifyTableHandlerCalled;
137 private boolean postModifyTableHandlerCalled;
138 private boolean preGetTableDescriptorsCalled;
139 private boolean postGetTableDescriptorsCalled;
140
141 public void enableBypass(boolean bypass) {
142 this.bypass = bypass;
143 }
144
145 public void resetStates() {
146 preCreateTableCalled = false;
147 postCreateTableCalled = false;
148 preDeleteTableCalled = false;
149 postDeleteTableCalled = false;
150 preTruncateTableCalled = false;
151 postTruncateTableCalled = false;
152 preModifyTableCalled = false;
153 postModifyTableCalled = false;
154 preCreateNamespaceCalled = false;
155 postCreateNamespaceCalled = false;
156 preDeleteNamespaceCalled = false;
157 postDeleteNamespaceCalled = false;
158 preModifyNamespaceCalled = false;
159 postModifyNamespaceCalled = false;
160 preAddColumnCalled = false;
161 postAddColumnCalled = false;
162 preModifyColumnCalled = false;
163 postModifyColumnCalled = false;
164 preDeleteColumnCalled = false;
165 postDeleteColumnCalled = false;
166 preEnableTableCalled = false;
167 postEnableTableCalled = false;
168 preDisableTableCalled = false;
169 postDisableTableCalled = false;
170 preMoveCalled= false;
171 postMoveCalled = false;
172 preAssignCalled = false;
173 postAssignCalled = false;
174 preUnassignCalled = false;
175 postUnassignCalled = false;
176 preRegionOfflineCalled = false;
177 postRegionOfflineCalled = false;
178 preBalanceCalled = false;
179 postBalanceCalled = false;
180 preBalanceSwitchCalled = false;
181 postBalanceSwitchCalled = false;
182 preSnapshotCalled = false;
183 postSnapshotCalled = false;
184 preCloneSnapshotCalled = false;
185 postCloneSnapshotCalled = false;
186 preRestoreSnapshotCalled = false;
187 postRestoreSnapshotCalled = false;
188 preDeleteSnapshotCalled = false;
189 postDeleteSnapshotCalled = false;
190 preCreateTableHandlerCalled = false;
191 postCreateTableHandlerCalled = false;
192 preDeleteTableHandlerCalled = false;
193 postDeleteTableHandlerCalled = false;
194 preTruncateTableHandlerCalled = false;
195 postTruncateTableHandlerCalled = false;
196 preModifyTableHandlerCalled = false;
197 postModifyTableHandlerCalled = false;
198 preAddColumnHandlerCalled = false;
199 postAddColumnHandlerCalled = false;
200 preModifyColumnHandlerCalled = false;
201 postModifyColumnHandlerCalled = false;
202 preDeleteColumnHandlerCalled = false;
203 postDeleteColumnHandlerCalled = false;
204 preEnableTableHandlerCalled = false;
205 postEnableTableHandlerCalled = false;
206 preDisableTableHandlerCalled = false;
207 postDisableTableHandlerCalled = false;
208 preModifyTableHandlerCalled = false;
209 postModifyTableHandlerCalled = false;
210 preGetTableDescriptorsCalled = false;
211 postGetTableDescriptorsCalled = false;
212 }
213
214 @Override
215 public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> env,
216 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
217 if (bypass) {
218 env.bypass();
219 }
220 preCreateTableCalled = true;
221 }
222
223 @Override
224 public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> env,
225 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
226 postCreateTableCalled = true;
227 }
228
229 public boolean wasCreateTableCalled() {
230 return preCreateTableCalled && postCreateTableCalled;
231 }
232
233 public boolean preCreateTableCalledOnly() {
234 return preCreateTableCalled && !postCreateTableCalled;
235 }
236
237 @Override
238 public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> env,
239 TableName tableName) throws IOException {
240 if (bypass) {
241 env.bypass();
242 }
243 preDeleteTableCalled = true;
244 }
245
246 @Override
247 public void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> env,
248 TableName tableName) throws IOException {
249 postDeleteTableCalled = true;
250 }
251
252 public boolean wasDeleteTableCalled() {
253 return preDeleteTableCalled && postDeleteTableCalled;
254 }
255
256 public boolean preDeleteTableCalledOnly() {
257 return preDeleteTableCalled && !postDeleteTableCalled;
258 }
259
260 @Override
261 public void preTruncateTable(ObserverContext<MasterCoprocessorEnvironment> env,
262 TableName tableName) throws IOException {
263 if (bypass) {
264 env.bypass();
265 }
266 preTruncateTableCalled = true;
267 }
268
269 @Override
270 public void postTruncateTable(ObserverContext<MasterCoprocessorEnvironment> env,
271 TableName tableName) throws IOException {
272 postTruncateTableCalled = true;
273 }
274
275 public boolean wasTruncateTableCalled() {
276 return preTruncateTableCalled && postTruncateTableCalled;
277 }
278
279 public boolean preTruncateTableCalledOnly() {
280 return preTruncateTableCalled && !postTruncateTableCalled;
281 }
282
283 @Override
284 public void preModifyTable(ObserverContext<MasterCoprocessorEnvironment> env,
285 TableName tableName, HTableDescriptor htd) throws IOException {
286 if (bypass) {
287 env.bypass();
288 }else{
289 env.shouldBypass();
290 }
291 preModifyTableCalled = true;
292 }
293
294 @Override
295 public void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> env,
296 TableName tableName, HTableDescriptor htd) throws IOException {
297 postModifyTableCalled = true;
298 }
299
300 public boolean wasModifyTableCalled() {
301 return preModifyTableCalled && postModifyTableCalled;
302 }
303
304 public boolean preModifyTableCalledOnly() {
305 return preModifyTableCalled && !postModifyTableCalled;
306 }
307
308 @Override
309 public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
310 NamespaceDescriptor ns) throws IOException {
311 if (bypass) {
312 env.bypass();
313 }
314 preCreateNamespaceCalled = true;
315 }
316
317 @Override
318 public void postCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
319 NamespaceDescriptor ns) throws IOException {
320 postCreateNamespaceCalled = true;
321 }
322
323 public boolean wasCreateNamespaceCalled() {
324 return preCreateNamespaceCalled && postCreateNamespaceCalled;
325 }
326
327 public boolean preCreateNamespaceCalledOnly() {
328 return preCreateNamespaceCalled && !postCreateNamespaceCalled;
329 }
330
331 @Override
332 public void preDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
333 String name) throws IOException {
334 if (bypass) {
335 env.bypass();
336 }
337 preDeleteNamespaceCalled = true;
338 }
339
340 @Override
341 public void postDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
342 String name) throws IOException {
343 postDeleteNamespaceCalled = true;
344 }
345
346 public boolean wasDeleteNamespaceCalled() {
347 return preDeleteNamespaceCalled && postDeleteNamespaceCalled;
348 }
349
350 public boolean preDeleteNamespaceCalledOnly() {
351 return preDeleteNamespaceCalled && !postDeleteNamespaceCalled;
352 }
353
354 @Override
355 public void preModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
356 NamespaceDescriptor ns) throws IOException {
357 if (bypass) {
358 env.bypass();
359 }
360 preModifyNamespaceCalled = true;
361 }
362
363 @Override
364 public void postModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
365 NamespaceDescriptor ns) throws IOException {
366 postModifyNamespaceCalled = true;
367 }
368
369 public boolean wasModifyNamespaceCalled() {
370 return preModifyNamespaceCalled && postModifyNamespaceCalled;
371 }
372
373 public boolean preModifyNamespaceCalledOnly() {
374 return preModifyNamespaceCalled && !postModifyNamespaceCalled;
375 }
376
377 @Override
378 public void preAddColumn(ObserverContext<MasterCoprocessorEnvironment> env,
379 TableName tableName, HColumnDescriptor column) throws IOException {
380 if (bypass) {
381 env.bypass();
382 }else{
383 env.shouldBypass();
384 }
385
386 preAddColumnCalled = true;
387 }
388
389 @Override
390 public void postAddColumn(ObserverContext<MasterCoprocessorEnvironment> env,
391 TableName tableName, HColumnDescriptor column) throws IOException {
392 postAddColumnCalled = true;
393 }
394
395 public boolean wasAddColumnCalled() {
396 return preAddColumnCalled && postAddColumnCalled;
397 }
398
399 public boolean preAddColumnCalledOnly() {
400 return preAddColumnCalled && !postAddColumnCalled;
401 }
402
403 @Override
404 public void preModifyColumn(ObserverContext<MasterCoprocessorEnvironment> env,
405 TableName tableName, HColumnDescriptor descriptor) throws IOException {
406 if (bypass) {
407 env.bypass();
408 }
409 preModifyColumnCalled = true;
410 }
411
412 @Override
413 public void postModifyColumn(ObserverContext<MasterCoprocessorEnvironment> env,
414 TableName tableName, HColumnDescriptor descriptor) throws IOException {
415 postModifyColumnCalled = true;
416 }
417
418 public boolean wasModifyColumnCalled() {
419 return preModifyColumnCalled && postModifyColumnCalled;
420 }
421
422 public boolean preModifyColumnCalledOnly() {
423 return preModifyColumnCalled && !postModifyColumnCalled;
424 }
425
426 @Override
427 public void preDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> env,
428 TableName tableName, byte[] c) throws IOException {
429 if (bypass) {
430 env.bypass();
431 }
432 preDeleteColumnCalled = true;
433 }
434
435 @Override
436 public void postDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> env,
437 TableName tableName, byte[] c) throws IOException {
438 postDeleteColumnCalled = true;
439 }
440
441 public boolean wasDeleteColumnCalled() {
442 return preDeleteColumnCalled && postDeleteColumnCalled;
443 }
444
445 public boolean preDeleteColumnCalledOnly() {
446 return preDeleteColumnCalled && !postDeleteColumnCalled;
447 }
448
449 @Override
450 public void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> env,
451 TableName tableName) throws IOException {
452 if (bypass) {
453 env.bypass();
454 }
455 preEnableTableCalled = true;
456 }
457
458 @Override
459 public void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> env,
460 TableName tableName) throws IOException {
461 postEnableTableCalled = true;
462 }
463
464 public boolean wasEnableTableCalled() {
465 return preEnableTableCalled && postEnableTableCalled;
466 }
467
468 public boolean preEnableTableCalledOnly() {
469 return preEnableTableCalled && !postEnableTableCalled;
470 }
471
472 @Override
473 public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> env,
474 TableName tableName) throws IOException {
475 if (bypass) {
476 env.bypass();
477 }
478 preDisableTableCalled = true;
479 }
480
481 @Override
482 public void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> env,
483 TableName tableName) throws IOException {
484 postDisableTableCalled = true;
485 }
486
487 public boolean wasDisableTableCalled() {
488 return preDisableTableCalled && postDisableTableCalled;
489 }
490
491 public boolean preDisableTableCalledOnly() {
492 return preDisableTableCalled && !postDisableTableCalled;
493 }
494
495 @Override
496 public void preMove(ObserverContext<MasterCoprocessorEnvironment> env,
497 HRegionInfo region, ServerName srcServer, ServerName destServer)
498 throws IOException {
499 if (bypass) {
500 env.bypass();
501 }
502 preMoveCalled = true;
503 }
504
505 @Override
506 public void postMove(ObserverContext<MasterCoprocessorEnvironment> env, HRegionInfo region,
507 ServerName srcServer, ServerName destServer)
508 throws IOException {
509 postMoveCalled = true;
510 }
511
512 public boolean wasMoveCalled() {
513 return preMoveCalled && postMoveCalled;
514 }
515
516 public boolean preMoveCalledOnly() {
517 return preMoveCalled && !postMoveCalled;
518 }
519
520 @Override
521 public void preAssign(ObserverContext<MasterCoprocessorEnvironment> env,
522 final HRegionInfo regionInfo) throws IOException {
523 if (bypass) {
524 env.bypass();
525 }
526 preAssignCalled = true;
527 }
528
529 @Override
530 public void postAssign(ObserverContext<MasterCoprocessorEnvironment> env,
531 final HRegionInfo regionInfo) throws IOException {
532 postAssignCalled = true;
533 }
534
535 public boolean wasAssignCalled() {
536 return preAssignCalled && postAssignCalled;
537 }
538
539 public boolean preAssignCalledOnly() {
540 return preAssignCalled && !postAssignCalled;
541 }
542
543 @Override
544 public void preUnassign(ObserverContext<MasterCoprocessorEnvironment> env,
545 final HRegionInfo regionInfo, final boolean force) throws IOException {
546 if (bypass) {
547 env.bypass();
548 }
549 preUnassignCalled = true;
550 }
551
552 @Override
553 public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> env,
554 final HRegionInfo regionInfo, final boolean force) throws IOException {
555 postUnassignCalled = true;
556 }
557
558 public boolean wasUnassignCalled() {
559 return preUnassignCalled && postUnassignCalled;
560 }
561
562 public boolean preUnassignCalledOnly() {
563 return preUnassignCalled && !postUnassignCalled;
564 }
565
566 @Override
567 public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env,
568 final HRegionInfo regionInfo) throws IOException {
569 preRegionOfflineCalled = true;
570 }
571
572 @Override
573 public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env,
574 final HRegionInfo regionInfo) throws IOException {
575 postRegionOfflineCalled = true;
576 }
577
578 public boolean wasRegionOfflineCalled() {
579 return preRegionOfflineCalled && postRegionOfflineCalled;
580 }
581
582 public boolean preRegionOfflineCalledOnly() {
583 return preRegionOfflineCalled && !postRegionOfflineCalled;
584 }
585
586 @Override
587 public void preBalance(ObserverContext<MasterCoprocessorEnvironment> env)
588 throws IOException {
589 if (bypass) {
590 env.bypass();
591 }
592 preBalanceCalled = true;
593 }
594
595 @Override
596 public void postBalance(ObserverContext<MasterCoprocessorEnvironment> env,
597 List<RegionPlan> plans) throws IOException {
598 postBalanceCalled = true;
599 }
600
601 public boolean wasBalanceCalled() {
602 return preBalanceCalled && postBalanceCalled;
603 }
604
605 public boolean preBalanceCalledOnly() {
606 return preBalanceCalled && !postBalanceCalled;
607 }
608
609 @Override
610 public boolean preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env, boolean b)
611 throws IOException {
612 if (bypass) {
613 env.bypass();
614 }
615 preBalanceSwitchCalled = true;
616 return b;
617 }
618
619 @Override
620 public void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env,
621 boolean oldValue, boolean newValue) throws IOException {
622 postBalanceSwitchCalled = true;
623 }
624
625 public boolean wasBalanceSwitchCalled() {
626 return preBalanceSwitchCalled && postBalanceSwitchCalled;
627 }
628
629 public boolean preBalanceSwitchCalledOnly() {
630 return preBalanceSwitchCalled && !postBalanceSwitchCalled;
631 }
632
633 @Override
634 public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> env)
635 throws IOException {
636 preShutdownCalled = true;
637 }
638
639 @Override
640 public void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> env)
641 throws IOException {
642 preStopMasterCalled = true;
643 }
644
645 @Override
646 public void preMasterInitialization(
647 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
648 preMasterInitializationCalled = true;
649 }
650
651 public boolean wasMasterInitializationCalled(){
652 return preMasterInitializationCalled;
653 }
654
655 @Override
656 public void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx)
657 throws IOException {
658 postStartMasterCalled = true;
659 }
660
661 public boolean wasStartMasterCalled() {
662 return postStartMasterCalled;
663 }
664
665 @Override
666 public void start(CoprocessorEnvironment env) throws IOException {
667 startCalled = true;
668 }
669
670 @Override
671 public void stop(CoprocessorEnvironment env) throws IOException {
672 stopCalled = true;
673 }
674
675 public boolean wasStarted() { return startCalled; }
676
677 public boolean wasStopped() { return stopCalled; }
678
679 @Override
680 public void preSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
681 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
682 throws IOException {
683 preSnapshotCalled = true;
684 }
685
686 @Override
687 public void postSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
688 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
689 throws IOException {
690 postSnapshotCalled = true;
691 }
692
693 public boolean wasSnapshotCalled() {
694 return preSnapshotCalled && postSnapshotCalled;
695 }
696
697 @Override
698 public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
699 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
700 throws IOException {
701 preCloneSnapshotCalled = true;
702 }
703
704 @Override
705 public void postCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
706 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
707 throws IOException {
708 postCloneSnapshotCalled = true;
709 }
710
711 public boolean wasCloneSnapshotCalled() {
712 return preCloneSnapshotCalled && postCloneSnapshotCalled;
713 }
714
715 @Override
716 public void preRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
717 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
718 throws IOException {
719 preRestoreSnapshotCalled = true;
720 }
721
722 @Override
723 public void postRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
724 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
725 throws IOException {
726 postRestoreSnapshotCalled = true;
727 }
728
729 public boolean wasRestoreSnapshotCalled() {
730 return preRestoreSnapshotCalled && postRestoreSnapshotCalled;
731 }
732
733 @Override
734 public void preDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
735 final SnapshotDescription snapshot) throws IOException {
736 preDeleteSnapshotCalled = true;
737 }
738
739 @Override
740 public void postDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
741 final SnapshotDescription snapshot) throws IOException {
742 postDeleteSnapshotCalled = true;
743 }
744
745 public boolean wasDeleteSnapshotCalled() {
746 return preDeleteSnapshotCalled && postDeleteSnapshotCalled;
747 }
748
749 @Override
750 public void preCreateTableHandler(
751 ObserverContext<MasterCoprocessorEnvironment> env,
752 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
753 if (bypass) {
754 env.bypass();
755 }
756 preCreateTableHandlerCalled = true;
757 }
758
759 @Override
760 public void postCreateTableHandler(
761 ObserverContext<MasterCoprocessorEnvironment> ctx,
762 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
763 postCreateTableHandlerCalled = true;
764 tableCreationLatch.countDown();
765 }
766
767 public boolean wasPreCreateTableHandlerCalled(){
768 return preCreateTableHandlerCalled;
769 }
770 public boolean wasCreateTableHandlerCalled() {
771 return preCreateTableHandlerCalled && postCreateTableHandlerCalled;
772 }
773
774 public boolean wasCreateTableHandlerCalledOnly() {
775 return preCreateTableHandlerCalled && !postCreateTableHandlerCalled;
776 }
777
778 @Override
779 public void preDeleteTableHandler(
780 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName)
781 throws IOException {
782 if (bypass) {
783 env.bypass();
784 }
785 preDeleteTableHandlerCalled = true;
786 }
787
788 @Override
789 public void postDeleteTableHandler(
790 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName)
791 throws IOException {
792 postDeleteTableHandlerCalled = true;
793 }
794
795 public boolean wasDeleteTableHandlerCalled() {
796 return preDeleteTableHandlerCalled && postDeleteTableHandlerCalled;
797 }
798
799 public boolean wasDeleteTableHandlerCalledOnly() {
800 return preDeleteTableHandlerCalled && !postDeleteTableHandlerCalled;
801 }
802
803 @Override
804 public void preTruncateTableHandler(
805 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName)
806 throws IOException {
807 if (bypass) {
808 env.bypass();
809 }
810 preTruncateTableHandlerCalled = true;
811 }
812
813 @Override
814 public void postTruncateTableHandler(
815 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName)
816 throws IOException {
817 postTruncateTableHandlerCalled = true;
818 }
819
820 public boolean wasTruncateTableHandlerCalled() {
821 return preTruncateTableHandlerCalled && postTruncateTableHandlerCalled;
822 }
823
824 public boolean wasTruncateTableHandlerCalledOnly() {
825 return preTruncateTableHandlerCalled && !postTruncateTableHandlerCalled;
826 }
827
828 @Override
829 public void preModifyTableHandler(
830 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName,
831 HTableDescriptor htd) throws IOException {
832 if (bypass) {
833 env.bypass();
834 }
835 preModifyTableHandlerCalled = true;
836 }
837
838 @Override
839 public void postModifyTableHandler(
840 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName,
841 HTableDescriptor htd) throws IOException {
842 postModifyTableHandlerCalled = true;
843 }
844
845 public boolean wasModifyTableHandlerCalled() {
846 return preModifyColumnHandlerCalled && postModifyColumnHandlerCalled;
847 }
848
849 public boolean wasModifyTableHandlerCalledOnly() {
850 return preModifyColumnHandlerCalled && !postModifyColumnHandlerCalled;
851 }
852
853 @Override
854 public void preAddColumnHandler(
855 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName,
856 HColumnDescriptor column) throws IOException {
857 if (bypass) {
858 env.bypass();
859 }
860 preAddColumnHandlerCalled = true;
861 }
862
863 @Override
864 public void postAddColumnHandler(
865 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName,
866 HColumnDescriptor column) throws IOException {
867 postAddColumnHandlerCalled = true;
868 }
869 public boolean wasAddColumnHandlerCalled() {
870 return preAddColumnHandlerCalled && postAddColumnHandlerCalled;
871 }
872
873 public boolean preAddColumnHandlerCalledOnly() {
874 return preAddColumnHandlerCalled && !postAddColumnHandlerCalled;
875 }
876
877 @Override
878 public void preModifyColumnHandler(
879 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName,
880 HColumnDescriptor descriptor) throws IOException {
881 if (bypass) {
882 env.bypass();
883 }
884 preModifyColumnHandlerCalled = true;
885 }
886
887 @Override
888 public void postModifyColumnHandler(
889 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName,
890 HColumnDescriptor descriptor) throws IOException {
891 postModifyColumnHandlerCalled = true;
892 }
893
894 public boolean wasModifyColumnHandlerCalled() {
895 return preModifyColumnHandlerCalled && postModifyColumnHandlerCalled;
896 }
897
898 public boolean preModifyColumnHandlerCalledOnly() {
899 return preModifyColumnHandlerCalled && !postModifyColumnHandlerCalled;
900 }
901 @Override
902 public void preDeleteColumnHandler(
903 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName,
904 byte[] c) throws IOException {
905 if (bypass) {
906 env.bypass();
907 }
908 preDeleteColumnHandlerCalled = true;
909 }
910
911 @Override
912 public void postDeleteColumnHandler(
913 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName,
914 byte[] c) throws IOException {
915 postDeleteColumnHandlerCalled = true;
916 }
917
918 public boolean wasDeleteColumnHandlerCalled() {
919 return preDeleteColumnHandlerCalled && postDeleteColumnHandlerCalled;
920 }
921
922 public boolean preDeleteColumnHandlerCalledOnly() {
923 return preDeleteColumnHandlerCalled && !postDeleteColumnHandlerCalled;
924 }
925
926 @Override
927 public void preEnableTableHandler(
928 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName)
929 throws IOException {
930 if (bypass) {
931 env.bypass();
932 }
933 preEnableTableHandlerCalled = true;
934 }
935
936 @Override
937 public void postEnableTableHandler(
938 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName)
939 throws IOException {
940 postEnableTableHandlerCalled = true;
941 }
942
943 public boolean wasEnableTableHandlerCalled() {
944 return preEnableTableHandlerCalled && postEnableTableHandlerCalled;
945 }
946
947 public boolean preEnableTableHandlerCalledOnly() {
948 return preEnableTableHandlerCalled && !postEnableTableHandlerCalled;
949 }
950
951 @Override
952 public void preDisableTableHandler(
953 ObserverContext<MasterCoprocessorEnvironment> env, TableName tableName)
954 throws IOException {
955 if (bypass) {
956 env.bypass();
957 }
958 preDisableTableHandlerCalled = true;
959 }
960
961 @Override
962 public void postDisableTableHandler(
963 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName)
964 throws IOException {
965 postDisableTableHandlerCalled = true;
966 }
967
968 public boolean wasDisableTableHandlerCalled() {
969 return preDisableTableHandlerCalled && postDisableTableHandlerCalled;
970 }
971
972 public boolean preDisableTableHandlerCalledOnly() {
973 return preDisableTableHandlerCalled && !postDisableTableHandlerCalled;
974 }
975
976 @Override
977 public void preGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx,
978 List<TableName> tableNamesList, List<HTableDescriptor> descriptors)
979 throws IOException {
980 preGetTableDescriptorsCalled = true;
981 }
982
983 @Override
984 public void postGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx,
985 List<HTableDescriptor> descriptors) throws IOException {
986 postGetTableDescriptorsCalled = true;
987 }
988
989 public boolean wasGetTableDescriptorsCalled() {
990 return preGetTableDescriptorsCalled && postGetTableDescriptorsCalled;
991 }
992 }
993
994 private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
995 private static byte[] TEST_SNAPSHOT = Bytes.toBytes("observed_snapshot");
996 private static TableName TEST_TABLE =
997 TableName.valueOf("observed_table");
998 private static byte[] TEST_CLONE = Bytes.toBytes("observed_clone");
999 private static byte[] TEST_FAMILY = Bytes.toBytes("fam1");
1000 private static byte[] TEST_FAMILY2 = Bytes.toBytes("fam2");
1001 private static byte[] TEST_FAMILY3 = Bytes.toBytes("fam3");
1002
1003 @BeforeClass
1004 public static void setupBeforeClass() throws Exception {
1005 Configuration conf = UTIL.getConfiguration();
1006 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
1007 CPMasterObserver.class.getName());
1008 conf.set("hbase.master.hfilecleaner.plugins",
1009 "org.apache.hadoop.hbase.master.cleaner.HFileLinkCleaner," +
1010 "org.apache.hadoop.hbase.master.snapshot.SnapshotHFileCleaner");
1011 conf.set("hbase.master.logcleaner.plugins",
1012 "org.apache.hadoop.hbase.master.snapshot.SnapshotLogCleaner");
1013
1014 UTIL.startMiniCluster(2);
1015 }
1016
1017 @AfterClass
1018 public static void tearDownAfterClass() throws Exception {
1019 UTIL.shutdownMiniCluster();
1020 }
1021
1022 @Test
1023 public void testStarted() throws Exception {
1024 MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1025
1026 HMaster master = cluster.getMaster();
1027 assertTrue("Master should be active", master.isActiveMaster());
1028 MasterCoprocessorHost host = master.getCoprocessorHost();
1029 assertNotNull("CoprocessorHost should not be null", host);
1030 CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
1031 CPMasterObserver.class.getName());
1032 assertNotNull("CPMasterObserver coprocessor not found or not installed!", cp);
1033
1034
1035 assertTrue("MasterObserver should have been started", cp.wasStarted());
1036 assertTrue("preMasterInitialization() hook should have been called",
1037 cp.wasMasterInitializationCalled());
1038 assertTrue("postStartMaster() hook should have been called",
1039 cp.wasStartMasterCalled());
1040 }
1041
1042 @Test
1043 public void testTableOperations() throws Exception {
1044 MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1045
1046 HMaster master = cluster.getMaster();
1047 MasterCoprocessorHost host = master.getCoprocessorHost();
1048 CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
1049 CPMasterObserver.class.getName());
1050 cp.enableBypass(true);
1051 cp.resetStates();
1052 assertFalse("No table created yet", cp.wasCreateTableCalled());
1053
1054
1055 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE);
1056 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
1057 HBaseAdmin admin = UTIL.getHBaseAdmin();
1058
1059 tableCreationLatch = new CountDownLatch(1);
1060 admin.createTable(htd);
1061
1062 assertTrue("Test table should be created", cp.wasCreateTableCalled());
1063 tableCreationLatch.await();
1064 assertTrue("Table pre create handler called.", cp
1065 .wasPreCreateTableHandlerCalled());
1066 assertTrue("Table create handler should be called.",
1067 cp.wasCreateTableHandlerCalled());
1068
1069 tableCreationLatch = new CountDownLatch(1);
1070 admin.disableTable(TEST_TABLE);
1071 assertTrue(admin.isTableDisabled(TEST_TABLE));
1072
1073 assertTrue("Coprocessor should have been called on table disable",
1074 cp.wasDisableTableCalled());
1075 assertTrue("Disable table handler should be called.",
1076 cp.wasDisableTableHandlerCalled());
1077
1078
1079 assertFalse(cp.wasEnableTableCalled());
1080 admin.enableTable(TEST_TABLE);
1081 assertTrue(admin.isTableEnabled(TEST_TABLE));
1082
1083 assertTrue("Coprocessor should have been called on table enable",
1084 cp.wasEnableTableCalled());
1085 assertTrue("Enable table handler should be called.",
1086 cp.wasEnableTableHandlerCalled());
1087
1088 admin.disableTable(TEST_TABLE);
1089 assertTrue(admin.isTableDisabled(TEST_TABLE));
1090
1091
1092 htd.setMaxFileSize(512 * 1024 * 1024);
1093 modifyTableSync(admin, TEST_TABLE, htd);
1094
1095 assertTrue("Test table should have been modified",
1096 cp.wasModifyTableCalled());
1097
1098
1099 admin.addColumn(TEST_TABLE, new HColumnDescriptor(TEST_FAMILY2));
1100 assertTrue("New column family shouldn't have been added to test table",
1101 cp.preAddColumnCalledOnly());
1102
1103
1104 HColumnDescriptor hcd1 = new HColumnDescriptor(TEST_FAMILY2);
1105 hcd1.setMaxVersions(25);
1106 admin.modifyColumn(TEST_TABLE, hcd1);
1107 assertTrue("Second column family should be modified",
1108 cp.preModifyColumnCalledOnly());
1109
1110
1111 admin.truncateTable(TEST_TABLE, false);
1112
1113
1114 admin.disableTable(TEST_TABLE);
1115 assertTrue(admin.isTableDisabled(TEST_TABLE));
1116 admin.deleteTable(TEST_TABLE);
1117 assertFalse("Test table should have been deleted",
1118 admin.tableExists(TEST_TABLE));
1119
1120 assertTrue("Coprocessor should have been called on table delete",
1121 cp.wasDeleteTableCalled());
1122 assertTrue("Delete table handler should be called.",
1123 cp.wasDeleteTableHandlerCalled());
1124
1125
1126 cp.enableBypass(false);
1127 cp.resetStates();
1128
1129 admin.createTable(htd);
1130 assertTrue("Test table should be created", cp.wasCreateTableCalled());
1131 tableCreationLatch.await();
1132 assertTrue("Table pre create handler called.", cp
1133 .wasPreCreateTableHandlerCalled());
1134 assertTrue("Table create handler should be called.",
1135 cp.wasCreateTableHandlerCalled());
1136
1137
1138 assertFalse(cp.wasDisableTableCalled());
1139 assertFalse(cp.wasDisableTableHandlerCalled());
1140 admin.disableTable(TEST_TABLE);
1141 assertTrue(admin.isTableDisabled(TEST_TABLE));
1142 assertTrue("Coprocessor should have been called on table disable",
1143 cp.wasDisableTableCalled());
1144 assertTrue("Disable table handler should be called.",
1145 cp.wasDisableTableHandlerCalled());
1146
1147
1148 htd.setMaxFileSize(512 * 1024 * 1024);
1149 modifyTableSync(admin, TEST_TABLE, htd);
1150 assertTrue("Test table should have been modified",
1151 cp.wasModifyTableCalled());
1152
1153 admin.addColumn(TEST_TABLE, new HColumnDescriptor(TEST_FAMILY2));
1154 assertTrue("New column family should have been added to test table",
1155 cp.wasAddColumnCalled());
1156 assertTrue("Add column handler should be called.",
1157 cp.wasAddColumnHandlerCalled());
1158
1159
1160 HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY2);
1161 hcd.setMaxVersions(25);
1162 admin.modifyColumn(TEST_TABLE, hcd);
1163 assertTrue("Second column family should be modified",
1164 cp.wasModifyColumnCalled());
1165 assertTrue("Modify table handler should be called.",
1166 cp.wasModifyColumnHandlerCalled());
1167
1168
1169 assertFalse(cp.wasEnableTableCalled());
1170 assertFalse(cp.wasEnableTableHandlerCalled());
1171 admin.enableTable(TEST_TABLE);
1172 assertTrue(admin.isTableEnabled(TEST_TABLE));
1173 assertTrue("Coprocessor should have been called on table enable",
1174 cp.wasEnableTableCalled());
1175 assertTrue("Enable table handler should be called.",
1176 cp.wasEnableTableHandlerCalled());
1177
1178
1179 admin.disableTable(TEST_TABLE);
1180 assertTrue(admin.isTableDisabled(TEST_TABLE));
1181
1182
1183 assertFalse("No column family deleted yet", cp.wasDeleteColumnCalled());
1184 assertFalse("Delete table column handler should not be called.",
1185 cp.wasDeleteColumnHandlerCalled());
1186 admin.deleteColumn(TEST_TABLE, TEST_FAMILY2);
1187 HTableDescriptor tableDesc = admin.getTableDescriptor(TEST_TABLE);
1188 assertNull("'"+Bytes.toString(TEST_FAMILY2)+"' should have been removed",
1189 tableDesc.getFamily(TEST_FAMILY2));
1190 assertTrue("Coprocessor should have been called on column delete",
1191 cp.wasDeleteColumnCalled());
1192 assertTrue("Delete table column handler should be called.",
1193 cp.wasDeleteColumnHandlerCalled());
1194
1195
1196 assertFalse("No table deleted yet", cp.wasDeleteTableCalled());
1197 assertFalse("Delete table handler should not be called.",
1198 cp.wasDeleteTableHandlerCalled());
1199 admin.deleteTable(TEST_TABLE);
1200 assertFalse("Test table should have been deleted",
1201 admin.tableExists(TEST_TABLE));
1202 assertTrue("Coprocessor should have been called on table delete",
1203 cp.wasDeleteTableCalled());
1204 assertTrue("Delete table handler should be called.",
1205 cp.wasDeleteTableHandlerCalled());
1206 }
1207
1208 @Test
1209 public void testSnapshotOperations() throws Exception {
1210 MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1211 HMaster master = cluster.getMaster();
1212 MasterCoprocessorHost host = master.getCoprocessorHost();
1213 CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
1214 CPMasterObserver.class.getName());
1215 cp.resetStates();
1216
1217
1218 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE);
1219 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
1220 HBaseAdmin admin = UTIL.getHBaseAdmin();
1221
1222 tableCreationLatch = new CountDownLatch(1);
1223 admin.createTable(htd);
1224 tableCreationLatch.await();
1225 tableCreationLatch = new CountDownLatch(1);
1226
1227 admin.disableTable(TEST_TABLE);
1228 assertTrue(admin.isTableDisabled(TEST_TABLE));
1229
1230 try {
1231
1232 assertFalse("Coprocessor should not have been called yet",
1233 cp.wasSnapshotCalled());
1234 admin.snapshot(TEST_SNAPSHOT, TEST_TABLE);
1235 assertTrue("Coprocessor should have been called on snapshot",
1236 cp.wasSnapshotCalled());
1237
1238
1239 admin.cloneSnapshot(TEST_SNAPSHOT, TEST_CLONE);
1240 assertTrue("Coprocessor should have been called on snapshot clone",
1241 cp.wasCloneSnapshotCalled());
1242 assertFalse("Coprocessor restore should not have been called on snapshot clone",
1243 cp.wasRestoreSnapshotCalled());
1244 admin.disableTable(TEST_CLONE);
1245 assertTrue(admin.isTableDisabled(TEST_TABLE));
1246 admin.deleteTable(TEST_CLONE);
1247
1248
1249 cp.resetStates();
1250 admin.restoreSnapshot(TEST_SNAPSHOT);
1251 assertTrue("Coprocessor should have been called on snapshot restore",
1252 cp.wasRestoreSnapshotCalled());
1253 assertFalse("Coprocessor clone should not have been called on snapshot restore",
1254 cp.wasCloneSnapshotCalled());
1255
1256 admin.deleteSnapshot(TEST_SNAPSHOT);
1257 assertTrue("Coprocessor should have been called on snapshot delete",
1258 cp.wasDeleteSnapshotCalled());
1259 } finally {
1260 admin.deleteTable(TEST_TABLE);
1261 }
1262 }
1263
1264 @Test
1265 public void testNamespaceOperations() throws Exception {
1266 MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1267 String testNamespace = "observed_ns";
1268 HMaster master = cluster.getMaster();
1269 MasterCoprocessorHost host = master.getCoprocessorHost();
1270 CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
1271 CPMasterObserver.class.getName());
1272
1273 cp.enableBypass(false);
1274 cp.resetStates();
1275
1276
1277
1278 HBaseAdmin admin = UTIL.getHBaseAdmin();
1279 admin.createNamespace(NamespaceDescriptor.create(testNamespace).build());
1280 assertTrue("Test namespace should be created", cp.wasCreateNamespaceCalled());
1281
1282 assertNotNull(admin.getNamespaceDescriptor(testNamespace));
1283
1284
1285 cp.enableBypass(true);
1286 cp.resetStates();
1287
1288 admin.modifyNamespace(NamespaceDescriptor.create(testNamespace).build());
1289 assertTrue("Test namespace should not have been modified",
1290 cp.preModifyNamespaceCalledOnly());
1291
1292 assertNotNull(admin.getNamespaceDescriptor(testNamespace));
1293
1294 admin.deleteNamespace(testNamespace);
1295 assertTrue("Test namespace should not have been deleted", cp.preDeleteNamespaceCalledOnly());
1296
1297 assertNotNull(admin.getNamespaceDescriptor(testNamespace));
1298
1299 cp.enableBypass(false);
1300 cp.resetStates();
1301
1302
1303 admin.modifyNamespace(NamespaceDescriptor.create(testNamespace).build());
1304 assertTrue("Test namespace should have been modified", cp.wasModifyNamespaceCalled());
1305
1306 admin.deleteNamespace(testNamespace);
1307 assertTrue("Test namespace should have been deleted", cp.wasDeleteNamespaceCalled());
1308
1309 cp.enableBypass(true);
1310 cp.resetStates();
1311
1312 admin.createNamespace(NamespaceDescriptor.create(testNamespace).build());
1313 assertTrue("Test namespace should not be created", cp.preCreateNamespaceCalledOnly());
1314 }
1315
1316 private void modifyTableSync(HBaseAdmin admin, TableName tableName, HTableDescriptor htd)
1317 throws IOException {
1318 admin.modifyTable(tableName, htd);
1319
1320 for (int t = 0; t < 100; t++) {
1321 HTableDescriptor td = admin.getTableDescriptor(htd.getTableName());
1322 if (td.equals(htd)) {
1323 break;
1324 }
1325 Threads.sleep(100);
1326 }
1327 }
1328
1329 @Test
1330 public void testRegionTransitionOperations() throws Exception {
1331 MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1332
1333 HMaster master = cluster.getMaster();
1334 MasterCoprocessorHost host = master.getCoprocessorHost();
1335 CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
1336 CPMasterObserver.class.getName());
1337 cp.enableBypass(false);
1338 cp.resetStates();
1339
1340 HTable table = UTIL.createTable(TEST_TABLE, TEST_FAMILY);
1341
1342 try {
1343 UTIL.createMultiRegions(table, TEST_FAMILY);
1344 UTIL.waitUntilAllRegionsAssigned(TEST_TABLE);
1345
1346 NavigableMap<HRegionInfo, ServerName> regions = table.getRegionLocations();
1347 Map.Entry<HRegionInfo, ServerName> firstGoodPair = null;
1348 for (Map.Entry<HRegionInfo, ServerName> e: regions.entrySet()) {
1349 if (e.getValue() != null) {
1350 firstGoodPair = e;
1351 break;
1352 }
1353 }
1354 assertNotNull("Found a non-null entry", firstGoodPair);
1355 LOG.info("Found " + firstGoodPair.toString());
1356
1357 Collection<ServerName> servers = master.getClusterStatus().getServers();
1358 String destName = null;
1359 String serverNameForFirstRegion = firstGoodPair.getValue().toString();
1360 LOG.info("serverNameForFirstRegion=" + serverNameForFirstRegion);
1361 boolean found = false;
1362
1363 for (ServerName info : servers) {
1364 LOG.info("ServerName=" + info);
1365 if (!serverNameForFirstRegion.equals(info.getServerName())) {
1366 destName = info.toString();
1367 found = true;
1368 break;
1369 }
1370 }
1371 assertTrue("Found server", found);
1372 LOG.info("Found " + destName);
1373 master.moveRegion(null,RequestConverter.buildMoveRegionRequest(
1374 firstGoodPair.getKey().getEncodedNameAsBytes(),Bytes.toBytes(destName)));
1375 assertTrue("Coprocessor should have been called on region move",
1376 cp.wasMoveCalled());
1377
1378
1379 master.balanceSwitch(true);
1380 assertTrue("Coprocessor should have been called on balance switch",
1381 cp.wasBalanceSwitchCalled());
1382
1383
1384 master.balanceSwitch(false);
1385
1386
1387 AssignmentManager mgr = master.getAssignmentManager();
1388 Collection<RegionState> transRegions =
1389 mgr.getRegionStates().getRegionsInTransition().values();
1390 for (RegionState state : transRegions) {
1391 mgr.getRegionStates().waitOnRegionToClearRegionsInTransition(state.getRegion());
1392 }
1393
1394
1395 HRegionServer rs = cluster.getRegionServer(0);
1396 byte[] destRS = Bytes.toBytes(cluster.getRegionServer(1).getServerName().toString());
1397
1398 waitForRITtoBeZero(master);
1399 List<HRegionInfo> openRegions = ProtobufUtil.getOnlineRegions(rs);
1400 int moveCnt = openRegions.size()/2;
1401 for (int i=0; i<moveCnt; i++) {
1402 HRegionInfo info = openRegions.get(i);
1403 if (!info.isMetaTable()) {
1404 master.moveRegion(null,RequestConverter.buildMoveRegionRequest(
1405 openRegions.get(i).getEncodedNameAsBytes(), destRS));
1406 }
1407 }
1408
1409 waitForRITtoBeZero(master);
1410
1411 master.balanceSwitch(true);
1412 boolean balanceRun = master.balance();
1413 assertTrue("Coprocessor should be called on region rebalancing",
1414 cp.wasBalanceCalled());
1415 } finally {
1416 UTIL.deleteTable(TEST_TABLE);
1417 }
1418 }
1419
1420 private void waitForRITtoBeZero(HMaster master) throws Exception {
1421
1422 AssignmentManager mgr = master.getAssignmentManager();
1423 Collection<RegionState> transRegions =
1424 mgr.getRegionStates().getRegionsInTransition().values();
1425 for (RegionState state : transRegions) {
1426 mgr.getRegionStates().waitOnRegionToClearRegionsInTransition(state.getRegion());
1427 }
1428 }
1429
1430 @Test
1431 public void testTableDescriptorsEnumeration() throws Exception {
1432 MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1433
1434 HMaster master = cluster.getMaster();
1435 MasterCoprocessorHost host = master.getCoprocessorHost();
1436 CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
1437 CPMasterObserver.class.getName());
1438 cp.resetStates();
1439
1440 GetTableDescriptorsRequest req =
1441 RequestConverter.buildGetTableDescriptorsRequest((List<TableName>)null);
1442 master.getTableDescriptors(null, req);
1443
1444 assertTrue("Coprocessor should be called on table descriptors request",
1445 cp.wasGetTableDescriptorsCalled());
1446 }
1447
1448 }