anmolnar commented on code in PR #8044:
URL: https://github.com/apache/hbase/pull/8044#discussion_r3076379044


##########
hbase-server/src/main/java/org/apache/hadoop/hbase/util/CoprocessorConfigurationUtil.java:
##########
@@ -102,4 +116,129 @@ private static boolean 
hasCoprocessorsConfigured(Configuration conf, String... c
     }
     return false;
   }
+
+  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);
+    };
+  }
+
+  /**
+   * This method adds or removes relevant ReadOnlyController coprocessors to 
the provided
+   * configuration based on whether read-only mode is enabled.
+   * @param conf               The up-to-date configuration used to determine 
how to handle
+   *                           coprocessors
+   * @param coprocessorConfKey The configuration key name
+   */
+  public static void syncReadOnlyConfigurations(Configuration conf, String 
coprocessorConfKey) {
+    boolean isReadOnlyModeEnabled = 
conf.getBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
+      HConstants.HBASE_GLOBAL_READONLY_ENABLED_DEFAULT);
+
+    List<String> cpList = getReadOnlyCoprocessors(coprocessorConfKey);
+    if (isReadOnlyModeEnabled) {
+      CoprocessorConfigurationUtil.addCoprocessors(conf, coprocessorConfKey, 
cpList);
+    } else {
+      CoprocessorConfigurationUtil.removeCoprocessors(conf, 
coprocessorConfKey, cpList);
+    }
+  }
+
+  /**
+   * This method updates the coprocessors on the master, region server, or 
region if a change has
+   * been detected. Detected changes include changes in coprocessors or 
changes in read-only mode
+   * configuration. If a change is detected, then new coprocessors are loaded 
using the provided
+   * reload method. The new value for the read-only config variable is updated 
as well.
+   * @param newConf                   an updated configuration
+   * @param originalIsReadOnlyEnabled the original value for
+   *                                  {@value 
HConstants#HBASE_GLOBAL_READONLY_ENABLED_KEY}
+   * @param coprocessorHost           the coprocessor host for HMaster, 
HRegionServer, or HRegion
+   * @param coprocessorConfKey        configuration key used for setting 
master, region server, or
+   *                                  region coprocessors
+   * @param isMaintenanceMode         whether maintenance mode is active 
(mainly for HMaster)
+   * @param instance                  string value of the instance calling 
this method (mainly helps
+   *                                  with tracking region logging)
+   * @param stateSetter               lambda function that sets the read-only 
instance variable with
+   *                                  an updated value from the config
+   * @param reloadTask                lambda function that reloads 
coprocessors on the master,
+   *                                  region server, or region
+   */
+  public static void maybeUpdateCoprocessors(Configuration newConf,
+    boolean originalIsReadOnlyEnabled, CoprocessorHost<?, ?> coprocessorHost,
+    String coprocessorConfKey, boolean isMaintenanceMode, String instance,
+    Consumer<Boolean> stateSetter, CoprocessorReloadTask reloadTask) {
+
+    boolean maybeUpdatedReadOnlyMode = 
ConfigurationUtil.isReadOnlyModeEnabled(newConf);
+    boolean hasReadOnlyModeChanged = originalIsReadOnlyEnabled != 
maybeUpdatedReadOnlyMode;

Review Comment:
   It's just a static method in an utility class, it's not stateful. Though we 
could make it stateful and instantiate in each caller which would allow us to 
encapsulate tracking of read-only mode. 
   
   Checking the loaded coprocessors might also work, since we already have a 
`getCoprocessorsFromConfig()` method here.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to