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.HBaseTestingUtility;
035import org.apache.hadoop.hbase.HColumnDescriptor;
036import org.apache.hadoop.hbase.HRegionLocation;
037import org.apache.hadoop.hbase.HTableDescriptor;
038import org.apache.hadoop.hbase.MiniHBaseCluster;
039import org.apache.hadoop.hbase.NamespaceDescriptor;
040import org.apache.hadoop.hbase.ServerName;
041import org.apache.hadoop.hbase.TableName;
042import org.apache.hadoop.hbase.client.Admin;
043import org.apache.hadoop.hbase.client.BalanceRequest;
044import org.apache.hadoop.hbase.client.BalanceResponse;
045import org.apache.hadoop.hbase.client.Connection;
046import org.apache.hadoop.hbase.client.ConnectionFactory;
047import org.apache.hadoop.hbase.client.MasterSwitchType;
048import org.apache.hadoop.hbase.client.Mutation;
049import org.apache.hadoop.hbase.client.RegionInfo;
050import org.apache.hadoop.hbase.client.RegionLocator;
051import org.apache.hadoop.hbase.client.SnapshotDescription;
052import org.apache.hadoop.hbase.client.Table;
053import org.apache.hadoop.hbase.client.TableDescriptor;
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, TableDescriptor currentDescriptor, TableDescriptor newDescriptor)
389      throws IOException {
390      preModifyTableCalled = true;
391      return newDescriptor;
392    }
393
394    @Override
395    public void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> env,
396      TableName tableName, TableDescriptor htd) throws IOException {
397      postModifyTableCalled = true;
398    }
399
400    public boolean wasModifyTableCalled() {
401      return preModifyTableCalled && postModifyTableCalled;
402    }
403
404    public boolean preModifyTableCalledOnly() {
405      return preModifyTableCalled && !postModifyTableCalled;
406    }
407
408    @Override
409    public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
410      NamespaceDescriptor ns) throws IOException {
411      preCreateNamespaceCalled = true;
412    }
413
414    @Override
415    public void postCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
416      NamespaceDescriptor ns) throws IOException {
417      postCreateNamespaceCalled = true;
418    }
419
420    public boolean wasCreateNamespaceCalled() {
421      return preCreateNamespaceCalled && postCreateNamespaceCalled;
422    }
423
424    public boolean preCreateNamespaceCalledOnly() {
425      return preCreateNamespaceCalled && !postCreateNamespaceCalled;
426    }
427
428    @Override
429    public void preDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env, String name)
430      throws IOException {
431      preDeleteNamespaceCalled = true;
432    }
433
434    @Override
435    public void postDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> env, String name)
436      throws IOException {
437      postDeleteNamespaceCalled = true;
438    }
439
440    public boolean wasDeleteNamespaceCalled() {
441      return preDeleteNamespaceCalled && postDeleteNamespaceCalled;
442    }
443
444    public boolean preDeleteNamespaceCalledOnly() {
445      return preDeleteNamespaceCalled && !postDeleteNamespaceCalled;
446    }
447
448    @Override
449    public void preModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
450      NamespaceDescriptor ns) throws IOException {
451      preModifyNamespaceCalled = true;
452    }
453
454    @Override
455    public void postModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> env,
456      NamespaceDescriptor ns) throws IOException {
457      postModifyNamespaceCalled = true;
458    }
459
460    public boolean wasModifyNamespaceCalled() {
461      return preModifyNamespaceCalled && postModifyNamespaceCalled;
462    }
463
464    public boolean preModifyNamespaceCalledOnly() {
465      return preModifyNamespaceCalled && !postModifyNamespaceCalled;
466    }
467
468    @Override
469    public void preGetNamespaceDescriptor(ObserverContext<MasterCoprocessorEnvironment> ctx,
470      String namespace) throws IOException {
471      preGetNamespaceDescriptorCalled = true;
472    }
473
474    @Override
475    public void postGetNamespaceDescriptor(ObserverContext<MasterCoprocessorEnvironment> ctx,
476      NamespaceDescriptor ns) throws IOException {
477      postGetNamespaceDescriptorCalled = true;
478    }
479
480    public boolean wasGetNamespaceDescriptorCalled() {
481      return preGetNamespaceDescriptorCalled && postGetNamespaceDescriptorCalled;
482    }
483
484    @Override
485    public void preListNamespaces(ObserverContext<MasterCoprocessorEnvironment> ctx,
486      List<String> namespaces) {
487      preListNamespacesCalled = true;
488    }
489
490    @Override
491    public void postListNamespaces(ObserverContext<MasterCoprocessorEnvironment> ctx,
492      List<String> namespaces) {
493      postListNamespacesCalled = true;
494    }
495
496    @Override
497    public void preListNamespaceDescriptors(ObserverContext<MasterCoprocessorEnvironment> env,
498      List<NamespaceDescriptor> descriptors) throws IOException {
499      preListNamespaceDescriptorsCalled = true;
500    }
501
502    @Override
503    public void postListNamespaceDescriptors(ObserverContext<MasterCoprocessorEnvironment> env,
504      List<NamespaceDescriptor> descriptors) throws IOException {
505      postListNamespaceDescriptorsCalled = true;
506    }
507
508    public boolean wasListNamespaceDescriptorsCalled() {
509      return preListNamespaceDescriptorsCalled && postListNamespaceDescriptorsCalled;
510    }
511
512    public boolean preListNamespaceDescriptorsCalledOnly() {
513      return preListNamespaceDescriptorsCalled && !postListNamespaceDescriptorsCalled;
514    }
515
516    @Override
517    public void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> env,
518      TableName tableName) throws IOException {
519      preEnableTableCalled = true;
520    }
521
522    @Override
523    public void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> env,
524      TableName tableName) throws IOException {
525      postEnableTableCalled = true;
526    }
527
528    public boolean wasEnableTableCalled() {
529      return preEnableTableCalled && postEnableTableCalled;
530    }
531
532    public boolean preEnableTableCalledOnly() {
533      return preEnableTableCalled && !postEnableTableCalled;
534    }
535
536    @Override
537    public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> env,
538      TableName tableName) throws IOException {
539      preDisableTableCalled = true;
540    }
541
542    @Override
543    public void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> env,
544      TableName tableName) throws IOException {
545      postDisableTableCalled = true;
546    }
547
548    public boolean wasDisableTableCalled() {
549      return preDisableTableCalled && postDisableTableCalled;
550    }
551
552    public boolean preDisableTableCalledOnly() {
553      return preDisableTableCalled && !postDisableTableCalled;
554    }
555
556    @Override
557    public void preAbortProcedure(ObserverContext<MasterCoprocessorEnvironment> ctx,
558      final long procId) throws IOException {
559      preAbortProcedureCalled = true;
560    }
561
562    @Override
563    public void postAbortProcedure(ObserverContext<MasterCoprocessorEnvironment> ctx)
564      throws IOException {
565      postAbortProcedureCalled = true;
566    }
567
568    public boolean wasAbortProcedureCalled() {
569      return preAbortProcedureCalled && postAbortProcedureCalled;
570    }
571
572    public boolean wasPreAbortProcedureCalledOnly() {
573      return preAbortProcedureCalled && !postAbortProcedureCalled;
574    }
575
576    @Override
577    public void preGetProcedures(ObserverContext<MasterCoprocessorEnvironment> ctx)
578      throws IOException {
579      preGetProceduresCalled = true;
580    }
581
582    @Override
583    public void postGetProcedures(ObserverContext<MasterCoprocessorEnvironment> ctx)
584      throws IOException {
585      postGetProceduresCalled = true;
586    }
587
588    public boolean wasGetProceduresCalled() {
589      return preGetProceduresCalled && postGetProceduresCalled;
590    }
591
592    public boolean wasPreGetProceduresCalledOnly() {
593      return preGetProceduresCalled && !postGetProceduresCalled;
594    }
595
596    @Override
597    public void preGetLocks(ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
598      preGetLocksCalled = true;
599    }
600
601    @Override
602    public void postGetLocks(ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
603      postGetLocksCalled = true;
604    }
605
606    public boolean wasGetLocksCalled() {
607      return preGetLocksCalled && postGetLocksCalled;
608    }
609
610    public boolean wasPreGetLocksCalledOnly() {
611      return preGetLocksCalled && !postGetLocksCalled;
612    }
613
614    @Override
615    public void preMove(ObserverContext<MasterCoprocessorEnvironment> env, RegionInfo region,
616      ServerName srcServer, ServerName destServer) throws IOException {
617      preMoveCalled = true;
618    }
619
620    @Override
621    public void postMove(ObserverContext<MasterCoprocessorEnvironment> env, RegionInfo region,
622      ServerName srcServer, ServerName destServer) 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, List<RegionPlan> plans) throws IOException {
703      postBalanceCalled = true;
704    }
705
706    public boolean wasBalanceCalled() {
707      return preBalanceCalled && postBalanceCalled;
708    }
709
710    public boolean preBalanceCalledOnly() {
711      return preBalanceCalled && !postBalanceCalled;
712    }
713
714    @Override
715    public void preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env, boolean b)
716      throws IOException {
717      preBalanceSwitchCalled = true;
718    }
719
720    @Override
721    public void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env,
722      boolean oldValue, boolean newValue) throws IOException {
723      postBalanceSwitchCalled = true;
724    }
725
726    public boolean wasBalanceSwitchCalled() {
727      return preBalanceSwitchCalled && postBalanceSwitchCalled;
728    }
729
730    public boolean preBalanceSwitchCalledOnly() {
731      return preBalanceSwitchCalled && !postBalanceSwitchCalled;
732    }
733
734    @Override
735    public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> env) throws IOException {
736      preShutdownCalled = true;
737    }
738
739    public boolean wasShutdownCalled() {
740      return preShutdownCalled;
741    }
742
743    @Override
744    public void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> env)
745      throws IOException {
746      preStopMasterCalled = true;
747    }
748
749    public boolean wasStopMasterCalled() {
750      return preStopMasterCalled;
751    }
752
753    @Override
754    public void preMasterInitialization(ObserverContext<MasterCoprocessorEnvironment> ctx)
755      throws IOException {
756      preMasterInitializationCalled = true;
757    }
758
759    public boolean wasMasterInitializationCalled() {
760      return preMasterInitializationCalled;
761    }
762
763    @Override
764    public void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx)
765      throws IOException {
766      postStartMasterCalled = true;
767    }
768
769    public boolean wasStartMasterCalled() {
770      return postStartMasterCalled;
771    }
772
773    @Override
774    public void start(CoprocessorEnvironment env) throws IOException {
775      startCalled = true;
776    }
777
778    @Override
779    public void stop(CoprocessorEnvironment env) throws IOException {
780      stopCalled = true;
781    }
782
783    public boolean wasStarted() {
784      return startCalled;
785    }
786
787    public boolean wasStopped() {
788      return stopCalled;
789    }
790
791    @Override
792    public void preSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
793      final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
794      throws IOException {
795      preSnapshotCalled = true;
796    }
797
798    @Override
799    public void postSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
800      final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
801      throws IOException {
802      postSnapshotCalled = true;
803    }
804
805    public boolean wasSnapshotCalled() {
806      return preSnapshotCalled && postSnapshotCalled;
807    }
808
809    @Override
810    public void preListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
811      final SnapshotDescription snapshot) throws IOException {
812      preListSnapshotCalled = true;
813    }
814
815    @Override
816    public void postListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
817      final SnapshotDescription snapshot) throws IOException {
818      postListSnapshotCalled = true;
819    }
820
821    public boolean wasListSnapshotCalled() {
822      return preListSnapshotCalled && postListSnapshotCalled;
823    }
824
825    @Override
826    public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
827      final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
828      throws IOException {
829      preCloneSnapshotCalled = true;
830    }
831
832    @Override
833    public void postCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
834      final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
835      throws IOException {
836      postCloneSnapshotCalled = true;
837    }
838
839    public boolean wasCloneSnapshotCalled() {
840      return preCloneSnapshotCalled && postCloneSnapshotCalled;
841    }
842
843    @Override
844    public void preRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
845      final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
846      throws IOException {
847      preRestoreSnapshotCalled = true;
848    }
849
850    @Override
851    public void postRestoreSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
852      final SnapshotDescription snapshot, final TableDescriptor hTableDescriptor)
853      throws IOException {
854      postRestoreSnapshotCalled = true;
855    }
856
857    public boolean wasRestoreSnapshotCalled() {
858      return preRestoreSnapshotCalled && postRestoreSnapshotCalled;
859    }
860
861    @Override
862    public void preDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
863      final SnapshotDescription snapshot) throws IOException {
864      preDeleteSnapshotCalled = true;
865    }
866
867    @Override
868    public void postDeleteSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
869      final SnapshotDescription snapshot) throws IOException {
870      postDeleteSnapshotCalled = true;
871    }
872
873    public boolean wasDeleteSnapshotCalled() {
874      return preDeleteSnapshotCalled && postDeleteSnapshotCalled;
875    }
876
877    @Override
878    public void preCreateTableAction(final ObserverContext<MasterCoprocessorEnvironment> env,
879      final TableDescriptor desc, final RegionInfo[] regions) throws IOException {
880      preCreateTableActionCalled = true;
881    }
882
883    @Override
884    public void postCompletedCreateTableAction(
885      final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableDescriptor desc,
886      final RegionInfo[] regions) throws IOException {
887      postCompletedCreateTableActionCalled = true;
888      tableCreationLatch.countDown();
889    }
890
891    public boolean wasPreCreateTableActionCalled() {
892      return preCreateTableActionCalled;
893    }
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(final ObserverContext<MasterCoprocessorEnvironment> env,
905      final TableName tableName) throws IOException {
906      preDeleteTableActionCalled = true;
907    }
908
909    @Override
910    public void postCompletedDeleteTableAction(
911      final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
912      throws IOException {
913      postCompletedDeleteTableActionCalled = true;
914      tableDeletionLatch.countDown();
915    }
916
917    public boolean wasDeleteTableActionCalled() {
918      return preDeleteTableActionCalled && postCompletedDeleteTableActionCalled;
919    }
920
921    public boolean wasDeleteTableActionCalledOnly() {
922      return preDeleteTableActionCalled && !postCompletedDeleteTableActionCalled;
923    }
924
925    @Override
926    public void preTruncateTableAction(final ObserverContext<MasterCoprocessorEnvironment> env,
927      final TableName tableName) throws IOException {
928      preTruncateTableActionCalled = true;
929    }
930
931    @Override
932    public void postCompletedTruncateTableAction(
933      final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
934      throws IOException {
935      postCompletedTruncateTableActionCalled = true;
936    }
937
938    public boolean wasTruncateTableActionCalled() {
939      return preTruncateTableActionCalled && postCompletedTruncateTableActionCalled;
940    }
941
942    public boolean wasTruncateTableActionCalledOnly() {
943      return preTruncateTableActionCalled && !postCompletedTruncateTableActionCalled;
944    }
945
946    @Override
947    public void preModifyTableAction(final ObserverContext<MasterCoprocessorEnvironment> env,
948      final TableName tableName, final TableDescriptor htd) throws IOException {
949      preModifyTableActionCalled = true;
950    }
951
952    @Override
953    public void postCompletedModifyTableAction(
954      final ObserverContext<MasterCoprocessorEnvironment> env, final TableName tableName,
955      final TableDescriptor htd) throws IOException {
956      postCompletedModifyTableActionCalled = true;
957    }
958
959    public boolean wasModifyTableActionCalled() {
960      return preModifyTableActionCalled && postCompletedModifyTableActionCalled;
961    }
962
963    public boolean wasModifyTableActionCalledOnly() {
964      return preModifyTableActionCalled && !postCompletedModifyTableActionCalled;
965    }
966
967    @Override
968    public void preEnableTableAction(final ObserverContext<MasterCoprocessorEnvironment> ctx,
969      final TableName tableName) throws IOException {
970      preEnableTableActionCalled = true;
971    }
972
973    @Override
974    public void postCompletedEnableTableAction(
975      final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
976      throws IOException {
977      postCompletedEnableTableActionCalled = true;
978    }
979
980    public boolean wasEnableTableActionCalled() {
981      return preEnableTableActionCalled && postCompletedEnableTableActionCalled;
982    }
983
984    public boolean preEnableTableActionCalledOnly() {
985      return preEnableTableActionCalled && !postCompletedEnableTableActionCalled;
986    }
987
988    @Override
989    public void preDisableTableAction(final ObserverContext<MasterCoprocessorEnvironment> ctx,
990      final TableName tableName) throws IOException {
991      preDisableTableActionCalled = true;
992    }
993
994    @Override
995    public void postCompletedDisableTableAction(
996      final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName)
997      throws IOException {
998      postCompletedDisableTableActionCalled = true;
999    }
1000
1001    public boolean wasDisableTableActionCalled() {
1002      return preDisableTableActionCalled && postCompletedDisableTableActionCalled;
1003    }
1004
1005    public boolean preDisableTableActionCalledOnly() {
1006      return preDisableTableActionCalled && !postCompletedDisableTableActionCalled;
1007    }
1008
1009    @Override
1010    public void preGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx,
1011      List<TableName> tableNamesList, List<TableDescriptor> descriptors, String regex)
1012      throws IOException {
1013      preGetTableDescriptorsCalled = true;
1014    }
1015
1016    @Override
1017    public void postGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx,
1018      List<TableName> tableNamesList, List<TableDescriptor> descriptors, String regex)
1019      throws IOException {
1020      postGetTableDescriptorsCalled = true;
1021    }
1022
1023    public boolean wasGetTableDescriptorsCalled() {
1024      return preGetTableDescriptorsCalled && postGetTableDescriptorsCalled;
1025    }
1026
1027    @Override
1028    public void preGetTableNames(ObserverContext<MasterCoprocessorEnvironment> ctx,
1029      List<TableDescriptor> descriptors, String regex) throws IOException {
1030      preGetTableNamesCalled = true;
1031    }
1032
1033    @Override
1034    public void postGetTableNames(ObserverContext<MasterCoprocessorEnvironment> ctx,
1035      List<TableDescriptor> descriptors, String regex) throws IOException {
1036      postGetTableNamesCalled = true;
1037    }
1038
1039    public boolean wasGetTableNamesCalled() {
1040      return preGetTableNamesCalled && postGetTableNamesCalled;
1041    }
1042
1043    @Override
1044    public void preTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx,
1045      TableName tableName) throws IOException {
1046    }
1047
1048    @Override
1049    public void postTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx,
1050      TableName tableName) throws IOException {
1051    }
1052
1053    @Override
1054    public void preMasterStoreFlush(ObserverContext<MasterCoprocessorEnvironment> ctx)
1055      throws IOException {
1056      preMasterStoreFlushCalled = true;
1057    }
1058
1059    @Override
1060    public void postMasterStoreFlush(ObserverContext<MasterCoprocessorEnvironment> ctx)
1061      throws IOException {
1062      postMasterStoreFlushCalled = true;
1063    }
1064
1065    @Override
1066    public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1067      final String userName, final GlobalQuotaSettings quotas) throws IOException {
1068    }
1069
1070    @Override
1071    public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1072      final String userName, final GlobalQuotaSettings quotas) throws IOException {
1073    }
1074
1075    @Override
1076    public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1077      final String userName, final TableName tableName, final GlobalQuotaSettings quotas)
1078      throws IOException {
1079    }
1080
1081    @Override
1082    public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1083      final String userName, final TableName tableName, final GlobalQuotaSettings quotas)
1084      throws IOException {
1085    }
1086
1087    @Override
1088    public void preSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1089      final String userName, final String namespace, final GlobalQuotaSettings quotas)
1090      throws IOException {
1091    }
1092
1093    @Override
1094    public void postSetUserQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1095      final String userName, final String namespace, final GlobalQuotaSettings quotas)
1096      throws IOException {
1097    }
1098
1099    @Override
1100    public void preSetTableQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1101      final TableName tableName, final GlobalQuotaSettings quotas) throws IOException {
1102    }
1103
1104    @Override
1105    public void postSetTableQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1106      final TableName tableName, final GlobalQuotaSettings quotas) throws IOException {
1107    }
1108
1109    @Override
1110    public void preSetNamespaceQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1111      final String namespace, final GlobalQuotaSettings quotas) throws IOException {
1112    }
1113
1114    @Override
1115    public void postSetNamespaceQuota(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1116      final String namespace, final GlobalQuotaSettings quotas) throws IOException {
1117    }
1118
1119    @Override
1120    public void preMoveServersAndTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1121      Set<Address> servers, Set<TableName> tables, String targetGroup) throws IOException {
1122    }
1123
1124    @Override
1125    public void postMoveServersAndTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1126      Set<Address> servers, Set<TableName> tables, String targetGroup) throws IOException {
1127    }
1128
1129    @Override
1130    public void preMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx,
1131      Set<Address> servers, String targetGroup) throws IOException {
1132    }
1133
1134    @Override
1135    public void postMoveServers(ObserverContext<MasterCoprocessorEnvironment> ctx,
1136      Set<Address> servers, String targetGroup) throws IOException {
1137    }
1138
1139    @Override
1140    public void preMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1141      Set<TableName> tables, String targetGroupGroup) throws IOException {
1142    }
1143
1144    @Override
1145    public void postMoveTables(ObserverContext<MasterCoprocessorEnvironment> ctx,
1146      Set<TableName> tables, String targetGroup) throws IOException {
1147    }
1148
1149    @Override
1150    public void preAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
1151      throws IOException {
1152    }
1153
1154    @Override
1155    public void postAddRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
1156      throws IOException {
1157    }
1158
1159    @Override
1160    public void preRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
1161      throws IOException {
1162    }
1163
1164    @Override
1165    public void postRemoveRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
1166      throws IOException {
1167    }
1168
1169    @Override
1170    public void preBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1171      String groupName, BalanceRequest request) throws IOException {
1172    }
1173
1174    @Override
1175    public void postBalanceRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
1176      String groupName, BalanceRequest request, BalanceResponse response) throws IOException {
1177    }
1178
1179    @Override
1180    public void preRequestLock(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace,
1181      TableName tableName, RegionInfo[] regionInfos, String description) throws IOException {
1182      preRequestLockCalled = true;
1183    }
1184
1185    @Override
1186    public void postRequestLock(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace,
1187      TableName tableName, RegionInfo[] regionInfos, String description) throws IOException {
1188      postRequestLockCalled = true;
1189    }
1190
1191    @Override
1192    public void preLockHeartbeat(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tn,
1193      String description) throws IOException {
1194      preLockHeartbeatCalled = true;
1195    }
1196
1197    @Override
1198    public void postLockHeartbeat(ObserverContext<MasterCoprocessorEnvironment> ctx)
1199      throws IOException {
1200      postLockHeartbeatCalled = true;
1201    }
1202
1203    public boolean preAndPostForQueueLockAndHeartbeatLockCalled() {
1204      return preRequestLockCalled && postRequestLockCalled && preLockHeartbeatCalled
1205        && postLockHeartbeatCalled;
1206    }
1207
1208    @Override
1209    public void preSplitRegion(final ObserverContext<MasterCoprocessorEnvironment> c,
1210      final TableName tableName, final byte[] splitRow) throws IOException {
1211    }
1212
1213    @Override
1214    public void preSplitRegionAction(final ObserverContext<MasterCoprocessorEnvironment> c,
1215      final TableName tableName, final byte[] splitRow) throws IOException {
1216    }
1217
1218    @Override
1219    public void postCompletedSplitRegionAction(
1220      final ObserverContext<MasterCoprocessorEnvironment> c, final RegionInfo regionInfoA,
1221      final RegionInfo regionInfoB) throws IOException {
1222    }
1223
1224    @Override
1225    public void preSplitRegionBeforeMETAAction(
1226      final ObserverContext<MasterCoprocessorEnvironment> ctx, final byte[] splitKey,
1227      final List<Mutation> metaEntries) throws IOException {
1228    }
1229
1230    @Override
1231    public void preSplitRegionAfterMETAAction(
1232      final ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
1233    }
1234
1235    @Override
1236    public void postRollBackSplitRegionAction(
1237      final ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
1238    }
1239
1240    @Override
1241    public void preMergeRegionsAction(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1242      final RegionInfo[] regionsToMerge) throws IOException {
1243    }
1244
1245    @Override
1246    public void postCompletedMergeRegionsAction(
1247      final ObserverContext<MasterCoprocessorEnvironment> c, final RegionInfo[] regionsToMerge,
1248      final RegionInfo mergedRegion) throws IOException {
1249    }
1250
1251    @Override
1252    public void preMergeRegionsCommitAction(final ObserverContext<MasterCoprocessorEnvironment> ctx,
1253      final RegionInfo[] regionsToMerge, final List<Mutation> metaEntries) throws IOException {
1254    }
1255
1256    @Override
1257    public void postMergeRegionsCommitAction(
1258      final ObserverContext<MasterCoprocessorEnvironment> ctx, final RegionInfo[] regionsToMerge,
1259      final RegionInfo mergedRegion) throws IOException {
1260    }
1261
1262    @Override
1263    public void postRollBackMergeRegionsAction(
1264      final ObserverContext<MasterCoprocessorEnvironment> ctx, final RegionInfo[] regionsToMerge)
1265      throws IOException {
1266    }
1267
1268    @Override
1269    public void preUpdateMasterConfiguration(ObserverContext<MasterCoprocessorEnvironment> ctx,
1270      Configuration preReloadConf) throws IOException {
1271      preUpdateMasterConfigurationCalled = true;
1272    }
1273
1274    @Override
1275    public void postUpdateMasterConfiguration(ObserverContext<MasterCoprocessorEnvironment> ctx,
1276      Configuration postReloadConf) throws IOException {
1277      postUpdateMasterConfigurationCalled = true;
1278    }
1279  }
1280
1281  private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
1282  private static byte[] TEST_SNAPSHOT = Bytes.toBytes("observed_snapshot");
1283  private static TableName TEST_CLONE = TableName.valueOf("observed_clone");
1284  private static byte[] TEST_FAMILY = Bytes.toBytes("fam1");
1285  private static byte[] TEST_FAMILY2 = Bytes.toBytes("fam2");
1286  @Rule
1287  public TestName name = new TestName();
1288
1289  @BeforeClass
1290  public static void setupBeforeClass() throws Exception {
1291    Configuration conf = UTIL.getConfiguration();
1292    conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, CPMasterObserver.class.getName());
1293    // We need more than one data server on this test
1294    UTIL.startMiniCluster(2);
1295  }
1296
1297  @AfterClass
1298  public static void tearDownAfterClass() throws Exception {
1299    UTIL.shutdownMiniCluster();
1300  }
1301
1302  @Test
1303  public void testStarted() throws Exception {
1304    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1305
1306    HMaster master = cluster.getMaster();
1307    assertTrue("Master should be active", master.isActiveMaster());
1308    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1309    assertNotNull("CoprocessorHost should not be null", host);
1310    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1311    assertNotNull("CPMasterObserver coprocessor not found or not installed!", cp);
1312
1313    // check basic lifecycle
1314    assertTrue("MasterObserver should have been started", cp.wasStarted());
1315    assertTrue("preMasterInitialization() hook should have been called",
1316      cp.wasMasterInitializationCalled());
1317    assertTrue("postStartMaster() hook should have been called", cp.wasStartMasterCalled());
1318  }
1319
1320  @Test
1321  public void testTableOperations() throws Exception {
1322    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1323    final TableName tableName = TableName.valueOf(name.getMethodName());
1324    HMaster master = cluster.getMaster();
1325    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1326    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1327    cp.resetStates();
1328    assertFalse("No table created yet", cp.wasCreateTableCalled());
1329
1330    // create a table
1331    HTableDescriptor htd = new HTableDescriptor(tableName);
1332    htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
1333    try (Connection connection = ConnectionFactory.createConnection(UTIL.getConfiguration());
1334      Admin admin = connection.getAdmin()) {
1335      tableCreationLatch = new CountDownLatch(1);
1336      admin.createTable(htd,
1337        Arrays.copyOfRange(HBaseTestingUtility.KEYS, 1, HBaseTestingUtility.KEYS.length));
1338
1339      assertTrue("Test table should be created", cp.wasCreateTableCalled());
1340      tableCreationLatch.await();
1341      assertTrue("Table pre create handler called.", cp.wasPreCreateTableActionCalled());
1342      assertTrue("Table create handler should be called.", cp.wasCreateTableActionCalled());
1343
1344      RegionLocator regionLocator = connection.getRegionLocator(htd.getTableName());
1345      List<HRegionLocation> regions = regionLocator.getAllRegionLocations();
1346
1347      admin.mergeRegionsAsync(regions.get(0).getRegionInfo().getEncodedNameAsBytes(),
1348        regions.get(1).getRegionInfo().getEncodedNameAsBytes(), true);
1349      assertTrue("Coprocessor should have been called on region merge", cp.wasMergeRegionsCalled());
1350
1351      tableCreationLatch = new CountDownLatch(1);
1352      admin.disableTable(tableName);
1353      assertTrue(admin.isTableDisabled(tableName));
1354      assertTrue("Coprocessor should have been called on table disable",
1355        cp.wasDisableTableCalled());
1356      assertTrue("Disable table handler should be called.", cp.wasDisableTableActionCalled());
1357
1358      // enable
1359      assertFalse(cp.wasEnableTableCalled());
1360      admin.enableTable(tableName);
1361      assertTrue(admin.isTableEnabled(tableName));
1362      assertTrue("Coprocessor should have been called on table enable", cp.wasEnableTableCalled());
1363      assertTrue("Enable table handler should be called.", cp.wasEnableTableActionCalled());
1364
1365      admin.disableTable(tableName);
1366      assertTrue(admin.isTableDisabled(tableName));
1367
1368      // modify table
1369      htd.setMaxFileSize(512 * 1024 * 1024);
1370      modifyTableSync(admin, tableName, htd);
1371      assertTrue("Test table should have been modified", cp.wasModifyTableCalled());
1372
1373      // truncate table
1374      admin.truncateTable(tableName, false);
1375
1376      // delete table
1377      admin.disableTable(tableName);
1378      assertTrue(admin.isTableDisabled(tableName));
1379      deleteTable(admin, tableName);
1380      assertFalse("Test table should have been deleted", admin.tableExists(tableName));
1381      assertTrue("Coprocessor should have been called on table delete", cp.wasDeleteTableCalled());
1382      assertTrue("Delete table handler should be called.", cp.wasDeleteTableActionCalled());
1383
1384      // When bypass was supported, we'd turn off bypass and rerun tests. Leaving rerun in place.
1385      cp.resetStates();
1386
1387      admin.createTable(htd);
1388      assertTrue("Test table should be created", cp.wasCreateTableCalled());
1389      tableCreationLatch.await();
1390      assertTrue("Table pre create handler called.", cp.wasPreCreateTableActionCalled());
1391      assertTrue("Table create handler should be called.", cp.wasCreateTableActionCalled());
1392
1393      // disable
1394      assertFalse(cp.wasDisableTableCalled());
1395      assertFalse(cp.wasDisableTableActionCalled());
1396      admin.disableTable(tableName);
1397      assertTrue(admin.isTableDisabled(tableName));
1398      assertTrue("Coprocessor should have been called on table disable",
1399        cp.wasDisableTableCalled());
1400      assertTrue("Disable table handler should be called.", cp.wasDisableTableActionCalled());
1401
1402      // modify table
1403      htd.setMaxFileSize(512 * 1024 * 1024);
1404      modifyTableSync(admin, tableName, htd);
1405      assertTrue("Test table should have been modified", cp.wasModifyTableCalled());
1406
1407      // enable
1408      assertFalse(cp.wasEnableTableCalled());
1409      assertFalse(cp.wasEnableTableActionCalled());
1410      admin.enableTable(tableName);
1411      assertTrue(admin.isTableEnabled(tableName));
1412      assertTrue("Coprocessor should have been called on table enable", cp.wasEnableTableCalled());
1413      assertTrue("Enable table handler should be called.", cp.wasEnableTableActionCalled());
1414
1415      // disable again
1416      admin.disableTable(tableName);
1417      assertTrue(admin.isTableDisabled(tableName));
1418
1419      // delete table
1420      assertFalse("No table deleted yet", cp.wasDeleteTableCalled());
1421      assertFalse("Delete table handler should not be called.", cp.wasDeleteTableActionCalled());
1422      deleteTable(admin, tableName);
1423      assertFalse("Test table should have been deleted", admin.tableExists(tableName));
1424      assertTrue("Coprocessor should have been called on table delete", cp.wasDeleteTableCalled());
1425      assertTrue("Delete table handler should be called.", cp.wasDeleteTableActionCalled());
1426    }
1427  }
1428
1429  @Test
1430  public void testSnapshotOperations() throws Exception {
1431    final TableName tableName = TableName.valueOf(name.getMethodName());
1432    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1433    HMaster master = cluster.getMaster();
1434    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1435    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1436    cp.resetStates();
1437
1438    // create a table
1439    HTableDescriptor htd = new HTableDescriptor(tableName);
1440    htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
1441    Admin admin = UTIL.getAdmin();
1442
1443    tableCreationLatch = new CountDownLatch(1);
1444    admin.createTable(htd);
1445    tableCreationLatch.await();
1446    tableCreationLatch = new CountDownLatch(1);
1447
1448    admin.disableTable(tableName);
1449    assertTrue(admin.isTableDisabled(tableName));
1450
1451    try {
1452      // Test snapshot operation
1453      assertFalse("Coprocessor should not have been called yet", cp.wasSnapshotCalled());
1454      admin.snapshot(TEST_SNAPSHOT, tableName);
1455      assertTrue("Coprocessor should have been called on snapshot", cp.wasSnapshotCalled());
1456
1457      // Test list operation
1458      admin.listSnapshots();
1459      assertTrue("Coprocessor should have been called on snapshot list",
1460        cp.wasListSnapshotCalled());
1461
1462      // Test clone operation
1463      admin.cloneSnapshot(TEST_SNAPSHOT, TEST_CLONE);
1464      assertTrue("Coprocessor should have been called on snapshot clone",
1465        cp.wasCloneSnapshotCalled());
1466      assertFalse("Coprocessor restore should not have been called on snapshot clone",
1467        cp.wasRestoreSnapshotCalled());
1468      admin.disableTable(TEST_CLONE);
1469      assertTrue(admin.isTableDisabled(tableName));
1470      deleteTable(admin, TEST_CLONE);
1471
1472      // Test restore operation
1473      cp.resetStates();
1474      admin.restoreSnapshot(TEST_SNAPSHOT);
1475      assertTrue("Coprocessor should have been called on snapshot restore",
1476        cp.wasRestoreSnapshotCalled());
1477      assertFalse("Coprocessor clone should not have been called on snapshot restore",
1478        cp.wasCloneSnapshotCalled());
1479
1480      admin.deleteSnapshot(TEST_SNAPSHOT);
1481      assertTrue("Coprocessor should have been called on snapshot delete",
1482        cp.wasDeleteSnapshotCalled());
1483    } finally {
1484      deleteTable(admin, tableName);
1485    }
1486  }
1487
1488  @Test
1489  public void testNamespaceOperations() throws Exception {
1490    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1491    String testNamespace = "observed_ns";
1492    HMaster master = cluster.getMaster();
1493    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1494    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1495
1496    // create a table
1497    Admin admin = UTIL.getAdmin();
1498
1499    admin.listNamespaces();
1500    assertTrue("preListNamespaces should have been called", cp.preListNamespacesCalled);
1501    assertTrue("postListNamespaces should have been called", cp.postListNamespacesCalled);
1502
1503    admin.createNamespace(NamespaceDescriptor.create(testNamespace).build());
1504    assertTrue("Test namespace should be created", cp.wasCreateNamespaceCalled());
1505
1506    assertNotNull(admin.getNamespaceDescriptor(testNamespace));
1507    assertTrue("Test namespace descriptor should have been called",
1508      cp.wasGetNamespaceDescriptorCalled());
1509    // This test used to do a bunch w/ bypass but bypass of these table and namespace stuff has
1510    // been removed so the testing code was removed.
1511  }
1512
1513  private void modifyTableSync(Admin admin, TableName tableName, HTableDescriptor htd)
1514    throws IOException {
1515    admin.modifyTable(tableName, htd);
1516    // wait until modify table finishes
1517    for (int t = 0; t < 100; t++) { // 10 sec timeout
1518      HTableDescriptor td = admin.getTableDescriptor(htd.getTableName());
1519      if (td.equals(htd)) {
1520        break;
1521      }
1522      Threads.sleep(100);
1523    }
1524  }
1525
1526  @Test
1527  public void testRegionTransitionOperations() throws Exception {
1528    final TableName tableName = TableName.valueOf(name.getMethodName());
1529    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1530
1531    HMaster master = cluster.getMaster();
1532    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1533    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1534    cp.resetStates();
1535
1536    Table table = UTIL.createMultiRegionTable(tableName, TEST_FAMILY);
1537
1538    try (RegionLocator r = UTIL.getConnection().getRegionLocator(tableName)) {
1539      UTIL.waitUntilAllRegionsAssigned(tableName);
1540
1541      List<HRegionLocation> regions = r.getAllRegionLocations();
1542      HRegionLocation firstGoodPair = null;
1543      for (HRegionLocation e : regions) {
1544        if (e.getServerName() != null) {
1545          firstGoodPair = e;
1546          break;
1547        }
1548      }
1549      assertNotNull("Found a non-null entry", firstGoodPair);
1550      LOG.info("Found " + firstGoodPair.toString());
1551      // Try to force a move
1552      Collection<ServerName> servers = master.getClusterMetrics().getLiveServerMetrics().keySet();
1553      String destName = null;
1554      String serverNameForFirstRegion = firstGoodPair.getServerName().toString();
1555      LOG.info("serverNameForFirstRegion=" + serverNameForFirstRegion);
1556      ServerName masterServerName = master.getServerName();
1557      boolean found = false;
1558      // Find server that is NOT carrying the first region
1559      for (ServerName info : servers) {
1560        LOG.info("ServerName=" + info);
1561        if (
1562          !serverNameForFirstRegion.equals(info.getServerName()) && !masterServerName.equals(info)
1563        ) {
1564          destName = info.toString();
1565          found = true;
1566          break;
1567        }
1568      }
1569      assertTrue("Found server", found);
1570      LOG.info("Found " + destName);
1571      master.getMasterRpcServices().moveRegion(null, RequestConverter.buildMoveRegionRequest(
1572        firstGoodPair.getRegionInfo().getEncodedNameAsBytes(), ServerName.valueOf(destName)));
1573      assertTrue("Coprocessor should have been called on region move", cp.wasMoveCalled());
1574
1575      // make sure balancer is on
1576      master.balanceSwitch(true);
1577      assertTrue("Coprocessor should have been called on balance switch",
1578        cp.wasBalanceSwitchCalled());
1579
1580      // turn balancer off
1581      master.balanceSwitch(false);
1582
1583      // wait for assignments to finish, if any
1584      UTIL.waitUntilNoRegionsInTransition();
1585
1586      // move half the open regions from RS 0 to RS 1
1587      HRegionServer rs = cluster.getRegionServer(0);
1588      byte[] destRS = Bytes.toBytes(cluster.getRegionServer(1).getServerName().toString());
1589      // Make sure no regions are in transition now
1590      UTIL.waitUntilNoRegionsInTransition();
1591      List<RegionInfo> openRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
1592      int moveCnt = openRegions.size() / 2;
1593      for (int i = 0; i < moveCnt; i++) {
1594        RegionInfo info = openRegions.get(i);
1595        if (!info.isMetaRegion()) {
1596          master.getMasterRpcServices().moveRegion(null,
1597            RequestConverter.buildMoveRegionRequest(openRegions.get(i).getEncodedNameAsBytes(),
1598              ServerName.valueOf(Bytes.toString(destRS))));
1599        }
1600      }
1601      // Make sure no regions are in transition now
1602      UTIL.waitUntilNoRegionsInTransition();
1603      // now trigger a balance
1604      master.balanceSwitch(true);
1605      master.balance();
1606      assertTrue("Coprocessor should be called on region rebalancing", cp.wasBalanceCalled());
1607    } finally {
1608      Admin admin = UTIL.getAdmin();
1609      admin.disableTable(tableName);
1610      deleteTable(admin, tableName);
1611    }
1612  }
1613
1614  @Test
1615  public void testTableDescriptorsEnumeration() throws Exception {
1616    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1617
1618    HMaster master = cluster.getMaster();
1619    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1620    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1621    cp.resetStates();
1622
1623    GetTableDescriptorsRequest req =
1624      RequestConverter.buildGetTableDescriptorsRequest((List<TableName>) null);
1625    master.getMasterRpcServices().getTableDescriptors(null, req);
1626
1627    assertTrue("Coprocessor should be called on table descriptors request",
1628      cp.wasGetTableDescriptorsCalled());
1629  }
1630
1631  @Test
1632  public void testTableNamesEnumeration() throws Exception {
1633    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1634
1635    HMaster master = cluster.getMaster();
1636    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1637    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1638    cp.resetStates();
1639
1640    master.getMasterRpcServices().getTableNames(null, GetTableNamesRequest.newBuilder().build());
1641    assertTrue("Coprocessor should be called on table names request", cp.wasGetTableNamesCalled());
1642  }
1643
1644  @Test
1645  public void testAbortProcedureOperation() throws Exception {
1646    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1647
1648    HMaster master = cluster.getMaster();
1649    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1650    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1651    cp.resetStates();
1652
1653    master.abortProcedure(1, true);
1654    assertTrue("Coprocessor should be called on abort procedure request",
1655      cp.wasAbortProcedureCalled());
1656  }
1657
1658  @Test
1659  public void testGetProceduresOperation() throws Exception {
1660    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1661
1662    HMaster master = cluster.getMaster();
1663    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1664    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1665    cp.resetStates();
1666
1667    master.getProcedures();
1668    assertTrue("Coprocessor should be called on get procedures request",
1669      cp.wasGetProceduresCalled());
1670  }
1671
1672  @Test
1673  public void testGetLocksOperation() throws Exception {
1674    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
1675
1676    HMaster master = cluster.getMaster();
1677    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1678    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1679    cp.resetStates();
1680
1681    master.getLocks();
1682    assertTrue("Coprocessor should be called on get locks request", cp.wasGetLocksCalled());
1683  }
1684
1685  private void deleteTable(Admin admin, TableName tableName) throws Exception {
1686    // NOTE: We need a latch because admin is not sync,
1687    // so the postOp coprocessor method may be called after the admin operation returned.
1688    tableDeletionLatch = new CountDownLatch(1);
1689    admin.deleteTable(tableName);
1690    tableDeletionLatch.await();
1691    tableDeletionLatch = new CountDownLatch(1);
1692  }
1693
1694  @Test
1695  public void testQueueLockAndLockHeartbeatOperations() throws Exception {
1696    HMaster master = UTIL.getMiniHBaseCluster().getMaster();
1697    CPMasterObserver cp = master.getMasterCoprocessorHost().findCoprocessor(CPMasterObserver.class);
1698    cp.resetStates();
1699
1700    final TableName tableName = TableName.valueOf("testLockedTable");
1701    long procId = master.getLockManager().remoteLocks().requestTableLock(tableName,
1702      LockType.EXCLUSIVE, "desc", null);
1703    master.getLockManager().remoteLocks().lockHeartbeat(procId, false);
1704
1705    assertTrue(cp.preAndPostForQueueLockAndHeartbeatLockCalled());
1706
1707    ProcedureTestingUtility.waitNoProcedureRunning(master.getMasterProcedureExecutor());
1708    ProcedureTestingUtility.assertProcNotFailed(master.getMasterProcedureExecutor(), procId);
1709  }
1710
1711  @Test
1712  public void testMasterStoreOperations() throws Exception {
1713    HMaster master = UTIL.getMiniHBaseCluster().getMaster();
1714    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1715    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1716    cp.resetStates();
1717    assertFalse("No master store flush call", cp.preMasterStoreFlushCalled);
1718    assertFalse("No master store flush call", cp.postMasterStoreFlushCalled);
1719
1720    try (Connection connection = ConnectionFactory.createConnection(UTIL.getConfiguration());
1721      Admin admin = connection.getAdmin()) {
1722      admin.flushMasterStore();
1723
1724      assertTrue("Master store flush called", cp.preMasterStoreFlushCalled);
1725      assertTrue("Master store flush called", cp.postMasterStoreFlushCalled);
1726    }
1727  }
1728
1729  @Test
1730  public void testUpdateConfiguration() throws Exception {
1731    HMaster master = UTIL.getMiniHBaseCluster().getMaster();
1732    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
1733    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
1734    cp.resetStates();
1735    assertFalse("No update configuration call", cp.preUpdateMasterConfigurationCalled);
1736    assertFalse("No update configuration call", cp.postUpdateMasterConfigurationCalled);
1737
1738    try (Connection connection = ConnectionFactory.createConnection(UTIL.getConfiguration());
1739      Admin admin = connection.getAdmin()) {
1740      admin.updateConfiguration();
1741
1742      assertTrue("Update configuration called", cp.preUpdateMasterConfigurationCalled);
1743      assertTrue("Update configuration called", cp.postUpdateMasterConfigurationCalled);
1744    }
1745  }
1746}