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