diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java index 0a07f6f6145..5fe80c0deb4 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java @@ -30,6 +30,7 @@ import org.apache.hadoop.hbase.CoprocessorEnvironment; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.master.RegionPlan; import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; @@ -358,6 +359,17 @@ public class BaseMasterObserver implements MasterObserver { HRegionInfo regionInfo) throws IOException { } + @Override + public boolean preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + return false; + } + + @Override + public void postSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + } + @Override public void preBalance(ObserverContext ctx) throws IOException { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java index f958621cd07..45888f169f4 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java @@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.master.RegionPlan; import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; @@ -562,6 +563,24 @@ public interface MasterObserver extends Coprocessor { void postBalance(final ObserverContext ctx, List plans) throws IOException; + /** + * Called prior to setting split / merge switch + * @param ctx the coprocessor instance's environment + * @param newValue the new value submitted in the call + * @param switchType type of switch + */ + boolean preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException; + + /** + * Called after setting split / merge switch + * @param ctx the coprocessor instance's environment + * @param newValue the new value submitted in the call + * @param switchType type of switch + */ + void postSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException; + /** * Called prior to modifying the flag used to enable/disable region balancing. * @param ctx the coprocessor instance's environment diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java index a8660e36452..9e7021a9d1f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java @@ -35,6 +35,7 @@ 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.Admin; import org.apache.hadoop.hbase.coprocessor.*; import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; @@ -752,6 +753,29 @@ public class MasterCoprocessorHost }); } + public boolean preSetSplitOrMergeEnabled(final boolean newValue, + final Admin.MasterSwitchType switchType) throws IOException { + return execOperation(coprocessors.isEmpty() ? null : + new CoprocessorOperation() { + @Override + public void call(MasterObserver oserver, ObserverContext ctx) + throws IOException { + oserver.preSetSplitOrMergeEnabled(ctx, newValue, switchType); + } + }); + } + + public void postSetSplitOrMergeEnabled(final boolean newValue, + final Admin.MasterSwitchType switchType) throws IOException { + execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { + @Override + public void call(MasterObserver oserver, ObserverContext ctx) + throws IOException { + oserver.postSetSplitOrMergeEnabled(ctx, newValue, switchType); + } + }); + } + public boolean preBalanceSwitch(final boolean b) throws IOException { return execOperationWithResult(b, coprocessors.isEmpty() ? null : new CoprocessorOperationWithResult() { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java index 3bbb7c9ff1c..f391ca39f5d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java @@ -1479,8 +1479,17 @@ public class MasterRpcServices extends RSRpcServices for (MasterProtos.MasterSwitchType masterSwitchType : request.getSwitchTypesList()) { Admin.MasterSwitchType switchType = convert(masterSwitchType); boolean oldValue = master.isSplitOrMergeEnabled(switchType); - master.getSplitOrMergeTracker().setSplitOrMergeEnabled(newValue, switchType); response.addPrevValue(oldValue); + boolean bypass = false; + if (master.cpHost != null) { + bypass = master.cpHost.preSetSplitOrMergeEnabled(newValue, switchType); + } + if (!bypass) { + master.getSplitOrMergeTracker().setSplitOrMergeEnabled(newValue, switchType); + } + if (master.cpHost != null) { + master.cpHost.postSetSplitOrMergeEnabled(newValue, switchType); + } } } catch (IOException e) { throw new ServiceException(e); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java index 237bbe34643..b0e8c8cb0e5 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java @@ -55,6 +55,7 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.Tag; import org.apache.hadoop.hbase.TagRewriteCell; import org.apache.hadoop.hbase.classification.InterfaceAudience; +import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.Append; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Durability; @@ -1259,6 +1260,18 @@ public class AccessController extends BaseMasterAndRegionObserver requirePermission("regionOffline", regionInfo.getTable(), null, null, Action.ADMIN); } + @Override + public boolean preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + requirePermission("setSplitOrMergeEnabled", Action.ADMIN); + return false; + } + + @Override + public void postSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + } + @Override public void preBalance(ObserverContext c) throws IOException { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java index d8e91e6fad3..5488597d60a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java @@ -50,6 +50,7 @@ import org.apache.hadoop.hbase.Tag; import org.apache.hadoop.hbase.TagRewriteCell; import org.apache.hadoop.hbase.TagType; import org.apache.hadoop.hbase.classification.InterfaceAudience; +import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.Append; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Get; @@ -307,6 +308,17 @@ public class VisibilityController extends BaseMasterAndRegionObserver implements } } + @Override + public boolean preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + return false; + } + + @Override + public void postSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + } + @Override public void preBatchMutate(ObserverContext c, MiniBatchOperationInProgress miniBatchOp) throws IOException { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java index 30928b9d1d9..a7a80b3a8d8 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java @@ -344,6 +344,17 @@ public class TestMasterObserver { return preTruncateTableCalled && !postTruncateTableCalled; } + @Override + public boolean preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + return false; + } + + @Override + public void postSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + } + @Override public void preModifyTable(ObserverContext env, TableName tableName, HTableDescriptor htd) throws IOException { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java index 75e69b67b2e..242101f5e14 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java @@ -706,6 +706,22 @@ public class TestAccessController extends SecureTestUtil { USER_GROUP_WRITE, USER_GROUP_CREATE); } + @Test (timeout=180000) + public void testSetSplitOrMergeEnabled() throws Exception { + AccessTestAction action = new AccessTestAction() { + @Override + public Object run() throws Exception { + ACCESS_CONTROLLER.preSetSplitOrMergeEnabled(ObserverContext.createAndPrepare(CP_ENV, null), + true, Admin.MasterSwitchType.MERGE); + return null; + } + }; + + verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); + verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, + USER_GROUP_WRITE, USER_GROUP_CREATE); + } + @Test (timeout=180000) public void testBalance() throws Exception { AccessTestAction action = new AccessTestAction() {