This is an automated email from the ASF dual-hosted git repository.
andor pushed a commit to branch HBASE-29081
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/HBASE-29081 by this push:
new a54b00684f1 HBASE-29756: Programmatically register related
co-processor during initialization (#7743)
a54b00684f1 is described below
commit a54b00684f17d29ee7e5d288639ed12d6f97a00a
Author: Anuj Sharma <[email protected]>
AuthorDate: Fri Feb 27 22:50:31 2026 +0530
HBASE-29756: Programmatically register related co-processor during
initialization (#7743)
* HBASE-29756: Programmatically register related co-processor during
initialization
* Apply Spotless
* Remove the cached globalReadOnlyMode variable and make
manageclusterIDFile static
* Address review comments
* Address review comments
* Make coprocessor addition and removal generic
* Make manageClusterIdFile Idempotent
* Address review comments
* Avoid intelliJ warning about fixed size array creation
---
.../org/apache/hadoop/hbase/master/HMaster.java | 16 +
.../apache/hadoop/hbase/regionserver/HRegion.java | 13 +
.../hadoop/hbase/regionserver/HRegionServer.java | 11 +
.../access/AbstractReadOnlyController.java | 59 +---
.../hadoop/hbase/util/ConfigurationUtil.java | 6 +
.../hbase/util/CoprocessorConfigurationUtil.java | 86 +++++
.../apache/hadoop/hbase/TestRefreshHFilesBase.java | 14 -
.../TestRefreshMetaProcedureIntegration.java | 15 -
.../access/TestCanStartHBaseInReadOnlyMode.java | 10 -
.../security/access/TestReadOnlyController.java | 24 +-
.../TestReadOnlyControllerBulkLoadObserver.java | 17 -
.../TestReadOnlyControllerCoprocessorLoading.java | 258 +++++++++++++++
.../TestReadOnlyControllerEndpointObserver.java | 12 -
.../TestReadOnlyControllerMasterObserver.java | 299 -----------------
.../TestReadOnlyControllerRegionObserver.java | 360 ---------------------
...TestReadOnlyControllerRegionServerObserver.java | 23 --
.../util/TestCoprocessorConfigurationUtil.java | 200 ++++++++++++
17 files changed, 613 insertions(+), 810 deletions(-)
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index c88fb535ce2..5c7bf34b1c5 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -250,10 +250,12 @@ import
org.apache.hadoop.hbase.security.AccessDeniedException;
import org.apache.hadoop.hbase.security.SecurityConstants;
import org.apache.hadoop.hbase.security.Superusers;
import org.apache.hadoop.hbase.security.UserProvider;
+import org.apache.hadoop.hbase.security.access.AbstractReadOnlyController;
import org.apache.hadoop.hbase.trace.TraceUtil;
import org.apache.hadoop.hbase.util.Addressing;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.CommonFSUtils;
+import org.apache.hadoop.hbase.util.ConfigurationUtil;
import org.apache.hadoop.hbase.util.CoprocessorConfigurationUtil;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.FSTableDescriptors;
@@ -1086,6 +1088,11 @@ public class HMaster extends
HBaseServerBase<MasterRpcServices> implements Maste
if (!maintenanceMode) {
startupTaskGroup.addTask("Initializing master coprocessors");
setQuotasObserver(conf);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(
+ ConfigurationUtil.isReadOnlyModeEnabled(conf), conf,
+ CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY);
+ AbstractReadOnlyController.manageActiveClusterIdFile(
+ ConfigurationUtil.isReadOnlyModeEnabled(conf),
this.getMasterFileSystem());
initializeCoprocessorHost(conf);
} else {
// start an in process region server for carrying system regions
@@ -4422,6 +4429,11 @@ public class HMaster extends
HBaseServerBase<MasterRpcServices> implements Maste
}
// append the quotas observer back to the master coprocessor key
setQuotasObserver(newConf);
+
+ boolean readOnlyMode = ConfigurationUtil.isReadOnlyModeEnabled(newConf);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(readOnlyMode,
newConf,
+ CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY);
+
// update region server coprocessor if the configuration has changed.
if (
CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(),
newConf,
@@ -4429,6 +4441,10 @@ public class HMaster extends
HBaseServerBase<MasterRpcServices> implements Maste
) {
LOG.info("Update the master coprocessor(s) because the configuration has
changed");
initializeCoprocessorHost(newConf);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(readOnlyMode,
this.conf,
+ CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY);
+ AbstractReadOnlyController.manageActiveClusterIdFile(
+ ConfigurationUtil.isReadOnlyModeEnabled(newConf),
this.getMasterFileSystem());
}
}
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
index 7c55241e5fe..357b035c537 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
@@ -174,6 +174,7 @@ import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.CancelableProgressable;
import org.apache.hadoop.hbase.util.ClassSize;
import org.apache.hadoop.hbase.util.CommonFSUtils;
+import org.apache.hadoop.hbase.util.ConfigurationUtil;
import org.apache.hadoop.hbase.util.CoprocessorConfigurationUtil;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.FSUtils;
@@ -885,6 +886,11 @@ public class HRegion implements HeapSize,
PropagatingConfigurationObserver, Regi
: this.htableDescriptor.getDurability();
decorateRegionConfiguration(conf);
+
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(
+ ConfigurationUtil.isReadOnlyModeEnabled(conf), this.conf,
+ CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);
+
if (rsServices != null) {
this.rsAccounting = this.rsServices.getRegionServerAccounting();
// don't initialize coprocessors if not running within a regionserver
@@ -8814,6 +8820,11 @@ public class HRegion implements HeapSize,
PropagatingConfigurationObserver, Regi
@Override
public void onConfigurationChange(Configuration conf) {
this.storeHotnessProtector.update(conf);
+
+ boolean readOnlyMode = ConfigurationUtil.isReadOnlyModeEnabled(conf);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(readOnlyMode, conf,
+ CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);
+
// update coprocessorHost if the configuration has changed.
if (
CoprocessorConfigurationUtil.checkConfigurationChange(getReadOnlyConfiguration(),
conf,
@@ -8823,6 +8834,8 @@ public class HRegion implements HeapSize,
PropagatingConfigurationObserver, Regi
LOG.info("Update the system coprocessors because the configuration has
changed");
decorateRegionConfiguration(conf);
this.coprocessorHost = new RegionCoprocessorHost(this, rsServices, conf);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(readOnlyMode,
this.conf,
+ CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);
}
}
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
index 86a9880e6b1..796a019e0f8 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
@@ -161,6 +161,7 @@ import org.apache.hadoop.hbase.security.UserProvider;
import org.apache.hadoop.hbase.trace.TraceUtil;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.CompressionTest;
+import org.apache.hadoop.hbase.util.ConfigurationUtil;
import org.apache.hadoop.hbase.util.CoprocessorConfigurationUtil;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.FSUtils;
@@ -825,6 +826,10 @@ public class HRegionServer extends
HBaseServerBase<RSRpcServices>
try {
if (!isStopped() && !isAborted()) {
installShutdownHook();
+
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(
+ ConfigurationUtil.isReadOnlyModeEnabled(conf), conf,
+ CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY);
// Initialize the RegionServerCoprocessorHost now that our ephemeral
// node was created, in case any coprocessors want to use ZooKeeper
this.rsHost = new RegionServerCoprocessorHost(this, this.conf);
@@ -3480,6 +3485,10 @@ public class HRegionServer extends
HBaseServerBase<RSRpcServices>
LOG.warn("Failed to initialize SuperUsers on reloading of the
configuration");
}
+ boolean readOnlyMode = ConfigurationUtil.isReadOnlyModeEnabled(newConf);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(readOnlyMode,
newConf,
+ CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY);
+
// update region server coprocessor if the configuration has changed.
if (
CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(),
newConf,
@@ -3487,6 +3496,8 @@ public class HRegionServer extends
HBaseServerBase<RSRpcServices>
) {
LOG.info("Update region server coprocessors because the configuration
has changed");
this.rsHost = new RegionServerCoprocessorHost(this, newConf);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(readOnlyMode,
this.conf,
+ CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY);
}
}
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AbstractReadOnlyController.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AbstractReadOnlyController.java
index 402009c025a..d5039f84348 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AbstractReadOnlyController.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AbstractReadOnlyController.java
@@ -18,7 +18,6 @@
package org.apache.hadoop.hbase.security.access;
import java.io.IOException;
-import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Coprocessor;
@@ -26,8 +25,6 @@ import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.hadoop.hbase.HConstants;
-import org.apache.hadoop.hbase.conf.ConfigurationObserver;
-import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
import org.apache.hadoop.hbase.master.MasterFileSystem;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.util.FSUtils;
@@ -35,40 +32,24 @@ import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
-public abstract class AbstractReadOnlyController implements
ConfigurationObserver, Coprocessor {
- protected volatile boolean globalReadOnlyEnabled;
+public abstract class AbstractReadOnlyController implements Coprocessor {
private MasterServices masterServices;
private static final Logger LOG =
LoggerFactory.getLogger(AbstractReadOnlyController.class);
protected void internalReadOnlyGuard() throws DoNotRetryIOException {
- if (this.globalReadOnlyEnabled) {
- throw new DoNotRetryIOException("Operation not allowed in Read-Only
Mode");
- }
+ throw new DoNotRetryIOException("Operation not allowed in Read-Only Mode");
}
@Override
public void start(CoprocessorEnvironment env) throws IOException {
- if (env instanceof MasterCoprocessorEnvironment) {
- this.masterServices = ((MasterCoprocessorEnvironment)
env).getMasterServices();
- LOG.info("ReadOnlyController obtained MasterServices reference from
start().");
- } else {
- LOG.debug("ReadOnlyController loaded in a non-Master environment. "
- + "File system operations for read-only state will not work.");
- }
-
- this.globalReadOnlyEnabled =
-
env.getConfiguration().getBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
- HConstants.HBASE_GLOBAL_READONLY_ENABLED_DEFAULT);
}
@Override
public void stop(CoprocessorEnvironment env) {
}
- private void manageActiveClusterIdFile(boolean readOnlyEnabled) {
- MasterFileSystem mfs = this.masterServices.getMasterFileSystem();
+ public static void manageActiveClusterIdFile(boolean readOnlyEnabled,
MasterFileSystem mfs) {
FileSystem fs = mfs.getFileSystem();
Path rootDir = mfs.getRootDir();
Path activeClusterFile = new Path(rootDir,
HConstants.ACTIVE_CLUSTER_SUFFIX_FILE_NAME);
@@ -79,8 +60,13 @@ public abstract class AbstractReadOnlyController implements
ConfigurationObserve
LOG.debug("Global read-only mode is being ENABLED. Deleting active
cluster file: {}",
activeClusterFile);
try {
- fs.delete(activeClusterFile, false);
- LOG.info("Successfully deleted active cluster file: {}",
activeClusterFile);
+ if (fs.exists(activeClusterFile)) {
+ fs.delete(activeClusterFile, false);
+ LOG.info("Successfully deleted active cluster file: {}",
activeClusterFile);
+ } else {
+ LOG.debug("Active cluster file does not exist at: {}. No need to
delete.",
+ activeClusterFile);
+ }
} catch (IOException e) {
LOG.error(
"Failed to delete active cluster file: {}. "
@@ -90,7 +76,12 @@ public abstract class AbstractReadOnlyController implements
ConfigurationObserve
} else {
// DISABLING READ-ONLY (true -> false), create the active cluster file
id file
int wait =
mfs.getConfiguration().getInt(HConstants.THREAD_WAKE_FREQUENCY, 10 * 1000);
- FSUtils.setActiveClusterSuffix(fs, rootDir,
mfs.getSuffixFileDataToWrite(), wait);
+ if (!fs.exists(activeClusterFile)) {
+ FSUtils.setActiveClusterSuffix(fs, rootDir,
mfs.getSuffixFileDataToWrite(), wait);
+ } else {
+ LOG.debug("Active cluster file already exists at: {}. No need to
create it again.",
+ activeClusterFile);
+ }
}
} catch (IOException e) {
// We still update the flag, but log that the operation failed.
@@ -98,22 +89,4 @@ public abstract class AbstractReadOnlyController implements
ConfigurationObserve
+ "Flag will be updated, but file system state may be inconsistent.",
e);
}
}
-
- @Override
- public void onConfigurationChange(Configuration conf) {
- boolean maybeUpdatedConfValue =
conf.getBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
- HConstants.HBASE_GLOBAL_READONLY_ENABLED_DEFAULT);
- if (this.globalReadOnlyEnabled != maybeUpdatedConfValue) {
- if (this.masterServices != null) {
- manageActiveClusterIdFile(maybeUpdatedConfValue);
- } else {
- LOG.debug("Global R/O flag changed, but not running on master");
- }
-
- this.globalReadOnlyEnabled = maybeUpdatedConfValue;
- LOG.info("Config {} has been dynamically changed to {}.",
- HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
this.globalReadOnlyEnabled);
- }
- }
-
}
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/ConfigurationUtil.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/ConfigurationUtil.java
index 555d1fa5a8a..aed30e46af7 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/ConfigurationUtil.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/ConfigurationUtil.java
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.util.StringUtils;
import org.apache.yetus.audience.InterfaceAudience;
@@ -114,4 +115,9 @@ public final class ConfigurationUtil {
}
return rtn;
}
+
+ public static boolean isReadOnlyModeEnabled(Configuration conf) {
+ return conf.getBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
+ HConstants.HBASE_GLOBAL_READONLY_ENABLED_DEFAULT);
+ }
}
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/CoprocessorConfigurationUtil.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/CoprocessorConfigurationUtil.java
index 93c88a89771..d5e564a804c 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/CoprocessorConfigurationUtil.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/CoprocessorConfigurationUtil.java
@@ -17,8 +17,18 @@
*/
package org.apache.hadoop.hbase.util;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
+import org.apache.hadoop.hbase.security.access.BulkLoadReadOnlyController;
+import org.apache.hadoop.hbase.security.access.EndpointReadOnlyController;
+import org.apache.hadoop.hbase.security.access.MasterReadOnlyController;
+import org.apache.hadoop.hbase.security.access.RegionReadOnlyController;
+import org.apache.hadoop.hbase.security.access.RegionServerReadOnlyController;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
@@ -47,4 +57,80 @@ public final class CoprocessorConfigurationUtil {
}
return isConfigurationChange;
}
+
+ private static List<String> getCoprocessorsFromConfig(Configuration conf,
+ String configurationKey) {
+ String[] existing = conf.getStrings(configurationKey);
+ return existing != null ? new ArrayList<>(Arrays.asList(existing)) : new
ArrayList<>();
+ }
+
+ public static void addCoprocessors(Configuration conf, String
configurationKey,
+ List<String> coprocessorsToAdd) {
+ List<String> existing = getCoprocessorsFromConfig(conf, configurationKey);
+
+ boolean isModified = false;
+
+ for (String coprocessor : coprocessorsToAdd) {
+ if (!existing.contains(coprocessor)) {
+ existing.add(coprocessor);
+ isModified = true;
+ }
+ }
+
+ if (isModified) {
+ conf.setStrings(configurationKey, existing.toArray(new String[0]));
+ }
+ }
+
+ public static void removeCoprocessors(Configuration conf, String
configurationKey,
+ List<String> coprocessorsToRemove) {
+ List<String> existing = getCoprocessorsFromConfig(conf, configurationKey);
+
+ if (existing.isEmpty()) {
+ return;
+ }
+
+ boolean isModified = false;
+
+ for (String coprocessor : coprocessorsToRemove) {
+ if (existing.contains(coprocessor)) {
+ existing.remove(coprocessor);
+ isModified = true;
+ }
+ }
+
+ if (isModified) {
+ conf.setStrings(configurationKey, existing.toArray(new String[0]));
+ }
+ }
+
+ private static List<String> getReadOnlyCoprocessors(String configurationKey)
{
+ return switch (configurationKey) {
+ case CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY -> List
+ .of(MasterReadOnlyController.class.getName());
+
+ case CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY -> List
+ .of(RegionServerReadOnlyController.class.getName());
+
+ case CoprocessorHost.REGION_COPROCESSOR_CONF_KEY -> List.of(
+ RegionReadOnlyController.class.getName(),
BulkLoadReadOnlyController.class.getName(),
+ EndpointReadOnlyController.class.getName());
+
+ default -> throw new IllegalArgumentException(
+ "Unsupported coprocessor configuration key: " + configurationKey);
+ };
+ }
+
+ public static void syncReadOnlyConfigurations(boolean readOnlyMode,
Configuration conf,
+ String configurationKey) {
+ conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
readOnlyMode);
+
+ List<String> cpList = getReadOnlyCoprocessors(configurationKey);
+ // If readonly is true then add the coprocessor of master
+ if (readOnlyMode) {
+ CoprocessorConfigurationUtil.addCoprocessors(conf, configurationKey,
cpList);
+ } else {
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, configurationKey,
cpList);
+ }
+ }
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestRefreshHFilesBase.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestRefreshHFilesBase.java
index b18503aa68c..5338b7a6260 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestRefreshHFilesBase.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestRefreshHFilesBase.java
@@ -25,18 +25,12 @@ import java.util.List;
import java.util.stream.Collectors;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Admin;
-import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
import org.apache.hadoop.hbase.master.procedure.RefreshHFilesTableProcedure;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
-import org.apache.hadoop.hbase.security.access.BulkLoadReadOnlyController;
-import org.apache.hadoop.hbase.security.access.EndpointReadOnlyController;
-import org.apache.hadoop.hbase.security.access.MasterReadOnlyController;
-import org.apache.hadoop.hbase.security.access.RegionReadOnlyController;
-import org.apache.hadoop.hbase.security.access.RegionServerReadOnlyController;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.JVMClusterUtil;
import org.slf4j.Logger;
@@ -124,14 +118,6 @@ public class TestRefreshHFilesBase {
private void setupReadOnlyConf(boolean addReadOnlyConf) {
if (!addReadOnlyConf) return;
- // Configure the cluster with ReadOnlyControllers
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
- MasterReadOnlyController.class.getName());
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
- String.join(",", RegionReadOnlyController.class.getName(),
- BulkLoadReadOnlyController.class.getName(),
EndpointReadOnlyController.class.getName()));
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,
- RegionServerReadOnlyController.class.getName());
// Keep ReadOnly property to false at the beginning so that create table
succeed.
conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, false);
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestRefreshMetaProcedureIntegration.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestRefreshMetaProcedureIntegration.java
index d0fced61975..208c2b04beb 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestRefreshMetaProcedureIntegration.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestRefreshMetaProcedureIntegration.java
@@ -42,16 +42,10 @@ import org.apache.hadoop.hbase.client.RegionInfoBuilder;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.client.TableState;
-import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
-import org.apache.hadoop.hbase.security.access.BulkLoadReadOnlyController;
-import org.apache.hadoop.hbase.security.access.EndpointReadOnlyController;
-import org.apache.hadoop.hbase.security.access.MasterReadOnlyController;
-import org.apache.hadoop.hbase.security.access.RegionReadOnlyController;
-import org.apache.hadoop.hbase.security.access.RegionServerReadOnlyController;
import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.util.Bytes;
@@ -77,15 +71,6 @@ public class TestRefreshMetaProcedureIntegration {
@Before
public void setup() throws Exception {
- // Configure the cluster with ReadOnlyControllers
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
- MasterReadOnlyController.class.getName());
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
- String.join(",", RegionReadOnlyController.class.getName(),
- BulkLoadReadOnlyController.class.getName(),
EndpointReadOnlyController.class.getName()));
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,
- RegionServerReadOnlyController.class.getName());
-
// Start in active mode
TEST_UTIL.getConfiguration().setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
false);
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestCanStartHBaseInReadOnlyMode.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestCanStartHBaseInReadOnlyMode.java
index 8607b170808..82bca89f443 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestCanStartHBaseInReadOnlyMode.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestCanStartHBaseInReadOnlyMode.java
@@ -22,7 +22,6 @@ import static
org.apache.hadoop.hbase.HConstants.HBASE_CLIENT_RETRIES_NUMBER;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
-import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.testclassification.SecurityTests;
import org.junit.*;
@@ -54,15 +53,6 @@ public class TestCanStartHBaseInReadOnlyMode {
// Enable Read-Only mode to prove the cluster can be started in this state
conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, true);
-
- // Add ReadOnlyController coprocessors to the master, region server, and
regions
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
- MasterReadOnlyController.class.getName());
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
- String.join(",", RegionReadOnlyController.class.getName(),
- BulkLoadReadOnlyController.class.getName(),
EndpointReadOnlyController.class.getName()));
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,
- RegionServerReadOnlyController.class.getName());
}
@AfterClass
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyController.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyController.java
index c7853b8adac..15ee2fdd45b 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyController.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyController.java
@@ -38,15 +38,14 @@ import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Row;
import org.apache.hadoop.hbase.client.Table;
-import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterFileSystem;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.testclassification.SecurityTests;
import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -65,7 +64,7 @@ public class TestReadOnlyController {
HBaseClassTestRule.forClass(TestReadOnlyController.class);
private static final Logger LOG =
LoggerFactory.getLogger(TestReadOnlyController.class);
- private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
+ private final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
private static final TableName TEST_TABLE =
TableName.valueOf("read_only_test_table");
private static final byte[] TEST_FAMILY =
Bytes.toBytes("read_only_table_col_fam");
private static HRegionServer hRegionServer;
@@ -81,8 +80,8 @@ public class TestReadOnlyController {
@Rule
public ExpectedException exception = ExpectedException.none();
- @BeforeClass
- public static void beforeClass() throws Exception {
+ @Before
+ public void beforeClass() throws Exception {
conf = TEST_UTIL.getConfiguration();
// Shorten the run time of failed unit tests by limiting retries and the
session timeout
@@ -93,15 +92,6 @@ public class TestReadOnlyController {
// Set up test class with Read-Only mode disabled so a table can be created
conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, false);
- // Add ReadOnlyController coprocessors to the master, region server, and
regions
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
- MasterReadOnlyController.class.getName());
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
- String.join(",", RegionReadOnlyController.class.getName(),
- BulkLoadReadOnlyController.class.getName(),
EndpointReadOnlyController.class.getName()));
-
TEST_UTIL.getConfiguration().set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,
- RegionServerReadOnlyController.class.getName());
-
try {
// Start the test cluster
cluster = TEST_UTIL.startMiniCluster(1);
@@ -123,8 +113,8 @@ public class TestReadOnlyController {
}
}
- @AfterClass
- public static void afterClass() throws Exception {
+ @After
+ public void afterClass() throws Exception {
if (connection != null) {
connection.close();
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerBulkLoadObserver.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerBulkLoadObserver.java
index 46984217282..9ac008fdaf8 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerBulkLoadObserver.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerBulkLoadObserver.java
@@ -17,13 +17,11 @@
*/
package org.apache.hadoop.hbase.security.access;
-import static
org.apache.hadoop.hbase.HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.testclassification.SecurityTests;
@@ -43,7 +41,6 @@ public class TestReadOnlyControllerBulkLoadObserver {
HBaseClassTestRule.forClass(TestReadOnlyControllerBulkLoadObserver.class);
BulkLoadReadOnlyController bulkLoadReadOnlyController;
- HBaseConfiguration readOnlyConf;
// Region Server Coprocessor mocking variables
ObserverContext<RegionCoprocessorEnvironment> ctx;
@@ -51,8 +48,6 @@ public class TestReadOnlyControllerBulkLoadObserver {
@Before
public void setup() throws Exception {
bulkLoadReadOnlyController = new BulkLoadReadOnlyController();
- readOnlyConf = new HBaseConfiguration();
- readOnlyConf.setBoolean(HBASE_GLOBAL_READONLY_ENABLED_KEY, true);
// mocking variables initialization
ctx = mock(ObserverContext.class);
@@ -65,23 +60,11 @@ public class TestReadOnlyControllerBulkLoadObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPrePrepareBulkLoadReadOnlyException() throws IOException {
- bulkLoadReadOnlyController.onConfigurationChange(readOnlyConf);
- bulkLoadReadOnlyController.prePrepareBulkLoad(ctx);
- }
-
- @Test
- public void testPrePrepareBulkLoadNoException() throws IOException {
bulkLoadReadOnlyController.prePrepareBulkLoad(ctx);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCleanupBulkLoadReadOnlyException() throws IOException {
- bulkLoadReadOnlyController.onConfigurationChange(readOnlyConf);
- bulkLoadReadOnlyController.preCleanupBulkLoad(ctx);
- }
-
- @Test
- public void testPreCleanupBulkLoadNoException() throws IOException {
bulkLoadReadOnlyController.preCleanupBulkLoad(ctx);
}
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerCoprocessorLoading.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerCoprocessorLoading.java
new file mode 100644
index 00000000000..4846e84bcd6
--- /dev/null
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerCoprocessorLoading.java
@@ -0,0 +1,258 @@
+/*
+ * 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.security.access;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseTestingUtil;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
+import org.apache.hadoop.hbase.client.TableDescriptor;
+import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
+import org.apache.hadoop.hbase.master.HMaster;
+import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
+import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.HRegionServer;
+import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost;
+import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.testclassification.SecurityTests;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(Parameterized.class)
+@Category({ SecurityTests.class, MediumTests.class })
+public class TestReadOnlyControllerCoprocessorLoading {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+
HBaseClassTestRule.forClass(TestReadOnlyControllerCoprocessorLoading.class);
+
+ private static final Logger LOG =
LoggerFactory.getLogger(TestReadOnlyController.class);
+ private HBaseTestingUtil TEST_UTIL;
+
+ Configuration conf;
+ TableName tableName = TableName.valueOf("test_table");
+ HMaster master;
+ HRegionServer regionServer;
+ HRegion region;
+
+ private final boolean initialReadOnlyMode;
+
+ public TestReadOnlyControllerCoprocessorLoading(boolean initialReadOnlyMode)
{
+ this.initialReadOnlyMode = initialReadOnlyMode;
+ }
+
+ @Before
+ public void setup() throws Exception {
+ TEST_UTIL = new HBaseTestingUtil();
+ if (TEST_UTIL.getMiniHBaseCluster() != null) {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+
+ private void setupMiniCluster(boolean isReadOnlyEnabled) throws Exception {
+ conf = TEST_UTIL.getConfiguration();
+ conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
isReadOnlyEnabled);
+ TEST_UTIL.startMiniCluster(1);
+
+ master = TEST_UTIL.getMiniHBaseCluster().getMaster();
+ regionServer = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0);
+ }
+
+ private void createTable() throws Exception {
+ // create a table to get at a region
+ TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
+ .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build();
+ TEST_UTIL.getAdmin().createTable(desc);
+
+ List<HRegion> regions = regionServer.getRegions(tableName);
+ assertFalse(regions.isEmpty());
+ region = regions.get(0);
+ }
+
+ private void setReadOnlyMode(boolean isReadOnlyEnabled) {
+ // Create a new configuration to micic client server behavior
+ // otherwise the existing conf object is shared with the cluster
+ // and can cause side effects on other tests if not reset properly.
+ // This way we can ensure that only the coprocessor loading is tested
+ // without impacting other tests.
+ HBaseTestingUtil NEW_TEST_UTIL = new HBaseTestingUtil();
+ Configuration newConf = NEW_TEST_UTIL.getConfiguration();
+ // Set the read-only enabled config dynamically after cluster startup
+ newConf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
isReadOnlyEnabled);
+ master.getConfigurationManager().notifyAllObservers(newConf);
+ regionServer.getConfigurationManager().notifyAllObservers(newConf);
+ }
+
+ private void verifyMasterReadOnlyControllerLoading(boolean
isReadOnlyEnabled) throws Exception {
+ MasterCoprocessorHost masterCPHost = master.getMasterCoprocessorHost();
+ if (isReadOnlyEnabled) {
+ assertNotNull(
+ MasterReadOnlyController.class.getName()
+ + " should be loaded at startup when readonly is true.",
+
masterCPHost.findCoprocessor(MasterReadOnlyController.class.getName()));
+ } else {
+ assertNull(
+ MasterReadOnlyController.class.getName()
+ + " should not be loaded at startup when readonly support property
is false.",
+
masterCPHost.findCoprocessor(MasterReadOnlyController.class.getName()));
+ }
+ }
+
+ private void verifyRegionServerReadOnlyControllerLoading(boolean
isReadOnlyEnabled)
+ throws Exception {
+ RegionServerCoprocessorHost rsCPHost =
regionServer.getRegionServerCoprocessorHost();
+ if (isReadOnlyEnabled) {
+ assertNotNull(
+ RegionServerReadOnlyController.class.getName()
+ + " should be loaded at startup when readonly is true.",
+
rsCPHost.findCoprocessor(RegionServerReadOnlyController.class.getName()));
+ } else {
+ assertNull(
+ RegionServerReadOnlyController.class.getName()
+ + " should not be loaded at startup when readonly support property
is false.",
+
rsCPHost.findCoprocessor(RegionServerReadOnlyController.class.getName()));
+ }
+ }
+
+ private void verifyRegionReadOnlyControllerLoading(boolean
isReadOnlyEnabled) throws Exception {
+ RegionCoprocessorHost regionCPHost = region.getCoprocessorHost();
+
+ if (isReadOnlyEnabled) {
+ assertNotNull(
+ RegionReadOnlyController.class.getName()
+ + " should be loaded at startup when readonly is true.",
+
regionCPHost.findCoprocessor(RegionReadOnlyController.class.getName()));
+ assertNotNull(
+ EndpointReadOnlyController.class.getName()
+ + " should be loaded at startup when readonly is true.",
+
regionCPHost.findCoprocessor(EndpointReadOnlyController.class.getName()));
+ assertNotNull(
+ BulkLoadReadOnlyController.class.getName()
+ + " should be loaded at startup when readonly is true.",
+
regionCPHost.findCoprocessor(BulkLoadReadOnlyController.class.getName()));
+ } else {
+ assertNull(
+ RegionReadOnlyController.class.getName()
+ + " should not be loaded at startup when readonly support property
is false",
+
regionCPHost.findCoprocessor(RegionReadOnlyController.class.getName()));
+ assertNull(
+ EndpointReadOnlyController.class.getName()
+ + " should not be loaded at startup when readonly support property
is false",
+
regionCPHost.findCoprocessor(EndpointReadOnlyController.class.getName()));
+ assertNull(
+ BulkLoadReadOnlyController.class.getName()
+ + " should not be loaded at startup when readonly support property
is false",
+
regionCPHost.findCoprocessor(BulkLoadReadOnlyController.class.getName()));
+ }
+ }
+
+ private void verifyReadOnlyState(boolean isReadOnlyEnabled) throws Exception
{
+ verifyMasterReadOnlyControllerLoading(isReadOnlyEnabled);
+ verifyRegionServerReadOnlyControllerLoading(isReadOnlyEnabled);
+ verifyRegionReadOnlyControllerLoading(isReadOnlyEnabled);
+ }
+
+ @Test
+ public void testReadOnlyControllerStartupBehavior() throws Exception {
+ setupMiniCluster(initialReadOnlyMode);
+ // Table creation is needed to get a region and verify region coprocessor
loading hence we can't
+ // test region coprocessor loading at startup.
+ // This will get covered in the dynamic loading test where we will also
verify that the
+ // coprocessors are loaded at after table creation dynamically.
+ verifyMasterReadOnlyControllerLoading(initialReadOnlyMode);
+ verifyRegionServerReadOnlyControllerLoading(initialReadOnlyMode);
+ }
+
+ @Test
+ public void testReadOnlyControllerLoadedWhenEnabledDynamically() throws
Exception {
+ setupMiniCluster(initialReadOnlyMode);
+ if (!initialReadOnlyMode) {
+ createTable();
+ }
+ boolean isReadOnlyEnabled = true;
+ setReadOnlyMode(isReadOnlyEnabled);
+ verifyMasterReadOnlyControllerLoading(isReadOnlyEnabled);
+ verifyRegionServerReadOnlyControllerLoading(isReadOnlyEnabled);
+ if (!initialReadOnlyMode) {
+ verifyRegionReadOnlyControllerLoading(isReadOnlyEnabled);
+ }
+ }
+
+ @Test
+ public void testReadOnlyControllerUnloadedWhenDisabledDynamically() throws
Exception {
+ setupMiniCluster(initialReadOnlyMode);
+ boolean isReadOnlyEnabled = false;
+ setReadOnlyMode(isReadOnlyEnabled);
+ createTable();
+ verifyMasterReadOnlyControllerLoading(isReadOnlyEnabled);
+ verifyRegionServerReadOnlyControllerLoading(isReadOnlyEnabled);
+ verifyRegionReadOnlyControllerLoading(isReadOnlyEnabled);
+ }
+
+ @Test
+ public void testReadOnlyControllerLoadUnloadedWhenMultipleReadOnlyToggle()
throws Exception {
+ setupMiniCluster(initialReadOnlyMode);
+
+ // Ensure region exists before validation
+ setReadOnlyMode(false);
+ createTable();
+ verifyReadOnlyState(false);
+
+ // Define toggle sequence
+ boolean[] toggleSequence = new boolean[] { true, false, // basic toggle
+ true, true, // idempotent enable
+ false, false // idempotent disable
+ };
+
+ for (int i = 0; i < toggleSequence.length; i++) {
+ boolean state = toggleSequence[i];
+ LOG.info("Toggling read-only mode to {} (step {})", state, i);
+
+ setReadOnlyMode(state);
+ verifyReadOnlyState(state);
+ }
+ }
+
+ @Parameters(name = "initialReadOnlyMode={0}")
+ public static Collection<Object[]> parameters() {
+ return Arrays.asList(new Object[][] { { Boolean.TRUE }, { Boolean.FALSE }
});
+ }
+}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerEndpointObserver.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerEndpointObserver.java
index 2ea46236426..460d1fd2aae 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerEndpointObserver.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerEndpointObserver.java
@@ -17,13 +17,11 @@
*/
package org.apache.hadoop.hbase.security.access;
-import static
org.apache.hadoop.hbase.HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.testclassification.SecurityTests;
@@ -46,8 +44,6 @@ public class TestReadOnlyControllerEndpointObserver {
HBaseClassTestRule.forClass(TestReadOnlyControllerEndpointObserver.class);
EndpointReadOnlyController endpointReadOnlyController;
- HBaseConfiguration readOnlyConf;
-
// Region Server Coprocessor mocking variables.
ObserverContext<? extends RegionCoprocessorEnvironment> ctx;
Service service;
@@ -57,8 +53,6 @@ public class TestReadOnlyControllerEndpointObserver {
@Before
public void setup() throws Exception {
endpointReadOnlyController = new EndpointReadOnlyController();
- readOnlyConf = new HBaseConfiguration();
- readOnlyConf.setBoolean(HBASE_GLOBAL_READONLY_ENABLED_KEY, true);
// mocking variables initialization
ctx = mock(ObserverContext.class);
@@ -76,12 +70,6 @@ public class TestReadOnlyControllerEndpointObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreEndpointInvocationReadOnlyException() throws IOException {
- endpointReadOnlyController.onConfigurationChange(readOnlyConf);
- endpointReadOnlyController.preEndpointInvocation(ctx, service, methodName,
request);
- }
-
- @Test
- public void testPreEndpointInvocationNoException() throws IOException {
endpointReadOnlyController.preEndpointInvocation(ctx, service, methodName,
request);
}
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerMasterObserver.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerMasterObserver.java
index 04f98e9789f..215edb49317 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerMasterObserver.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerMasterObserver.java
@@ -17,7 +17,6 @@
*/
package org.apache.hadoop.hbase.security.access;
-import static
org.apache.hadoop.hbase.HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY;
import static org.mockito.Mockito.mock;
import java.io.IOException;
@@ -26,7 +25,6 @@ import java.util.Map;
import java.util.Set;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.BalanceRequest;
@@ -59,7 +57,6 @@ public class TestReadOnlyControllerMasterObserver {
HBaseClassTestRule.forClass(TestReadOnlyControllerMasterObserver.class);
MasterReadOnlyController MasterReadOnlyController;
- HBaseConfiguration readOnlyConf;
// Master Coprocessor mocking variables
ObserverContext<MasterCoprocessorEnvironment> c, ctx;
@@ -98,8 +95,6 @@ public class TestReadOnlyControllerMasterObserver {
@Before
public void setup() throws Exception {
MasterReadOnlyController = new MasterReadOnlyController();
- readOnlyConf = new HBaseConfiguration();
- readOnlyConf.setBoolean(HBASE_GLOBAL_READONLY_ENABLED_KEY, true);
// mocking variables initialization
c = mock(ObserverContext.class);
@@ -152,541 +147,247 @@ public class TestReadOnlyControllerMasterObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreCreateTableRegionsInfosReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preCreateTableRegionsInfos(ctx, desc);
- }
-
- @Test
- public void testPreCreateTableRegionsInfosNoException() throws IOException {
MasterReadOnlyController.preCreateTableRegionsInfos(ctx, desc);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCreateTableReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preCreateTable(ctx, desc, regions);
- }
-
- @Test
- public void testPreCreateTableNoException() throws IOException {
MasterReadOnlyController.preCreateTable(ctx, desc, regions);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCreateTableActionReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preCreateTableAction(ctx, desc, regions);
- }
-
- @Test
- public void testPreCreateTableActionNoException() throws IOException {
MasterReadOnlyController.preCreateTableAction(ctx, desc, regions);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreDeleteTableReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preDeleteTable(ctx, tableName);
- }
-
- @Test
- public void testPreDeleteTableNoException() throws IOException {
MasterReadOnlyController.preDeleteTable(ctx, tableName);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreDeleteTableActionReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preDeleteTableAction(ctx, tableName);
- }
-
- @Test
- public void testPreDeleteTableActionNoException() throws IOException {
MasterReadOnlyController.preDeleteTableAction(ctx, tableName);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreTruncateTableReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preTruncateTable(ctx, tableName);
- }
-
- @Test
- public void testPreTruncateTableNoException() throws IOException {
MasterReadOnlyController.preTruncateTable(ctx, tableName);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreTruncateTableActionReadOnlyException() throws IOException
{
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preTruncateTableAction(ctx, tableName);
- }
-
- @Test
- public void testPreTruncateTableActionNoException() throws IOException {
MasterReadOnlyController.preTruncateTableAction(ctx, tableName);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreModifyTableReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preModifyTable(ctx, tableName, currentDescriptor,
newDescriptor);
- }
-
- @Test
- public void testPreModifyTableNoException() throws IOException {
MasterReadOnlyController.preModifyTable(ctx, tableName, currentDescriptor,
newDescriptor);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreModifyTableStoreFileTrackerReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preModifyTableStoreFileTracker(ctx, tableName,
dstSFT);
- }
-
- @Test
- public void testPreModifyTableStoreFileTrackerNoException() throws
IOException {
MasterReadOnlyController.preModifyTableStoreFileTracker(ctx, tableName,
dstSFT);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreModifyColumnFamilyStoreFileTrackerReadOnlyException()
throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preModifyColumnFamilyStoreFileTracker(ctx,
tableName, family, dstSFT);
- }
-
- @Test
- public void testPreModifyColumnFamilyStoreFileTrackerNoException() throws
IOException {
MasterReadOnlyController.preModifyColumnFamilyStoreFileTracker(ctx,
tableName, family, dstSFT);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreModifyTableActionReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preModifyTableAction(ctx, tableName,
currentDescriptor, newDescriptor);
- }
-
- @Test
- public void testPreModifyTableActionNoException() throws IOException {
MasterReadOnlyController.preModifyTableAction(ctx, tableName,
currentDescriptor, newDescriptor);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSplitRegionReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSplitRegion(c, tableName, splitRow);
- }
-
- @Test
- public void testPreSplitRegionNoException() throws IOException {
MasterReadOnlyController.preSplitRegion(c, tableName, splitRow);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSplitRegionActionReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSplitRegionAction(c, tableName, splitRow);
- }
-
- @Test
- public void testPreSplitRegionActionNoException() throws IOException {
MasterReadOnlyController.preSplitRegionAction(c, tableName, splitRow);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSplitRegionBeforeMETAActionReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSplitRegionBeforeMETAAction(ctx, splitKey,
metaEntries);
- }
-
- @Test
- public void testPreSplitRegionBeforeMETAActionNoException() throws
IOException {
MasterReadOnlyController.preSplitRegionBeforeMETAAction(ctx, splitKey,
metaEntries);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSplitRegionAfterMETAActionReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSplitRegionAfterMETAAction(ctx);
- }
-
- @Test
- public void testPreSplitRegionAfterMETAActionNoException() throws
IOException {
MasterReadOnlyController.preSplitRegionAfterMETAAction(ctx);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMergeRegionsActionReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preMergeRegionsAction(ctx, regionsToMerge);
- }
-
- @Test
- public void testPreMergeRegionsActionNoException() throws IOException {
MasterReadOnlyController.preMergeRegionsAction(ctx, regionsToMerge);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMergeRegionsCommitActionReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preMergeRegionsCommitAction(ctx, regionsToMerge,
metaEntries);
- }
-
- @Test
- public void testPreMergeRegionsCommitActionNoException() throws IOException {
MasterReadOnlyController.preMergeRegionsCommitAction(ctx, regionsToMerge,
metaEntries);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSnapshotReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSnapshot(ctx, snapshot, tableDescriptor);
- }
-
- @Test
- public void testPreSnapshotNoException() throws IOException {
MasterReadOnlyController.preSnapshot(ctx, snapshot, tableDescriptor);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCloneSnapshotReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preCloneSnapshot(ctx, snapshot, tableDescriptor);
- }
-
- @Test
- public void testPreCloneSnapshotNoException() throws IOException {
MasterReadOnlyController.preCloneSnapshot(ctx, snapshot, tableDescriptor);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreRestoreSnapshotReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preRestoreSnapshot(ctx, snapshot,
tableDescriptor);
- }
-
- @Test
- public void testPreRestoreSnapshotNoException() throws IOException {
MasterReadOnlyController.preRestoreSnapshot(ctx, snapshot,
tableDescriptor);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreDeleteSnapshotReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preDeleteSnapshot(ctx, snapshot);
- }
-
- @Test
- public void testPreDeleteSnapshotNoException() throws IOException {
MasterReadOnlyController.preDeleteSnapshot(ctx, snapshot);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCreateNamespaceReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preCreateNamespace(ctx, ns);
- }
-
- @Test
- public void testPreCreateNamespaceNoException() throws IOException {
MasterReadOnlyController.preCreateNamespace(ctx, ns);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreModifyNamespaceReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preModifyNamespace(ctx, currentNsDescriptor,
newNsDescriptor);
- }
-
- @Test
- public void testPreModifyNamespaceNoException() throws IOException {
MasterReadOnlyController.preModifyNamespace(ctx, currentNsDescriptor,
newNsDescriptor);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreDeleteNamespaceReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preDeleteNamespace(ctx, namespace);
- }
-
- @Test
- public void testPreDeleteNamespaceNoException() throws IOException {
MasterReadOnlyController.preDeleteNamespace(ctx, namespace);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMasterStoreFlushReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preMasterStoreFlush(ctx);
- }
-
- @Test
- public void testPreMasterStoreFlushNoException() throws IOException {
MasterReadOnlyController.preMasterStoreFlush(ctx);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSetUserQuotaReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSetUserQuota(ctx, userName, quotas);
- }
-
- @Test
- public void testPreSetUserQuotaNoException() throws IOException {
MasterReadOnlyController.preSetUserQuota(ctx, userName, quotas);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSetUserQuotaOnTableReadOnlyException() throws IOException
{
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSetUserQuota(ctx, userName, tableName, quotas);
- }
-
- @Test
- public void testPreSetUserQuotaOnTableNoException() throws IOException {
MasterReadOnlyController.preSetUserQuota(ctx, userName, tableName, quotas);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSetUserQuotaOnNamespaceReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSetUserQuota(ctx, userName, namespace, quotas);
- }
-
- @Test
- public void testPreSetUserQuotaOnNamespaceNoException() throws IOException {
MasterReadOnlyController.preSetUserQuota(ctx, userName, namespace, quotas);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSetTableQuotaReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSetTableQuota(ctx, tableName, quotas);
- }
-
- @Test
- public void testPreSetTableQuotaNoException() throws IOException {
MasterReadOnlyController.preSetTableQuota(ctx, tableName, quotas);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSetNamespaceQuotaReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSetNamespaceQuota(ctx, namespace, quotas);
- }
-
- @Test
- public void testPreSetNamespaceQuotaNoException() throws IOException {
MasterReadOnlyController.preSetNamespaceQuota(ctx, namespace, quotas);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreSetRegionServerQuotaReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preSetRegionServerQuota(ctx, regionServer,
quotas);
- }
-
- @Test
- public void testPreSetRegionServerQuotaNoException() throws IOException {
MasterReadOnlyController.preSetRegionServerQuota(ctx, regionServer,
quotas);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMergeRegionsReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preMergeRegions(ctx, regionsToMerge);
- }
-
- @Test
- public void testPreMergeRegionsNoException() throws IOException {
MasterReadOnlyController.preMergeRegions(ctx, regionsToMerge);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMoveServersAndTablesReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preMoveServersAndTables(ctx, servers, tables,
targetGroup);
- }
-
- @Test
- public void testPreMoveServersAndTablesNoException() throws IOException {
MasterReadOnlyController.preMoveServersAndTables(ctx, servers, tables,
targetGroup);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMoveServersReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preMoveServers(ctx, servers, targetGroup);
- }
-
- @Test
- public void testPreMoveServersNoException() throws IOException {
MasterReadOnlyController.preMoveServers(ctx, servers, targetGroup);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMoveTablesReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preMoveTables(ctx, tables, targetGroup);
- }
-
- @Test
- public void testPreMoveTablesNoException() throws IOException {
MasterReadOnlyController.preMoveTables(ctx, tables, targetGroup);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreAddRSGroupReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preAddRSGroup(ctx, name);
- }
-
- @Test
- public void testPreAddRSGroupNoException() throws IOException {
MasterReadOnlyController.preAddRSGroup(ctx, name);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreRemoveRSGroupReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preRemoveRSGroup(ctx, name);
- }
-
- @Test
- public void testPreRemoveRSGroupNoException() throws IOException {
MasterReadOnlyController.preRemoveRSGroup(ctx, name);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreBalanceRSGroupReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preBalanceRSGroup(ctx, groupName, request);
- }
-
- @Test
- public void testPreBalanceRSGroupNoException() throws IOException {
MasterReadOnlyController.preBalanceRSGroup(ctx, groupName, request);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreRemoveServersReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preRemoveServers(ctx, servers);
- }
-
- @Test
- public void testPreRemoveServersNoException() throws IOException {
MasterReadOnlyController.preRemoveServers(ctx, servers);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreRenameRSGroupReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preRenameRSGroup(ctx, oldName, newName);
- }
-
- @Test
- public void testPreRenameRSGroupNoException() throws IOException {
MasterReadOnlyController.preRenameRSGroup(ctx, oldName, newName);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreUpdateRSGroupConfigReadOnlyException() throws IOException
{
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preUpdateRSGroupConfig(ctx, groupName,
configuration);
- }
-
- @Test
- public void testPreUpdateRSGroupConfigNoException() throws IOException {
MasterReadOnlyController.preUpdateRSGroupConfig(ctx, groupName,
configuration);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreAddReplicationPeerReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preAddReplicationPeer(ctx, peerId, peerConfig);
- }
-
- @Test
- public void testPreAddReplicationPeerNoException() throws IOException {
MasterReadOnlyController.preAddReplicationPeer(ctx, peerId, peerConfig);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreRemoveReplicationPeerReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preRemoveReplicationPeer(ctx, peerId);
- }
-
- @Test
- public void testPreRemoveReplicationPeerNoException() throws IOException {
MasterReadOnlyController.preRemoveReplicationPeer(ctx, peerId);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreEnableReplicationPeerReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preEnableReplicationPeer(ctx, peerId);
- }
-
- @Test
- public void testPreEnableReplicationPeerNoException() throws IOException {
MasterReadOnlyController.preEnableReplicationPeer(ctx, peerId);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreDisableReplicationPeerReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preDisableReplicationPeer(ctx, peerId);
- }
-
- @Test
- public void testPreDisableReplicationPeerNoException() throws IOException {
MasterReadOnlyController.preDisableReplicationPeer(ctx, peerId);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreUpdateReplicationPeerConfigReadOnlyException() throws
IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preUpdateReplicationPeerConfig(ctx, peerId,
peerConfig);
- }
-
- @Test
- public void testPreUpdateReplicationPeerConfigNoException() throws
IOException {
MasterReadOnlyController.preUpdateReplicationPeerConfig(ctx, peerId,
peerConfig);
}
@Test(expected = DoNotRetryIOException.class)
public void
testPreTransitReplicationPeerSyncReplicationStateReadOnlyException()
throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
-
MasterReadOnlyController.preTransitReplicationPeerSyncReplicationState(ctx,
peerId, state);
- }
-
- @Test
- public void testPreTransitReplicationPeerSyncReplicationStateNoException()
throws IOException {
MasterReadOnlyController.preTransitReplicationPeerSyncReplicationState(ctx,
peerId, state);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreGrantReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preGrant(ctx, userPermission,
mergeExistingPermissions);
- }
-
- @Test
- public void testPreGrantNoException() throws IOException {
MasterReadOnlyController.preGrant(ctx, userPermission,
mergeExistingPermissions);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreRevokeReadOnlyException() throws IOException {
- MasterReadOnlyController.onConfigurationChange(readOnlyConf);
- MasterReadOnlyController.preRevoke(ctx, userPermission);
- }
-
- @Test
- public void testPreRevokeNoException() throws IOException {
MasterReadOnlyController.preRevoke(ctx, userPermission);
}
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionObserver.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionObserver.java
index 33f9a337cbe..b2e53860124 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionObserver.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionObserver.java
@@ -17,7 +17,6 @@
*/
package org.apache.hadoop.hbase.security.access;
-import static
org.apache.hadoop.hbase.HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -27,7 +26,6 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.CompareOperator;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Append;
import org.apache.hadoop.hbase.client.CheckAndMutate;
@@ -69,7 +67,6 @@ import org.junit.experimental.categories.Category;
// For example, prePut has 2 versions:
// V1: prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put,
WALEdit edit)
// V2: prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put,
WALEdit edit, Durability durability)
-
@Category({ SecurityTests.class, SmallTests.class })
public class TestReadOnlyControllerRegionObserver {
@ClassRule
@@ -77,7 +74,6 @@ public class TestReadOnlyControllerRegionObserver {
HBaseClassTestRule.forClass(TestReadOnlyControllerRegionObserver.class);
RegionReadOnlyController regionReadOnlyController;
- HBaseConfiguration readOnlyConf;
// Region Coprocessor mocking variables
ObserverContext<RegionCoprocessorEnvironment> c, ctx;
@@ -117,8 +113,6 @@ public class TestReadOnlyControllerRegionObserver {
@Before
public void setup() throws Exception {
regionReadOnlyController = new RegionReadOnlyController();
- readOnlyConf = new HBaseConfiguration();
- readOnlyConf.setBoolean(HBASE_GLOBAL_READONLY_ENABLED_KEY, true);
// mocking variables initialization
c = mock(ObserverContext.class);
@@ -183,156 +177,71 @@ public class TestReadOnlyControllerRegionObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreFlushV1ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preFlush(c, flushLifeCycleTracker);
- }
-
- @Test
- public void testPreFlushV1NoException() throws IOException {
regionReadOnlyController.preFlush(c, flushLifeCycleTracker);
}
@Test
public void testPreFlushV1ReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preFlush(c, flushLifeCycleTracker);
- }
-
- @Test
- public void testPreFlushV1MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preFlush(c, flushLifeCycleTracker);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreFlushV2ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preFlush(c, store, scanner,
flushLifeCycleTracker);
- }
-
- @Test
- public void testPreFlushV2NoException() throws IOException {
regionReadOnlyController.preFlush(c, store, scanner,
flushLifeCycleTracker);
}
@Test
public void testPreFlushV2ReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preFlush(c, store, scanner,
flushLifeCycleTracker);
- }
-
- @Test
- public void testPreFlushV2MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preFlush(c, store, scanner,
flushLifeCycleTracker);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreFlushScannerOpenReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preFlushScannerOpen(c, store, options,
flushLifeCycleTracker);
- }
-
- @Test
- public void testPreFlushScannerOpenNoException() throws IOException {
regionReadOnlyController.preFlushScannerOpen(c, store, options,
flushLifeCycleTracker);
}
@Test
public void testPreFlushScannerOpenReadOnlyMetaNoException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preFlushScannerOpen(c, store, options,
flushLifeCycleTracker);
- }
-
- @Test
- public void testPreFlushScannerOpenMetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preFlushScannerOpen(c, store, options,
flushLifeCycleTracker);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMemStoreCompactionReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preMemStoreCompaction(c, store);
- }
-
- @Test
- public void testPreMemStoreCompactionNoException() throws IOException {
regionReadOnlyController.preMemStoreCompaction(c, store);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMemStoreCompactionCompactScannerOpenReadOnlyException()
throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preMemStoreCompactionCompactScannerOpen(c, store,
options);
- }
-
- @Test
- public void testPreMemStoreCompactionCompactScannerOpenNoException() throws
IOException {
regionReadOnlyController.preMemStoreCompactionCompactScannerOpen(c, store,
options);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreMemStoreCompactionCompactReadOnlyException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preMemStoreCompactionCompact(c, store, scanner);
- }
-
- @Test
- public void testPreMemStoreCompactionCompactNoException() throws IOException
{
regionReadOnlyController.preMemStoreCompactionCompact(c, store, scanner);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCompactSelectionReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCompactSelection(c, store, candidates,
compactionLifeCycleTracker);
- }
-
- @Test
- public void testPreCompactSelectionNoException() throws IOException {
regionReadOnlyController.preCompactSelection(c, store, candidates,
compactionLifeCycleTracker);
}
@Test
public void testPreCompactSelectionReadOnlyMetaNoException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCompactSelection(c, store, candidates,
compactionLifeCycleTracker);
- }
-
- @Test
- public void testPreCompactSelectionMetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCompactSelection(c, store, candidates,
compactionLifeCycleTracker);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCompactScannerOpenReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCompactScannerOpen(c, store, scanType, options,
- compactionLifeCycleTracker, compactionRequest);
- }
-
- @Test
- public void testPreCompactScannerOpenNoException() throws IOException {
regionReadOnlyController.preCompactScannerOpen(c, store, scanType, options,
compactionLifeCycleTracker, compactionRequest);
}
@Test
public void testPreCompactScannerOpenReadOnlyMetaNoException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCompactScannerOpen(c, store, scanType, options,
- compactionLifeCycleTracker, compactionRequest);
- }
-
- @Test
- public void testPreCompactScannerOpenMetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCompactScannerOpen(c, store, scanType, options,
compactionLifeCycleTracker, compactionRequest);
@@ -340,27 +249,12 @@ public class TestReadOnlyControllerRegionObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreCompactReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCompact(c, store, scanner, scanType,
compactionLifeCycleTracker,
- compactionRequest);
- }
-
- @Test
- public void testPreCompactNoException() throws IOException {
regionReadOnlyController.preCompact(c, store, scanner, scanType,
compactionLifeCycleTracker,
compactionRequest);
}
@Test
public void testPreCompactReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCompact(c, store, scanner, scanType,
compactionLifeCycleTracker,
- compactionRequest);
- }
-
- @Test
- public void testPreCompactMetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCompact(c, store, scanner, scanType,
compactionLifeCycleTracker,
compactionRequest);
@@ -368,195 +262,89 @@ public class TestReadOnlyControllerRegionObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPrePutV1ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.prePut(c, put, edit);
- }
-
- @Test
- public void testPrePutV1NoException() throws IOException {
regionReadOnlyController.prePut(c, put, edit);
}
@Test
public void testPrePutV1ReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.prePut(c, put, edit);
- }
-
- @Test
- public void testPrePutV1MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.prePut(c, put, edit);
}
@Test(expected = DoNotRetryIOException.class)
public void testPrePutV2ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.prePut(c, put, edit, durability);
- }
-
- @Test
- public void testPrePutV2NoException() throws IOException {
regionReadOnlyController.prePut(c, put, edit, durability);
}
@Test
public void testPrePutV2ReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.prePut(c, put, edit, durability);
- }
-
- @Test
- public void testPrePutV2MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.prePut(c, put, edit, durability);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreDeleteV1ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preDelete(c, delete, edit);
- }
-
- @Test
- public void testPreDeleteV1NoException() throws IOException {
regionReadOnlyController.preDelete(c, delete, edit);
}
@Test
public void testPreDeleteV1ReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preDelete(c, delete, edit);
- }
-
- @Test
- public void testPreDeleteV1MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preDelete(c, delete, edit);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreDeleteV2ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preDelete(c, delete, edit, durability);
- }
-
- @Test
- public void testPreDeleteV2NoException() throws IOException {
regionReadOnlyController.preDelete(c, delete, edit, durability);
}
@Test
public void testPreDeleteV2ReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preDelete(c, delete, edit, durability);
- }
-
- @Test
- public void testPreDeleteV2MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preDelete(c, delete, edit, durability);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreBatchMutateReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preBatchMutate(c, miniBatchOp);
- }
-
- @Test
- public void testPreBatchMutateNoException() throws IOException {
regionReadOnlyController.preBatchMutate(c, miniBatchOp);
}
@Test
public void testPreBatchMutateReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preBatchMutate(c, miniBatchOp);
- }
-
- @Test
- public void testPreBatchMutateMetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preBatchMutate(c, miniBatchOp);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndPutV1ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndPut(c, row, family, qualifier, op,
comparator, put, result);
- }
-
- @Test
- public void testPreCheckAndPutV1NoException() throws IOException {
regionReadOnlyController.preCheckAndPut(c, row, family, qualifier, op,
comparator, put, result);
}
@Test
public void testPreCheckAndPutV1ReadOnlyMetaNoException() throws IOException
{
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndPut(c, row, family, qualifier, op,
comparator, put, result);
- }
-
- @Test
- public void testPreCheckAndPutV1MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndPut(c, row, family, qualifier, op,
comparator, put, result);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndPutV2ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndPut(c, row, filter, put, result);
- }
-
- @Test
- public void testPreCheckAndPutV2NoException() throws IOException {
regionReadOnlyController.preCheckAndPut(c, row, filter, put, result);
}
@Test
public void testPreCheckAndPutV2ReadOnlyMetaNoException() throws IOException
{
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndPut(c, row, filter, put, result);
- }
-
- @Test
- public void testPreCheckAndPutV2MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndPut(c, row, filter, put, result);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndPutAfterRowLockV1ReadOnlyException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, family,
qualifier, op, comparator,
- put, result);
- }
-
- @Test
- public void testPreCheckAndPutAfterRowLockV1NoException() throws IOException
{
regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, family,
qualifier, op, comparator,
put, result);
}
@Test
public void testPreCheckAndPutAfterRowLockV1ReadOnlyMetaNoException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, family,
qualifier, op, comparator,
- put, result);
- }
-
- @Test
- public void testPreCheckAndPutAfterRowLockV1MetaNoException() throws
IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, family,
qualifier, op, comparator,
put, result);
@@ -564,51 +352,23 @@ public class TestReadOnlyControllerRegionObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndPutAfterRowLockV2ReadOnlyException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, filter, put,
result);
- }
-
- @Test
- public void testPreCheckAndPutAfterRowLockV2NoException() throws IOException
{
regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, filter, put,
result);
}
@Test
public void testPreCheckAndPutAfterRowLockV2ReadOnlyMetaNoException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, filter, put,
result);
- }
-
- @Test
- public void testPreCheckAndPutAfterRowLockV2MetaNoException() throws
IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndPutAfterRowLock(c, row, filter, put,
result);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndDeleteV1ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndDelete(c, row, family, qualifier, op,
comparator, delete,
- result);
- }
-
- @Test
- public void testPreCheckAndDeleteV1NoException() throws IOException {
regionReadOnlyController.preCheckAndDelete(c, row, family, qualifier, op,
comparator, delete,
result);
}
@Test
public void testPreCheckAndDeleteV1ReadOnlyMetaNoException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndDelete(c, row, family, qualifier, op,
comparator, delete,
- result);
- }
-
- @Test
- public void testPreCheckAndDeleteV1MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndDelete(c, row, family, qualifier, op,
comparator, delete,
result);
@@ -616,51 +376,23 @@ public class TestReadOnlyControllerRegionObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndDeleteV2ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndDelete(c, row, filter, delete, result);
- }
-
- @Test
- public void testPreCheckAndDeleteV2NoException() throws IOException {
regionReadOnlyController.preCheckAndDelete(c, row, filter, delete, result);
}
@Test
public void testPreCheckAndDeleteV2ReadOnlyMetaNoException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndDelete(c, row, filter, delete, result);
- }
-
- @Test
- public void testPreCheckAndDeleteV2MetaNoException() throws IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndDelete(c, row, filter, delete, result);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndDeleteAfterRowLockV1ReadOnlyException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, family,
qualifier, op,
- comparator, delete, result);
- }
-
- @Test
- public void testPreCheckAndDeleteAfterRowLockV1NoException() throws
IOException {
regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, family,
qualifier, op,
comparator, delete, result);
}
@Test
public void testPreCheckAndDeleteAfterRowLockV1ReadOnlyMetaNoException()
throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, family,
qualifier, op,
- comparator, delete, result);
- }
-
- @Test
- public void testPreCheckAndDeleteAfterRowLockV1MetaNoException() throws
IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, family,
qualifier, op,
comparator, delete, result);
@@ -668,169 +400,77 @@ public class TestReadOnlyControllerRegionObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndDeleteAfterRowLockV2ReadOnlyException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, filter,
delete, result);
- }
-
- @Test
- public void testPreCheckAndDeleteAfterRowLockV2NoException() throws
IOException {
regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, filter,
delete, result);
}
@Test
public void testPreCheckAndDeleteAfterRowLockV2ReadOnlyMetaNoException()
throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- mockOperationForMetaTable();
- regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, filter,
delete, result);
- }
-
- @Test
- public void testPreCheckAndDeleteAfterRowLockV2MetaNoException() throws
IOException {
mockOperationForMetaTable();
regionReadOnlyController.preCheckAndDeleteAfterRowLock(c, row, filter,
delete, result);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndMutateReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndMutate(c, checkAndMutate,
checkAndMutateResult);
- }
-
- @Test
- public void testPreCheckAndMutateNoException() throws IOException {
regionReadOnlyController.preCheckAndMutate(c, checkAndMutate,
checkAndMutateResult);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCheckAndMutateAfterRowLockReadOnlyException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCheckAndMutateAfterRowLock(c, checkAndMutate,
checkAndMutateResult);
- }
-
- @Test
- public void testPreCheckAndMutateAfterRowLockNoException() throws
IOException {
regionReadOnlyController.preCheckAndMutateAfterRowLock(c, checkAndMutate,
checkAndMutateResult);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreAppendV1ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preAppend(c, append);
- }
-
- @Test
- public void testPreAppendV1NoException() throws IOException {
regionReadOnlyController.preAppend(c, append);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreAppendV2ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preAppend(c, append, edit);
- }
-
- @Test
- public void testPreAppendV2NoException() throws IOException {
regionReadOnlyController.preAppend(c, append, edit);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreAppendAfterRowLockReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preAppendAfterRowLock(c, append);
- }
-
- @Test
- public void testPreAppendAfterRowLockNoException() throws IOException {
regionReadOnlyController.preAppendAfterRowLock(c, append);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreIncrementV1ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preIncrement(c, increment);
- }
-
- @Test
- public void testPreIncrementV1NoException() throws IOException {
regionReadOnlyController.preIncrement(c, increment);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreIncrementV2ReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preIncrement(c, increment, edit);
- }
-
- @Test
- public void testPreIncrementV2NoException() throws IOException {
regionReadOnlyController.preIncrement(c, increment, edit);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreIncrementAfterRowLockReadOnlyException() throws
IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preIncrementAfterRowLock(c, increment);
- }
-
- @Test
- public void testPreIncrementAfterRowLockNoException() throws IOException {
regionReadOnlyController.preIncrementAfterRowLock(c, increment);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreReplayWALsReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preReplayWALs(ctx, info, edits);
- }
-
- @Test
- public void testPreReplayWALsNoException() throws IOException {
regionReadOnlyController.preReplayWALs(ctx, info, edits);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreBulkLoadHFileReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preBulkLoadHFile(ctx, familyPaths);
- }
-
- @Test
- public void testPreBulkLoadHFileNoException() throws IOException {
regionReadOnlyController.preBulkLoadHFile(ctx, familyPaths);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreCommitStoreFileReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preCommitStoreFile(ctx, family, pairs);
- }
-
- @Test
- public void testPreCommitStoreFileNoException() throws IOException {
regionReadOnlyController.preCommitStoreFile(ctx, family, pairs);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreWALAppendReadOnlyException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- regionReadOnlyController.preWALAppend(ctx, key, edit);
- }
-
- @Test
- public void testPreWALAppendNoException() throws IOException {
regionReadOnlyController.preWALAppend(ctx, key, edit);
}
@Test
public void testPreWALAppendReadOnlyMetaNoException() throws IOException {
- regionReadOnlyController.onConfigurationChange(readOnlyConf);
- when(key.getTableName()).thenReturn(TableName.META_TABLE_NAME);
- regionReadOnlyController.preWALAppend(ctx, key, edit);
- }
-
- @Test
- public void testPreWALAppendMetaNoException() throws IOException {
when(key.getTableName()).thenReturn(TableName.META_TABLE_NAME);
regionReadOnlyController.preWALAppend(ctx, key, edit);
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionServerObserver.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionServerObserver.java
index 57424085504..382e55a0c40 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionServerObserver.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestReadOnlyControllerRegionServerObserver.java
@@ -17,13 +17,11 @@
*/
package org.apache.hadoop.hbase.security.access;
-import static
org.apache.hadoop.hbase.HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
@@ -49,7 +47,6 @@ public class TestReadOnlyControllerRegionServerObserver {
HBaseClassTestRule.forClass(TestReadOnlyControllerRegionServerObserver.class);
RegionServerReadOnlyController regionServerReadOnlyController;
- HBaseConfiguration readOnlyConf;
// Region Server Coprocessor mocking variables
ObserverContext<RegionServerCoprocessorEnvironment> ctx;
@@ -59,8 +56,6 @@ public class TestReadOnlyControllerRegionServerObserver {
@Before
public void setup() throws Exception {
regionServerReadOnlyController = new RegionServerReadOnlyController();
- readOnlyConf = new HBaseConfiguration();
- readOnlyConf.setBoolean(HBASE_GLOBAL_READONLY_ENABLED_KEY, true);
// mocking variables initialization
ctx = mock(ObserverContext.class);
@@ -79,34 +74,16 @@ public class TestReadOnlyControllerRegionServerObserver {
@Test(expected = DoNotRetryIOException.class)
public void testPreRollWALWriterRequestReadOnlyException() throws
IOException {
- regionServerReadOnlyController.onConfigurationChange(readOnlyConf);
- regionServerReadOnlyController.preRollWALWriterRequest(ctx);
- }
-
- @Test
- public void testPreRollWALWriterRequestNoException() throws IOException {
regionServerReadOnlyController.preRollWALWriterRequest(ctx);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreReplicationSinkBatchMutateReadOnlyException() throws
IOException {
- regionServerReadOnlyController.onConfigurationChange(readOnlyConf);
- regionServerReadOnlyController.preReplicationSinkBatchMutate(ctx,
walEntry, mutation);
- }
-
- @Test
- public void testPreReplicationSinkBatchMutateNoException() throws
IOException {
regionServerReadOnlyController.preReplicationSinkBatchMutate(ctx,
walEntry, mutation);
}
@Test(expected = DoNotRetryIOException.class)
public void testPreReplicateLogEntriesReadOnlyException() throws IOException
{
- regionServerReadOnlyController.onConfigurationChange(readOnlyConf);
- regionServerReadOnlyController.preReplicateLogEntries(ctx);
- }
-
- @Test
- public void testPreReplicateLogEntriesNoException() throws IOException {
regionServerReadOnlyController.preReplicateLogEntries(ctx);
}
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestCoprocessorConfigurationUtil.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestCoprocessorConfigurationUtil.java
new file mode 100644
index 00000000000..eeda7194982
--- /dev/null
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestCoprocessorConfigurationUtil.java
@@ -0,0 +1,200 @@
+/*
+ * 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.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
+import org.apache.hadoop.hbase.security.access.BulkLoadReadOnlyController;
+import org.apache.hadoop.hbase.security.access.EndpointReadOnlyController;
+import org.apache.hadoop.hbase.security.access.MasterReadOnlyController;
+import org.apache.hadoop.hbase.security.access.RegionReadOnlyController;
+import org.apache.hadoop.hbase.security.access.RegionServerReadOnlyController;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCoprocessorConfigurationUtil {
+
+ private Configuration conf;
+ private String key;
+
+ @Before
+ public void setUp() {
+ conf = new Configuration();
+ key = "test.key";
+ }
+
+ @Test
+ public void testAddCoprocessorsEmptyCPList() {
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp1",
"cp2"));
+ assertArrayEquals(new String[] { "cp1", "cp2" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testAddCoprocessorsNonEmptyCPList() {
+ conf.setStrings(key, "cp1");
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp1",
"cp2"));
+ assertArrayEquals(new String[] { "cp1", "cp2" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testAddCoprocessorsNoChange() {
+ conf.setStrings(key, "cp1");
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp1"));
+ assertArrayEquals(new String[] { "cp1" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testAddCoprocessorsIdempotent() {
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp1",
"cp2"));
+ // Call again
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp1",
"cp2"));
+ assertArrayEquals(new String[] { "cp1", "cp2" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testAddCoprocessorsIdempotentWithOverlap() {
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp1"));
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp1",
"cp2"));
+ CoprocessorConfigurationUtil.addCoprocessors(conf, key, List.of("cp2"));
+ assertArrayEquals(new String[] { "cp1", "cp2" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testRemoveCoprocessorsEmptyCPList() {
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, key, List.of("cp1"));
+ assertNull(conf.getStrings(key));
+ }
+
+ @Test
+ public void testRemoveCoprocessorsNonEmptyCPList() {
+ conf.setStrings(key, "cp1", "cp2", "cp3");
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, key, List.of("cp2"));
+ assertArrayEquals(new String[] { "cp1", "cp3" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testRemoveCoprocessorsNoChange() {
+ conf.setStrings(key, "cp1");
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, key, List.of("cp2"));
+ assertArrayEquals(new String[] { "cp1" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testRemoveCoprocessorsIdempotent() {
+ conf.setStrings(key, "cp1", "cp2");
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, key, List.of("cp2"));
+ // Call again
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, key, List.of("cp2"));
+ assertArrayEquals(new String[] { "cp1" }, conf.getStrings(key));
+ }
+
+ @Test
+ public void testRemoveCoprocessorsIdempotentWhenNotPresent() {
+ conf.setStrings(key, "cp1");
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, key, List.of("cp2"));
+ CoprocessorConfigurationUtil.removeCoprocessors(conf, key, List.of("cp2"));
+ assertArrayEquals(new String[] { "cp1" }, conf.getStrings(key));
+ }
+
+ private void assertEnable(String key, List<String> expected) {
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(true, conf, key);
+ assertTrue(conf.getBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
false));
+ String[] result = conf.getStrings(key);
+ assertNotNull(result);
+ assertEquals(expected.size(), result.length);
+ assertTrue(Arrays.asList(result).containsAll(expected));
+ }
+
+ @Test
+ public void testSyncReadOnlyConfigurationsReadOnlyEnableAllKeys() {
+ assertEnable(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
+ List.of(MasterReadOnlyController.class.getName()));
+
+ assertEnable(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,
+ List.of(RegionServerReadOnlyController.class.getName()));
+ assertEnable(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
+ List.of(RegionReadOnlyController.class.getName(),
BulkLoadReadOnlyController.class.getName(),
+ EndpointReadOnlyController.class.getName()));
+ }
+
+ private void assertDisable(String key, List<String> initialCoprocs) {
+ conf.setStrings(key, initialCoprocs.toArray(new String[0]));
+ conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, true);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(false, conf, key);
+ assertFalse(conf.getBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
true));
+ String[] result = conf.getStrings(key);
+ assertTrue(result == null || result.length == 0);
+ }
+
+ @Test
+ public void testSyncReadOnlyConfigurationsReadOnlyDisableAllKeys() {
+ assertDisable(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
+ List.of(MasterReadOnlyController.class.getName()));
+
+ assertDisable(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,
+ List.of(RegionServerReadOnlyController.class.getName()));
+
+ assertDisable(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
+ List.of(RegionReadOnlyController.class.getName(),
BulkLoadReadOnlyController.class.getName(),
+ EndpointReadOnlyController.class.getName()));
+ }
+
+ @Test
+ public void
testSyncReadOnlyConfigurationsReadOnlyEnablePreservesExistingCoprocessors() {
+ String key = CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY;
+ conf.setStrings(key, "existingCp");
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(true, conf, key);
+ List<String> result = Arrays.asList(conf.getStrings(key));
+ assertTrue(result.contains("existingCp"));
+ assertTrue(result.contains(MasterReadOnlyController.class.getName()));
+ }
+
+ @Test
+ public void
testSyncReadOnlyConfigurationsReadOnlyDisableRemovesOnlyReadOnlyCoprocessor() {
+ Configuration conf = new Configuration(false);
+ String key = CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY;
+ String existingCp = "org.example.OtherCP";
+ conf.setStrings(key, existingCp, MasterReadOnlyController.class.getName());
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(false, conf, key);
+ String[] cps = conf.getStrings(key);
+ assertNotNull(cps);
+ assertEquals(1, cps.length);
+ assertEquals(existingCp, cps[0]);
+ }
+
+ @Test
+ public void testSyncReadOnlyConfigurationsIsIdempotent() {
+ Configuration conf = new Configuration(false);
+ String key = CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY;
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(true, conf, key);
+ CoprocessorConfigurationUtil.syncReadOnlyConfigurations(true, conf, key);
+ String[] cps = conf.getStrings(key);
+ assertNotNull(cps);
+ assertEquals(1, cps.length);
+ }
+}