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