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