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