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