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