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 0a07f6f..b765847 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; @@ -359,6 +360,11 @@ public class BaseMasterObserver implements MasterObserver { } @Override + public void preSetSplitOrMergeEnabled(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 f958621..1944a21 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; @@ -563,6 +564,15 @@ public interface MasterObserver extends Coprocessor { 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 + */ + void preSetSplitOrMergeEnabled(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 * @param newValue the new flag value submitted in the call 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 a8660e3..5138631 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,17 @@ public class MasterCoprocessorHost }); } + public void preSetSplitOrMergeEnabled(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.preSetSplitOrMergeEnabled(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 3bbb7c9..8275efd 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 @@ -1478,6 +1478,9 @@ public class MasterRpcServices extends RSRpcServices boolean newValue = request.getEnabled(); for (MasterProtos.MasterSwitchType masterSwitchType : request.getSwitchTypesList()) { Admin.MasterSwitchType switchType = convert(masterSwitchType); + if (master.cpHost != null) { + master.cpHost.preSetSplitOrMergeEnabled(newValue, switchType); + } boolean oldValue = master.isSplitOrMergeEnabled(switchType); master.getSplitOrMergeTracker().setSplitOrMergeEnabled(newValue, switchType); response.addPrevValue(oldValue); 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 237bbe3..8c3551b 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; @@ -1260,6 +1261,12 @@ public class AccessController extends BaseMasterAndRegionObserver } @Override + public void preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + requirePermission("setSplitOrMergeEnabled", Action.ADMIN); + } + + @Override public void preBalance(ObserverContext c) throws IOException { requirePermission("balance", Action.ADMIN); 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 d8e91e6..8c3c50e 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; @@ -308,6 +309,11 @@ public class VisibilityController extends BaseMasterAndRegionObserver implements } @Override + public void preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + } + + @Override public void preBatchMutate(ObserverContext c, MiniBatchOperationInProgress miniBatchOp) throws IOException { if (c.getEnvironment().getRegion().getRegionInfo().getTable().isSystemTable()) { 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 30928b9..a28daa3 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 @@ -345,6 +345,11 @@ public class TestMasterObserver { } @Override + public void preSetSplitOrMergeEnabled(final ObserverContext ctx, + final boolean newValue, final Admin.MasterSwitchType switchType) throws IOException { + } + + @Override public void preModifyTable(ObserverContext env, TableName tableName, HTableDescriptor htd) throws IOException { if (bypass) { 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 75e69b6..242101f 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 @@ -707,6 +707,22 @@ public class TestAccessController extends SecureTestUtil { } @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() { @Override