001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.coprocessor;
019
020import static org.junit.Assert.assertFalse;
021import static org.junit.Assert.assertNotNull;
022import static org.junit.Assert.assertTrue;
023
024import java.io.IOException;
025import java.util.Arrays;
026import java.util.Collection;
027import java.util.List;
028import java.util.Optional;
029import java.util.Set;
030import java.util.concurrent.CountDownLatch;
031import org.apache.hadoop.conf.Configuration;
032import org.apache.hadoop.hbase.CoprocessorEnvironment;
033import org.apache.hadoop.hbase.HBaseClassTestRule;
034import org.apache.hadoop.hbase.HBaseTestingUtil;
035import org.apache.hadoop.hbase.HRegionLocation;
036import org.apache.hadoop.hbase.NamespaceDescriptor;
037import org.apache.hadoop.hbase.ServerName;
038import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
039import org.apache.hadoop.hbase.TableName;
040import org.apache.hadoop.hbase.client.Admin;
041import org.apache.hadoop.hbase.client.BalanceRequest;
042import org.apache.hadoop.hbase.client.BalanceResponse;
043import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
044import org.apache.hadoop.hbase.client.Connection;
045import org.apache.hadoop.hbase.client.ConnectionFactory;
046import org.apache.hadoop.hbase.client.MasterSwitchType;
047import org.apache.hadoop.hbase.client.Mutation;
048import org.apache.hadoop.hbase.client.RegionInfo;
049import org.apache.hadoop.hbase.client.RegionLocator;
050import org.apache.hadoop.hbase.client.SnapshotDescription;
051import org.apache.hadoop.hbase.client.Table;
052import org.apache.hadoop.hbase.client.TableDescriptor;
053import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
054import org.apache.hadoop.hbase.master.HMaster;
055import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
056import org.apache.hadoop.hbase.master.RegionPlan;
057import org.apache.hadoop.hbase.net.Address;
058import org.apache.hadoop.hbase.procedure2.LockType;
059import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
060import org.apache.hadoop.hbase.quotas.GlobalQuotaSettings;
061import org.apache.hadoop.hbase.regionserver.HRegionServer;
062import org.apache.hadoop.hbase.testclassification.CoprocessorTests;
063import org.apache.hadoop.hbase.testclassification.MediumTests;
064import org.apache.hadoop.hbase.util.Bytes;
065import org.apache.hadoop.hbase.util.Threads;
066import org.junit.AfterClass;
067import org.junit.BeforeClass;
068import org.junit.ClassRule;
069import org.junit.Rule;
070import org.junit.Test;
071import org.junit.experimental.categories.Category;
072import org.junit.rules.TestName;
073import org.slf4j.Logger;
074import org.slf4j.LoggerFactory;
075
076import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
077import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
078import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
079import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableNamesRequest;
080
081/**
082 * Tests invocation of the {@link org.apache.hadoop.hbase.coprocessor.MasterObserver}
083 * interface hooks at all appropriate times during normal HMaster operations.
084 */
085@Category({CoprocessorTests.class, MediumTests.class})
086public class TestMasterObserver {
087
088  @ClassRule
089  public static final HBaseClassTestRule CLASS_RULE =
090      HBaseClassTestRule.forClass(TestMasterObserver.class);
091
092  private static final Logger LOG = LoggerFactory.getLogger(TestMasterObserver.class);
093
094  public static CountDownLatch tableCreationLatch = new CountDownLatch(1);
095  public static CountDownLatch tableDeletionLatch = new CountDownLatch(1);
096
097  public static class CPMasterObserver implements MasterCoprocessor, MasterObserver {
098
099    private boolean preCreateTableRegionInfosCalled;
100    private boolean preCreateTableCalled;
101    private boolean postCreateTableCalled;
102    private boolean preDeleteTableCalled;
103    private boolean postDeleteTableCalled;
104    private boolean preTruncateTableCalled;
105    private boolean postTruncateTableCalled;
106    private boolean preModifyTableCalled;
107    private boolean postModifyTableCalled;
108    private boolean preCreateNamespaceCalled;
109    private boolean postCreateNamespaceCalled;
110    private boolean preDeleteNamespaceCalled;
111    private boolean postDeleteNamespaceCalled;
112    private boolean preModifyNamespaceCalled;
113    private boolean postModifyNamespaceCalled;
114    private boolean preGetNamespaceDescriptorCalled;
115    private boolean postGetNamespaceDescriptorCalled;
116    private boolean preListNamespacesCalled;
117    private boolean postListNamespacesCalled;
118    private boolean preListNamespaceDescriptorsCalled;
119    private boolean postListNamespaceDescriptorsCalled;
120    private boolean preAddColumnCalled;
121    private boolean postAddColumnCalled;
122    private boolean preModifyColumnCalled;
123    private boolean postModifyColumnCalled;
124    private boolean preDeleteColumnCalled;
125    private boolean postDeleteColumnCalled;
126    private boolean preEnableTableCalled;
127    private boolean postEnableTableCalled;
128    private boolean preDisableTableCalled;
129    private boolean postDisableTableCalled;
130    private boolean preAbortProcedureCalled;
131    private boolean postAbortProcedureCalled;
132    private boolean preGetProceduresCalled;
133    private boolean postGetProceduresCalled;
134    private boolean preGetLocksCalled;
135    private boolean postGetLocksCalled;
136    private boolean preMoveCalled;
137    private boolean postMoveCalled;
138    private boolean preAssignCalled;
139    private boolean postAssignCalled;
140    private boolean preUnassignCalled;
141    private boolean postUnassignCalled;
142    private boolean preRegionOfflineCalled;
143    private boolean postRegionOfflineCalled;
144    private boolean preBalanceCalled;
145    private boolean postBalanceCalled;
146    private boolean preBalanceSwitchCalled;
147    private boolean postBalanceSwitchCalled;
148    private boolean preShutdownCalled;
149    private boolean preStopMasterCalled;
150    private boolean preMasterInitializationCalled;
151    private boolean postStartMasterCalled;
152    private boolean startCalled;
153    private boolean stopCalled;
154    private boolean preSnapshotCalled;
155    private boolean postSnapshotCalled;
156    private boolean preListSnapshotCalled;
157    private boolean postListSnapshotCalled;
158    private boolean preCloneSnapshotCalled;
159    private boolean postCloneSnapshotCalled;
160    private boolean preRestoreSnapshotCalled;
161    private boolean postRestoreSnapshotCalled;
162    private boolean preDeleteSnapshotCalled;
163    private boolean postDeleteSnapshotCalled;
164    private boolean preCreateTableActionCalled;
165    private boolean postCompletedCreateTableActionCalled;
166    private boolean preDeleteTableActionCalled;
167    private boolean postCompletedDeleteTableActionCalled;
168    private boolean preTruncateTableActionCalled;
169    private boolean postCompletedTruncateTableActionCalled;
170    private boolean preAddColumnFamilyActionCalled;
171    private boolean postCompletedAddColumnFamilyActionCalled;
172    private boolean preModifyColumnFamilyActionCalled;
173    private boolean postCompletedModifyColumnFamilyActionCalled;
174    private boolean preDeleteColumnFamilyActionCalled;
175    private boolean postCompletedDeleteColumnFamilyActionCalled;
176    private boolean preEnableTableActionCalled;
177    private boolean postCompletedEnableTableActionCalled;
178    private boolean preDisableTableActionCalled;
179    private boolean postCompletedDisableTableActionCalled;
180    private boolean preModifyTableActionCalled;
181    private boolean postCompletedModifyTableActionCalled;
182    private boolean preGetTableDescriptorsCalled;
183    private boolean postGetTableDescriptorsCalled;
184    private boolean postGetTableNamesCalled;
185    private boolean preGetTableNamesCalled;
186    private boolean preMergeRegionsCalled;
187    private boolean postMergeRegionsCalled;
188    private boolean preRequestLockCalled;
189    private boolean postRequestLockCalled;
190    private boolean preLockHeartbeatCalled;
191    private boolean postLockHeartbeatCalled;
192
193    public void resetStates() {
194      preCreateTableRegionInfosCalled = false;
195      preCreateTableCalled = false;
196      postCreateTableCalled = false;
197      preDeleteTableCalled = false;
198      postDeleteTableCalled = false;
199      preTruncateTableCalled = false;
200      postTruncateTableCalled = false;
201      preModifyTableCalled = false;
202      postModifyTableCalled = false;
203      preCreateNamespaceCalled = false;
204      postCreateNamespaceCalled = false;
205      preDeleteNamespaceCalled = false;
206      postDeleteNamespaceCalled = false;
207      preModifyNamespaceCalled = false;
208      postModifyNamespaceCalled = false;
209      preGetNamespaceDescriptorCalled = false;
210      postGetNamespaceDescriptorCalled = false;
211      preListNamespacesCalled = false;
212      postListNamespacesCalled = false;
213      preListNamespaceDescriptorsCalled = false;
214      postListNamespaceDescriptorsCalled = false;
215      preAddColumnCalled = false;
216      postAddColumnCalled = false;
217      preModifyColumnCalled = false;
218      postModifyColumnCalled = false;
219      preDeleteColumnCalled = false;
220      postDeleteColumnCalled = false;
221      preEnableTableCalled = false;
222      postEnableTableCalled = false;
223      preDisableTableCalled = false;
224      postDisableTableCalled = false;
225      preAbortProcedureCalled = false;
226      postAbortProcedureCalled = false;
227      preGetProceduresCalled = false;
228      postGetProceduresCalled = false;
229      preGetLocksCalled = false;
230      postGetLocksCalled = false;
231      preMoveCalled= false;
232      postMoveCalled = false;
233      preAssignCalled = false;
234      postAssignCalled = false;
235      preUnassignCalled = false;
236      postUnassignCalled = false;
237      preRegionOfflineCalled = false;
238      postRegionOfflineCalled = false;
239      preBalanceCalled = false;
240      postBalanceCalled = false;
241      preBalanceSwitchCalled = false;
242      postBalanceSwitchCalled = false;
243      preShutdownCalled = false;
244      preStopMasterCalled = false;
245      preSnapshotCalled = false;
246      postSnapshotCalled = false;
247      preListSnapshotCalled = false;
248      postListSnapshotCalled = false;
249      preCloneSnapshotCalled = false;
250      postCloneSnapshotCalled = false;
251      preRestoreSnapshotCalled = false;
252      postRestoreSnapshotCalled = false;
253      preDeleteSnapshotCalled = false;
254      postDeleteSnapshotCalled = false;
255      preCreateTableActionCalled = false;
256      postCompletedCreateTableActionCalled = false;
257      preDeleteTableActionCalled = false;
258      postCompletedDeleteTableActionCalled = false;
259      preTruncateTableActionCalled = false;
260      postCompletedTruncateTableActionCalled = false;
261      preModifyTableActionCalled = false;
262      postCompletedModifyTableActionCalled = false;
263      preAddColumnFamilyActionCalled = false;
264      postCompletedAddColumnFamilyActionCalled = false;
265      preModifyColumnFamilyActionCalled = false;
266      postCompletedModifyColumnFamilyActionCalled = false;
267      preDeleteColumnFamilyActionCalled = false;
268      postCompletedDeleteColumnFamilyActionCalled = false;
269      preEnableTableActionCalled = false;
270      postCompletedEnableTableActionCalled = false;
271      preDisableTableActionCalled = false;
272      postCompletedDisableTableActionCalled = false;
273      preGetTableDescriptorsCalled = false;
274      postGetTableDescriptorsCalled = false;
275      postGetTableNamesCalled = false;
276      preGetTableNamesCalled = false;
277      preMergeRegionsCalled = false;
278      postMergeRegionsCalled = false;
279      preRequestLockCalled = false;
280      postRequestLockCalled = false;
281      preLockHeartbeatCalled = false;
282      postLockHeartbeatCalled = false;
283    }
284
285    @Override
286    public Optional<MasterObserver> getMasterObserver() {
287      return Optional.of(this);
288    }
289
290    @Override
291    public void preMergeRegions(
292        final ObserverContext<MasterCoprocessorEnvironment> ctx,
293        final RegionInfo[] regionsToMerge) throws IOException {
294      preMergeRegionsCalled = true;
295    }
296
297    @Override
298    public void postMergeRegions(
299        final ObserverContext<MasterCoprocessorEnvironment> ctx,
300        final RegionInfo[] regionsToMerge) throws IOException {
301      postMergeRegionsCalled = true;
302    }
303
304    public boolean wasMergeRegionsCalled() {
305      return preMergeRegionsCalled && postMergeRegionsCalled;
306    }
307
308    @Override
309    public TableDescriptor preCreateTableRegionsInfos(
310        ObserverContext<MasterCoprocessorEnvironment> ctx, TableDescriptor desc)
311        throws IOException {
312      preCreateTableRegionInfosCalled = true;
313      return desc;
314    }
315
316    @Override
317    public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> env,
318        TableDescriptor desc, RegionInfo[] regions) throws IOException {
319      preCreateTableCalled = true;
320    }
321
322    @Override
323    public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> env,
324        TableDescriptor desc, RegionInfo[] regions) throws IOException {
325      postCreateTableCalled = true;
326    }
327
328    public boolean wasCreateTableCalled() {
329      return preCreateTableRegionInfosCalled && preCreateTableCalled && postCreateTableCalled;
330    }
331
332    public boolean preCreateTableCalledOnly() {
333      return preCreateTableRegionInfosCalled && preCreateTableCalled && !postCreateTableCalled;
334    }
335
336    @Override
337    public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> env,
338        TableName tableName) throws IOException {
339      preDeleteTableCalled = true;
340    }
341
342    @Override
343    public void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> env,
344        TableName tableName) throws IOException {
345      postDeleteTableCalled = true;
346    }
347
348    public boolean wasDeleteTableCalled() {
349      return preDeleteTableCalled && postDeleteTableCalled;
350    }
351
352    public boolean preDeleteTableCalledOnly() {
353      return preDeleteTableCalled && !postDeleteTableCalled;
354    }
355
356    @Override
357    public void preTruncateTable(ObserverContext<MasterCoprocessorEnvironment> env,
358        TableName tableName) throws IOException {
359      preTruncateTableCalled = true;
360    }
361
362    @Override
363    public void postTruncateTable(ObserverContext<MasterCoprocessorEnvironment> env,
364        TableName tableName) throws IOException {
365      postTruncateTableCalled = true;
366    }
367
368    public boolean wasTruncateTableCalled() {
369      return preTruncateTableCalled && postTruncateTableCalled;
370    }
371
372    public boolean preTruncateTableCalledOnly() {
373      return preTruncateTableCalled && !postTruncateTableCalled;
374    }
375
376    @Override
377    public void postSetSplitOrMergeEnabled(final ObserverContext<MasterCoprocessorEnvironment> ctx,
378        final boolean newValue, final MasterSwitchType switchType) throws IOException {
379    }
380
381    @Override
382    public TableDescriptor preModifyTable(ObserverContext<MasterCoprocessorEnvironment> env,
383        TableName tableName, final TableDescriptor currentDescriptor,
384      final TableDescriptor newDescriptor) throws IOException {
385      preModifyTableCalled = true;
386      return newDescriptor;
387    }
388
389    @Override
390    public void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> env,
391        TableName tableName, final TableDescriptor oldDescriptor,
392      final TableDescriptor currentDescriptor) throws IOException {
393      postModifyTableCalled = true;
394    }
395
396    public boolean wasModifyTableCalled() {
397      return preModifyTableCalled && postModifyTableCalled;
398    }
399
400    public boolean preModifyTableCalledOnly() {
401      return preModifyTableCalled && !postModifyTableCalled;
402    }
403
404    @Override
405    public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
406        NamespaceDescriptor ns) throws IOException {
407      preCreateNamespaceCalled = true;
408    }
409
410    @Override
411    public void postCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
412        NamespaceDescriptor ns) throws IOException {
413      postCreateNamespaceCalled = true;
414    }
415
416    public boolean wasCreateNamespaceCalled() {
417      return preCreateNamespaceCalled && postCreateNamespaceCalled;
418    }
419
420    public boolean preCreateNamespaceCalledOnly() {
421      return preCreateNamespaceCalled && !postCreateNamespaceCalled;
422    }
423
424    @Override
425    public void preDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
426        String name) throws IOException {
427      preDeleteNamespaceCalled = true;
428    }
429
430    @Override
431    public void postDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
432        String name) throws IOException {
433      postDeleteNamespaceCalled = true;
434    }
435
436    public boolean wasDeleteNamespaceCalled() {
437      return preDeleteNamespaceCalled && postDeleteNamespaceCalled;
438    }
439
440    public boolean preDeleteNamespaceCalledOnly() {
441      return preDeleteNamespaceCalled && !postDeleteNamespaceCalled;
442    }
443
444    @Override
445    public void preModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
446        NamespaceDescriptor currentNsDesc, NamespaceDescriptor newNsDesc) throws IOException {
447      preModifyNamespaceCalled = true;
448    }
449
450    @Override
451    public void postModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
452        NamespaceDescriptor oldNsDesc, NamespaceDescriptor currentNsDesc) throws IOException {
453      postModifyNamespaceCalled = true;
454    }
455
456    public boolean wasModifyNamespaceCalled() {
457      return preModifyNamespaceCalled && postModifyNamespaceCalled;
458    }
459
460    public boolean preModifyNamespaceCalledOnly() {
461      return preModifyNamespaceCalled && !postModifyNamespaceCalled;
462    }
463
464
465    @Override
466    public void preGetNamespaceDescriptor(ObserverContext<MasterCoprocessorEnvironment> ctx,
467        String namespace) throws IOException {
468      preGetNamespaceDescriptorCalled = true;
469    }
470
471    @Override
472    public void postGetNamespaceDescriptor(ObserverContext<MasterCoprocessorEnvironment> ctx,
473        NamespaceDescriptor ns) throws IOException {
474      postGetNamespaceDescriptorCalled = true;
475    }
476
477    public boolean wasGetNamespaceDescriptorCalled() {
478      return preGetNamespaceDescriptorCalled && postGetNamespaceDescriptorCalled;
479    }
480
481    @Override
482    public void preListNamespaces(ObserverContext<MasterCoprocessorEnvironment> ctx,
483        List<String> namespaces) {
484      preListNamespacesCalled = true;
485    }
486
487    @Override
488    public void postListNamespaces(ObserverContext<MasterCoprocessorEnvironment> ctx,
489        List<String> namespaces) {
490      postListNamespacesCalled = true;
491    }
492
493    @Override
494    public void preListNamespaceDescriptors(ObserverContext<MasterCoprocessorEnvironment> env,
495        List<NamespaceDescriptor> descriptors) throws IOException {
496      preListNamespaceDescriptorsCalled = true;
497    }
498
499    @Override
500    public void postListNamespaceDescriptors(ObserverContext<MasterCoprocessorEnvironment> env,
501        List<NamespaceDescriptor> descriptors) throws IOException {
502      postListNamespaceDescriptorsCalled = true;
503    }
504
505    public boolean wasListNamespaceDescriptorsCalled() {
506      return preListNamespaceDescriptorsCalled && postListNamespaceDescriptorsCalled;
507    }
508
509    public boolean preListNamespaceDescriptorsCalledOnly() {
510      return preListNamespaceDescriptorsCalled && !postListNamespaceDescriptorsCalled;
511    }
512
513    @Override
514    public void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> env,
515        TableName tableName) throws IOException {
516      preEnableTableCalled = true;
517    }
518
519    @Override
520    public void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> env,
521        TableName tableName) throws IOException {
522      postEnableTableCalled = true;
523    }
524
525    public boolean wasEnableTableCalled() {
526      return preEnableTableCalled && postEnableTableCalled;
527    }
528
529    public boolean preEnableTableCalledOnly() {
530      return preEnableTableCalled && !postEnableTableCalled;
531    }
532
533    @Override
534    public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> env,
535        TableName tableName) throws IOException {
536      preDisableTableCalled = true;
537    }
538
539    @Override
540    public void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> env,
541        TableName tableName) throws IOException {
542      postDisableTableCalled = true;
543    }
544
545    public boolean wasDisableTableCalled() {
546      return preDisableTableCalled && postDisableTableCalled;
547    }
548
549    public boolean preDisableTableCalledOnly() {
550      return preDisableTableCalled && !postDisableTableCalled;
551    }
552
553    @Override
554    public void preAbortProcedure(
555        ObserverContext<MasterCoprocessorEnvironment> ctx, final long procId) throws IOException {
556      preAbortProcedureCalled = true;
557    }
558
559    @Override
560    public void postAbortProcedure(
561        ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
562      postAbortProcedureCalled = true;
563    }
564
565    public boolean wasAbortProcedureCalled() {
566      return preAbortProcedureCalled && postAbortProcedureCalled;
567    }
568
569    public boolean wasPreAbortProcedureCalledOnly() {
570      return preAbortProcedureCalled && !postAbortProcedureCalled;
571    }
572
573    @Override
574    public void preGetProcedures(
575        ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
576      preGetProceduresCalled = true;
577    }
578
579    @Override
580    public void postGetProcedures(
581        ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
582      postGetProceduresCalled = true;
583    }
584
585    public boolean wasGetProceduresCalled() {
586      return preGetProceduresCalled && postGetProceduresCalled;
587    }
588
589    public boolean wasPreGetProceduresCalledOnly() {
590      return preGetProceduresCalled && !postGetProceduresCalled;
591    }
592
593    @Override
594    public void preGetLocks(ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
595      preGetLocksCalled = true;
596    }
597
598    @Override
599    public void postGetLocks(ObserverContext<MasterCoprocessorEnvironment> ctx)
600        throws IOException {
601      postGetLocksCalled = true;
602    }
603
604    public boolean wasGetLocksCalled() {
605      return preGetLocksCalled && postGetLocksCalled;
606    }
607
608    public boolean wasPreGetLocksCalledOnly() {
609      return preGetLocksCalled && !postGetLocksCalled;
610    }
611
612    @Override
613    public void preMove(ObserverContext<MasterCoprocessorEnvironment> env,
614        RegionInfo region, ServerName srcServer, ServerName destServer)
615    throws IOException {
616      preMoveCalled = true;
617    }
618
619    @Override
620    public void postMove(ObserverContext<MasterCoprocessorEnvironment> env, RegionInfo region,
621        ServerName srcServer, ServerName destServer)
622    throws IOException {
623      postMoveCalled = true;
624    }
625
626    public boolean wasMoveCalled() {
627      return preMoveCalled && postMoveCalled;
628    }
629
630    public boolean preMoveCalledOnly() {
631      return preMoveCalled && !postMoveCalled;
632    }
633
634    @Override
635    public void preAssign(ObserverContext<MasterCoprocessorEnvironment> env,
636        final RegionInfo regionInfo) throws IOException {
637      preAssignCalled = true;
638    }
639
640    @Override
641    public void postAssign(ObserverContext<MasterCoprocessorEnvironment> env,
642        final RegionInfo regionInfo) throws IOException {
643      postAssignCalled = true;
644    }
645
646    public boolean wasAssignCalled() {
647      return preAssignCalled && postAssignCalled;
648    }
649
650    public boolean preAssignCalledOnly() {
651      return preAssignCalled && !postAssignCalled;
652    }
653
654    @Override
655    public void preUnassign(ObserverContext<MasterCoprocessorEnvironment> env,
656        final RegionInfo regionInfo) throws IOException {
657      preUnassignCalled = true;
658    }
659
660    @Override
661    public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> env,
662        final RegionInfo regionInfo) throws IOException {
663      postUnassignCalled = true;
664    }
665
666    public boolean wasUnassignCalled() {
667      return preUnassignCalled && postUnassignCalled;
668    }
669
670    public boolean preUnassignCalledOnly() {
671      return preUnassignCalled && !postUnassignCalled;
672    }
673
674    @Override
675    public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env,
676        final RegionInfo regionInfo) throws IOException {
677      preRegionOfflineCalled = true;
678    }
679
680    @Override
681    public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> env,
682        final RegionInfo regionInfo) throws IOException {
683      postRegionOfflineCalled = true;
684    }
685
686    public boolean wasRegionOfflineCalled() {
687      return preRegionOfflineCalled && postRegionOfflineCalled;
688    }
689
690    public boolean preRegionOfflineCalledOnly() {
691      return preRegionOfflineCalled && !postRegionOfflineCalled;
692    }
693
694    @Override
695    public void preBalance(ObserverContext<MasterCoprocessorEnvironment> env,
696      BalanceRequest request) throws IOException {
697      preBalanceCalled = true;
698    }
699
700    @Override
701    public void postBalance(ObserverContext<MasterCoprocessorEnvironment> env,
702        BalanceRequest request,
703        List<RegionPlan> plans) throws IOException {
704      postBalanceCalled = true;
705    }
706
707    public boolean wasBalanceCalled() {
708      return preBalanceCalled && postBalanceCalled;
709    }
710
711    public boolean preBalanceCalledOnly() {
712      return preBalanceCalled && !postBalanceCalled;
713    }
714
715    @Override
716    public void preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env, boolean b)
717        throws IOException {
718      preBalanceSwitchCalled = true;
719    }
720
721    @Override
722    public void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env,
723        boolean oldValue, boolean newValue) throws IOException {
724      postBalanceSwitchCalled = true;
725    }
726
727    public boolean wasBalanceSwitchCalled() {
728      return preBalanceSwitchCalled && postBalanceSwitchCalled;
729    }
730
731    public boolean preBalanceSwitchCalledOnly() {
732      return preBalanceSwitchCalled && !postBalanceSwitchCalled;
733    }
734
735    @Override
736    public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> env)
737        throws IOException {
738      preShutdownCalled = true;
739    }
740
741    public boolean wasShutdownCalled() {
742      return preShutdownCalled;
743    }
744
745    @Override
746    public void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> env)
747        throws IOException {
748      preStopMasterCalled = true;
749    }
750
751    public boolean wasStopMasterCalled() {
752      return preStopMasterCalled;
753    }
754
755    @Override
756    public void preMasterInitialization(
757        ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
758      preMasterInitializationCalled = true;
759    }
760
761    public boolean wasMasterInitializationCalled(){
762      return preMasterInitializationCalled;
763    }
764
765    @Override
766    public void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx)
767        throws IOException {
768      postStartMasterCalled = true;
769    }
770
771    public boolean wasStartMasterCalled() {
772      return postStartMasterCalled;
773    }
774
775    @Override
776    public void start(CoprocessorEnvironment env) throws IOException {
777      startCalled = true;
778    }
779
780    @Override
781    public void stop(CoprocessorEnvironment env) throws IOException {
782      stopCalled = true;
783    }
784
785    public boolean wasStarted() { return startCalled; }
786
787    public boolean wasStopped() { return stopCalled; }
788
789    @Override
790    public void preSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
791        final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
792        throws IOException {
793      preSnapshotCalled = true;
794    }
795
796    @Override
797    public void postSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
798        final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
799        throws IOException {
800      postSnapshotCalled = true;
801    }
802
803    public boolean wasSnapshotCalled() {
804      return preSnapshotCalled && postSnapshotCalled;
805    }
806
807    @Override
808    public void preListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
809        final SnapshotDescription snapshot) throws IOException {
810      preListSnapshotCalled = true;
811    }
812
813    @Override
814    public void postListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
815        final SnapshotDescription snapshot) throws IOException {
816      postListSnapshotCalled = true;
817    }
818
819    public boolean wasListSnapshotCalled() {
820      return preListSnapshotCalled && postListSnapshotCalled;
821    }
822
823    @Override
824    public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
825        final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
826        throws IOException {
827      preCloneSnapshotCalled = true;
828    }
829
830    @Override
831    public void postCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
832        final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
833        throws IOException {
834      postCloneSnapshotCalled = true;
835    }
836
837    public boolean wasCloneSnapshotCalled() {
838      return preCloneSnapshotCalled && postCloneSnapshotCalled;
839    }
840
841    @Override
842    public void preRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
843        final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
844        throws IOException {
845      preRestoreSnapshotCalled = true;
846    }
847
848    @Override
849    public void postRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
850        final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
851        throws IOException {
852      postRestoreSnapshotCalled = true;
853    }
854
855    public boolean wasRestoreSnapshotCalled() {
856      return preRestoreSnapshotCalled && postRestoreSnapshotCalled;
857    }
858
859    @Override
860    public void preDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
861        final SnapshotDescription snapshot) throws IOException {
862      preDeleteSnapshotCalled = true;
863    }
864
865    @Override
866    public void postDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
867        final SnapshotDescription snapshot) throws IOException {
868      postDeleteSnapshotCalled = true;
869    }
870
871    public boolean wasDeleteSnapshotCalled() {
872      return preDeleteSnapshotCalled && postDeleteSnapshotCalled;
873    }
874
875    @Override
876    public void preCreateTableAction(
877        final ObserverContext<MasterCoprocessorEnvironment> env,
878        final TableDescriptor desc,
879        final RegionInfo[] regions) throws IOException {
880      preCreateTableActionCalled = true;
881    }
882
883    @Override
884    public void postCompletedCreateTableAction(
885        final ObserverContext<MasterCoprocessorEnvironment> ctx,
886        final TableDescriptor desc,
887        final RegionInfo[] regions) throws IOException {
888      postCompletedCreateTableActionCalled = true;
889      tableCreationLatch.countDown();
890    }
891
892    public boolean wasPreCreateTableActionCalled(){
893      return preCreateTableActionCalled;
894    }
895    public boolean wasCreateTableActionCalled() {
896      return preCreateTableActionCalled && postCompletedCreateTableActionCalled;
897    }
898
899    public boolean wasCreateTableActionCalledOnly() {
900      return preCreateTableActionCalled && !postCompletedCreateTableActionCalled;
901    }
902
903    @Override
904    public void preDeleteTableAction(
905        final ObserverContext<MasterCoprocessorEnvironment> env, final TableName tableName)
906        throws IOException {
907      preDeleteTableActionCalled = true;
908    }
909
910    @Override
911    public void postCompletedDeleteTableAction(
912        final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
913        throws IOException {
914      postCompletedDeleteTableActionCalled = true;
915      tableDeletionLatch.countDown();
916    }
917
918    public boolean wasDeleteTableActionCalled() {
919      return preDeleteTableActionCalled && postCompletedDeleteTableActionCalled;
920    }
921
922    public boolean wasDeleteTableActionCalledOnly() {
923      return preDeleteTableActionCalled && !postCompletedDeleteTableActionCalled;
924    }
925
926    @Override
927    public void preTruncateTableAction(
928        final ObserverContext<MasterCoprocessorEnvironment> env, final TableName tableName)
929        throws IOException {
930      preTruncateTableActionCalled = true;
931    }
932
933    @Override
934    public void postCompletedTruncateTableAction(
935        final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
936        throws IOException {
937      postCompletedTruncateTableActionCalled = true;
938    }
939
940    public boolean wasTruncateTableActionCalled() {
941      return preTruncateTableActionCalled && postCompletedTruncateTableActionCalled;
942    }
943
944    public boolean wasTruncateTableActionCalledOnly() {
945      return preTruncateTableActionCalled && !postCompletedTruncateTableActionCalled;
946    }
947
948    @Override
949    public void preModifyTableAction(
950        final ObserverContext<MasterCoprocessorEnvironment> env,
951        final TableName tableName,
952        final TableDescriptor currentDescriptor,
953        final TableDescriptor newDescriptor) throws IOException {
954      preModifyTableActionCalled = true;
955    }
956
957    @Override
958    public void postCompletedModifyTableAction(
959        final ObserverContext<MasterCoprocessorEnvironment> env,
960        final TableName tableName,
961        final TableDescriptor oldDescriptor,
962        final TableDescriptor currentDescriptor) throws IOException {
963      postCompletedModifyTableActionCalled = true;
964    }
965
966    public boolean wasModifyTableActionCalled() {
967      return preModifyTableActionCalled && postCompletedModifyTableActionCalled;
968    }
969
970    public boolean wasModifyTableActionCalledOnly() {
971      return preModifyTableActionCalled && !postCompletedModifyTableActionCalled;
972    }
973
974    @Override
975    public void preEnableTableAction(
976        final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
977        throws IOException {
978      preEnableTableActionCalled = true;
979    }
980
981    @Override
982    public void postCompletedEnableTableAction(
983        final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
984        throws IOException {
985      postCompletedEnableTableActionCalled = true;
986    }
987
988    public boolean wasEnableTableActionCalled() {
989      return preEnableTableActionCalled && postCompletedEnableTableActionCalled;
990    }
991
992    public boolean preEnableTableActionCalledOnly() {
993      return preEnableTableActionCalled && !postCompletedEnableTableActionCalled;
994    }
995
996    @Override
997    public void preDisableTableAction(
998        final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
999        throws IOException {
1000      preDisableTableActionCalled = true;
1001    }
1002
1003    @Override
1004    public void postCompletedDisableTableAction(
1005        final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
1006        throws IOException {
1007      postCompletedDisableTableActionCalled = true;
1008    }
1009
1010    public boolean wasDisableTableActionCalled() {
1011      return preDisableTableActionCalled && postCompletedDisableTableActionCalled;
1012    }
1013
1014    public boolean preDisableTableActionCalledOnly() {
1015      return preDisableTableActionCalled && !postCompletedDisableTableActionCalled;
1016    }
1017
1018    @Override
1019    public void preGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx,
1020        List<TableName> tableNamesList, List<TableDescriptor> descriptors, String regex)
1021        throws IOException {
1022      preGetTableDescriptorsCalled = true;
1023    }
1024
1025    @Override
1026    public void postGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx,
1027        List<TableName> tableNamesList, List<TableDescriptor> descriptors,
1028        String regex) throws IOException {
1029      postGetTableDescriptorsCalled = true;
1030    }
1031
1032    public boolean wasGetTableDescriptorsCalled() {
1033      return preGetTableDescriptorsCalled && postGetTableDescriptorsCalled;
1034    }
1035
1036    @Override
1037    public void preGetTableNames(ObserverContext<MasterCoprocessorEnvironment> ctx,
1038        List<TableDescriptor> descriptors, String regex) throws IOException {
1039      preGetTableNamesCalled = true;
1040    }
1041
1042    @Override
1043    public void postGetTableNames(ObserverContext<MasterCoprocessorEnvironment> ctx,
1044        List<TableDescriptor> descriptors, String regex) throws IOException {
1045      postGetTableNamesCalled = true;
1046    }
1047
1048    public boolean wasGetTableNamesCalled() {
1049      return preGetTableNamesCalled && postGetTableNamesCalled;
1050    }
1051
1052    @Override
1053    public void preTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx,
1054        TableName tableName) throws IOException {
1055    }
1056
1057    @Override
1058    public void postTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx,
1059        TableName tableName) throws IOException {
1060    }
1061
1062    @Override
1063    public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1064        final String userName, final GlobalQuotaSettings quotas) throws IOException {
1065    }
1066
1067    @Override
1068    public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1069        final String userName, final GlobalQuotaSettings quotas) throws IOException {
1070    }
1071
1072    @Override
1073    public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1074        final String userName, final TableName tableName, final GlobalQuotaSettings quotas)
1075            throws IOException {
1076    }
1077
1078    @Override
1079    public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1080        final String userName, final TableName tableName, final GlobalQuotaSettings quotas)
1081            throws IOException {
1082    }
1083
1084    @Override
1085    public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1086        final String userName, final String namespace, final GlobalQuotaSettings quotas)
1087            throws IOException {
1088    }
1089
1090    @Override
1091    public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1092        final String userName, final String namespace, final GlobalQuotaSettings quotas)
1093            throws IOException {
1094    }
1095
1096    @Override
1097    public void preSetTableQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1098        final TableName tableName, final GlobalQuotaSettings quotas) throws IOException {
1099    }
1100
1101    @Override
1102    public void postSetTableQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1103        final TableName tableName, final GlobalQuotaSettings quotas) throws IOException {
1104    }
1105
1106    @Override
1107    public void preSetNamespaceQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1108        final String namespace, final GlobalQuotaSettings quotas) throws IOException {
1109    }
1110
1111    @Override
1112    public void postSetNamespaceQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1113        final String namespace, final GlobalQuotaSettings quotas) throws IOException {
1114    }
1115
1116    @Override
1117    public void preMoveServersAndTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1118        Set<Address> servers, Set<TableName> tables, String targetGroup) throws IOException {
1119    }
1120
1121    @Override
1122    public void postMoveServersAndTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1123        Set<Address> servers, Set<TableName> tables,String targetGroup) throws IOException {
1124    }
1125
1126    @Override
1127    public void preMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx,
1128                               Set<Address> servers, String targetGroup) throws IOException {
1129    }
1130
1131    @Override
1132    public void postMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx,
1133                                Set<Address> servers, String targetGroup) throws IOException {
1134    }
1135
1136    @Override
1137    public void preMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1138                              Set<TableName> tables, String targetGroupGroup) throws IOException {
1139    }
1140
1141    @Override
1142    public void postMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1143                               Set<TableName> tables, String targetGroup) throws IOException {
1144    }
1145
1146    @Override
1147    public void preAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1148                              String name) throws IOException {
1149    }
1150
1151    @Override
1152    public void postAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1153                               String name) throws IOException {
1154    }
1155
1156    @Override
1157    public void preRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1158                                 String name) throws IOException {
1159    }
1160
1161    @Override
1162    public void postRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1163                                  String name) throws IOException {
1164    }
1165
1166    @Override
1167    public void preBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1168                                  String groupName, BalanceRequest request) throws IOException {
1169    }
1170
1171    @Override
1172    public void postBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1173        String groupName, BalanceRequest request, BalanceResponse response) throws IOException {
1174    }
1175
1176    @Override
1177    public void preRequestLock(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace,
1178        TableName tableName, RegionInfo[] regionInfos, String description) throws IOException {
1179      preRequestLockCalled = true;
1180    }
1181
1182    @Override
1183    public void postRequestLock(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace,
1184        TableName tableName, RegionInfo[] regionInfos, String description) throws IOException {
1185      postRequestLockCalled = true;
1186    }
1187
1188    @Override
1189    public void preLockHeartbeat(ObserverContext<MasterCoprocessorEnvironment> ctx,
1190        TableName tn, String description) throws IOException {
1191      preLockHeartbeatCalled = true;
1192    }
1193
1194    @Override
1195    public void postLockHeartbeat(ObserverContext<MasterCoprocessorEnvironment> ctx)
1196        throws IOException {
1197      postLockHeartbeatCalled = true;
1198    }
1199
1200    public boolean preAndPostForQueueLockAndHeartbeatLockCalled() {
1201      return preRequestLockCalled && postRequestLockCalled && preLockHeartbeatCalled &&
1202          postLockHeartbeatCalled;
1203    }
1204
1205    @Override
1206    public void preSplitRegion(
1207        final ObserverContext<MasterCoprocessorEnvironment> c,
1208        final TableName tableName,
1209        final byte[] splitRow) throws IOException {
1210    }
1211
1212    @Override
1213    public void preSplitRegionAction(
1214        final ObserverContext<MasterCoprocessorEnvironment> c,
1215        final TableName tableName,
1216        final byte[] splitRow) throws IOException {
1217    }
1218
1219    @Override
1220    public void postCompletedSplitRegionAction(
1221        final ObserverContext<MasterCoprocessorEnvironment> c,
1222        final RegionInfo regionInfoA,
1223        final RegionInfo regionInfoB) throws IOException {
1224    }
1225
1226    @Override
1227    public void preSplitRegionBeforeMETAAction(
1228        final ObserverContext<MasterCoprocessorEnvironment> ctx,
1229        final byte[] splitKey,
1230        final List<Mutation> metaEntries) throws IOException {
1231    }
1232
1233    @Override
1234    public void preSplitRegionAfterMETAAction(
1235        final ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
1236    }
1237
1238    @Override
1239    public void postRollBackSplitRegionAction(
1240        final ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
1241    }
1242
1243    @Override
1244    public void preMergeRegionsAction(
1245        final ObserverContext<MasterCoprocessorEnvironment> ctx,
1246        final RegionInfo[] regionsToMerge) throws IOException {
1247    }
1248
1249    @Override
1250    public void postCompletedMergeRegionsAction(
1251        final ObserverContext<MasterCoprocessorEnvironment> c,
1252        final RegionInfo[] regionsToMerge,
1253        final RegionInfo mergedRegion) throws IOException {
1254    }
1255
1256    @Override
1257    public void preMergeRegionsCommitAction(
1258        final ObserverContext<MasterCoprocessorEnvironment> ctx,
1259        final RegionInfo[] regionsToMerge,
1260        final List<Mutation> metaEntries) throws IOException {
1261    }
1262
1263    @Override
1264    public void postMergeRegionsCommitAction(
1265        final ObserverContext<MasterCoprocessorEnvironment> ctx,
1266        final RegionInfo[] regionsToMerge,
1267        final RegionInfo mergedRegion) throws IOException {
1268    }
1269
1270    @Override
1271    public void postRollBackMergeRegionsAction(
1272        final ObserverContext<MasterCoprocessorEnvironment> ctx,
1273        final RegionInfo[] regionsToMerge) throws IOException {
1274    }
1275
1276  }
1277
1278  private static HBaseTestingUtil UTIL = new HBaseTestingUtil();
1279  private static String TEST_SNAPSHOT = "observed_snapshot";
1280  private static TableName TEST_CLONE = TableName.valueOf("observed_clone");
1281  private static byte[] TEST_FAMILY = Bytes.toBytes("fam1");
1282  @Rule
1283  public TestName name = new TestName();
1284
1285  @BeforeClass
1286  public static void setupBeforeClass() throws Exception {
1287    Configuration conf = UTIL.getConfiguration();
1288    conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
1289        CPMasterObserver.class.getName());
1290    // We need more than one data server on this test
1291    UTIL.startMiniCluster(2);
1292  }
1293
1294  @AfterClass
1295  public static void tearDownAfterClass() throws Exception {
1296    UTIL.shutdownMiniCluster();
1297  }
1298
1299  @Test
1300  public void testStarted() throws Exception {
1301    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1302
1303    HMaster master = cluster.getMaster();
1304    assertTrue("Master should be active", master.isActiveMaster());
1305    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1306    assertNotNull("CoprocessorHost should not be null", host);
1307    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1308    assertNotNull("CPMasterObserver coprocessor not found or not installed!", cp);
1309
1310    // check basic lifecycle
1311    assertTrue("MasterObserver should have been started", cp.wasStarted());
1312    assertTrue("preMasterInitialization() hook should have been called",
1313        cp.wasMasterInitializationCalled());
1314    assertTrue("postStartMaster() hook should have been called",
1315        cp.wasStartMasterCalled());
1316  }
1317
1318  @Test
1319  public void testTableOperations() throws Exception {
1320    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1321    final TableName tableName = TableName.valueOf(name.getMethodName());
1322    HMaster master = cluster.getMaster();
1323    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1324    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1325    cp.resetStates();
1326    assertFalse("No table created yet", cp.wasCreateTableCalled());
1327
1328    // create a table
1329    TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
1330      .setColumnFamily(ColumnFamilyDescriptorBuilder.of(TEST_FAMILY)).build();
1331    try(Connection connection = ConnectionFactory.createConnection(UTIL.getConfiguration());
1332        Admin admin = connection.getAdmin()) {
1333      tableCreationLatch = new CountDownLatch(1);
1334      admin.createTable(tableDescriptor, Arrays.copyOfRange(HBaseTestingUtil.KEYS,
1335        1, HBaseTestingUtil.KEYS.length));
1336
1337      assertTrue("Test table should be created", cp.wasCreateTableCalled());
1338      tableCreationLatch.await();
1339      assertTrue("Table pre create handler called.", cp
1340        .wasPreCreateTableActionCalled());
1341      assertTrue("Table create handler should be called.",
1342        cp.wasCreateTableActionCalled());
1343
1344      RegionLocator regionLocator = connection.getRegionLocator(tableDescriptor.getTableName());
1345      List<HRegionLocation> regions = regionLocator.getAllRegionLocations();
1346
1347      admin.mergeRegionsAsync(regions.get(0).getRegion().getEncodedNameAsBytes(),
1348        regions.get(1).getRegion().getEncodedNameAsBytes(), true).get();
1349      assertTrue("Coprocessor should have been called on region merge",
1350        cp.wasMergeRegionsCalled());
1351
1352      tableCreationLatch = new CountDownLatch(1);
1353      admin.disableTable(tableName);
1354      assertTrue(admin.isTableDisabled(tableName));
1355      assertTrue("Coprocessor should have been called on table disable",
1356        cp.wasDisableTableCalled());
1357      assertTrue("Disable table handler should be called.",
1358        cp.wasDisableTableActionCalled());
1359
1360      // enable
1361      assertFalse(cp.wasEnableTableCalled());
1362      admin.enableTable(tableName);
1363      assertTrue(admin.isTableEnabled(tableName));
1364      assertTrue("Coprocessor should have been called on table enable",
1365        cp.wasEnableTableCalled());
1366      assertTrue("Enable table handler should be called.",
1367        cp.wasEnableTableActionCalled());
1368
1369      admin.disableTable(tableName);
1370      assertTrue(admin.isTableDisabled(tableName));
1371
1372      // modify table
1373      tableDescriptor = TableDescriptorBuilder.newBuilder(tableDescriptor)
1374        .setMaxFileSize(512 * 1024 * 1024).build();
1375      modifyTableSync(admin, tableName, tableDescriptor);
1376      assertTrue("Test table should have been modified",
1377        cp.wasModifyTableCalled());
1378
1379      // truncate table
1380      admin.truncateTable(tableName, false);
1381
1382      // delete table
1383      admin.disableTable(tableName);
1384      assertTrue(admin.isTableDisabled(tableName));
1385      deleteTable(admin, tableName);
1386      assertFalse("Test table should have been deleted",
1387        admin.tableExists(tableName));
1388      assertTrue("Coprocessor should have been called on table delete",
1389        cp.wasDeleteTableCalled());
1390      assertTrue("Delete table handler should be called.",
1391        cp.wasDeleteTableActionCalled());
1392
1393      // When bypass was supported, we'd turn off bypass and rerun tests. Leaving rerun in place.
1394      cp.resetStates();
1395
1396      admin.createTable(tableDescriptor);
1397      assertTrue("Test table should be created", cp.wasCreateTableCalled());
1398      tableCreationLatch.await();
1399      assertTrue("Table pre create handler called.", cp
1400        .wasPreCreateTableActionCalled());
1401      assertTrue("Table create handler should be called.",
1402        cp.wasCreateTableActionCalled());
1403
1404      // disable
1405      assertFalse(cp.wasDisableTableCalled());
1406      assertFalse(cp.wasDisableTableActionCalled());
1407      admin.disableTable(tableName);
1408      assertTrue(admin.isTableDisabled(tableName));
1409      assertTrue("Coprocessor should have been called on table disable",
1410        cp.wasDisableTableCalled());
1411      assertTrue("Disable table handler should be called.",
1412        cp.wasDisableTableActionCalled());
1413
1414      // modify table
1415      tableDescriptor = TableDescriptorBuilder.newBuilder(tableDescriptor)
1416        .setMaxFileSize(512 * 1024 * 1024).build();
1417      modifyTableSync(admin, tableName, tableDescriptor);
1418      assertTrue("Test table should have been modified",
1419        cp.wasModifyTableCalled());
1420
1421      // enable
1422      assertFalse(cp.wasEnableTableCalled());
1423      assertFalse(cp.wasEnableTableActionCalled());
1424      admin.enableTable(tableName);
1425      assertTrue(admin.isTableEnabled(tableName));
1426      assertTrue("Coprocessor should have been called on table enable",
1427        cp.wasEnableTableCalled());
1428      assertTrue("Enable table handler should be called.",
1429        cp.wasEnableTableActionCalled());
1430
1431      // disable again
1432      admin.disableTable(tableName);
1433      assertTrue(admin.isTableDisabled(tableName));
1434
1435      // delete table
1436      assertFalse("No table deleted yet", cp.wasDeleteTableCalled());
1437      assertFalse("Delete table handler should not be called.",
1438        cp.wasDeleteTableActionCalled());
1439      deleteTable(admin, tableName);
1440      assertFalse("Test table should have been deleted",
1441        admin.tableExists(tableName));
1442      assertTrue("Coprocessor should have been called on table delete",
1443        cp.wasDeleteTableCalled());
1444      assertTrue("Delete table handler should be called.",
1445        cp.wasDeleteTableActionCalled());
1446    }
1447  }
1448
1449  @Test
1450  public void testSnapshotOperations() throws Exception {
1451    final TableName tableName = TableName.valueOf(name.getMethodName());
1452    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1453    HMaster master = cluster.getMaster();
1454    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1455    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1456    cp.resetStates();
1457
1458    // create a table
1459    TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
1460      .setColumnFamily(ColumnFamilyDescriptorBuilder.of(TEST_FAMILY)).build();
1461    Admin admin = UTIL.getAdmin();
1462
1463    tableCreationLatch = new CountDownLatch(1);
1464    admin.createTable(tableDescriptor);
1465    tableCreationLatch.await();
1466    tableCreationLatch = new CountDownLatch(1);
1467
1468    admin.disableTable(tableName);
1469    assertTrue(admin.isTableDisabled(tableName));
1470
1471    try {
1472      // Test snapshot operation
1473      assertFalse("Coprocessor should not have been called yet",
1474        cp.wasSnapshotCalled());
1475      admin.snapshot(TEST_SNAPSHOT, tableName);
1476      assertTrue("Coprocessor should have been called on snapshot",
1477        cp.wasSnapshotCalled());
1478
1479      //Test list operation
1480      admin.listSnapshots();
1481      assertTrue("Coprocessor should have been called on snapshot list",
1482        cp.wasListSnapshotCalled());
1483
1484      // Test clone operation
1485      admin.cloneSnapshot(TEST_SNAPSHOT, TEST_CLONE);
1486      assertTrue("Coprocessor should have been called on snapshot clone",
1487        cp.wasCloneSnapshotCalled());
1488      assertFalse("Coprocessor restore should not have been called on snapshot clone",
1489        cp.wasRestoreSnapshotCalled());
1490      admin.disableTable(TEST_CLONE);
1491      assertTrue(admin.isTableDisabled(tableName));
1492      deleteTable(admin, TEST_CLONE);
1493
1494      // Test restore operation
1495      cp.resetStates();
1496      admin.restoreSnapshot(TEST_SNAPSHOT);
1497      assertTrue("Coprocessor should have been called on snapshot restore",
1498        cp.wasRestoreSnapshotCalled());
1499      assertFalse("Coprocessor clone should not have been called on snapshot restore",
1500        cp.wasCloneSnapshotCalled());
1501
1502      admin.deleteSnapshot(TEST_SNAPSHOT);
1503      assertTrue("Coprocessor should have been called on snapshot delete",
1504        cp.wasDeleteSnapshotCalled());
1505    } finally {
1506      deleteTable(admin, tableName);
1507    }
1508  }
1509
1510  @Test
1511  public void testNamespaceOperations() throws Exception {
1512    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1513    String testNamespace = "observed_ns";
1514    HMaster master = cluster.getMaster();
1515    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1516    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1517
1518    // create a table
1519    Admin admin = UTIL.getAdmin();
1520
1521    admin.listNamespaces();
1522    assertTrue("preListNamespaces should have been called", cp.preListNamespacesCalled);
1523    assertTrue("postListNamespaces should have been called", cp.postListNamespacesCalled);
1524
1525    admin.createNamespace(NamespaceDescriptor.create(testNamespace).build());
1526    assertTrue("Test namespace should be created", cp.wasCreateNamespaceCalled());
1527
1528    assertNotNull(admin.getNamespaceDescriptor(testNamespace));
1529    assertTrue("Test namespace descriptor should have been called",
1530        cp.wasGetNamespaceDescriptorCalled());
1531    // This test used to do a bunch w/ bypass but bypass of these table and namespace stuff has
1532    // been removed so the testing code was removed.
1533  }
1534
1535  private void modifyTableSync(Admin admin, TableName tableName, TableDescriptor tableDescriptor)
1536    throws IOException {
1537    admin.modifyTable(tableDescriptor);
1538    // wait until modify table finishes
1539    for (int t = 0; t < 100; t++) { // 10 sec timeout
1540      TableDescriptor td = admin.getDescriptor(tableDescriptor.getTableName());
1541      if (td.equals(tableDescriptor)) {
1542        break;
1543      }
1544      Threads.sleep(100);
1545    }
1546  }
1547
1548  @Test
1549  public void testRegionTransitionOperations() throws Exception {
1550    final TableName tableName = TableName.valueOf(name.getMethodName());
1551    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1552
1553    HMaster master = cluster.getMaster();
1554    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1555    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1556    cp.resetStates();
1557
1558    Table table = UTIL.createMultiRegionTable(tableName, TEST_FAMILY);
1559
1560    try (RegionLocator r = UTIL.getConnection().getRegionLocator(tableName)) {
1561      UTIL.waitUntilAllRegionsAssigned(tableName);
1562
1563      List<HRegionLocation> regions = r.getAllRegionLocations();
1564      HRegionLocation firstGoodPair = null;
1565      for (HRegionLocation e: regions) {
1566        if (e.getServerName() != null) {
1567          firstGoodPair = e;
1568          break;
1569        }
1570      }
1571      assertNotNull("Found a non-null entry", firstGoodPair);
1572      LOG.info("Found " + firstGoodPair.toString());
1573      // Try to force a move
1574      Collection<ServerName> servers = master.getClusterMetrics().getLiveServerMetrics().keySet();
1575      String destName = null;
1576      String serverNameForFirstRegion = firstGoodPair.getServerName().toString();
1577      LOG.info("serverNameForFirstRegion=" + serverNameForFirstRegion);
1578      ServerName masterServerName = master.getServerName();
1579      boolean found = false;
1580      // Find server that is NOT carrying the first region
1581      for (ServerName info : servers) {
1582        LOG.info("ServerName=" + info);
1583        if (!serverNameForFirstRegion.equals(info.getServerName())
1584            && !masterServerName.equals(info)) {
1585          destName = info.toString();
1586          found = true;
1587          break;
1588        }
1589      }
1590      assertTrue("Found server", found);
1591      LOG.info("Found " + destName);
1592      master.getMasterRpcServices().moveRegion(null, RequestConverter.buildMoveRegionRequest(
1593          firstGoodPair.getRegion().getEncodedNameAsBytes(), ServerName.valueOf(destName)));
1594      assertTrue("Coprocessor should have been called on region move",
1595        cp.wasMoveCalled());
1596
1597      // make sure balancer is on
1598      master.balanceSwitch(true);
1599      assertTrue("Coprocessor should have been called on balance switch",
1600          cp.wasBalanceSwitchCalled());
1601
1602      // turn balancer off
1603      master.balanceSwitch(false);
1604
1605      // wait for assignments to finish, if any
1606      UTIL.waitUntilNoRegionsInTransition();
1607
1608      // move half the open regions from RS 0 to RS 1
1609      HRegionServer rs = cluster.getRegionServer(0);
1610      byte[] destRS = Bytes.toBytes(cluster.getRegionServer(1).getServerName().toString());
1611      //Make sure no regions are in transition now
1612      UTIL.waitUntilNoRegionsInTransition();
1613      List<RegionInfo> openRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
1614      int moveCnt = openRegions.size()/2;
1615      for (int i = 0; i < moveCnt; i++) {
1616        RegionInfo info = openRegions.get(i);
1617        if (!info.isMetaRegion()) {
1618          master.getMasterRpcServices().moveRegion(null,
1619            RequestConverter.buildMoveRegionRequest(openRegions.get(i).getEncodedNameAsBytes(),
1620              ServerName.valueOf(Bytes.toString(destRS))));
1621        }
1622      }
1623      //Make sure no regions are in transition now
1624      UTIL.waitUntilNoRegionsInTransition();
1625      // now trigger a balance
1626      master.balanceSwitch(true);
1627      master.balance();
1628      assertTrue("Coprocessor should be called on region rebalancing",
1629          cp.wasBalanceCalled());
1630    } finally {
1631      Admin admin = UTIL.getAdmin();
1632      admin.disableTable(tableName);
1633      deleteTable(admin, tableName);
1634    }
1635  }
1636
1637  @Test
1638  public void testTableDescriptorsEnumeration() throws Exception {
1639    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1640
1641    HMaster master = cluster.getMaster();
1642    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1643    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1644    cp.resetStates();
1645
1646    GetTableDescriptorsRequest req =
1647        RequestConverter.buildGetTableDescriptorsRequest((List<TableName>)null);
1648    master.getMasterRpcServices().getTableDescriptors(null, req);
1649
1650    assertTrue("Coprocessor should be called on table descriptors request",
1651      cp.wasGetTableDescriptorsCalled());
1652  }
1653
1654  @Test
1655  public void testTableNamesEnumeration() throws Exception {
1656    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1657
1658    HMaster master = cluster.getMaster();
1659    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1660    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1661    cp.resetStates();
1662
1663    master.getMasterRpcServices().getTableNames(null,
1664        GetTableNamesRequest.newBuilder().build());
1665    assertTrue("Coprocessor should be called on table names request",
1666      cp.wasGetTableNamesCalled());
1667  }
1668
1669  @Test
1670  public void testAbortProcedureOperation() throws Exception {
1671    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1672
1673    HMaster master = cluster.getMaster();
1674    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1675    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1676    cp.resetStates();
1677
1678    master.abortProcedure(1, true);
1679    assertTrue(
1680      "Coprocessor should be called on abort procedure request",
1681      cp.wasAbortProcedureCalled());
1682  }
1683
1684  @Test
1685  public void testGetProceduresOperation() throws Exception {
1686    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1687
1688    HMaster master = cluster.getMaster();
1689    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1690    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1691    cp.resetStates();
1692
1693    master.getProcedures();
1694    assertTrue(
1695      "Coprocessor should be called on get procedures request",
1696      cp.wasGetProceduresCalled());
1697  }
1698
1699  @Test
1700  public void testGetLocksOperation() throws Exception {
1701    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();
1702
1703    HMaster master = cluster.getMaster();
1704    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1705    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1706    cp.resetStates();
1707
1708    master.getLocks();
1709    assertTrue(
1710      "Coprocessor should be called on get locks request",
1711      cp.wasGetLocksCalled());
1712  }
1713
1714  private void deleteTable(Admin admin, TableName tableName) throws Exception {
1715    // NOTE: We need a latch because admin is not sync,
1716    // so the postOp coprocessor method may be called after the admin operation returned.
1717    tableDeletionLatch = new CountDownLatch(1);
1718    admin.deleteTable(tableName);
1719    tableDeletionLatch.await();
1720    tableDeletionLatch = new CountDownLatch(1);
1721  }
1722
1723  @Test
1724  public void testQueueLockAndLockHeartbeatOperations() throws Exception {
1725    HMaster master = UTIL.getMiniHBaseCluster().getMaster();
1726    CPMasterObserver cp = master.getMasterCoprocessorHost().findCoprocessor(CPMasterObserver.class);
1727    cp.resetStates();
1728
1729    final TableName tableName = TableName.valueOf("testLockedTable");
1730    long procId = master.getLockManager().remoteLocks().requestTableLock(tableName,
1731          LockType.EXCLUSIVE, "desc", null);
1732    master.getLockManager().remoteLocks().lockHeartbeat(procId, false);
1733
1734    assertTrue(cp.preAndPostForQueueLockAndHeartbeatLockCalled());
1735
1736    ProcedureTestingUtility.waitNoProcedureRunning(master.getMasterProcedureExecutor());
1737    ProcedureTestingUtility.assertProcNotFailed(master.getMasterProcedureExecutor(), procId);
1738  }
1739}