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 */
018
019package org.apache.hadoop.hbase.master;
020
021import java.io.IOException;
022import java.lang.reflect.InvocationTargetException;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026import org.apache.hadoop.conf.Configuration;
027import org.apache.hadoop.hbase.ClusterMetrics;
028import org.apache.hadoop.hbase.MetaMutationAnnotation;
029import org.apache.hadoop.hbase.NamespaceDescriptor;
030import org.apache.hadoop.hbase.ServerName;
031import org.apache.hadoop.hbase.TableName;
032import org.apache.hadoop.hbase.client.Connection;
033import org.apache.hadoop.hbase.client.MasterSwitchType;
034import org.apache.hadoop.hbase.client.Mutation;
035import org.apache.hadoop.hbase.client.RegionInfo;
036import org.apache.hadoop.hbase.client.SharedConnection;
037import org.apache.hadoop.hbase.client.SnapshotDescription;
038import org.apache.hadoop.hbase.client.TableDescriptor;
039import org.apache.hadoop.hbase.coprocessor.BaseEnvironment;
040import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
041import org.apache.hadoop.hbase.coprocessor.CoreCoprocessor;
042import org.apache.hadoop.hbase.coprocessor.HasMasterServices;
043import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor;
044import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
045import org.apache.hadoop.hbase.coprocessor.MasterObserver;
046import org.apache.hadoop.hbase.coprocessor.MetricsCoprocessor;
047import org.apache.hadoop.hbase.master.locking.LockProcedure;
048import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
049import org.apache.hadoop.hbase.metrics.MetricRegistry;
050import org.apache.hadoop.hbase.net.Address;
051import org.apache.hadoop.hbase.procedure2.LockType;
052import org.apache.hadoop.hbase.procedure2.LockedResource;
053import org.apache.hadoop.hbase.procedure2.Procedure;
054import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
055import org.apache.hadoop.hbase.quotas.GlobalQuotaSettings;
056import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
057import org.apache.hadoop.hbase.replication.SyncReplicationState;
058import org.apache.hadoop.hbase.security.User;
059import org.apache.hadoop.hbase.security.access.Permission;
060import org.apache.hadoop.hbase.security.access.UserPermission;
061import org.apache.yetus.audience.InterfaceAudience;
062import org.slf4j.Logger;
063import org.slf4j.LoggerFactory;
064
065import org.apache.hbase.thirdparty.com.google.protobuf.Service;
066
067/**
068 * Provides the coprocessor framework and environment for master oriented
069 * operations.  {@link HMaster} interacts with the loaded coprocessors
070 * through this class.
071 */
072@InterfaceAudience.Private
073public class MasterCoprocessorHost
074    extends CoprocessorHost<MasterCoprocessor, MasterCoprocessorEnvironment> {
075
076  private static final Logger LOG = LoggerFactory.getLogger(MasterCoprocessorHost.class);
077
078  /**
079   * Coprocessor environment extension providing access to master related
080   * services.
081   */
082  private static class MasterEnvironment extends BaseEnvironment<MasterCoprocessor>
083      implements MasterCoprocessorEnvironment {
084    private final MetricRegistry metricRegistry;
085    private final MasterServices services;
086
087    public MasterEnvironment(final MasterCoprocessor impl, final int priority, final int seq,
088        final Configuration conf, final MasterServices services) {
089      super(impl, priority, seq, conf);
090      this.services = services;
091      this.metricRegistry =
092          MetricsCoprocessor.createRegistryForMasterCoprocessor(impl.getClass().getName());
093    }
094
095    @Override
096    public ServerName getServerName() {
097      return this.services.getServerName();
098    }
099
100    @Override
101    public Connection getConnection() {
102      return new SharedConnection(this.services.getConnection());
103    }
104
105    @Override
106    public Connection createConnection(Configuration conf) throws IOException {
107      return this.services.createConnection(conf);
108    }
109
110    @Override
111    public MetricRegistry getMetricRegistryForMaster() {
112      return metricRegistry;
113    }
114
115    @Override
116    public void shutdown() {
117      super.shutdown();
118      MetricsCoprocessor.removeRegistry(this.metricRegistry);
119    }
120  }
121
122  /**
123   * Special version of MasterEnvironment that exposes MasterServices for Core Coprocessors only.
124   * Temporary hack until Core Coprocessors are integrated into Core.
125   */
126  private static class MasterEnvironmentForCoreCoprocessors extends MasterEnvironment
127      implements HasMasterServices {
128    private final MasterServices masterServices;
129
130    public MasterEnvironmentForCoreCoprocessors(final MasterCoprocessor impl, final int priority,
131        final int seq, final Configuration conf, final MasterServices services) {
132      super(impl, priority, seq, conf, services);
133      this.masterServices = services;
134    }
135
136    /**
137     * @return An instance of MasterServices, an object NOT for general user-space Coprocessor
138     * consumption.
139     */
140    @Override
141    public MasterServices getMasterServices() {
142      return this.masterServices;
143    }
144  }
145
146  private MasterServices masterServices;
147
148  public MasterCoprocessorHost(final MasterServices services, final Configuration conf) {
149    super(services);
150    this.conf = conf;
151    this.masterServices = services;
152    // Log the state of coprocessor loading here; should appear only once or
153    // twice in the daemon log, depending on HBase version, because there is
154    // only one MasterCoprocessorHost instance in the master process
155    boolean coprocessorsEnabled = conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY,
156      DEFAULT_COPROCESSORS_ENABLED);
157    LOG.trace("System coprocessor loading is {}",  (coprocessorsEnabled ? "enabled" : "disabled"));
158    loadSystemCoprocessors(conf, MASTER_COPROCESSOR_CONF_KEY);
159  }
160
161  @Override
162  public MasterEnvironment createEnvironment(final MasterCoprocessor instance, final int priority,
163      final int seq, final Configuration conf) {
164    // If coprocessor exposes any services, register them.
165    for (Service service : instance.getServices()) {
166      masterServices.registerService(service);
167    }
168    // If a CoreCoprocessor, return a 'richer' environment, one laden with MasterServices.
169    return instance.getClass().isAnnotationPresent(CoreCoprocessor.class)?
170        new MasterEnvironmentForCoreCoprocessors(instance, priority, seq, conf, masterServices):
171        new MasterEnvironment(instance, priority, seq, conf, masterServices);
172  }
173
174  @Override
175  public MasterCoprocessor checkAndGetInstance(Class<?> implClass)
176      throws InstantiationException, IllegalAccessException {
177    try {
178      if (MasterCoprocessor.class.isAssignableFrom(implClass)) {
179        return implClass.asSubclass(MasterCoprocessor.class).getDeclaredConstructor().newInstance();
180      } else {
181        LOG.error("{} is not of type MasterCoprocessor. Check the configuration of {}",
182            implClass.getName(), CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY);
183        return null;
184      }
185    } catch (NoSuchMethodException | InvocationTargetException e) {
186      throw (InstantiationException) new InstantiationException(implClass.getName()).initCause(e);
187    }
188  }
189
190  private ObserverGetter<MasterCoprocessor, MasterObserver> masterObserverGetter =
191      MasterCoprocessor::getMasterObserver;
192
193  abstract class MasterObserverOperation extends
194      ObserverOperationWithoutResult<MasterObserver> {
195    public MasterObserverOperation(){
196      super(masterObserverGetter);
197    }
198
199    public MasterObserverOperation(boolean bypassable) {
200      this(null, bypassable);
201    }
202
203    public MasterObserverOperation(User user) {
204      super(masterObserverGetter, user);
205    }
206
207    public MasterObserverOperation(User user, boolean bypassable) {
208      super(masterObserverGetter, user, bypassable);
209    }
210  }
211
212
213  //////////////////////////////////////////////////////////////////////////////////////////////////
214  // MasterObserver operations
215  //////////////////////////////////////////////////////////////////////////////////////////////////
216
217
218  public void preCreateNamespace(final NamespaceDescriptor ns) throws IOException {
219    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
220      @Override
221      public void call(MasterObserver observer) throws IOException {
222        observer.preCreateNamespace(this, ns);
223      }
224    });
225  }
226
227  public void postCreateNamespace(final NamespaceDescriptor ns) throws IOException {
228    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
229      @Override
230      public void call(MasterObserver observer) throws IOException {
231        observer.postCreateNamespace(this, ns);
232      }
233    });
234  }
235
236  public void preDeleteNamespace(final String namespaceName) throws IOException {
237    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
238      @Override
239      public void call(MasterObserver observer) throws IOException {
240        observer.preDeleteNamespace(this, namespaceName);
241      }
242    });
243  }
244
245  public void postDeleteNamespace(final String namespaceName) throws IOException {
246    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
247      @Override
248      public void call(MasterObserver observer) throws IOException {
249        observer.postDeleteNamespace(this, namespaceName);
250      }
251    });
252  }
253
254  public void preModifyNamespace(final NamespaceDescriptor currentNsDescriptor,
255    final NamespaceDescriptor newNsDescriptor) throws IOException {
256    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
257      @Override
258      public void call(MasterObserver observer) throws IOException {
259        observer.preModifyNamespace(this, currentNsDescriptor, newNsDescriptor);
260      }
261    });
262  }
263
264  public void postModifyNamespace(final NamespaceDescriptor oldNsDescriptor,
265    final NamespaceDescriptor currentNsDescriptor) throws IOException {
266    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
267      @Override
268      public void call(MasterObserver observer) throws IOException {
269        observer.postModifyNamespace(this, oldNsDescriptor, currentNsDescriptor);
270      }
271    });
272  }
273
274  public void preGetNamespaceDescriptor(final String namespaceName)
275      throws IOException {
276    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
277      @Override
278      public void call(MasterObserver observer) throws IOException {
279        observer.preGetNamespaceDescriptor(this, namespaceName);
280      }
281    });
282  }
283
284  public void postGetNamespaceDescriptor(final NamespaceDescriptor ns)
285      throws IOException {
286    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
287      @Override
288      public void call(MasterObserver observer) throws IOException {
289        observer.postGetNamespaceDescriptor(this, ns);
290      }
291    });
292  }
293
294  public void preListNamespaces(final List<String> namespaces) throws IOException {
295    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
296      @Override
297      public void call(MasterObserver oserver) throws IOException {
298        oserver.preListNamespaces(this, namespaces);
299      }
300    });
301  }
302
303  public void postListNamespaces(final List<String> namespaces) throws IOException {
304    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
305      @Override
306      public void call(MasterObserver oserver) throws IOException {
307        oserver.postListNamespaces(this, namespaces);
308      }
309    });
310  }
311
312  public void preListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors)
313      throws IOException {
314    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
315      @Override
316      public void call(MasterObserver observer) throws IOException {
317        observer.preListNamespaceDescriptors(this, descriptors);
318      }
319    });
320  }
321
322  public void postListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors)
323      throws IOException {
324    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
325      @Override
326      public void call(MasterObserver observer) throws IOException {
327        observer.postListNamespaceDescriptors(this, descriptors);
328      }
329    });
330  }
331
332  /* Implementation of hooks for invoking MasterObservers */
333
334  public TableDescriptor preCreateTableRegionsInfos(TableDescriptor desc) throws IOException {
335    if (coprocEnvironments.isEmpty()) {
336      return desc;
337    }
338    return execOperationWithResult(
339      new ObserverOperationWithResult<MasterObserver, TableDescriptor>(masterObserverGetter, desc) {
340
341        @Override
342        protected TableDescriptor call(MasterObserver observer) throws IOException {
343          return observer.preCreateTableRegionsInfos(this, getResult());
344        }
345      });
346  }
347
348  public void preCreateTable(final TableDescriptor htd, final RegionInfo[] regions)
349      throws IOException {
350    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
351      @Override
352      public void call(MasterObserver observer) throws IOException {
353        observer.preCreateTable(this, htd, regions);
354      }
355    });
356  }
357
358  public void postCreateTable(final TableDescriptor htd, final RegionInfo[] regions)
359      throws IOException {
360    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
361      @Override
362      public void call(MasterObserver observer) throws IOException {
363        observer.postCreateTable(this, htd, regions);
364      }
365    });
366  }
367
368  public void preCreateTableAction(final TableDescriptor htd, final RegionInfo[] regions,
369      final User user) throws IOException {
370    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
371      @Override
372      public void call(MasterObserver observer) throws IOException {
373        observer.preCreateTableAction(this, htd, regions);
374      }
375    });
376  }
377
378  public void postCompletedCreateTableAction(
379      final TableDescriptor htd, final RegionInfo[] regions, final User user) throws IOException {
380    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
381      @Override
382      public void call(MasterObserver observer) throws IOException {
383        observer.postCompletedCreateTableAction(this, htd, regions);
384      }
385    });
386  }
387
388  public void preDeleteTable(final TableName tableName) throws IOException {
389    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
390      @Override
391      public void call(MasterObserver observer) throws IOException {
392        observer.preDeleteTable(this, tableName);
393      }
394    });
395  }
396
397  public void postDeleteTable(final TableName tableName) throws IOException {
398    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
399      @Override
400      public void call(MasterObserver observer) throws IOException {
401        observer.postDeleteTable(this, tableName);
402      }
403    });
404  }
405
406  public void preDeleteTableAction(final TableName tableName, final User user) throws IOException {
407    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
408      @Override
409      public void call(MasterObserver observer) throws IOException {
410        observer.preDeleteTableAction(this, tableName);
411      }
412    });
413  }
414
415  public void postCompletedDeleteTableAction(final TableName tableName, final User user)
416      throws IOException {
417    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
418      @Override
419      public void call(MasterObserver observer) throws IOException {
420        observer.postCompletedDeleteTableAction(this, tableName);
421      }
422    });
423  }
424
425  public void preTruncateTable(final TableName tableName) throws IOException {
426    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
427      @Override
428      public void call(MasterObserver observer) throws IOException {
429        observer.preTruncateTable(this, tableName);
430      }
431    });
432  }
433
434  public void postTruncateTable(final TableName tableName) throws IOException {
435    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
436      @Override
437      public void call(MasterObserver observer) throws IOException {
438        observer.postTruncateTable(this, tableName);
439      }
440    });
441  }
442
443  public void preTruncateTableAction(final TableName tableName, final User user)
444      throws IOException {
445    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
446      @Override
447      public void call(MasterObserver observer) throws IOException {
448        observer.preTruncateTableAction(this, tableName);
449      }
450    });
451  }
452
453  public void postCompletedTruncateTableAction(final TableName tableName, final User user)
454      throws IOException {
455    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
456      @Override
457      public void call(MasterObserver observer) throws IOException {
458        observer.postCompletedTruncateTableAction(this, tableName);
459      }
460    });
461  }
462
463  public TableDescriptor preModifyTable(final TableName tableName,
464      final TableDescriptor currentDescriptor, final TableDescriptor newDescriptor)
465      throws IOException {
466    if (coprocEnvironments.isEmpty()) {
467      return newDescriptor;
468    }
469    return execOperationWithResult(
470        new ObserverOperationWithResult<MasterObserver, TableDescriptor>(masterObserverGetter,
471            newDescriptor) {
472          @Override
473          protected TableDescriptor call(MasterObserver observer) throws IOException {
474            return observer.preModifyTable(this, tableName, currentDescriptor, getResult());
475          }
476        });
477  }
478
479  public void postModifyTable(final TableName tableName, final TableDescriptor oldDescriptor,
480    final TableDescriptor currentDescriptor) throws IOException {
481    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
482      @Override
483      public void call(MasterObserver observer) throws IOException {
484        observer.postModifyTable(this, tableName, oldDescriptor, currentDescriptor);
485      }
486    });
487  }
488
489  public void preModifyTableAction(final TableName tableName,
490    final TableDescriptor currentDescriptor, final TableDescriptor newDescriptor, final User user)
491    throws IOException {
492    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
493      @Override
494      public void call(MasterObserver observer) throws IOException {
495        observer.preModifyTableAction(this, tableName, currentDescriptor, newDescriptor);
496      }
497    });
498  }
499
500  public void postCompletedModifyTableAction(final TableName tableName,
501    final TableDescriptor oldDescriptor, final TableDescriptor currentDescriptor, final User user)
502    throws IOException {
503    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
504      @Override
505      public void call(MasterObserver observer) throws IOException {
506        observer.postCompletedModifyTableAction(this, tableName, oldDescriptor, currentDescriptor);
507      }
508    });
509  }
510
511  public void preEnableTable(final TableName tableName) throws IOException {
512    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
513      @Override
514      public void call(MasterObserver observer) throws IOException {
515        observer.preEnableTable(this, tableName);
516      }
517    });
518  }
519
520  public void postEnableTable(final TableName tableName) throws IOException {
521    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
522      @Override
523      public void call(MasterObserver observer) throws IOException {
524        observer.postEnableTable(this, tableName);
525      }
526    });
527  }
528
529  public void preEnableTableAction(final TableName tableName, final User user) throws IOException {
530    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
531      @Override
532      public void call(MasterObserver observer) throws IOException {
533        observer.preEnableTableAction(this, tableName);
534      }
535    });
536  }
537
538  public void postCompletedEnableTableAction(final TableName tableName, final User user)
539      throws IOException {
540    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
541      @Override
542      public void call(MasterObserver observer) throws IOException {
543        observer.postCompletedEnableTableAction(this, tableName);
544      }
545    });
546  }
547
548  public void preDisableTable(final TableName tableName) throws IOException {
549    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
550      @Override
551      public void call(MasterObserver observer) throws IOException {
552        observer.preDisableTable(this, tableName);
553      }
554    });
555  }
556
557  public void postDisableTable(final TableName tableName) throws IOException {
558    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
559      @Override
560      public void call(MasterObserver observer) throws IOException {
561        observer.postDisableTable(this, tableName);
562      }
563    });
564  }
565
566  public void preDisableTableAction(final TableName tableName, final User user) throws IOException {
567    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
568      @Override
569      public void call(MasterObserver observer) throws IOException {
570        observer.preDisableTableAction(this, tableName);
571      }
572    });
573  }
574
575  public void postCompletedDisableTableAction(final TableName tableName, final User user)
576      throws IOException {
577    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
578      @Override
579      public void call(MasterObserver observer) throws IOException {
580        observer.postCompletedDisableTableAction(this, tableName);
581      }
582    });
583  }
584
585  public void preAbortProcedure(
586      final ProcedureExecutor<MasterProcedureEnv> procEnv,
587      final long procId) throws IOException {
588    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
589      @Override
590      public void call(MasterObserver observer) throws IOException {
591        observer.preAbortProcedure(this,  procId);
592      }
593    });
594  }
595
596  public void postAbortProcedure() throws IOException {
597    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
598      @Override
599      public void call(MasterObserver observer) throws IOException {
600        observer.postAbortProcedure(this);
601      }
602    });
603  }
604
605  public void preGetProcedures() throws IOException {
606    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
607      @Override
608      public void call(MasterObserver observer) throws IOException {
609        observer.preGetProcedures(this);
610      }
611    });
612  }
613
614  public void postGetProcedures(final List<Procedure<?>> procInfoList) throws IOException {
615    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
616      @Override
617      public void call(MasterObserver observer) throws IOException {
618        observer.postGetProcedures(this);
619      }
620    });
621  }
622
623  public void preGetLocks() throws IOException {
624    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
625      @Override
626      public void call(MasterObserver observer) throws IOException {
627        observer.preGetLocks(this);
628      }
629    });
630  }
631
632  public void postGetLocks(final List<LockedResource> lockedResources) throws IOException {
633    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
634      @Override
635      public void call(MasterObserver observer) throws IOException {
636        observer.postGetLocks(this);
637      }
638    });
639  }
640
641  public void preMove(final RegionInfo region, final ServerName srcServer,
642      final ServerName destServer) throws IOException {
643    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
644      @Override
645      public void call(MasterObserver observer) throws IOException {
646        observer.preMove(this, region, srcServer, destServer);
647      }
648    });
649  }
650
651  public void postMove(final RegionInfo region, final ServerName srcServer,
652      final ServerName destServer) throws IOException {
653    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
654      @Override
655      public void call(MasterObserver observer) throws IOException {
656        observer.postMove(this, region, srcServer, destServer);
657      }
658    });
659  }
660
661  public void preAssign(final RegionInfo regionInfo) throws IOException {
662    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
663      @Override
664      public void call(MasterObserver observer) throws IOException {
665        observer.preAssign(this, regionInfo);
666      }
667    });
668  }
669
670  public void postAssign(final RegionInfo regionInfo) throws IOException {
671    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
672      @Override
673      public void call(MasterObserver observer) throws IOException {
674        observer.postAssign(this, regionInfo);
675      }
676    });
677  }
678
679  public void preUnassign(final RegionInfo regionInfo, final boolean force)
680      throws IOException {
681    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
682      @Override
683      public void call(MasterObserver observer) throws IOException {
684        observer.preUnassign(this, regionInfo, force);
685      }
686    });
687  }
688
689  public void postUnassign(final RegionInfo regionInfo, final boolean force) throws IOException {
690    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
691      @Override
692      public void call(MasterObserver observer) throws IOException {
693        observer.postUnassign(this, regionInfo, force);
694      }
695    });
696  }
697
698  public void preRegionOffline(final RegionInfo regionInfo) throws IOException {
699    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
700      @Override
701      public void call(MasterObserver observer) throws IOException {
702        observer.preRegionOffline(this, regionInfo);
703      }
704    });
705  }
706
707  public void postRegionOffline(final RegionInfo regionInfo) throws IOException {
708    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
709      @Override
710      public void call(MasterObserver observer) throws IOException {
711        observer.postRegionOffline(this, regionInfo);
712      }
713    });
714  }
715
716  public void preMergeRegions(final RegionInfo[] regionsToMerge)
717      throws IOException {
718    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
719      @Override
720      public void call(MasterObserver observer) throws IOException {
721        observer.preMergeRegions(this, regionsToMerge);
722      }
723    });
724  }
725
726  public void postMergeRegions(final RegionInfo[] regionsToMerge)
727      throws IOException {
728    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
729      @Override
730      public void call(MasterObserver observer) throws IOException {
731        observer.postMergeRegions(this, regionsToMerge);
732      }
733    });
734  }
735
736  public boolean preBalance() throws IOException {
737    return execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
738      @Override
739      public void call(MasterObserver observer) throws IOException {
740        observer.preBalance(this);
741      }
742    });
743  }
744
745  public void postBalance(final List<RegionPlan> plans) throws IOException {
746    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
747      @Override
748      public void call(MasterObserver observer) throws IOException {
749        observer.postBalance(this, plans);
750      }
751    });
752  }
753
754  public void preSetSplitOrMergeEnabled(final boolean newValue,
755      final MasterSwitchType switchType) throws IOException {
756    execOperation(coprocEnvironments.isEmpty()? null: new MasterObserverOperation() {
757      @Override
758      public void call(MasterObserver observer) throws IOException {
759        observer.preSetSplitOrMergeEnabled(this, newValue, switchType);
760      }
761    });
762  }
763
764  public void postSetSplitOrMergeEnabled(final boolean newValue,
765      final MasterSwitchType switchType) throws IOException {
766    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
767      @Override
768      public void call(MasterObserver observer) throws IOException {
769        observer.postSetSplitOrMergeEnabled(this, newValue, switchType);
770      }
771    });
772  }
773
774  /**
775   * Invoked just before calling the split region procedure
776   * @param tableName the table where the region belongs to
777   * @param splitRow the split point
778   * @throws IOException
779   */
780  public void preSplitRegion(
781      final TableName tableName,
782      final byte[] splitRow) throws IOException {
783    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
784      @Override
785      public void call(MasterObserver observer) throws IOException {
786        observer.preSplitRegion(this, tableName, splitRow);
787      }
788    });
789  }
790
791  /**
792   * Invoked just before a split
793   * @param tableName the table where the region belongs to
794   * @param splitRow the split point
795   * @param user the user
796   * @throws IOException
797   */
798  public void preSplitRegionAction(
799      final TableName tableName,
800      final byte[] splitRow,
801      final User user) throws IOException {
802    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
803      @Override
804      public void call(MasterObserver observer) throws IOException {
805        observer.preSplitRegionAction(this, tableName, splitRow);
806      }
807    });
808  }
809
810  /**
811   * Invoked just after a split
812   * @param regionInfoA the new left-hand daughter region
813   * @param regionInfoB the new right-hand daughter region
814   * @param user the user
815   * @throws IOException
816   */
817  public void postCompletedSplitRegionAction(
818      final RegionInfo regionInfoA,
819      final RegionInfo regionInfoB,
820      final User user) throws IOException {
821    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
822      @Override
823      public void call(MasterObserver observer) throws IOException {
824        observer.postCompletedSplitRegionAction(this, regionInfoA, regionInfoB);
825      }
826    });
827  }
828
829  /**
830   * This will be called before update META step as part of split table region procedure.
831   * @param splitKey
832   * @param metaEntries
833   * @param user the user
834   * @throws IOException
835   */
836  public void preSplitBeforeMETAAction(
837      final byte[] splitKey,
838      final List<Mutation> metaEntries,
839      final User user) throws IOException {
840    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
841      @Override
842      public void call(MasterObserver observer) throws IOException {
843        observer.preSplitRegionBeforeMETAAction(this, splitKey, metaEntries);
844      }
845    });
846  }
847
848  /**
849   * This will be called after update META step as part of split table region procedure.
850   * @param user the user
851   * @throws IOException
852   */
853  public void preSplitAfterMETAAction(final User user) throws IOException {
854    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
855      @Override
856      public void call(MasterObserver observer) throws IOException {
857        observer.preSplitRegionAfterMETAAction(this);
858      }
859    });
860  }
861
862  /**
863   * Invoked just after the rollback of a failed split
864   * @param user the user
865   * @throws IOException
866   */
867  public void postRollBackSplitRegionAction(final User user) throws IOException {
868    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
869      @Override
870      public void call(MasterObserver observer) throws IOException {
871        observer.postRollBackSplitRegionAction(this);
872      }
873    });
874  }
875
876  /**
877   * Invoked just before a merge
878   * @param regionsToMerge the regions to merge
879   * @param user the user
880   * @throws IOException
881   */
882  public void preMergeRegionsAction(
883      final RegionInfo[] regionsToMerge, final User user) throws IOException {
884    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
885      @Override
886      public void call(MasterObserver observer) throws IOException {
887        observer.preMergeRegionsAction(this, regionsToMerge);
888      }
889    });
890  }
891
892  /**
893   * Invoked after completing merge regions operation
894   * @param regionsToMerge the regions to merge
895   * @param mergedRegion the new merged region
896   * @param user the user
897   * @throws IOException
898   */
899  public void postCompletedMergeRegionsAction(
900      final RegionInfo[] regionsToMerge,
901      final RegionInfo mergedRegion,
902      final User user) throws IOException {
903    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
904      @Override
905      public void call(MasterObserver observer) throws IOException {
906        observer.postCompletedMergeRegionsAction(this, regionsToMerge, mergedRegion);
907      }
908    });
909  }
910
911  /**
912   * Invoked before merge regions operation writes the new region to hbase:meta
913   * @param regionsToMerge the regions to merge
914   * @param metaEntries the meta entry
915   * @param user the user
916   * @throws IOException
917   */
918  public void preMergeRegionsCommit(
919      final RegionInfo[] regionsToMerge,
920      final @MetaMutationAnnotation List<Mutation> metaEntries,
921      final User user) throws IOException {
922    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
923      @Override
924      public void call(MasterObserver observer) throws IOException {
925        observer.preMergeRegionsCommitAction(this, regionsToMerge, metaEntries);
926      }
927    });
928  }
929
930  /**
931   * Invoked after merge regions operation writes the new region to hbase:meta
932   * @param regionsToMerge the regions to merge
933   * @param mergedRegion the new merged region
934   * @param user the user
935   * @throws IOException
936   */
937  public void postMergeRegionsCommit(
938      final RegionInfo[] regionsToMerge,
939      final RegionInfo mergedRegion,
940      final User user) throws IOException {
941    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
942      @Override
943      public void call(MasterObserver observer) throws IOException {
944        observer.postMergeRegionsCommitAction(this, regionsToMerge, mergedRegion);
945      }
946    });
947  }
948
949  /**
950   * Invoked after rollback merge regions operation
951   * @param regionsToMerge the regions to merge
952   * @param user the user
953   * @throws IOException
954   */
955  public void postRollBackMergeRegionsAction(
956      final RegionInfo[] regionsToMerge, final User user) throws IOException {
957    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
958      @Override
959      public void call(MasterObserver observer) throws IOException {
960        observer.postRollBackMergeRegionsAction(this, regionsToMerge);
961      }
962    });
963  }
964
965  // This hook allows Coprocessor change value of balance switch.
966  public void preBalanceSwitch(final boolean b) throws IOException {
967    if (this.coprocEnvironments.isEmpty()) {
968      return;
969    }
970    execOperation(new MasterObserverOperation() {
971      @Override
972      public void call(MasterObserver observer) throws IOException {
973        observer.preBalanceSwitch(this, b);
974      }
975    });
976  }
977
978  public void postBalanceSwitch(final boolean oldValue, final boolean newValue)
979      throws IOException {
980    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
981      @Override
982      public void call(MasterObserver observer) throws IOException {
983        observer.postBalanceSwitch(this, oldValue, newValue);
984      }
985    });
986  }
987
988  public void preShutdown() throws IOException {
989    // While stopping the cluster all coprocessors method should be executed first then the
990    // coprocessor should be cleaned up.
991    if (coprocEnvironments.isEmpty()) {
992      return;
993    }
994    execShutdown(new MasterObserverOperation() {
995      @Override
996      public void call(MasterObserver observer) throws IOException {
997        observer.preShutdown(this);
998      }
999      @Override
1000      public void postEnvCall() {
1001        // invoke coprocessor stop method
1002        shutdown(this.getEnvironment());
1003      }
1004    });
1005  }
1006
1007  public void preStopMaster() throws IOException {
1008    // While stopping master all coprocessors method should be executed first then the coprocessor
1009    // environment should be cleaned up.
1010    if (coprocEnvironments.isEmpty()) {
1011      return;
1012    }
1013    execShutdown(new MasterObserverOperation() {
1014      @Override
1015      public void call(MasterObserver observer) throws IOException {
1016        observer.preStopMaster(this);
1017      }
1018      @Override
1019      public void postEnvCall() {
1020        // invoke coprocessor stop method
1021        shutdown(this.getEnvironment());
1022      }
1023    });
1024  }
1025
1026  public void preMasterInitialization() throws IOException {
1027    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1028      @Override
1029      public void call(MasterObserver observer) throws IOException {
1030        observer.preMasterInitialization(this);
1031      }
1032    });
1033  }
1034
1035  public void postStartMaster() throws IOException {
1036    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1037      @Override
1038      public void call(MasterObserver observer) throws IOException {
1039        observer.postStartMaster(this);
1040      }
1041    });
1042  }
1043
1044  public void preSnapshot(final SnapshotDescription snapshot,
1045      final TableDescriptor hTableDescriptor) throws IOException {
1046    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1047      @Override
1048      public void call(MasterObserver observer) throws IOException {
1049        observer.preSnapshot(this, snapshot, hTableDescriptor);
1050      }
1051    });
1052  }
1053
1054  public void postSnapshot(final SnapshotDescription snapshot,
1055      final TableDescriptor hTableDescriptor) throws IOException {
1056    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1057      @Override
1058      public void call(MasterObserver observer) throws IOException {
1059        observer.postSnapshot(this, snapshot, hTableDescriptor);
1060      }
1061    });
1062  }
1063
1064  public void postCompletedSnapshotAction(SnapshotDescription snapshot,
1065      TableDescriptor hTableDescriptor) throws IOException {
1066    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1067      @Override
1068      public void call(MasterObserver observer) throws IOException {
1069        observer.postCompletedSnapshotAction(this, snapshot, hTableDescriptor);
1070      }
1071    });
1072  }
1073
1074  public void preListSnapshot(final SnapshotDescription snapshot) throws IOException {
1075    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1076      @Override
1077      public void call(MasterObserver observer) throws IOException {
1078        observer.preListSnapshot(this, snapshot);
1079      }
1080    });
1081  }
1082
1083  public void postListSnapshot(final SnapshotDescription snapshot) throws IOException {
1084    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1085      @Override
1086      public void call(MasterObserver observer) throws IOException {
1087        observer.postListSnapshot(this, snapshot);
1088      }
1089    });
1090  }
1091
1092  public void preCloneSnapshot(final SnapshotDescription snapshot,
1093      final TableDescriptor hTableDescriptor) throws IOException {
1094    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1095      @Override
1096      public void call(MasterObserver observer) throws IOException {
1097        observer.preCloneSnapshot(this, snapshot, hTableDescriptor);
1098      }
1099    });
1100  }
1101
1102  public void postCloneSnapshot(final SnapshotDescription snapshot,
1103      final TableDescriptor hTableDescriptor) throws IOException {
1104    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1105      @Override
1106      public void call(MasterObserver observer) throws IOException {
1107        observer.postCloneSnapshot(this, snapshot, hTableDescriptor);
1108      }
1109    });
1110  }
1111
1112  public void preRestoreSnapshot(final SnapshotDescription snapshot,
1113      final TableDescriptor hTableDescriptor) throws IOException {
1114    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1115      @Override
1116      public void call(MasterObserver observer) throws IOException {
1117        observer.preRestoreSnapshot(this, snapshot, hTableDescriptor);
1118      }
1119    });
1120  }
1121
1122  public void postRestoreSnapshot(final SnapshotDescription snapshot,
1123      final TableDescriptor hTableDescriptor) throws IOException {
1124    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1125      @Override
1126      public void call(MasterObserver observer) throws IOException {
1127        observer.postRestoreSnapshot(this, snapshot, hTableDescriptor);
1128      }
1129    });
1130  }
1131
1132  public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
1133    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1134      @Override
1135      public void call(MasterObserver observer) throws IOException {
1136        observer.preDeleteSnapshot(this, snapshot);
1137      }
1138    });
1139  }
1140
1141  public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
1142    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1143      @Override
1144      public void call(MasterObserver observer) throws IOException {
1145        observer.postDeleteSnapshot(this, snapshot);
1146      }
1147    });
1148  }
1149
1150  public void preGetTableDescriptors(final List<TableName> tableNamesList,
1151      final List<TableDescriptor> descriptors, final String regex) throws IOException {
1152    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1153      @Override
1154      public void call(MasterObserver observer) throws IOException {
1155        observer.preGetTableDescriptors(this, tableNamesList, descriptors, regex);
1156      }
1157    });
1158  }
1159
1160  public void postGetTableDescriptors(final List<TableName> tableNamesList,
1161      final List<TableDescriptor> descriptors, final String regex) throws IOException {
1162    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1163      @Override
1164      public void call(MasterObserver observer) throws IOException {
1165        observer.postGetTableDescriptors(this, tableNamesList, descriptors, regex);
1166      }
1167    });
1168  }
1169
1170  public void preGetTableNames(final List<TableDescriptor> descriptors,
1171      final String regex) throws IOException {
1172    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1173      @Override
1174      public void call(MasterObserver observer) throws IOException {
1175        observer.preGetTableNames(this, descriptors, regex);
1176      }
1177    });
1178  }
1179
1180  public void postGetTableNames(final List<TableDescriptor> descriptors,
1181      final String regex) throws IOException {
1182    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1183      @Override
1184      public void call(MasterObserver observer) throws IOException {
1185        observer.postGetTableNames(this, descriptors, regex);
1186      }
1187    });
1188  }
1189
1190  public void preTableFlush(final TableName tableName) throws IOException {
1191    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1192      @Override
1193      public void call(MasterObserver observer) throws IOException {
1194        observer.preTableFlush(this, tableName);
1195      }
1196    });
1197  }
1198
1199  public void postTableFlush(final TableName tableName) throws IOException {
1200    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1201      @Override
1202      public void call(MasterObserver observer) throws IOException {
1203        observer.postTableFlush(this, tableName);
1204      }
1205    });
1206  }
1207
1208  public void preSetUserQuota(
1209      final String user, final GlobalQuotaSettings quotas) throws IOException {
1210    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1211      @Override
1212      public void call(MasterObserver observer) throws IOException {
1213        observer.preSetUserQuota(this, user, quotas);
1214      }
1215    });
1216  }
1217
1218  public void postSetUserQuota(
1219      final String user, final GlobalQuotaSettings quotas) throws IOException {
1220    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1221      @Override
1222      public void call(MasterObserver observer) throws IOException {
1223        observer.postSetUserQuota(this, user, quotas);
1224      }
1225    });
1226  }
1227
1228  public void preSetUserQuota(
1229      final String user, final TableName table, final GlobalQuotaSettings quotas)
1230          throws IOException {
1231    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1232      @Override
1233      public void call(MasterObserver observer) throws IOException {
1234        observer.preSetUserQuota(this, user, table, quotas);
1235      }
1236    });
1237  }
1238
1239  public void postSetUserQuota(
1240      final String user, final TableName table, final GlobalQuotaSettings quotas)
1241          throws IOException {
1242    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1243      @Override
1244      public void call(MasterObserver observer) throws IOException {
1245        observer.postSetUserQuota(this, user, table, quotas);
1246      }
1247    });
1248  }
1249
1250  public void preSetUserQuota(
1251      final String user, final String namespace, final GlobalQuotaSettings quotas)
1252          throws IOException {
1253    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1254      @Override
1255      public void call(MasterObserver observer) throws IOException {
1256        observer.preSetUserQuota(this, user, namespace, quotas);
1257      }
1258    });
1259  }
1260
1261  public void postSetUserQuota(
1262      final String user, final String namespace, final GlobalQuotaSettings quotas)
1263          throws IOException {
1264    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1265      @Override
1266      public void call(MasterObserver observer) throws IOException {
1267        observer.postSetUserQuota(this, user, namespace, quotas);
1268      }
1269    });
1270  }
1271
1272  public void preSetTableQuota(
1273      final TableName table, final GlobalQuotaSettings quotas) throws IOException {
1274    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1275      @Override
1276      public void call(MasterObserver observer) throws IOException {
1277        observer.preSetTableQuota(this, table, quotas);
1278      }
1279    });
1280  }
1281
1282  public void postSetTableQuota(
1283      final TableName table, final GlobalQuotaSettings quotas) throws IOException {
1284    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1285      @Override
1286      public void call(MasterObserver observer) throws IOException {
1287        observer.postSetTableQuota(this, table, quotas);
1288      }
1289    });
1290  }
1291
1292  public void preSetNamespaceQuota(
1293      final String namespace, final GlobalQuotaSettings quotas) throws IOException {
1294    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1295      @Override
1296      public void call(MasterObserver observer) throws IOException {
1297        observer.preSetNamespaceQuota(this, namespace, quotas);
1298      }
1299    });
1300  }
1301
1302  public void postSetNamespaceQuota(
1303      final String namespace, final GlobalQuotaSettings quotas) throws IOException{
1304    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1305      @Override
1306      public void call(MasterObserver observer) throws IOException {
1307        observer.postSetNamespaceQuota(this, namespace, quotas);
1308      }
1309    });
1310  }
1311
1312  public void preSetRegionServerQuota(final String regionServer, final GlobalQuotaSettings quotas)
1313      throws IOException {
1314    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1315      @Override
1316      public void call(MasterObserver observer) throws IOException {
1317        observer.preSetRegionServerQuota(this, regionServer, quotas);
1318      }
1319    });
1320  }
1321
1322  public void postSetRegionServerQuota(final String regionServer, final GlobalQuotaSettings quotas)
1323      throws IOException {
1324    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1325      @Override
1326      public void call(MasterObserver observer) throws IOException {
1327        observer.postSetRegionServerQuota(this, regionServer, quotas);
1328      }
1329    });
1330  }
1331
1332  public void preMoveServersAndTables(final Set<Address> servers, final Set<TableName> tables,
1333      final String targetGroup) throws IOException {
1334    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1335      @Override
1336      public void call(MasterObserver observer) throws IOException {
1337        observer.preMoveServersAndTables(this, servers, tables, targetGroup);
1338      }
1339    });
1340  }
1341
1342  public void postMoveServersAndTables(final Set<Address> servers, final Set<TableName> tables,
1343      final String targetGroup) throws IOException {
1344    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1345      @Override
1346      public void call(MasterObserver observer) throws IOException {
1347        observer.postMoveServersAndTables(this, servers, tables, targetGroup);
1348      }
1349    });
1350  }
1351
1352  public void preMoveServers(final Set<Address> servers, final String targetGroup)
1353      throws IOException {
1354    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1355      @Override
1356      public void call(MasterObserver observer) throws IOException {
1357        observer.preMoveServers(this, servers, targetGroup);
1358      }
1359    });
1360  }
1361
1362  public void postMoveServers(final Set<Address> servers, final String targetGroup)
1363      throws IOException {
1364    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1365      @Override
1366      public void call(MasterObserver observer) throws IOException {
1367        observer.postMoveServers(this, servers, targetGroup);
1368      }
1369    });
1370  }
1371
1372  public void preMoveTables(final Set<TableName> tables, final String targetGroup)
1373      throws IOException {
1374    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1375      @Override
1376      public void call(MasterObserver observer) throws IOException {
1377        observer.preMoveTables(this, tables, targetGroup);
1378      }
1379    });
1380  }
1381
1382  public void postMoveTables(final Set<TableName> tables, final String targetGroup)
1383      throws IOException {
1384    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1385      @Override
1386      public void call(MasterObserver observer) throws IOException {
1387        observer.postMoveTables(this, tables, targetGroup);
1388      }
1389    });
1390  }
1391
1392  public void preAddRSGroup(final String name)
1393      throws IOException {
1394    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1395      @Override
1396      public void call(MasterObserver observer) throws IOException {
1397        observer.preAddRSGroup(this, name);
1398      }
1399    });
1400  }
1401
1402  public void postAddRSGroup(final String name)
1403      throws IOException {
1404    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1405      @Override
1406      public void call(MasterObserver observer) throws IOException {
1407        observer.postAddRSGroup(this, name);
1408      }
1409    });
1410  }
1411
1412  public void preRemoveRSGroup(final String name)
1413      throws IOException {
1414    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1415      @Override
1416      public void call(MasterObserver observer) throws IOException {
1417        observer.preRemoveRSGroup(this, name);
1418      }
1419    });
1420  }
1421
1422  public void postRemoveRSGroup(final String name)
1423      throws IOException {
1424    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1425      @Override
1426      public void call(MasterObserver observer) throws IOException {
1427        observer.postRemoveRSGroup(this, name);
1428      }
1429    });
1430  }
1431
1432  public void preBalanceRSGroup(final String name)
1433      throws IOException {
1434    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1435      @Override
1436      public void call(MasterObserver observer) throws IOException {
1437        observer.preBalanceRSGroup(this, name);
1438      }
1439    });
1440  }
1441
1442  public void postBalanceRSGroup(final String name, final boolean balanceRan)
1443      throws IOException {
1444    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1445      @Override
1446      public void call(MasterObserver observer) throws IOException {
1447        observer.postBalanceRSGroup(this, name, balanceRan);
1448      }
1449    });
1450  }
1451
1452  public void preRemoveServers(final Set<Address> servers)
1453      throws IOException {
1454    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1455      @Override
1456      public void call(MasterObserver observer) throws IOException {
1457        observer.preRemoveServers(this, servers);
1458      }
1459    });
1460  }
1461
1462  public void postRemoveServers(final Set<Address> servers)
1463      throws IOException {
1464    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1465      @Override
1466      public void call(MasterObserver observer) throws IOException {
1467        observer.postRemoveServers(this, servers);
1468      }
1469    });
1470  }
1471
1472  public void preGetRSGroupInfo(final String groupName) throws IOException {
1473    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1474      @Override
1475      public void call(MasterObserver observer) throws IOException {
1476        observer.preGetRSGroupInfo(this, groupName);
1477      }
1478    });
1479  }
1480
1481  public void postGetRSGroupInfo(final String groupName) throws IOException {
1482    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1483      @Override
1484      public void call(MasterObserver observer) throws IOException {
1485        observer.postGetRSGroupInfo(this, groupName);
1486      }
1487    });
1488  }
1489
1490  public void preGetRSGroupInfoOfTable(final TableName tableName) throws IOException {
1491    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1492      @Override
1493      public void call(MasterObserver observer) throws IOException {
1494        observer.preGetRSGroupInfoOfTable(this, tableName);
1495      }
1496    });
1497  }
1498
1499  public void postGetRSGroupInfoOfTable(final TableName tableName) throws IOException {
1500    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1501      @Override
1502      public void call(MasterObserver observer) throws IOException {
1503        observer.postGetRSGroupInfoOfTable(this, tableName);
1504      }
1505    });
1506  }
1507
1508  public void preListRSGroups() throws IOException {
1509    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1510      @Override
1511      public void call(MasterObserver observer) throws IOException {
1512        observer.preListRSGroups(this);
1513      }
1514    });
1515  }
1516
1517  public void postListRSGroups() throws IOException {
1518    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1519      @Override
1520      public void call(MasterObserver observer) throws IOException {
1521        observer.postListRSGroups(this);
1522      }
1523    });
1524  }
1525
1526  public void preListTablesInRSGroup(final String groupName) throws IOException {
1527    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1528
1529      @Override
1530      protected void call(MasterObserver observer) throws IOException {
1531        observer.preListTablesInRSGroup(this, groupName);
1532      }
1533    });
1534  }
1535
1536  public void postListTablesInRSGroup(final String groupName) throws IOException {
1537    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1538
1539      @Override
1540      protected void call(MasterObserver observer) throws IOException {
1541        observer.postListTablesInRSGroup(this, groupName);
1542      }
1543    });
1544  }
1545
1546  public void preRenameRSGroup(final String oldName, final String newName) throws IOException {
1547    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1548
1549      @Override
1550      protected void call(MasterObserver observer) throws IOException {
1551        observer.preRenameRSGroup(this, oldName, newName);
1552      }
1553    });
1554  }
1555
1556  public void postRenameRSGroup(final String oldName, final String newName) throws IOException {
1557    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1558
1559      @Override
1560      protected void call(MasterObserver observer) throws IOException {
1561        observer.postRenameRSGroup(this, oldName, newName);
1562      }
1563    });
1564  }
1565
1566  public void preUpdateRSGroupConfig(final String groupName,
1567                                     final Map<String, String> configuration) throws IOException {
1568    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1569      @Override
1570      protected void call(MasterObserver observer) throws IOException {
1571        observer.preUpdateRSGroupConfig(this, groupName, configuration);
1572      }
1573    });
1574  }
1575
1576  public void postUpdateRSGroupConfig(final String groupName,
1577                                      final Map<String, String> configuration) throws IOException {
1578    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1579      @Override
1580      protected void call(MasterObserver observer) throws IOException {
1581        observer.postUpdateRSGroupConfig(this, groupName, configuration);
1582      }
1583    });
1584  }
1585
1586  public void preGetConfiguredNamespacesAndTablesInRSGroup(final String groupName)
1587    throws IOException {
1588    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1589
1590      @Override
1591      protected void call(MasterObserver observer) throws IOException {
1592        observer.preGetConfiguredNamespacesAndTablesInRSGroup(this, groupName);
1593      }
1594    });
1595  }
1596
1597  public void postGetConfiguredNamespacesAndTablesInRSGroup(final String groupName)
1598    throws IOException {
1599    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1600
1601      @Override
1602      protected void call(MasterObserver observer) throws IOException {
1603        observer.postGetConfiguredNamespacesAndTablesInRSGroup(this, groupName);
1604      }
1605    });
1606  }
1607
1608  public void preGetRSGroupInfoOfServer(final Address server) throws IOException {
1609    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1610      @Override
1611      public void call(MasterObserver observer) throws IOException {
1612        observer.preGetRSGroupInfoOfServer(this, server);
1613      }
1614    });
1615  }
1616
1617  public void postGetRSGroupInfoOfServer(final Address server) throws IOException {
1618    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1619      @Override
1620      public void call(MasterObserver observer) throws IOException {
1621        observer.postGetRSGroupInfoOfServer(this, server);
1622      }
1623    });
1624  }
1625
1626  public void preAddReplicationPeer(final String peerId, final ReplicationPeerConfig peerConfig)
1627      throws IOException {
1628    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1629      @Override
1630      public void call(MasterObserver observer) throws IOException {
1631        observer.preAddReplicationPeer(this, peerId, peerConfig);
1632      }
1633    });
1634  }
1635
1636  public void postAddReplicationPeer(final String peerId, final ReplicationPeerConfig peerConfig)
1637      throws IOException {
1638    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1639      @Override
1640      public void call(MasterObserver observer) throws IOException {
1641        observer.postAddReplicationPeer(this, peerId, peerConfig);
1642      }
1643    });
1644  }
1645
1646  public void preRemoveReplicationPeer(final String peerId) throws IOException {
1647    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1648      @Override
1649      public void call(MasterObserver observer) throws IOException {
1650        observer.preRemoveReplicationPeer(this, peerId);
1651      }
1652    });
1653  }
1654
1655  public void postRemoveReplicationPeer(final String peerId) throws IOException {
1656    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1657      @Override
1658      public void call(MasterObserver observer) throws IOException {
1659        observer.postRemoveReplicationPeer(this, peerId);
1660      }
1661    });
1662  }
1663
1664  public void preEnableReplicationPeer(final String peerId) throws IOException {
1665    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1666      @Override
1667      public void call(MasterObserver observer) throws IOException {
1668        observer.preEnableReplicationPeer(this, peerId);
1669      }
1670    });
1671  }
1672
1673  public void postEnableReplicationPeer(final String peerId) throws IOException {
1674    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1675      @Override
1676      public void call(MasterObserver observer) throws IOException {
1677        observer.postEnableReplicationPeer(this, peerId);
1678      }
1679    });
1680  }
1681
1682  public void preDisableReplicationPeer(final String peerId) throws IOException {
1683    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1684      @Override
1685      public void call(MasterObserver observer) throws IOException {
1686        observer.preDisableReplicationPeer(this, peerId);
1687      }
1688    });
1689  }
1690
1691  public void postDisableReplicationPeer(final String peerId) throws IOException {
1692    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1693      @Override
1694      public void call(MasterObserver observer) throws IOException {
1695        observer.postDisableReplicationPeer(this, peerId);
1696      }
1697    });
1698  }
1699
1700  public void preGetReplicationPeerConfig(final String peerId) throws IOException {
1701    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1702      @Override
1703      public void call(MasterObserver observer) throws IOException {
1704        observer.preGetReplicationPeerConfig(this, peerId);
1705      }
1706    });
1707  }
1708
1709  public void postGetReplicationPeerConfig(final String peerId) throws IOException {
1710    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1711      @Override
1712      public void call(MasterObserver observer) throws IOException {
1713        observer.postGetReplicationPeerConfig(this, peerId);
1714      }
1715    });
1716  }
1717
1718  public void preUpdateReplicationPeerConfig(final String peerId,
1719      final ReplicationPeerConfig peerConfig) throws IOException {
1720    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1721      @Override
1722      public void call(MasterObserver observer) throws IOException {
1723        observer.preUpdateReplicationPeerConfig(this, peerId, peerConfig);
1724      }
1725    });
1726  }
1727
1728  public void postUpdateReplicationPeerConfig(final String peerId,
1729      final ReplicationPeerConfig peerConfig) throws IOException {
1730    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1731      @Override
1732      public void call(MasterObserver observer) throws IOException {
1733        observer.postUpdateReplicationPeerConfig(this, peerId, peerConfig);
1734      }
1735    });
1736  }
1737
1738  public void preListReplicationPeers(final String regex) throws IOException {
1739    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1740      @Override
1741      public void call(MasterObserver observer) throws IOException {
1742        observer.preListReplicationPeers(this, regex);
1743      }
1744    });
1745  }
1746
1747  public void postListReplicationPeers(final String regex) throws IOException {
1748    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1749      @Override
1750      public void call(MasterObserver observer) throws IOException {
1751        observer.postListReplicationPeers(this, regex);
1752      }
1753    });
1754  }
1755
1756  public void preTransitReplicationPeerSyncReplicationState(String peerId,
1757      SyncReplicationState state) throws IOException {
1758    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1759      @Override
1760      public void call(MasterObserver observer) throws IOException {
1761        observer.preTransitReplicationPeerSyncReplicationState(this, peerId, state);
1762      }
1763    });
1764  }
1765
1766  public void postTransitReplicationPeerSyncReplicationState(String peerId,
1767      SyncReplicationState from, SyncReplicationState to) throws IOException {
1768    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1769      @Override
1770      public void call(MasterObserver observer) throws IOException {
1771        observer.postTransitReplicationPeerSyncReplicationState(this, peerId, from, to);
1772      }
1773    });
1774  }
1775
1776  public void preRequestLock(String namespace, TableName tableName, RegionInfo[] regionInfos,
1777      LockType type, String description) throws IOException {
1778    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1779      @Override
1780      public void call(MasterObserver observer) throws IOException {
1781        observer.preRequestLock(this, namespace, tableName, regionInfos, description);
1782      }
1783    });
1784  }
1785
1786  public void postRequestLock(String namespace, TableName tableName, RegionInfo[] regionInfos,
1787      LockType type, String description) throws IOException {
1788    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1789      @Override
1790      public void call(MasterObserver observer) throws IOException {
1791        observer.postRequestLock(this, namespace, tableName, regionInfos, description);
1792      }
1793    });
1794  }
1795
1796  public void preLockHeartbeat(LockProcedure proc, boolean keepAlive) throws IOException {
1797    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1798      @Override
1799      public void call(MasterObserver observer) throws IOException {
1800        observer.preLockHeartbeat(this, proc.getTableName(), proc.getDescription());
1801      }
1802    });
1803  }
1804
1805  public void postLockHeartbeat(LockProcedure proc, boolean keepAlive) throws IOException {
1806    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1807      @Override
1808      public void call(MasterObserver observer) throws IOException {
1809        observer.postLockHeartbeat(this);
1810      }
1811    });
1812  }
1813
1814  public void preGetClusterMetrics() throws IOException {
1815    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1816      @Override
1817      public void call(MasterObserver observer) throws IOException {
1818        observer.preGetClusterMetrics(this);
1819      }
1820    });
1821  }
1822
1823  public void postGetClusterMetrics(ClusterMetrics status) throws IOException {
1824    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1825      @Override
1826      public void call(MasterObserver observer) throws IOException {
1827        observer.postGetClusterMetrics(this, status);
1828      }
1829    });
1830  }
1831
1832  public void preClearDeadServers() throws IOException {
1833    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1834      @Override
1835      public void call(MasterObserver observer) throws IOException {
1836        observer.preClearDeadServers(this);
1837      }
1838    });
1839  }
1840
1841  public void postClearDeadServers(List<ServerName> servers,
1842      List<ServerName> notClearedServers) throws IOException {
1843    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1844      @Override
1845      public void call(MasterObserver observer) throws IOException {
1846        observer.postClearDeadServers(this, servers, notClearedServers);
1847      }
1848    });
1849  }
1850
1851  public void preDecommissionRegionServers(List<ServerName> servers, boolean offload)
1852      throws IOException {
1853    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1854      @Override
1855      public void call(MasterObserver observer) throws IOException {
1856        observer.preDecommissionRegionServers(this, servers, offload);
1857      }
1858    });
1859  }
1860
1861  public void postDecommissionRegionServers(List<ServerName> servers, boolean offload)
1862      throws IOException {
1863    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1864      @Override
1865      public void call(MasterObserver observer) throws IOException {
1866        observer.postDecommissionRegionServers(this, servers, offload);
1867      }
1868    });
1869  }
1870
1871  public void preListDecommissionedRegionServers() throws IOException {
1872    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1873      @Override
1874      public void call(MasterObserver observer) throws IOException {
1875        observer.preListDecommissionedRegionServers(this);
1876      }
1877    });
1878  }
1879
1880  public void postListDecommissionedRegionServers() throws IOException {
1881    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1882      @Override
1883      public void call(MasterObserver observer) throws IOException {
1884        observer.postListDecommissionedRegionServers(this);
1885      }
1886    });
1887  }
1888
1889  public void preRecommissionRegionServer(ServerName server, List<byte[]> encodedRegionNames)
1890      throws IOException {
1891    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1892      @Override
1893      public void call(MasterObserver observer) throws IOException {
1894        observer.preRecommissionRegionServer(this, server, encodedRegionNames);
1895      }
1896    });
1897  }
1898
1899  public void postRecommissionRegionServer(ServerName server, List<byte[]> encodedRegionNames)
1900      throws IOException {
1901    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1902      @Override
1903      public void call(MasterObserver observer) throws IOException {
1904        observer.postRecommissionRegionServer(this, server, encodedRegionNames);
1905      }
1906    });
1907  }
1908
1909  public void preSwitchRpcThrottle(boolean enable) throws IOException {
1910    execOperation(coprocEnvironments.isEmpty() ? null :new MasterObserverOperation() {
1911      @Override
1912      public void call(MasterObserver observer) throws IOException {
1913        observer.preSwitchRpcThrottle(this, enable);
1914      }
1915    });
1916  }
1917
1918  public void postSwitchRpcThrottle(final boolean oldValue, final boolean newValue)
1919      throws IOException {
1920    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1921      @Override
1922      public void call(MasterObserver observer) throws IOException {
1923        observer.postSwitchRpcThrottle(this, oldValue, newValue);
1924      }
1925    });
1926  }
1927
1928  public void preIsRpcThrottleEnabled() throws IOException {
1929    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1930      @Override
1931      public void call(MasterObserver observer) throws IOException {
1932        observer.preIsRpcThrottleEnabled(this);
1933      }
1934    });
1935  }
1936
1937  public void postIsRpcThrottleEnabled(boolean enabled) throws IOException {
1938    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1939      @Override
1940      public void call(MasterObserver observer) throws IOException {
1941        observer.postIsRpcThrottleEnabled(this, enabled);
1942      }
1943    });
1944  }
1945
1946  public void preSwitchExceedThrottleQuota(boolean enable) throws IOException {
1947    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1948      @Override
1949      public void call(MasterObserver observer) throws IOException {
1950        observer.preSwitchExceedThrottleQuota(this, enable);
1951      }
1952    });
1953  }
1954
1955  public void postSwitchExceedThrottleQuota(final boolean oldValue, final boolean newValue)
1956      throws IOException {
1957    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1958      @Override
1959      public void call(MasterObserver observer) throws IOException {
1960        observer.postSwitchExceedThrottleQuota(this, oldValue, newValue);
1961      }
1962    });
1963  }
1964
1965  public void preGrant(UserPermission userPermission, boolean mergeExistingPermissions)
1966      throws IOException {
1967    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1968      @Override
1969      public void call(MasterObserver observer) throws IOException {
1970        observer.preGrant(this, userPermission, mergeExistingPermissions);
1971      }
1972    });
1973  }
1974
1975  public void postGrant(UserPermission userPermission, boolean mergeExistingPermissions)
1976      throws IOException {
1977    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1978      @Override
1979      public void call(MasterObserver observer) throws IOException {
1980        observer.postGrant(this, userPermission, mergeExistingPermissions);
1981      }
1982    });
1983  }
1984
1985  public void preRevoke(UserPermission userPermission) throws IOException {
1986    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1987      @Override
1988      public void call(MasterObserver observer) throws IOException {
1989        observer.preRevoke(this, userPermission);
1990      }
1991    });
1992  }
1993
1994  public void postRevoke(UserPermission userPermission) throws IOException {
1995    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1996      @Override
1997      public void call(MasterObserver observer) throws IOException {
1998        observer.postRevoke(this, userPermission);
1999      }
2000    });
2001  }
2002
2003  public void preGetUserPermissions(String userName, String namespace, TableName tableName,
2004      byte[] family, byte[] qualifier) throws IOException {
2005    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2006      @Override
2007      public void call(MasterObserver observer) throws IOException {
2008        observer.preGetUserPermissions(this, userName, namespace, tableName, family, qualifier);
2009      }
2010    });
2011  }
2012
2013  public void postGetUserPermissions(String userName, String namespace, TableName tableName,
2014      byte[] family, byte[] qualifier) throws IOException {
2015    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2016      @Override
2017      public void call(MasterObserver observer) throws IOException {
2018        observer.postGetUserPermissions(this, userName, namespace, tableName, family, qualifier);
2019      }
2020    });
2021  }
2022
2023  public void preHasUserPermissions(String userName, List<Permission> permissions)
2024      throws IOException {
2025    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2026      @Override
2027      public void call(MasterObserver observer) throws IOException {
2028        observer.preHasUserPermissions(this, userName, permissions);
2029      }
2030    });
2031  }
2032
2033  public void postHasUserPermissions(String userName, List<Permission> permissions)
2034      throws IOException {
2035    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2036      @Override
2037      public void call(MasterObserver observer) throws IOException {
2038        observer.postHasUserPermissions(this, userName, permissions);
2039      }
2040    });
2041  }
2042}