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