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.rsgroup;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021import static org.junit.jupiter.api.Assertions.assertFalse;
022import static org.junit.jupiter.api.Assertions.assertTrue;
023
024import java.io.IOException;
025import java.util.ArrayList;
026import java.util.EnumSet;
027import java.util.HashSet;
028import java.util.LinkedList;
029import java.util.List;
030import java.util.Map;
031import java.util.Optional;
032import java.util.Set;
033import java.util.TreeMap;
034import java.util.concurrent.ThreadLocalRandom;
035import java.util.regex.Pattern;
036import org.apache.hadoop.conf.Configuration;
037import org.apache.hadoop.hbase.ClusterMetrics;
038import org.apache.hadoop.hbase.ClusterMetrics.Option;
039import org.apache.hadoop.hbase.HBaseClusterInterface;
040import org.apache.hadoop.hbase.HBaseTestingUtil;
041import org.apache.hadoop.hbase.NamespaceDescriptor;
042import org.apache.hadoop.hbase.ServerName;
043import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
044import org.apache.hadoop.hbase.TableName;
045import org.apache.hadoop.hbase.Waiter;
046import org.apache.hadoop.hbase.client.AbstractTestUpdateConfiguration;
047import org.apache.hadoop.hbase.client.Admin;
048import org.apache.hadoop.hbase.client.BalanceRequest;
049import org.apache.hadoop.hbase.client.BalanceResponse;
050import org.apache.hadoop.hbase.client.RegionInfo;
051import org.apache.hadoop.hbase.client.TableDescriptor;
052import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
053import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor;
054import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
055import org.apache.hadoop.hbase.coprocessor.MasterObserver;
056import org.apache.hadoop.hbase.coprocessor.ObserverContext;
057import org.apache.hadoop.hbase.master.HMaster;
058import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
059import org.apache.hadoop.hbase.master.ServerManager;
060import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
061import org.apache.hadoop.hbase.net.Address;
062import org.apache.hadoop.hbase.quotas.QuotaUtil;
063import org.junit.jupiter.api.TestInfo;
064import org.slf4j.Logger;
065import org.slf4j.LoggerFactory;
066
067import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
068import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
069
070public abstract class TestRSGroupsBase extends AbstractTestUpdateConfiguration {
071  protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsBase.class);
072
073  // shared
074  protected static final String GROUP_PREFIX = "Group";
075  protected static final String TABLE_PREFIX = "Group";
076
077  // shared, cluster type specific
078  protected static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
079  protected static Admin ADMIN;
080  protected static HBaseClusterInterface CLUSTER;
081  protected static HMaster MASTER;
082  protected boolean INIT = false;
083  protected static CPMasterObserver OBSERVER;
084
085  public final static long WAIT_TIMEOUT = 60000;
086  public final static int NUM_SLAVES_BASE = 4; // number of slaves for the smallest cluster
087  public static int NUM_DEAD_SERVERS = 0;
088
089  protected static final class MethodName {
090    private String methodName;
091
092    public String getMethodName() {
093      return methodName;
094    }
095
096    void setMethodName(String methodName) {
097      this.methodName = methodName;
098    }
099  }
100
101  // Per test variables
102  protected final MethodName name = new MethodName();
103  protected TableName tableName;
104
105  public static String getNameWithoutIndex(String name) {
106    return name.split("\\[")[0];
107  }
108
109  public static void setUpTestBeforeClass() throws Exception {
110    Configuration conf = TEST_UTIL.getConfiguration();
111    conf.setFloat("hbase.master.balancer.stochastic.tableSkewCost", 6000);
112    if (conf.get(RSGroupUtil.RS_GROUP_ENABLED) == null) {
113      RSGroupUtil.enableRSGroup(conf);
114    }
115    if (conf.get(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) != null) {
116      conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
117        conf.get(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) + ","
118          + CPMasterObserver.class.getName());
119    } else {
120      conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, CPMasterObserver.class.getName());
121    }
122
123    conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, NUM_SLAVES_BASE);
124    conf.setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
125    conf.setInt("hbase.rpc.timeout", 100000);
126
127    TEST_UTIL.startMiniCluster(NUM_SLAVES_BASE);
128    initialize();
129  }
130
131  protected static void initialize() throws Exception {
132    ADMIN = new VerifyingRSGroupAdmin(TEST_UTIL.getConfiguration());
133    CLUSTER = TEST_UTIL.getHBaseCluster();
134    MASTER = TEST_UTIL.getMiniHBaseCluster().getMaster();
135
136    // wait for balancer to come online
137    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
138      @Override
139      public boolean evaluate() throws Exception {
140        return MASTER.isInitialized()
141          && ((RSGroupBasedLoadBalancer) MASTER.getLoadBalancer()).isOnline();
142      }
143    });
144    ADMIN.balancerSwitch(false, true);
145    MasterCoprocessorHost host = MASTER.getMasterCoprocessorHost();
146    OBSERVER = (CPMasterObserver) host.findCoprocessor(CPMasterObserver.class.getName());
147  }
148
149  public static void tearDownAfterClass() throws Exception {
150    TEST_UTIL.shutdownMiniCluster();
151  }
152
153  public void setUpBeforeMethod(TestInfo testInfo) throws Exception {
154    name.setMethodName(testInfo.getTestMethod().get().getName());
155    LOG.info(name.getMethodName());
156    tableName = TableName.valueOf(TABLE_PREFIX + "_" + name.getMethodName().split("\\[")[0]);
157    if (!INIT) {
158      INIT = true;
159      tearDownAfterMethod();
160    }
161    OBSERVER.resetFlags();
162  }
163
164  public void tearDownAfterMethod() throws Exception {
165    deleteTableIfNecessary();
166    deleteNamespaceIfNecessary();
167    deleteGroups();
168
169    for (ServerName sn : ADMIN.listDecommissionedRegionServers()) {
170      ADMIN.recommissionRegionServer(sn, null);
171    }
172    assertTrue(ADMIN.listDecommissionedRegionServers().isEmpty());
173
174    int missing = NUM_SLAVES_BASE - getNumServers();
175    LOG.info("Restoring servers: " + missing);
176    for (int i = 0; i < missing; i++) {
177      ((SingleProcessHBaseCluster) CLUSTER).startRegionServer();
178    }
179    ADMIN.addRSGroup("master");
180    ServerName masterServerName = ((SingleProcessHBaseCluster) CLUSTER).getMaster().getServerName();
181    try {
182      ADMIN.moveServersToRSGroup(Sets.newHashSet(masterServerName.getAddress()), "master");
183    } catch (Exception ex) {
184      LOG.warn("Got this on setup, FYI", ex);
185    }
186    assertTrue(OBSERVER.preMoveServersCalled);
187    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
188      @Override
189      public boolean evaluate() throws Exception {
190        LOG.info("Waiting for cleanup to finish " + ADMIN.listRSGroups());
191        // Might be greater since moving servers back to default
192        // is after starting a server
193
194        return ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size() == NUM_SLAVES_BASE;
195      }
196    });
197  }
198
199  protected final RSGroupInfo addGroup(String groupName, int serverCount)
200    throws IOException, InterruptedException {
201    RSGroupInfo defaultInfo = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
202    ADMIN.addRSGroup(groupName);
203    Set<Address> set = new HashSet<>();
204    for (Address server : defaultInfo.getServers()) {
205      if (set.size() == serverCount) {
206        break;
207      }
208      set.add(server);
209    }
210    ADMIN.moveServersToRSGroup(set, groupName);
211    RSGroupInfo result = ADMIN.getRSGroup(groupName);
212    assertEquals(set, result.getServers());
213    Set<Address> remainingDefaultServers = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers();
214    for (Address server : set) {
215      assertFalse(remainingDefaultServers.contains(server));
216    }
217    return result;
218  }
219
220  protected final void removeGroup(String groupName) throws IOException {
221    Set<TableName> tables = new HashSet<>();
222    for (TableDescriptor td : ADMIN.listTableDescriptors(true)) {
223      RSGroupInfo groupInfo = ADMIN.getRSGroup(td.getTableName());
224      if (groupInfo != null && groupInfo.getName().equals(groupName)) {
225        tables.add(td.getTableName());
226      }
227    }
228    ADMIN.setRSGroup(tables, RSGroupInfo.DEFAULT_GROUP);
229    for (NamespaceDescriptor nd : ADMIN.listNamespaceDescriptors()) {
230      if (groupName.equals(nd.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP))) {
231        nd.removeConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP);
232        ADMIN.modifyNamespace(nd);
233      }
234    }
235    RSGroupInfo groupInfo = ADMIN.getRSGroup(groupName);
236    Set<Address> servers = groupInfo.getServers();
237    ADMIN.moveServersToRSGroup(servers, RSGroupInfo.DEFAULT_GROUP);
238    ADMIN.removeRSGroup(groupName);
239    assertFalse(ADMIN.listRSGroups().stream().anyMatch(g -> g.getName().equals(groupName)));
240    Set<Address> onlineServers = new HashSet<>();
241    for (ServerName sn : MASTER.getServerManager().getOnlineServersList()) {
242      onlineServers.add(sn.getAddress());
243    }
244    RSGroupInfo defaultInfo = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
245    for (Address server : servers) {
246      // moveServersToRSGroup()-to-'default' silently drops servers that are no longer online
247      // (see RSGroupInfoManagerImpl#moveServers), so only online servers are guaranteed to land
248      // in 'default'; an offline server's former group membership is simply dropped.
249      if (onlineServers.contains(server)) {
250        assertTrue(defaultInfo.getServers().contains(server));
251      }
252    }
253    for (TableName table : tables) {
254      // ADMIN.getRSGroup(String)/listRSGroups() do not resolve table membership from the
255      // TableDescriptor's RegionServerGroup attribute (only ADMIN.getRSGroup(TableName) does),
256      // so look up each table's group individually rather than via defaultInfo.getTables().
257      assertEquals(RSGroupInfo.DEFAULT_GROUP, ADMIN.getRSGroup(table).getName());
258    }
259  }
260
261  protected final void deleteTableIfNecessary() throws IOException {
262    for (TableDescriptor desc : TEST_UTIL.getAdmin()
263      .listTableDescriptors(Pattern.compile(TABLE_PREFIX + ".*"))) {
264      TEST_UTIL.deleteTable(desc.getTableName());
265    }
266  }
267
268  protected final void deleteNamespaceIfNecessary() throws IOException {
269    for (NamespaceDescriptor desc : TEST_UTIL.getAdmin().listNamespaceDescriptors()) {
270      if (desc.getName().startsWith(TABLE_PREFIX)) {
271        ADMIN.deleteNamespace(desc.getName());
272      }
273    }
274  }
275
276  protected final void deleteGroups() throws IOException {
277    for (RSGroupInfo groupInfo : ADMIN.listRSGroups()) {
278      if (!groupInfo.getName().equals(RSGroupInfo.DEFAULT_GROUP)) {
279        removeGroup(groupInfo.getName());
280      }
281    }
282  }
283
284  protected Map<TableName, List<String>> getTableRegionMap() throws IOException {
285    Map<TableName, List<String>> map = Maps.newTreeMap();
286    Map<TableName, Map<ServerName, List<String>>> tableServerRegionMap = getTableServerRegionMap();
287    for (TableName tableName : tableServerRegionMap.keySet()) {
288      if (!map.containsKey(tableName)) {
289        map.put(tableName, new LinkedList<>());
290      }
291      for (List<String> subset : tableServerRegionMap.get(tableName).values()) {
292        map.get(tableName).addAll(subset);
293      }
294    }
295    return map;
296  }
297
298  protected Map<TableName, Map<ServerName, List<String>>> getTableServerRegionMap()
299    throws IOException {
300    Map<TableName, Map<ServerName, List<String>>> map = Maps.newTreeMap();
301    Admin admin = TEST_UTIL.getAdmin();
302    ClusterMetrics metrics =
303      admin.getClusterMetrics(EnumSet.of(ClusterMetrics.Option.SERVERS_NAME));
304    for (ServerName serverName : metrics.getServersName()) {
305      for (RegionInfo region : admin.getRegions(serverName)) {
306        TableName tableName = region.getTable();
307        map.computeIfAbsent(tableName, k -> new TreeMap<>())
308          .computeIfAbsent(serverName, k -> new ArrayList<>()).add(region.getRegionNameAsString());
309      }
310    }
311    return map;
312  }
313
314  // return the real number of region servers, excluding the master embedded region server in 2.0+
315  protected int getNumServers() throws IOException {
316    ClusterMetrics status = ADMIN.getClusterMetrics(EnumSet.of(Option.MASTER, Option.LIVE_SERVERS));
317    ServerName masterName = status.getMasterName();
318    int count = 0;
319    for (ServerName sn : status.getLiveServerMetrics().keySet()) {
320      if (!sn.equals(masterName)) {
321        count++;
322      }
323    }
324    return count;
325  }
326
327  protected final String getGroupName(String baseName) {
328    return GROUP_PREFIX + "_" + getNameWithoutIndex(baseName) + "_"
329      + ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
330  }
331
332  /**
333   * The server name in group does not contain the start code, this method will find out the start
334   * code and construct the ServerName object.
335   */
336  protected final ServerName getServerName(Address addr) {
337    return TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads().stream()
338      .map(t -> t.getRegionServer().getServerName()).filter(sn -> sn.getAddress().equals(addr))
339      .findFirst().get();
340  }
341
342  protected final void toggleQuotaCheckAndRestartMiniCluster(boolean enable) throws Exception {
343    TEST_UTIL.shutdownMiniCluster();
344    TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, enable);
345    TEST_UTIL.startMiniCluster(NUM_SLAVES_BASE);
346    TEST_UTIL.getConfiguration().setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART,
347      NUM_SLAVES_BASE);
348    TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
349    initialize();
350  }
351
352  public static class CPMasterObserver implements MasterCoprocessor, MasterObserver {
353    boolean preBalanceRSGroupCalled = false;
354    boolean postBalanceRSGroupCalled = false;
355    boolean preMoveServersCalled = false;
356    boolean postMoveServersCalled = false;
357    boolean preMoveTablesCalled = false;
358    boolean postMoveTablesCalled = false;
359    boolean preAddRSGroupCalled = false;
360    boolean postAddRSGroupCalled = false;
361    boolean preRemoveRSGroupCalled = false;
362    boolean postRemoveRSGroupCalled = false;
363    boolean preRemoveServersCalled = false;
364    boolean postRemoveServersCalled = false;
365    boolean preMoveServersAndTables = false;
366    boolean postMoveServersAndTables = false;
367    boolean preGetRSGroupInfoCalled = false;
368    boolean postGetRSGroupInfoCalled = false;
369    boolean preGetRSGroupInfoOfTableCalled = false;
370    boolean postGetRSGroupInfoOfTableCalled = false;
371    boolean preListRSGroupsCalled = false;
372    boolean postListRSGroupsCalled = false;
373    boolean preGetRSGroupInfoOfServerCalled = false;
374    boolean postGetRSGroupInfoOfServerCalled = false;
375    boolean preSetRSGroupForTablesCalled = false;
376    boolean postSetRSGroupForTablesCalled = false;
377    boolean preListTablesInRSGroupCalled = false;
378    boolean postListTablesInRSGroupCalled = false;
379    boolean preGetConfiguredNamespacesAndTablesInRSGroupCalled = false;
380    boolean postGetConfiguredNamespacesAndTablesInRSGroupCalled = false;
381    boolean preRenameRSGroup = false;
382    boolean postRenameRSGroup = false;
383    boolean preUpdateRSGroupConfig = false;
384    boolean postUpdateRSGroupConfig = false;
385
386    public void resetFlags() {
387      preBalanceRSGroupCalled = false;
388      postBalanceRSGroupCalled = false;
389      preMoveServersCalled = false;
390      postMoveServersCalled = false;
391      preMoveTablesCalled = false;
392      postMoveTablesCalled = false;
393      preAddRSGroupCalled = false;
394      postAddRSGroupCalled = false;
395      preRemoveRSGroupCalled = false;
396      postRemoveRSGroupCalled = false;
397      preRemoveServersCalled = false;
398      postRemoveServersCalled = false;
399      preMoveServersAndTables = false;
400      postMoveServersAndTables = false;
401      preGetRSGroupInfoCalled = false;
402      postGetRSGroupInfoCalled = false;
403      preGetRSGroupInfoOfTableCalled = false;
404      postGetRSGroupInfoOfTableCalled = false;
405      preListRSGroupsCalled = false;
406      postListRSGroupsCalled = false;
407      preGetRSGroupInfoOfServerCalled = false;
408      postGetRSGroupInfoOfServerCalled = false;
409      preSetRSGroupForTablesCalled = false;
410      postSetRSGroupForTablesCalled = false;
411      preListTablesInRSGroupCalled = false;
412      postListTablesInRSGroupCalled = false;
413      preGetConfiguredNamespacesAndTablesInRSGroupCalled = false;
414      postGetConfiguredNamespacesAndTablesInRSGroupCalled = false;
415      preRenameRSGroup = false;
416      postRenameRSGroup = false;
417      preUpdateRSGroupConfig = false;
418      postUpdateRSGroupConfig = false;
419    }
420
421    @Override
422    public Optional<MasterObserver> getMasterObserver() {
423      return Optional.of(this);
424    }
425
426    @Override
427    public void preMoveServersAndTables(final ObserverContext<MasterCoprocessorEnvironment> ctx,
428      Set<Address> servers, Set<TableName> tables, String targetGroup) throws IOException {
429      preMoveServersAndTables = true;
430    }
431
432    @Override
433    public void postMoveServersAndTables(final ObserverContext<MasterCoprocessorEnvironment> ctx,
434      Set<Address> servers, Set<TableName> tables, String targetGroup) throws IOException {
435      postMoveServersAndTables = true;
436    }
437
438    @Override
439    public void preRemoveServers(final ObserverContext<MasterCoprocessorEnvironment> ctx,
440      Set<Address> servers) throws IOException {
441      preRemoveServersCalled = true;
442    }
443
444    @Override
445    public void postRemoveServers(final ObserverContext<MasterCoprocessorEnvironment> ctx,
446      Set<Address> servers) throws IOException {
447      postRemoveServersCalled = true;
448    }
449
450    @Override
451    public void preRemoveRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx,
452      String name) throws IOException {
453      preRemoveRSGroupCalled = true;
454    }
455
456    @Override
457    public void postRemoveRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx,
458      String name) throws IOException {
459      postRemoveRSGroupCalled = true;
460    }
461
462    @Override
463    public void preAddRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
464      throws IOException {
465      preAddRSGroupCalled = true;
466    }
467
468    @Override
469    public void postAddRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
470      throws IOException {
471      postAddRSGroupCalled = true;
472    }
473
474    @Override
475    public void preMoveTables(final ObserverContext<MasterCoprocessorEnvironment> ctx,
476      Set<TableName> tables, String targetGroup) throws IOException {
477      preMoveTablesCalled = true;
478    }
479
480    @Override
481    public void postMoveTables(final ObserverContext<MasterCoprocessorEnvironment> ctx,
482      Set<TableName> tables, String targetGroup) throws IOException {
483      postMoveTablesCalled = true;
484    }
485
486    @Override
487    public void preMoveServers(final ObserverContext<MasterCoprocessorEnvironment> ctx,
488      Set<Address> servers, String targetGroup) throws IOException {
489      preMoveServersCalled = true;
490    }
491
492    @Override
493    public void postMoveServers(final ObserverContext<MasterCoprocessorEnvironment> ctx,
494      Set<Address> servers, String targetGroup) throws IOException {
495      postMoveServersCalled = true;
496    }
497
498    @Override
499    public void preBalanceRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx,
500      String groupName, BalanceRequest request) throws IOException {
501      preBalanceRSGroupCalled = true;
502    }
503
504    @Override
505    public void postBalanceRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx,
506      String groupName, BalanceRequest request, BalanceResponse response) throws IOException {
507      postBalanceRSGroupCalled = true;
508    }
509
510    @Override
511    public void preGetRSGroupInfo(final ObserverContext<MasterCoprocessorEnvironment> ctx,
512      final String groupName) throws IOException {
513      preGetRSGroupInfoCalled = true;
514    }
515
516    @Override
517    public void postGetRSGroupInfo(final ObserverContext<MasterCoprocessorEnvironment> ctx,
518      final String groupName) throws IOException {
519      postGetRSGroupInfoCalled = true;
520    }
521
522    @Override
523    public void preGetRSGroupInfoOfTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
524      final TableName tableName) throws IOException {
525      preGetRSGroupInfoOfTableCalled = true;
526    }
527
528    @Override
529    public void postGetRSGroupInfoOfTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
530      final TableName tableName) throws IOException {
531      postGetRSGroupInfoOfTableCalled = true;
532    }
533
534    @Override
535    public void preListRSGroups(final ObserverContext<MasterCoprocessorEnvironment> ctx)
536      throws IOException {
537      preListRSGroupsCalled = true;
538    }
539
540    @Override
541    public void postListRSGroups(final ObserverContext<MasterCoprocessorEnvironment> ctx)
542      throws IOException {
543      postListRSGroupsCalled = true;
544    }
545
546    @Override
547    public void preGetRSGroupInfoOfServer(final ObserverContext<MasterCoprocessorEnvironment> ctx,
548      final Address server) throws IOException {
549      preGetRSGroupInfoOfServerCalled = true;
550    }
551
552    @Override
553    public void postGetRSGroupInfoOfServer(final ObserverContext<MasterCoprocessorEnvironment> ctx,
554      final Address server) throws IOException {
555      postGetRSGroupInfoOfServerCalled = true;
556    }
557
558    @Override
559    public void preListTablesInRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
560      String groupName) throws IOException {
561      preListTablesInRSGroupCalled = true;
562    }
563
564    @Override
565    public void postListTablesInRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx,
566      String groupName) throws IOException {
567      postListTablesInRSGroupCalled = true;
568    }
569
570    @Override
571    public void preGetConfiguredNamespacesAndTablesInRSGroup(
572      ObserverContext<MasterCoprocessorEnvironment> ctx, String groupName) throws IOException {
573      preGetConfiguredNamespacesAndTablesInRSGroupCalled = true;
574    }
575
576    @Override
577    public void postGetConfiguredNamespacesAndTablesInRSGroup(
578      ObserverContext<MasterCoprocessorEnvironment> ctx, String groupName) throws IOException {
579      postGetConfiguredNamespacesAndTablesInRSGroupCalled = true;
580    }
581
582    @Override
583    public void preRenameRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String oldName,
584      String newName) throws IOException {
585      preRenameRSGroup = true;
586    }
587
588    @Override
589    public void postRenameRSGroup(ObserverContext<MasterCoprocessorEnvironment> ctx, String oldName,
590      String newName) throws IOException {
591      postRenameRSGroup = true;
592    }
593
594    @Override
595    public void preUpdateRSGroupConfig(final ObserverContext<MasterCoprocessorEnvironment> ctx,
596      final String groupName, final Map<String, String> configuration) throws IOException {
597      preUpdateRSGroupConfig = true;
598    }
599
600    @Override
601    public void postUpdateRSGroupConfig(final ObserverContext<MasterCoprocessorEnvironment> ctx,
602      final String groupName, final Map<String, String> configuration) throws IOException {
603      postUpdateRSGroupConfig = true;
604    }
605  }
606}