| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.hadoop.hbase.master; |
| |
| import com.google.common.net.HostAndPort; |
| |
| import java.io.IOException; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.apache.commons.lang.ClassUtils; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.hbase.Coprocessor; |
| import org.apache.hadoop.hbase.HColumnDescriptor; |
| import org.apache.hadoop.hbase.HRegionInfo; |
| import org.apache.hadoop.hbase.HTableDescriptor; |
| import org.apache.hadoop.hbase.NamespaceDescriptor; |
| import org.apache.hadoop.hbase.ProcedureInfo; |
| import org.apache.hadoop.hbase.ServerName; |
| import org.apache.hadoop.hbase.TableName; |
| import org.apache.hadoop.hbase.classification.InterfaceAudience; |
| import org.apache.hadoop.hbase.client.MasterSwitchType; |
| import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; |
| import org.apache.hadoop.hbase.coprocessor.CoprocessorService; |
| import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; |
| import org.apache.hadoop.hbase.coprocessor.MasterObserver; |
| import org.apache.hadoop.hbase.coprocessor.ObserverContext; |
| import org.apache.hadoop.hbase.ipc.RpcServer; |
| import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; |
| import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; |
| import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription; |
| import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas; |
| import org.apache.hadoop.hbase.security.User; |
| |
| /** |
| * Provides the coprocessor framework and environment for master oriented |
| * operations. {@link HMaster} interacts with the loaded coprocessors |
| * through this class. |
| */ |
| @InterfaceAudience.Private |
| public class MasterCoprocessorHost |
| extends CoprocessorHost<MasterCoprocessorHost.MasterEnvironment> { |
| |
| private static final Log LOG = LogFactory.getLog(MasterCoprocessorHost.class); |
| |
| /** |
| * Coprocessor environment extension providing access to master related |
| * services. |
| */ |
| static class MasterEnvironment extends CoprocessorHost.Environment |
| implements MasterCoprocessorEnvironment { |
| private MasterServices masterServices; |
| final boolean supportGroupCPs; |
| |
| public MasterEnvironment(final Class<?> implClass, final Coprocessor impl, |
| final int priority, final int seq, final Configuration conf, |
| final MasterServices services) { |
| super(impl, priority, seq, conf); |
| this.masterServices = services; |
| supportGroupCPs = !useLegacyMethod(impl.getClass(), |
| "preBalanceRSGroup", ObserverContext.class, String.class); |
| } |
| |
| public MasterServices getMasterServices() { |
| return masterServices; |
| } |
| } |
| |
| private MasterServices masterServices; |
| |
| public MasterCoprocessorHost(final MasterServices services, final Configuration conf) { |
| super(services); |
| this.conf = conf; |
| this.masterServices = services; |
| // Log the state of coprocessor loading here; should appear only once or |
| // twice in the daemon log, depending on HBase version, because there is |
| // only one MasterCoprocessorHost instance in the master process |
| boolean coprocessorsEnabled = conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, |
| DEFAULT_COPROCESSORS_ENABLED); |
| LOG.info("System coprocessor loading is " + (coprocessorsEnabled ? "enabled" : "disabled")); |
| loadSystemCoprocessors(conf, MASTER_COPROCESSOR_CONF_KEY); |
| } |
| |
| @Override |
| public MasterEnvironment createEnvironment(final Class<?> implClass, |
| final Coprocessor instance, final int priority, final int seq, |
| final Configuration conf) { |
| for (Object itf : ClassUtils.getAllInterfaces(implClass)) { |
| Class<?> c = (Class<?>) itf; |
| if (CoprocessorService.class.isAssignableFrom(c)) { |
| masterServices.registerService(((CoprocessorService)instance).getService()); |
| } |
| } |
| return new MasterEnvironment(implClass, instance, priority, seq, conf, |
| masterServices); |
| } |
| |
| public boolean preCreateNamespace(final NamespaceDescriptor ns) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preCreateNamespace(ctx, ns); |
| } |
| }); |
| } |
| |
| public void postCreateNamespace(final NamespaceDescriptor ns) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postCreateNamespace(ctx, ns); |
| } |
| }); |
| } |
| |
| public boolean preDeleteNamespace(final String namespaceName) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDeleteNamespace(ctx, namespaceName); |
| } |
| }); |
| } |
| |
| public void postDeleteNamespace(final String namespaceName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDeleteNamespace(ctx, namespaceName); |
| } |
| }); |
| } |
| |
| public boolean preModifyNamespace(final NamespaceDescriptor ns) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preModifyNamespace(ctx, ns); |
| } |
| }); |
| } |
| |
| public void postModifyNamespace(final NamespaceDescriptor ns) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postModifyNamespace(ctx, ns); |
| } |
| }); |
| } |
| |
| public void preGetNamespaceDescriptor(final String namespaceName) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preGetNamespaceDescriptor(ctx, namespaceName); |
| } |
| }); |
| } |
| |
| public void postGetNamespaceDescriptor(final NamespaceDescriptor ns) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postGetNamespaceDescriptor(ctx, ns); |
| } |
| }); |
| } |
| |
| public boolean preListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors) |
| throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preListNamespaceDescriptors(ctx, descriptors); |
| } |
| }); |
| } |
| |
| public void postListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postListNamespaceDescriptors(ctx, descriptors); |
| } |
| }); |
| } |
| |
| /* Implementation of hooks for invoking MasterObservers */ |
| |
| public void preCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preCreateTable(ctx, htd, regions); |
| } |
| }); |
| } |
| |
| public void postCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postCreateTable(ctx, htd, regions); |
| } |
| }); |
| } |
| |
| public void preCreateTableAction(final HTableDescriptor htd, final HRegionInfo[] regions, |
| final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preCreateTableHandler(ctx, htd, regions); |
| oserver.preCreateTableAction(ctx, htd, regions); |
| } |
| }); |
| } |
| |
| public void postCompletedCreateTableAction( |
| final HTableDescriptor htd, final HRegionInfo[] regions, final User user) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postCreateTableHandler(ctx, htd, regions); |
| oserver.postCompletedCreateTableAction(ctx, htd, regions); |
| } |
| }); |
| } |
| |
| public void preDeleteTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDeleteTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postDeleteTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDeleteTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preDeleteTableAction(final TableName tableName, final User user) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDeleteTableHandler(ctx, tableName); |
| oserver.preDeleteTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postCompletedDeleteTableAction(final TableName tableName, final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDeleteTableHandler(ctx, tableName); |
| oserver.postCompletedDeleteTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preTruncateTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preTruncateTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postTruncateTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postTruncateTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preTruncateTableAction(final TableName tableName, final User user) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preTruncateTableHandler(ctx, tableName); |
| oserver.preTruncateTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postCompletedTruncateTableAction(final TableName tableName, final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postTruncateTableHandler(ctx, tableName); |
| oserver.postCompletedTruncateTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preModifyTable(final TableName tableName, final HTableDescriptor htd) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preModifyTable(ctx, tableName, htd); |
| } |
| }); |
| } |
| |
| public void postModifyTable(final TableName tableName, final HTableDescriptor htd) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postModifyTable(ctx, tableName, htd); |
| } |
| }); |
| } |
| |
| public void preModifyTableAction(final TableName tableName, final HTableDescriptor htd, |
| final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preModifyTableHandler(ctx, tableName, htd); |
| oserver.preModifyTableAction(ctx, tableName, htd); |
| } |
| }); |
| } |
| |
| public void postCompletedModifyTableAction(final TableName tableName, final HTableDescriptor htd, |
| final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postModifyTableHandler(ctx, tableName, htd); |
| oserver.postCompletedModifyTableAction(ctx, tableName, htd); |
| } |
| }); |
| } |
| |
| public boolean preAddColumn(final TableName tableName, final HColumnDescriptor columnFamily) |
| throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preAddColumn(ctx, tableName, columnFamily); |
| oserver.preAddColumnFamily(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public void postAddColumn(final TableName tableName, final HColumnDescriptor columnFamily) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postAddColumn(ctx, tableName, columnFamily); |
| oserver.postAddColumnFamily(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public boolean preAddColumnFamilyAction( |
| final TableName tableName, |
| final HColumnDescriptor columnFamily, |
| final User user) |
| throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preAddColumnHandler(ctx, tableName, columnFamily); |
| oserver.preAddColumnFamilyAction(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public void postCompletedAddColumnFamilyAction( |
| final TableName tableName, |
| final HColumnDescriptor columnFamily, |
| final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postAddColumnHandler(ctx, tableName, columnFamily); |
| oserver.postCompletedAddColumnFamilyAction(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public boolean preModifyColumn(final TableName tableName, final HColumnDescriptor columnFamily) |
| throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preModifyColumn(ctx, tableName, columnFamily); |
| oserver.preModifyColumnFamily(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public void postModifyColumn(final TableName tableName, final HColumnDescriptor columnFamily) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postModifyColumn(ctx, tableName, columnFamily); |
| oserver.postModifyColumnFamily(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public boolean preModifyColumnFamilyAction( |
| final TableName tableName, |
| final HColumnDescriptor columnFamily, |
| final User user) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preModifyColumnHandler(ctx, tableName, columnFamily); |
| oserver.preModifyColumnFamilyAction(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public void postCompletedModifyColumnFamilyAction( |
| final TableName tableName, |
| final HColumnDescriptor columnFamily, |
| final User user) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postModifyColumnHandler(ctx, tableName, columnFamily); |
| oserver.postCompletedModifyColumnFamilyAction(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public boolean preDeleteColumn(final TableName tableName, final byte[] columnFamily) |
| throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDeleteColumn(ctx, tableName, columnFamily); |
| oserver.preDeleteColumnFamily(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public void postDeleteColumn(final TableName tableName, final byte[] columnFamily) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDeleteColumn(ctx, tableName, columnFamily); |
| oserver.postDeleteColumnFamily(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public boolean preDeleteColumnFamilyAction( |
| final TableName tableName, |
| final byte[] columnFamily, |
| final User user) |
| throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDeleteColumnHandler(ctx, tableName, columnFamily); |
| oserver.preDeleteColumnFamilyAction(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public void postCompletedDeleteColumnFamilyAction( |
| final TableName tableName, final byte[] columnFamily, final User user) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDeleteColumnHandler(ctx, tableName, columnFamily); |
| oserver.postCompletedDeleteColumnFamilyAction(ctx, tableName, columnFamily); |
| } |
| }); |
| } |
| |
| public void preEnableTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preEnableTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postEnableTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postEnableTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preEnableTableAction(final TableName tableName, final User user) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preEnableTableHandler(ctx, tableName); |
| oserver.preEnableTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postCompletedEnableTableAction(final TableName tableName, final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postEnableTableHandler(ctx, tableName); |
| oserver.postCompletedEnableTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preDisableTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDisableTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postDisableTable(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDisableTable(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preDisableTableAction(final TableName tableName, final User user) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDisableTableHandler(ctx, tableName); |
| oserver.preDisableTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postCompletedDisableTableAction(final TableName tableName, final User user) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDisableTableHandler(ctx, tableName); |
| oserver.postCompletedDisableTableAction(ctx, tableName); |
| } |
| }); |
| } |
| |
| public boolean preAbortProcedure( |
| final ProcedureExecutor<MasterProcedureEnv> procEnv, |
| final long procId) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preAbortProcedure(ctx, procEnv, procId); |
| } |
| }); |
| } |
| |
| public void postAbortProcedure() throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postAbortProcedure(ctx); |
| } |
| }); |
| } |
| |
| public boolean preListProcedures() throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preListProcedures(ctx); |
| } |
| }); |
| } |
| |
| public void postListProcedures(final List<ProcedureInfo> procInfoList) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postListProcedures(ctx, procInfoList); |
| } |
| }); |
| } |
| |
| public boolean preMove(final HRegionInfo region, final ServerName srcServer, |
| final ServerName destServer) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preMove(ctx, region, srcServer, destServer); |
| } |
| }); |
| } |
| |
| public void postMove(final HRegionInfo region, final ServerName srcServer, |
| final ServerName destServer) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postMove(ctx, region, srcServer, destServer); |
| } |
| }); |
| } |
| |
| public boolean preAssign(final HRegionInfo regionInfo) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preAssign(ctx, regionInfo); |
| } |
| }); |
| } |
| |
| public void postAssign(final HRegionInfo regionInfo) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postAssign(ctx, regionInfo); |
| } |
| }); |
| } |
| |
| public boolean preUnassign(final HRegionInfo regionInfo, final boolean force) |
| throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preUnassign(ctx, regionInfo, force); |
| } |
| }); |
| } |
| |
| public void postUnassign(final HRegionInfo regionInfo, final boolean force) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postUnassign(ctx, regionInfo, force); |
| } |
| }); |
| } |
| |
| public void preRegionOffline(final HRegionInfo regionInfo) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preRegionOffline(ctx, regionInfo); |
| } |
| }); |
| } |
| |
| public void postRegionOffline(final HRegionInfo regionInfo) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postRegionOffline(ctx, regionInfo); |
| } |
| }); |
| } |
| |
| public void preDispatchMerge(final HRegionInfo regionInfoA, final HRegionInfo regionInfoB) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDispatchMerge(ctx, regionInfoA, regionInfoB); |
| } |
| }); |
| } |
| |
| public void postDispatchMerge(final HRegionInfo regionInfoA, final HRegionInfo regionInfoB) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDispatchMerge(ctx, regionInfoA, regionInfoB); |
| } |
| }); |
| } |
| |
| public boolean preBalance() throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preBalance(ctx); |
| } |
| }); |
| } |
| |
| public void postBalance(final List<RegionPlan> plans) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postBalance(ctx, plans); |
| } |
| }); |
| } |
| |
| public boolean preSetSplitOrMergeEnabled(final boolean newValue, |
| final MasterSwitchType switchType) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preSetSplitOrMergeEnabled(ctx, newValue, switchType); |
| } |
| }); |
| } |
| |
| public void postSetSplitOrMergeEnabled(final boolean newValue, |
| final MasterSwitchType switchType) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postSetSplitOrMergeEnabled(ctx, newValue, switchType); |
| } |
| }); |
| } |
| |
| public boolean preBalanceSwitch(final boolean b) throws IOException { |
| return execOperationWithResult(b, coprocessors.isEmpty() ? null : |
| new CoprocessorOperationWithResult<Boolean>() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| setResult(oserver.preBalanceSwitch(ctx, getResult())); |
| } |
| }); |
| } |
| |
| public void postBalanceSwitch(final boolean oldValue, final boolean newValue) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postBalanceSwitch(ctx, oldValue, newValue); |
| } |
| }); |
| } |
| |
| public void preShutdown() throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preShutdown(ctx); |
| } |
| @Override |
| public void postEnvCall(MasterEnvironment env) { |
| // invoke coprocessor stop method |
| shutdown(env); |
| } |
| }); |
| } |
| |
| public void preStopMaster() throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preStopMaster(ctx); |
| } |
| @Override |
| public void postEnvCall(MasterEnvironment env) { |
| // invoke coprocessor stop method |
| shutdown(env); |
| } |
| }); |
| } |
| |
| public void preMasterInitialization() throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preMasterInitialization(ctx); |
| } |
| }); |
| } |
| |
| public void postStartMaster() throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postStartMaster(ctx); |
| } |
| }); |
| } |
| |
| public void preSnapshot(final SnapshotDescription snapshot, |
| final HTableDescriptor hTableDescriptor) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preSnapshot(ctx, snapshot, hTableDescriptor); |
| } |
| }); |
| } |
| |
| public void postSnapshot(final SnapshotDescription snapshot, |
| final HTableDescriptor hTableDescriptor) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postSnapshot(ctx, snapshot, hTableDescriptor); |
| } |
| }); |
| } |
| |
| public void preListSnapshot(final SnapshotDescription snapshot) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver observer, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| observer.preListSnapshot(ctx, snapshot); |
| } |
| }); |
| } |
| |
| public void postListSnapshot(final SnapshotDescription snapshot) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver observer, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| observer.postListSnapshot(ctx, snapshot); |
| } |
| }); |
| } |
| |
| public void preCloneSnapshot(final SnapshotDescription snapshot, |
| final HTableDescriptor hTableDescriptor) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preCloneSnapshot(ctx, snapshot, hTableDescriptor); |
| } |
| }); |
| } |
| |
| public void postCloneSnapshot(final SnapshotDescription snapshot, |
| final HTableDescriptor hTableDescriptor) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postCloneSnapshot(ctx, snapshot, hTableDescriptor); |
| } |
| }); |
| } |
| |
| public void preRestoreSnapshot(final SnapshotDescription snapshot, |
| final HTableDescriptor hTableDescriptor) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preRestoreSnapshot(ctx, snapshot, hTableDescriptor); |
| } |
| }); |
| } |
| |
| public void postRestoreSnapshot(final SnapshotDescription snapshot, |
| final HTableDescriptor hTableDescriptor) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postRestoreSnapshot(ctx, snapshot, hTableDescriptor); |
| } |
| }); |
| } |
| |
| public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preDeleteSnapshot(ctx, snapshot); |
| } |
| }); |
| } |
| |
| public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postDeleteSnapshot(ctx, snapshot); |
| } |
| }); |
| } |
| |
| public boolean preGetTableDescriptors(final List<TableName> tableNamesList, |
| final List<HTableDescriptor> descriptors, final String regex) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors, regex); |
| } |
| }); |
| } |
| |
| public void postGetTableDescriptors(final List<TableName> tableNamesList, |
| final List<HTableDescriptor> descriptors, final String regex) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postGetTableDescriptors(ctx, tableNamesList, descriptors, regex); |
| } |
| }); |
| } |
| |
| public boolean preGetTableNames(final List<HTableDescriptor> descriptors, |
| final String regex) throws IOException { |
| return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preGetTableNames(ctx, descriptors, regex); |
| } |
| }); |
| } |
| |
| public void postGetTableNames(final List<HTableDescriptor> descriptors, |
| final String regex) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postGetTableNames(ctx, descriptors, regex); |
| } |
| }); |
| } |
| |
| public void preTableFlush(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preTableFlush(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void postTableFlush(final TableName tableName) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postTableFlush(ctx, tableName); |
| } |
| }); |
| } |
| |
| public void preSetUserQuota(final String user, final Quotas quotas) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preSetUserQuota(ctx, user, quotas); |
| } |
| }); |
| } |
| |
| public void postSetUserQuota(final String user, final Quotas quotas) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postSetUserQuota(ctx, user, quotas); |
| } |
| }); |
| } |
| |
| public void preSetUserQuota(final String user, final TableName table, final Quotas quotas) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preSetUserQuota(ctx, user, table, quotas); |
| } |
| }); |
| } |
| |
| public void postSetUserQuota(final String user, final TableName table, final Quotas quotas) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postSetUserQuota(ctx, user, table, quotas); |
| } |
| }); |
| } |
| |
| public void preSetUserQuota(final String user, final String namespace, final Quotas quotas) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preSetUserQuota(ctx, user, namespace, quotas); |
| } |
| }); |
| } |
| |
| public void postSetUserQuota(final String user, final String namespace, final Quotas quotas) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postSetUserQuota(ctx, user, namespace, quotas); |
| } |
| }); |
| } |
| |
| public void preSetTableQuota(final TableName table, final Quotas quotas) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preSetTableQuota(ctx, table, quotas); |
| } |
| }); |
| } |
| |
| public void postSetTableQuota(final TableName table, final Quotas quotas) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postSetTableQuota(ctx, table, quotas); |
| } |
| }); |
| } |
| |
| public void preSetNamespaceQuota(final String namespace, final Quotas quotas) throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.preSetNamespaceQuota(ctx, namespace, quotas); |
| } |
| }); |
| } |
| |
| public void postSetNamespaceQuota(final String namespace, final Quotas quotas) throws IOException{ |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx) |
| throws IOException { |
| oserver.postSetNamespaceQuota(ctx, namespace, quotas); |
| } |
| }); |
| } |
| |
| private static abstract class CoprocessorOperation |
| extends ObserverContext<MasterCoprocessorEnvironment> { |
| public CoprocessorOperation() { |
| this(RpcServer.getRequestUser()); |
| } |
| |
| public CoprocessorOperation(User user) { |
| super(user); |
| } |
| |
| public abstract void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException; |
| |
| public void postEnvCall(MasterEnvironment env) { |
| } |
| } |
| |
| private static abstract class CoprocessorOperationWithResult<T> extends CoprocessorOperation { |
| private T result = null; |
| public void setResult(final T result) { this.result = result; } |
| public T getResult() { return this.result; } |
| } |
| |
| private <T> T execOperationWithResult(final T defaultValue, |
| final CoprocessorOperationWithResult<T> ctx) throws IOException { |
| if (ctx == null) return defaultValue; |
| ctx.setResult(defaultValue); |
| execOperation(ctx); |
| return ctx.getResult(); |
| } |
| |
| private boolean execOperation(final CoprocessorOperation ctx) throws IOException { |
| if (ctx == null) return false; |
| boolean bypass = false; |
| List<MasterEnvironment> envs = coprocessors.get(); |
| for (int i = 0; i < envs.size(); i++) { |
| MasterEnvironment env = envs.get(i); |
| if (env.getInstance() instanceof MasterObserver) { |
| ctx.prepare(env); |
| Thread currentThread = Thread.currentThread(); |
| ClassLoader cl = currentThread.getContextClassLoader(); |
| try { |
| currentThread.setContextClassLoader(env.getClassLoader()); |
| ctx.call((MasterObserver)env.getInstance(), ctx); |
| } catch (Throwable e) { |
| handleCoprocessorThrowable(env, e); |
| } finally { |
| currentThread.setContextClassLoader(cl); |
| } |
| bypass |= ctx.shouldBypass(); |
| if (ctx.shouldComplete()) { |
| break; |
| } |
| } |
| ctx.postEnvCall(env); |
| } |
| return bypass; |
| } |
| |
| public void preMoveServers(final Set<HostAndPort> servers, final String targetGroup) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.preMoveServers(ctx, servers, targetGroup); |
| } |
| } |
| }); |
| } |
| |
| public void postMoveServers(final Set<HostAndPort> servers, final String targetGroup) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.postMoveServers(ctx, servers, targetGroup); |
| } |
| } |
| }); |
| } |
| |
| public void preMoveTables(final Set<TableName> tables, final String targetGroup) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.preMoveTables(ctx, tables, targetGroup); |
| } |
| } |
| }); |
| } |
| |
| public void postMoveTables(final Set<TableName> tables, final String targetGroup) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.postMoveTables(ctx, tables, targetGroup); |
| } |
| } |
| }); |
| } |
| |
| public void preAddRSGroup(final String name) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.preAddRSGroup(ctx, name); |
| } |
| } |
| }); |
| } |
| |
| public void postAddRSGroup(final String name) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if (((MasterEnvironment) ctx.getEnvironment()).supportGroupCPs) { |
| oserver.postAddRSGroup(ctx, name); |
| } |
| } |
| }); |
| } |
| |
| public void preRemoveRSGroup(final String name) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.preRemoveRSGroup(ctx, name); |
| } |
| } |
| }); |
| } |
| |
| public void postRemoveRSGroup(final String name) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.postRemoveRSGroup(ctx, name); |
| } |
| } |
| }); |
| } |
| |
| public void preBalanceRSGroup(final String name) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.preBalanceRSGroup(ctx, name); |
| } |
| } |
| }); |
| } |
| |
| public void postBalanceRSGroup(final String name, final boolean balanceRan) |
| throws IOException { |
| execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { |
| @Override |
| public void call(MasterObserver oserver, |
| ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException { |
| if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) { |
| oserver.postBalanceRSGroup(ctx, name, balanceRan); |
| } |
| } |
| }); |
| } |
| |
| } |