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