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) throws IOException {
680    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
681      @Override
682      public void call(MasterObserver observer) throws IOException {
683        observer.preUnassign(this, regionInfo);
684      }
685    });
686  }
687
688  public void postUnassign(final RegionInfo regionInfo) throws IOException {
689    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
690      @Override
691      public void call(MasterObserver observer) throws IOException {
692        observer.postUnassign(this, regionInfo);
693      }
694    });
695  }
696
697  public void preRegionOffline(final RegionInfo regionInfo) throws IOException {
698    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
699      @Override
700      public void call(MasterObserver observer) throws IOException {
701        observer.preRegionOffline(this, regionInfo);
702      }
703    });
704  }
705
706  public void postRegionOffline(final RegionInfo regionInfo) throws IOException {
707    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
708      @Override
709      public void call(MasterObserver observer) throws IOException {
710        observer.postRegionOffline(this, regionInfo);
711      }
712    });
713  }
714
715  public void preMergeRegions(final RegionInfo[] regionsToMerge)
716      throws IOException {
717    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
718      @Override
719      public void call(MasterObserver observer) throws IOException {
720        observer.preMergeRegions(this, regionsToMerge);
721      }
722    });
723  }
724
725  public void postMergeRegions(final RegionInfo[] regionsToMerge)
726      throws IOException {
727    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
728      @Override
729      public void call(MasterObserver observer) throws IOException {
730        observer.postMergeRegions(this, regionsToMerge);
731      }
732    });
733  }
734
735  public boolean preBalance() throws IOException {
736    return execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
737      @Override
738      public void call(MasterObserver observer) throws IOException {
739        observer.preBalance(this);
740      }
741    });
742  }
743
744  public void postBalance(final List<RegionPlan> plans) throws IOException {
745    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
746      @Override
747      public void call(MasterObserver observer) throws IOException {
748        observer.postBalance(this, plans);
749      }
750    });
751  }
752
753  public void preSetSplitOrMergeEnabled(final boolean newValue,
754      final MasterSwitchType switchType) throws IOException {
755    execOperation(coprocEnvironments.isEmpty()? null: new MasterObserverOperation() {
756      @Override
757      public void call(MasterObserver observer) throws IOException {
758        observer.preSetSplitOrMergeEnabled(this, newValue, switchType);
759      }
760    });
761  }
762
763  public void postSetSplitOrMergeEnabled(final boolean newValue,
764      final MasterSwitchType switchType) throws IOException {
765    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
766      @Override
767      public void call(MasterObserver observer) throws IOException {
768        observer.postSetSplitOrMergeEnabled(this, newValue, switchType);
769      }
770    });
771  }
772
773  /**
774   * Invoked just before calling the split region procedure
775   * @param tableName the table where the region belongs to
776   * @param splitRow the split point
777   * @throws IOException
778   */
779  public void preSplitRegion(
780      final TableName tableName,
781      final byte[] splitRow) throws IOException {
782    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
783      @Override
784      public void call(MasterObserver observer) throws IOException {
785        observer.preSplitRegion(this, tableName, splitRow);
786      }
787    });
788  }
789
790  /**
791   * Invoked just before a split
792   * @param tableName the table where the region belongs to
793   * @param splitRow the split point
794   * @param user the user
795   * @throws IOException
796   */
797  public void preSplitRegionAction(
798      final TableName tableName,
799      final byte[] splitRow,
800      final User user) throws IOException {
801    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
802      @Override
803      public void call(MasterObserver observer) throws IOException {
804        observer.preSplitRegionAction(this, tableName, splitRow);
805      }
806    });
807  }
808
809  /**
810   * Invoked just after a split
811   * @param regionInfoA the new left-hand daughter region
812   * @param regionInfoB the new right-hand daughter region
813   * @param user the user
814   * @throws IOException
815   */
816  public void postCompletedSplitRegionAction(
817      final RegionInfo regionInfoA,
818      final RegionInfo regionInfoB,
819      final User user) throws IOException {
820    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
821      @Override
822      public void call(MasterObserver observer) throws IOException {
823        observer.postCompletedSplitRegionAction(this, regionInfoA, regionInfoB);
824      }
825    });
826  }
827
828  /**
829   * This will be called before update META step as part of split table region procedure.
830   * @param splitKey
831   * @param metaEntries
832   * @param user the user
833   * @throws IOException
834   */
835  public void preSplitBeforeMETAAction(
836      final byte[] splitKey,
837      final List<Mutation> metaEntries,
838      final User user) throws IOException {
839    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
840      @Override
841      public void call(MasterObserver observer) throws IOException {
842        observer.preSplitRegionBeforeMETAAction(this, splitKey, metaEntries);
843      }
844    });
845  }
846
847  /**
848   * This will be called after update META step as part of split table region procedure.
849   * @param user the user
850   * @throws IOException
851   */
852  public void preSplitAfterMETAAction(final User user) throws IOException {
853    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
854      @Override
855      public void call(MasterObserver observer) throws IOException {
856        observer.preSplitRegionAfterMETAAction(this);
857      }
858    });
859  }
860
861  /**
862   * Invoked just after the rollback of a failed split
863   * @param user the user
864   * @throws IOException
865   */
866  public void postRollBackSplitRegionAction(final User user) throws IOException {
867    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
868      @Override
869      public void call(MasterObserver observer) throws IOException {
870        observer.postRollBackSplitRegionAction(this);
871      }
872    });
873  }
874
875  /**
876   * Invoked just before a merge
877   * @param regionsToMerge the regions to merge
878   * @param user the user
879   * @throws IOException
880   */
881  public void preMergeRegionsAction(
882      final RegionInfo[] regionsToMerge, final User user) throws IOException {
883    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
884      @Override
885      public void call(MasterObserver observer) throws IOException {
886        observer.preMergeRegionsAction(this, regionsToMerge);
887      }
888    });
889  }
890
891  /**
892   * Invoked after completing merge regions operation
893   * @param regionsToMerge the regions to merge
894   * @param mergedRegion the new merged region
895   * @param user the user
896   * @throws IOException
897   */
898  public void postCompletedMergeRegionsAction(
899      final RegionInfo[] regionsToMerge,
900      final RegionInfo mergedRegion,
901      final User user) throws IOException {
902    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
903      @Override
904      public void call(MasterObserver observer) throws IOException {
905        observer.postCompletedMergeRegionsAction(this, regionsToMerge, mergedRegion);
906      }
907    });
908  }
909
910  /**
911   * Invoked before merge regions operation writes the new region to hbase:meta
912   * @param regionsToMerge the regions to merge
913   * @param metaEntries the meta entry
914   * @param user the user
915   * @throws IOException
916   */
917  public void preMergeRegionsCommit(
918      final RegionInfo[] regionsToMerge,
919      final @MetaMutationAnnotation List<Mutation> metaEntries,
920      final User user) throws IOException {
921    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
922      @Override
923      public void call(MasterObserver observer) throws IOException {
924        observer.preMergeRegionsCommitAction(this, regionsToMerge, metaEntries);
925      }
926    });
927  }
928
929  /**
930   * Invoked after merge regions operation writes the new region to hbase:meta
931   * @param regionsToMerge the regions to merge
932   * @param mergedRegion the new merged region
933   * @param user the user
934   * @throws IOException
935   */
936  public void postMergeRegionsCommit(
937      final RegionInfo[] regionsToMerge,
938      final RegionInfo mergedRegion,
939      final User user) throws IOException {
940    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
941      @Override
942      public void call(MasterObserver observer) throws IOException {
943        observer.postMergeRegionsCommitAction(this, regionsToMerge, mergedRegion);
944      }
945    });
946  }
947
948  /**
949   * Invoked after rollback merge regions operation
950   * @param regionsToMerge the regions to merge
951   * @param user the user
952   * @throws IOException
953   */
954  public void postRollBackMergeRegionsAction(
955      final RegionInfo[] regionsToMerge, final User user) throws IOException {
956    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
957      @Override
958      public void call(MasterObserver observer) throws IOException {
959        observer.postRollBackMergeRegionsAction(this, regionsToMerge);
960      }
961    });
962  }
963
964  // This hook allows Coprocessor change value of balance switch.
965  public void preBalanceSwitch(final boolean b) throws IOException {
966    if (this.coprocEnvironments.isEmpty()) {
967      return;
968    }
969    execOperation(new MasterObserverOperation() {
970      @Override
971      public void call(MasterObserver observer) throws IOException {
972        observer.preBalanceSwitch(this, b);
973      }
974    });
975  }
976
977  public void postBalanceSwitch(final boolean oldValue, final boolean newValue)
978      throws IOException {
979    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
980      @Override
981      public void call(MasterObserver observer) throws IOException {
982        observer.postBalanceSwitch(this, oldValue, newValue);
983      }
984    });
985  }
986
987  public void preShutdown() throws IOException {
988    // While stopping the cluster all coprocessors method should be executed first then the
989    // coprocessor should be cleaned up.
990    if (coprocEnvironments.isEmpty()) {
991      return;
992    }
993    execShutdown(new MasterObserverOperation() {
994      @Override
995      public void call(MasterObserver observer) throws IOException {
996        observer.preShutdown(this);
997      }
998      @Override
999      public void postEnvCall() {
1000        // invoke coprocessor stop method
1001        shutdown(this.getEnvironment());
1002      }
1003    });
1004  }
1005
1006  public void preStopMaster() throws IOException {
1007    // While stopping master all coprocessors method should be executed first then the coprocessor
1008    // environment should be cleaned up.
1009    if (coprocEnvironments.isEmpty()) {
1010      return;
1011    }
1012    execShutdown(new MasterObserverOperation() {
1013      @Override
1014      public void call(MasterObserver observer) throws IOException {
1015        observer.preStopMaster(this);
1016      }
1017      @Override
1018      public void postEnvCall() {
1019        // invoke coprocessor stop method
1020        shutdown(this.getEnvironment());
1021      }
1022    });
1023  }
1024
1025  public void preMasterInitialization() throws IOException {
1026    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1027      @Override
1028      public void call(MasterObserver observer) throws IOException {
1029        observer.preMasterInitialization(this);
1030      }
1031    });
1032  }
1033
1034  public void postStartMaster() throws IOException {
1035    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1036      @Override
1037      public void call(MasterObserver observer) throws IOException {
1038        observer.postStartMaster(this);
1039      }
1040    });
1041  }
1042
1043  public void preSnapshot(final SnapshotDescription snapshot,
1044      final TableDescriptor hTableDescriptor) throws IOException {
1045    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1046      @Override
1047      public void call(MasterObserver observer) throws IOException {
1048        observer.preSnapshot(this, snapshot, hTableDescriptor);
1049      }
1050    });
1051  }
1052
1053  public void postSnapshot(final SnapshotDescription snapshot,
1054      final TableDescriptor hTableDescriptor) throws IOException {
1055    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1056      @Override
1057      public void call(MasterObserver observer) throws IOException {
1058        observer.postSnapshot(this, snapshot, hTableDescriptor);
1059      }
1060    });
1061  }
1062
1063  public void postCompletedSnapshotAction(SnapshotDescription snapshot,
1064      TableDescriptor hTableDescriptor) throws IOException {
1065    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1066      @Override
1067      public void call(MasterObserver observer) throws IOException {
1068        observer.postCompletedSnapshotAction(this, snapshot, hTableDescriptor);
1069      }
1070    });
1071  }
1072
1073  public void preListSnapshot(final SnapshotDescription snapshot) throws IOException {
1074    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1075      @Override
1076      public void call(MasterObserver observer) throws IOException {
1077        observer.preListSnapshot(this, snapshot);
1078      }
1079    });
1080  }
1081
1082  public void postListSnapshot(final SnapshotDescription snapshot) throws IOException {
1083    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1084      @Override
1085      public void call(MasterObserver observer) throws IOException {
1086        observer.postListSnapshot(this, snapshot);
1087      }
1088    });
1089  }
1090
1091  public void preCloneSnapshot(final SnapshotDescription snapshot,
1092      final TableDescriptor hTableDescriptor) throws IOException {
1093    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1094      @Override
1095      public void call(MasterObserver observer) throws IOException {
1096        observer.preCloneSnapshot(this, snapshot, hTableDescriptor);
1097      }
1098    });
1099  }
1100
1101  public void postCloneSnapshot(final SnapshotDescription snapshot,
1102      final TableDescriptor hTableDescriptor) throws IOException {
1103    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1104      @Override
1105      public void call(MasterObserver observer) throws IOException {
1106        observer.postCloneSnapshot(this, snapshot, hTableDescriptor);
1107      }
1108    });
1109  }
1110
1111  public void preRestoreSnapshot(final SnapshotDescription snapshot,
1112      final TableDescriptor hTableDescriptor) throws IOException {
1113    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1114      @Override
1115      public void call(MasterObserver observer) throws IOException {
1116        observer.preRestoreSnapshot(this, snapshot, hTableDescriptor);
1117      }
1118    });
1119  }
1120
1121  public void postRestoreSnapshot(final SnapshotDescription snapshot,
1122      final TableDescriptor hTableDescriptor) throws IOException {
1123    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1124      @Override
1125      public void call(MasterObserver observer) throws IOException {
1126        observer.postRestoreSnapshot(this, snapshot, hTableDescriptor);
1127      }
1128    });
1129  }
1130
1131  public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
1132    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1133      @Override
1134      public void call(MasterObserver observer) throws IOException {
1135        observer.preDeleteSnapshot(this, snapshot);
1136      }
1137    });
1138  }
1139
1140  public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
1141    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1142      @Override
1143      public void call(MasterObserver observer) throws IOException {
1144        observer.postDeleteSnapshot(this, snapshot);
1145      }
1146    });
1147  }
1148
1149  public void preGetTableDescriptors(final List<TableName> tableNamesList,
1150      final List<TableDescriptor> descriptors, final String regex) throws IOException {
1151    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1152      @Override
1153      public void call(MasterObserver observer) throws IOException {
1154        observer.preGetTableDescriptors(this, tableNamesList, descriptors, regex);
1155      }
1156    });
1157  }
1158
1159  public void postGetTableDescriptors(final List<TableName> tableNamesList,
1160      final List<TableDescriptor> descriptors, final String regex) throws IOException {
1161    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1162      @Override
1163      public void call(MasterObserver observer) throws IOException {
1164        observer.postGetTableDescriptors(this, tableNamesList, descriptors, regex);
1165      }
1166    });
1167  }
1168
1169  public void preGetTableNames(final List<TableDescriptor> descriptors,
1170      final String regex) throws IOException {
1171    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1172      @Override
1173      public void call(MasterObserver observer) throws IOException {
1174        observer.preGetTableNames(this, descriptors, regex);
1175      }
1176    });
1177  }
1178
1179  public void postGetTableNames(final List<TableDescriptor> descriptors,
1180      final String regex) throws IOException {
1181    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1182      @Override
1183      public void call(MasterObserver observer) throws IOException {
1184        observer.postGetTableNames(this, descriptors, regex);
1185      }
1186    });
1187  }
1188
1189  public void preTableFlush(final TableName tableName) throws IOException {
1190    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1191      @Override
1192      public void call(MasterObserver observer) throws IOException {
1193        observer.preTableFlush(this, tableName);
1194      }
1195    });
1196  }
1197
1198  public void postTableFlush(final TableName tableName) throws IOException {
1199    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1200      @Override
1201      public void call(MasterObserver observer) throws IOException {
1202        observer.postTableFlush(this, tableName);
1203      }
1204    });
1205  }
1206
1207  public void preSetUserQuota(
1208      final String user, final GlobalQuotaSettings quotas) throws IOException {
1209    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1210      @Override
1211      public void call(MasterObserver observer) throws IOException {
1212        observer.preSetUserQuota(this, user, quotas);
1213      }
1214    });
1215  }
1216
1217  public void postSetUserQuota(
1218      final String user, final GlobalQuotaSettings quotas) throws IOException {
1219    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1220      @Override
1221      public void call(MasterObserver observer) throws IOException {
1222        observer.postSetUserQuota(this, user, quotas);
1223      }
1224    });
1225  }
1226
1227  public void preSetUserQuota(
1228      final String user, final TableName table, final GlobalQuotaSettings quotas)
1229          throws IOException {
1230    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1231      @Override
1232      public void call(MasterObserver observer) throws IOException {
1233        observer.preSetUserQuota(this, user, table, quotas);
1234      }
1235    });
1236  }
1237
1238  public void postSetUserQuota(
1239      final String user, final TableName table, final GlobalQuotaSettings quotas)
1240          throws IOException {
1241    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1242      @Override
1243      public void call(MasterObserver observer) throws IOException {
1244        observer.postSetUserQuota(this, user, table, quotas);
1245      }
1246    });
1247  }
1248
1249  public void preSetUserQuota(
1250      final String user, final String namespace, final GlobalQuotaSettings quotas)
1251          throws IOException {
1252    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1253      @Override
1254      public void call(MasterObserver observer) throws IOException {
1255        observer.preSetUserQuota(this, user, namespace, quotas);
1256      }
1257    });
1258  }
1259
1260  public void postSetUserQuota(
1261      final String user, final String namespace, final GlobalQuotaSettings quotas)
1262          throws IOException {
1263    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1264      @Override
1265      public void call(MasterObserver observer) throws IOException {
1266        observer.postSetUserQuota(this, user, namespace, quotas);
1267      }
1268    });
1269  }
1270
1271  public void preSetTableQuota(
1272      final TableName table, final GlobalQuotaSettings quotas) throws IOException {
1273    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1274      @Override
1275      public void call(MasterObserver observer) throws IOException {
1276        observer.preSetTableQuota(this, table, quotas);
1277      }
1278    });
1279  }
1280
1281  public void postSetTableQuota(
1282      final TableName table, final GlobalQuotaSettings quotas) throws IOException {
1283    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1284      @Override
1285      public void call(MasterObserver observer) throws IOException {
1286        observer.postSetTableQuota(this, table, quotas);
1287      }
1288    });
1289  }
1290
1291  public void preSetNamespaceQuota(
1292      final String namespace, final GlobalQuotaSettings quotas) throws IOException {
1293    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1294      @Override
1295      public void call(MasterObserver observer) throws IOException {
1296        observer.preSetNamespaceQuota(this, namespace, quotas);
1297      }
1298    });
1299  }
1300
1301  public void postSetNamespaceQuota(
1302      final String namespace, final GlobalQuotaSettings quotas) throws IOException{
1303    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1304      @Override
1305      public void call(MasterObserver observer) throws IOException {
1306        observer.postSetNamespaceQuota(this, namespace, quotas);
1307      }
1308    });
1309  }
1310
1311  public void preSetRegionServerQuota(final String regionServer, final GlobalQuotaSettings quotas)
1312      throws IOException {
1313    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1314      @Override
1315      public void call(MasterObserver observer) throws IOException {
1316        observer.preSetRegionServerQuota(this, regionServer, quotas);
1317      }
1318    });
1319  }
1320
1321  public void postSetRegionServerQuota(final String regionServer, final GlobalQuotaSettings quotas)
1322      throws IOException {
1323    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1324      @Override
1325      public void call(MasterObserver observer) throws IOException {
1326        observer.postSetRegionServerQuota(this, regionServer, quotas);
1327      }
1328    });
1329  }
1330
1331  public void preMoveServersAndTables(final Set<Address> servers, final Set<TableName> tables,
1332      final String targetGroup) throws IOException {
1333    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1334      @Override
1335      public void call(MasterObserver observer) throws IOException {
1336        observer.preMoveServersAndTables(this, servers, tables, targetGroup);
1337      }
1338    });
1339  }
1340
1341  public void postMoveServersAndTables(final Set<Address> servers, final Set<TableName> tables,
1342      final String targetGroup) throws IOException {
1343    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1344      @Override
1345      public void call(MasterObserver observer) throws IOException {
1346        observer.postMoveServersAndTables(this, servers, tables, targetGroup);
1347      }
1348    });
1349  }
1350
1351  public void preMoveServers(final Set<Address> servers, final String targetGroup)
1352      throws IOException {
1353    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1354      @Override
1355      public void call(MasterObserver observer) throws IOException {
1356        observer.preMoveServers(this, servers, targetGroup);
1357      }
1358    });
1359  }
1360
1361  public void postMoveServers(final Set<Address> servers, final String targetGroup)
1362      throws IOException {
1363    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1364      @Override
1365      public void call(MasterObserver observer) throws IOException {
1366        observer.postMoveServers(this, servers, targetGroup);
1367      }
1368    });
1369  }
1370
1371  public void preMoveTables(final Set<TableName> tables, final String targetGroup)
1372      throws IOException {
1373    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1374      @Override
1375      public void call(MasterObserver observer) throws IOException {
1376        observer.preMoveTables(this, tables, targetGroup);
1377      }
1378    });
1379  }
1380
1381  public void postMoveTables(final Set<TableName> tables, final String targetGroup)
1382      throws IOException {
1383    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1384      @Override
1385      public void call(MasterObserver observer) throws IOException {
1386        observer.postMoveTables(this, tables, targetGroup);
1387      }
1388    });
1389  }
1390
1391  public void preAddRSGroup(final String name)
1392      throws IOException {
1393    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1394      @Override
1395      public void call(MasterObserver observer) throws IOException {
1396        observer.preAddRSGroup(this, name);
1397      }
1398    });
1399  }
1400
1401  public void postAddRSGroup(final String name)
1402      throws IOException {
1403    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1404      @Override
1405      public void call(MasterObserver observer) throws IOException {
1406        observer.postAddRSGroup(this, name);
1407      }
1408    });
1409  }
1410
1411  public void preRemoveRSGroup(final String name)
1412      throws IOException {
1413    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1414      @Override
1415      public void call(MasterObserver observer) throws IOException {
1416        observer.preRemoveRSGroup(this, name);
1417      }
1418    });
1419  }
1420
1421  public void postRemoveRSGroup(final String name)
1422      throws IOException {
1423    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1424      @Override
1425      public void call(MasterObserver observer) throws IOException {
1426        observer.postRemoveRSGroup(this, name);
1427      }
1428    });
1429  }
1430
1431  public void preBalanceRSGroup(final String name)
1432      throws IOException {
1433    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1434      @Override
1435      public void call(MasterObserver observer) throws IOException {
1436        observer.preBalanceRSGroup(this, name);
1437      }
1438    });
1439  }
1440
1441  public void postBalanceRSGroup(final String name, final boolean balanceRan)
1442      throws IOException {
1443    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1444      @Override
1445      public void call(MasterObserver observer) throws IOException {
1446        observer.postBalanceRSGroup(this, name, balanceRan);
1447      }
1448    });
1449  }
1450
1451  public void preRemoveServers(final Set<Address> servers)
1452      throws IOException {
1453    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1454      @Override
1455      public void call(MasterObserver observer) throws IOException {
1456        observer.preRemoveServers(this, servers);
1457      }
1458    });
1459  }
1460
1461  public void postRemoveServers(final Set<Address> servers)
1462      throws IOException {
1463    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1464      @Override
1465      public void call(MasterObserver observer) throws IOException {
1466        observer.postRemoveServers(this, servers);
1467      }
1468    });
1469  }
1470
1471  public void preGetRSGroupInfo(final String groupName) throws IOException {
1472    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1473      @Override
1474      public void call(MasterObserver observer) throws IOException {
1475        observer.preGetRSGroupInfo(this, groupName);
1476      }
1477    });
1478  }
1479
1480  public void postGetRSGroupInfo(final String groupName) throws IOException {
1481    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1482      @Override
1483      public void call(MasterObserver observer) throws IOException {
1484        observer.postGetRSGroupInfo(this, groupName);
1485      }
1486    });
1487  }
1488
1489  public void preGetRSGroupInfoOfTable(final TableName tableName) throws IOException {
1490    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1491      @Override
1492      public void call(MasterObserver observer) throws IOException {
1493        observer.preGetRSGroupInfoOfTable(this, tableName);
1494      }
1495    });
1496  }
1497
1498  public void postGetRSGroupInfoOfTable(final TableName tableName) throws IOException {
1499    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1500      @Override
1501      public void call(MasterObserver observer) throws IOException {
1502        observer.postGetRSGroupInfoOfTable(this, tableName);
1503      }
1504    });
1505  }
1506
1507  public void preListRSGroups() throws IOException {
1508    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1509      @Override
1510      public void call(MasterObserver observer) throws IOException {
1511        observer.preListRSGroups(this);
1512      }
1513    });
1514  }
1515
1516  public void postListRSGroups() throws IOException {
1517    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1518      @Override
1519      public void call(MasterObserver observer) throws IOException {
1520        observer.postListRSGroups(this);
1521      }
1522    });
1523  }
1524
1525  public void preListTablesInRSGroup(final String groupName) throws IOException {
1526    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1527
1528      @Override
1529      protected void call(MasterObserver observer) throws IOException {
1530        observer.preListTablesInRSGroup(this, groupName);
1531      }
1532    });
1533  }
1534
1535  public void postListTablesInRSGroup(final String groupName) throws IOException {
1536    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1537
1538      @Override
1539      protected void call(MasterObserver observer) throws IOException {
1540        observer.postListTablesInRSGroup(this, groupName);
1541      }
1542    });
1543  }
1544
1545  public void preRenameRSGroup(final String oldName, final String newName) throws IOException {
1546    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1547
1548      @Override
1549      protected void call(MasterObserver observer) throws IOException {
1550        observer.preRenameRSGroup(this, oldName, newName);
1551      }
1552    });
1553  }
1554
1555  public void postRenameRSGroup(final String oldName, final String newName) throws IOException {
1556    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1557
1558      @Override
1559      protected void call(MasterObserver observer) throws IOException {
1560        observer.postRenameRSGroup(this, oldName, newName);
1561      }
1562    });
1563  }
1564
1565  public void preUpdateRSGroupConfig(final String groupName,
1566                                     final Map<String, String> configuration) throws IOException {
1567    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1568      @Override
1569      protected void call(MasterObserver observer) throws IOException {
1570        observer.preUpdateRSGroupConfig(this, groupName, configuration);
1571      }
1572    });
1573  }
1574
1575  public void postUpdateRSGroupConfig(final String groupName,
1576                                      final Map<String, String> configuration) throws IOException {
1577    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1578      @Override
1579      protected void call(MasterObserver observer) throws IOException {
1580        observer.postUpdateRSGroupConfig(this, groupName, configuration);
1581      }
1582    });
1583  }
1584
1585  public void preGetConfiguredNamespacesAndTablesInRSGroup(final String groupName)
1586    throws IOException {
1587    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1588
1589      @Override
1590      protected void call(MasterObserver observer) throws IOException {
1591        observer.preGetConfiguredNamespacesAndTablesInRSGroup(this, groupName);
1592      }
1593    });
1594  }
1595
1596  public void postGetConfiguredNamespacesAndTablesInRSGroup(final String groupName)
1597    throws IOException {
1598    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1599
1600      @Override
1601      protected void call(MasterObserver observer) throws IOException {
1602        observer.postGetConfiguredNamespacesAndTablesInRSGroup(this, groupName);
1603      }
1604    });
1605  }
1606
1607  public void preGetRSGroupInfoOfServer(final Address server) throws IOException {
1608    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1609      @Override
1610      public void call(MasterObserver observer) throws IOException {
1611        observer.preGetRSGroupInfoOfServer(this, server);
1612      }
1613    });
1614  }
1615
1616  public void postGetRSGroupInfoOfServer(final Address server) throws IOException {
1617    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1618      @Override
1619      public void call(MasterObserver observer) throws IOException {
1620        observer.postGetRSGroupInfoOfServer(this, server);
1621      }
1622    });
1623  }
1624
1625  public void preAddReplicationPeer(final String peerId, final ReplicationPeerConfig peerConfig)
1626      throws IOException {
1627    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1628      @Override
1629      public void call(MasterObserver observer) throws IOException {
1630        observer.preAddReplicationPeer(this, peerId, peerConfig);
1631      }
1632    });
1633  }
1634
1635  public void postAddReplicationPeer(final String peerId, final ReplicationPeerConfig peerConfig)
1636      throws IOException {
1637    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1638      @Override
1639      public void call(MasterObserver observer) throws IOException {
1640        observer.postAddReplicationPeer(this, peerId, peerConfig);
1641      }
1642    });
1643  }
1644
1645  public void preRemoveReplicationPeer(final String peerId) throws IOException {
1646    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1647      @Override
1648      public void call(MasterObserver observer) throws IOException {
1649        observer.preRemoveReplicationPeer(this, peerId);
1650      }
1651    });
1652  }
1653
1654  public void postRemoveReplicationPeer(final String peerId) throws IOException {
1655    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1656      @Override
1657      public void call(MasterObserver observer) throws IOException {
1658        observer.postRemoveReplicationPeer(this, peerId);
1659      }
1660    });
1661  }
1662
1663  public void preEnableReplicationPeer(final String peerId) throws IOException {
1664    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1665      @Override
1666      public void call(MasterObserver observer) throws IOException {
1667        observer.preEnableReplicationPeer(this, peerId);
1668      }
1669    });
1670  }
1671
1672  public void postEnableReplicationPeer(final String peerId) throws IOException {
1673    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1674      @Override
1675      public void call(MasterObserver observer) throws IOException {
1676        observer.postEnableReplicationPeer(this, peerId);
1677      }
1678    });
1679  }
1680
1681  public void preDisableReplicationPeer(final String peerId) throws IOException {
1682    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1683      @Override
1684      public void call(MasterObserver observer) throws IOException {
1685        observer.preDisableReplicationPeer(this, peerId);
1686      }
1687    });
1688  }
1689
1690  public void postDisableReplicationPeer(final String peerId) throws IOException {
1691    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1692      @Override
1693      public void call(MasterObserver observer) throws IOException {
1694        observer.postDisableReplicationPeer(this, peerId);
1695      }
1696    });
1697  }
1698
1699  public void preGetReplicationPeerConfig(final String peerId) throws IOException {
1700    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1701      @Override
1702      public void call(MasterObserver observer) throws IOException {
1703        observer.preGetReplicationPeerConfig(this, peerId);
1704      }
1705    });
1706  }
1707
1708  public void postGetReplicationPeerConfig(final String peerId) throws IOException {
1709    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1710      @Override
1711      public void call(MasterObserver observer) throws IOException {
1712        observer.postGetReplicationPeerConfig(this, peerId);
1713      }
1714    });
1715  }
1716
1717  public void preUpdateReplicationPeerConfig(final String peerId,
1718      final ReplicationPeerConfig peerConfig) throws IOException {
1719    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1720      @Override
1721      public void call(MasterObserver observer) throws IOException {
1722        observer.preUpdateReplicationPeerConfig(this, peerId, peerConfig);
1723      }
1724    });
1725  }
1726
1727  public void postUpdateReplicationPeerConfig(final String peerId,
1728      final ReplicationPeerConfig peerConfig) throws IOException {
1729    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1730      @Override
1731      public void call(MasterObserver observer) throws IOException {
1732        observer.postUpdateReplicationPeerConfig(this, peerId, peerConfig);
1733      }
1734    });
1735  }
1736
1737  public void preListReplicationPeers(final String regex) throws IOException {
1738    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1739      @Override
1740      public void call(MasterObserver observer) throws IOException {
1741        observer.preListReplicationPeers(this, regex);
1742      }
1743    });
1744  }
1745
1746  public void postListReplicationPeers(final String regex) throws IOException {
1747    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1748      @Override
1749      public void call(MasterObserver observer) throws IOException {
1750        observer.postListReplicationPeers(this, regex);
1751      }
1752    });
1753  }
1754
1755  public void preTransitReplicationPeerSyncReplicationState(String peerId,
1756      SyncReplicationState state) throws IOException {
1757    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1758      @Override
1759      public void call(MasterObserver observer) throws IOException {
1760        observer.preTransitReplicationPeerSyncReplicationState(this, peerId, state);
1761      }
1762    });
1763  }
1764
1765  public void postTransitReplicationPeerSyncReplicationState(String peerId,
1766      SyncReplicationState from, SyncReplicationState to) throws IOException {
1767    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1768      @Override
1769      public void call(MasterObserver observer) throws IOException {
1770        observer.postTransitReplicationPeerSyncReplicationState(this, peerId, from, to);
1771      }
1772    });
1773  }
1774
1775  public void preRequestLock(String namespace, TableName tableName, RegionInfo[] regionInfos,
1776      LockType type, String description) throws IOException {
1777    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1778      @Override
1779      public void call(MasterObserver observer) throws IOException {
1780        observer.preRequestLock(this, namespace, tableName, regionInfos, description);
1781      }
1782    });
1783  }
1784
1785  public void postRequestLock(String namespace, TableName tableName, RegionInfo[] regionInfos,
1786      LockType type, String description) throws IOException {
1787    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1788      @Override
1789      public void call(MasterObserver observer) throws IOException {
1790        observer.postRequestLock(this, namespace, tableName, regionInfos, description);
1791      }
1792    });
1793  }
1794
1795  public void preLockHeartbeat(LockProcedure proc, boolean keepAlive) throws IOException {
1796    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1797      @Override
1798      public void call(MasterObserver observer) throws IOException {
1799        observer.preLockHeartbeat(this, proc.getTableName(), proc.getDescription());
1800      }
1801    });
1802  }
1803
1804  public void postLockHeartbeat(LockProcedure proc, boolean keepAlive) throws IOException {
1805    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1806      @Override
1807      public void call(MasterObserver observer) throws IOException {
1808        observer.postLockHeartbeat(this);
1809      }
1810    });
1811  }
1812
1813  public void preGetClusterMetrics() throws IOException {
1814    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1815      @Override
1816      public void call(MasterObserver observer) throws IOException {
1817        observer.preGetClusterMetrics(this);
1818      }
1819    });
1820  }
1821
1822  public void postGetClusterMetrics(ClusterMetrics status) throws IOException {
1823    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1824      @Override
1825      public void call(MasterObserver observer) throws IOException {
1826        observer.postGetClusterMetrics(this, status);
1827      }
1828    });
1829  }
1830
1831  public void preClearDeadServers() throws IOException {
1832    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1833      @Override
1834      public void call(MasterObserver observer) throws IOException {
1835        observer.preClearDeadServers(this);
1836      }
1837    });
1838  }
1839
1840  public void postClearDeadServers(List<ServerName> servers,
1841      List<ServerName> notClearedServers) throws IOException {
1842    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1843      @Override
1844      public void call(MasterObserver observer) throws IOException {
1845        observer.postClearDeadServers(this, servers, notClearedServers);
1846      }
1847    });
1848  }
1849
1850  public void preDecommissionRegionServers(List<ServerName> servers, boolean offload)
1851      throws IOException {
1852    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1853      @Override
1854      public void call(MasterObserver observer) throws IOException {
1855        observer.preDecommissionRegionServers(this, servers, offload);
1856      }
1857    });
1858  }
1859
1860  public void postDecommissionRegionServers(List<ServerName> servers, boolean offload)
1861      throws IOException {
1862    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1863      @Override
1864      public void call(MasterObserver observer) throws IOException {
1865        observer.postDecommissionRegionServers(this, servers, offload);
1866      }
1867    });
1868  }
1869
1870  public void preListDecommissionedRegionServers() throws IOException {
1871    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1872      @Override
1873      public void call(MasterObserver observer) throws IOException {
1874        observer.preListDecommissionedRegionServers(this);
1875      }
1876    });
1877  }
1878
1879  public void postListDecommissionedRegionServers() throws IOException {
1880    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1881      @Override
1882      public void call(MasterObserver observer) throws IOException {
1883        observer.postListDecommissionedRegionServers(this);
1884      }
1885    });
1886  }
1887
1888  public void preRecommissionRegionServer(ServerName server, List<byte[]> encodedRegionNames)
1889      throws IOException {
1890    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1891      @Override
1892      public void call(MasterObserver observer) throws IOException {
1893        observer.preRecommissionRegionServer(this, server, encodedRegionNames);
1894      }
1895    });
1896  }
1897
1898  public void postRecommissionRegionServer(ServerName server, List<byte[]> encodedRegionNames)
1899      throws IOException {
1900    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1901      @Override
1902      public void call(MasterObserver observer) throws IOException {
1903        observer.postRecommissionRegionServer(this, server, encodedRegionNames);
1904      }
1905    });
1906  }
1907
1908  public void preSwitchRpcThrottle(boolean enable) throws IOException {
1909    execOperation(coprocEnvironments.isEmpty() ? null :new MasterObserverOperation() {
1910      @Override
1911      public void call(MasterObserver observer) throws IOException {
1912        observer.preSwitchRpcThrottle(this, enable);
1913      }
1914    });
1915  }
1916
1917  public void postSwitchRpcThrottle(final boolean oldValue, final boolean newValue)
1918      throws IOException {
1919    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1920      @Override
1921      public void call(MasterObserver observer) throws IOException {
1922        observer.postSwitchRpcThrottle(this, oldValue, newValue);
1923      }
1924    });
1925  }
1926
1927  public void preIsRpcThrottleEnabled() throws IOException {
1928    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1929      @Override
1930      public void call(MasterObserver observer) throws IOException {
1931        observer.preIsRpcThrottleEnabled(this);
1932      }
1933    });
1934  }
1935
1936  public void postIsRpcThrottleEnabled(boolean enabled) throws IOException {
1937    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1938      @Override
1939      public void call(MasterObserver observer) throws IOException {
1940        observer.postIsRpcThrottleEnabled(this, enabled);
1941      }
1942    });
1943  }
1944
1945  public void preSwitchExceedThrottleQuota(boolean enable) throws IOException {
1946    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1947      @Override
1948      public void call(MasterObserver observer) throws IOException {
1949        observer.preSwitchExceedThrottleQuota(this, enable);
1950      }
1951    });
1952  }
1953
1954  public void postSwitchExceedThrottleQuota(final boolean oldValue, final boolean newValue)
1955      throws IOException {
1956    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1957      @Override
1958      public void call(MasterObserver observer) throws IOException {
1959        observer.postSwitchExceedThrottleQuota(this, oldValue, newValue);
1960      }
1961    });
1962  }
1963
1964  public void preGrant(UserPermission userPermission, boolean mergeExistingPermissions)
1965      throws IOException {
1966    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1967      @Override
1968      public void call(MasterObserver observer) throws IOException {
1969        observer.preGrant(this, userPermission, mergeExistingPermissions);
1970      }
1971    });
1972  }
1973
1974  public void postGrant(UserPermission userPermission, boolean mergeExistingPermissions)
1975      throws IOException {
1976    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1977      @Override
1978      public void call(MasterObserver observer) throws IOException {
1979        observer.postGrant(this, userPermission, mergeExistingPermissions);
1980      }
1981    });
1982  }
1983
1984  public void preRevoke(UserPermission userPermission) throws IOException {
1985    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1986      @Override
1987      public void call(MasterObserver observer) throws IOException {
1988        observer.preRevoke(this, userPermission);
1989      }
1990    });
1991  }
1992
1993  public void postRevoke(UserPermission userPermission) throws IOException {
1994    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
1995      @Override
1996      public void call(MasterObserver observer) throws IOException {
1997        observer.postRevoke(this, userPermission);
1998      }
1999    });
2000  }
2001
2002  public void preGetUserPermissions(String userName, String namespace, TableName tableName,
2003      byte[] family, byte[] qualifier) throws IOException {
2004    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2005      @Override
2006      public void call(MasterObserver observer) throws IOException {
2007        observer.preGetUserPermissions(this, userName, namespace, tableName, family, qualifier);
2008      }
2009    });
2010  }
2011
2012  public void postGetUserPermissions(String userName, String namespace, TableName tableName,
2013      byte[] family, byte[] qualifier) throws IOException {
2014    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2015      @Override
2016      public void call(MasterObserver observer) throws IOException {
2017        observer.postGetUserPermissions(this, userName, namespace, tableName, family, qualifier);
2018      }
2019    });
2020  }
2021
2022  public void preHasUserPermissions(String userName, List<Permission> permissions)
2023      throws IOException {
2024    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2025      @Override
2026      public void call(MasterObserver observer) throws IOException {
2027        observer.preHasUserPermissions(this, userName, permissions);
2028      }
2029    });
2030  }
2031
2032  public void postHasUserPermissions(String userName, List<Permission> permissions)
2033      throws IOException {
2034    execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
2035      @Override
2036      public void call(MasterObserver observer) throws IOException {
2037        observer.postHasUserPermissions(this, userName, permissions);
2038      }
2039    });
2040  }
2041}