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