Skip to content

Commit c8a4c3e

Browse files
committed
HBASE-29526 Dynamic configuration not working for coprocessor
1 parent 7e96a90 commit c8a4c3e

File tree

7 files changed

+87
-26
lines changed

7 files changed

+87
-26
lines changed

hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,19 @@ public Set<String> getCoprocessors() {
116116
return returnValue;
117117
}
118118

119+
/**
120+
* Get the full class names of all loaded coprocessors. This method returns the complete class
121+
* names including package information, which is useful for precise coprocessor identification and
122+
* comparison.
123+
*/
124+
public Set<String> getCoprocessorClassNames() {
125+
Set<String> returnValue = new TreeSet<>();
126+
for (E e : coprocEnvironments) {
127+
returnValue.add(e.getInstance().getClass().getName());
128+
}
129+
return returnValue;
130+
}
131+
119132
/**
120133
* Load system coprocessors once only. Read the class names from configuration. Called by
121134
* constructor.

hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/RpcServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ public void onConfigurationChange(Configuration newConf) {
332332
}
333333
refreshSlowLogConfiguration(newConf);
334334
if (
335-
CoprocessorConfigurationUtil.checkConfigurationChange(getConf(), newConf,
335+
CoprocessorConfigurationUtil.checkConfigurationChange(this.cpHost, newConf,
336336
CoprocessorHost.RPC_COPROCESSOR_CONF_KEY)
337337
) {
338338
LOG.info("Update the RPC coprocessor(s) because the configuration has changed");

hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ private void finishActiveMasterInitialization() throws IOException, InterruptedE
10801080
if (!maintenanceMode) {
10811081
startupTaskGroup.addTask("Initializing master coprocessors");
10821082
setQuotasObserver(conf);
1083-
initializeCoprocessorHost(conf);
1083+
this.cpHost = new MasterCoprocessorHost(this, conf);
10841084
} else {
10851085
// start an in process region server for carrying system regions
10861086
maintenanceRegionServer =
@@ -4417,11 +4417,11 @@ public void onConfigurationChange(Configuration newConf) {
44174417
setQuotasObserver(newConf);
44184418
// update region server coprocessor if the configuration has changed.
44194419
if (
4420-
CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(), newConf,
4420+
CoprocessorConfigurationUtil.checkConfigurationChange(this.cpHost, newConf,
44214421
CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) && !maintenanceMode
44224422
) {
44234423
LOG.info("Update the master coprocessor(s) because the configuration has changed");
4424-
initializeCoprocessorHost(newConf);
4424+
this.cpHost = new MasterCoprocessorHost(this, newConf);
44254425
}
44264426
}
44274427

@@ -4520,11 +4520,6 @@ private void setQuotasObserver(Configuration conf) {
45204520
}
45214521
}
45224522

4523-
private void initializeCoprocessorHost(Configuration conf) {
4524-
// initialize master side coprocessors before we start handling requests
4525-
this.cpHost = new MasterCoprocessorHost(this, conf);
4526-
}
4527-
45284523
@Override
45294524
public long flushTable(TableName tableName, List<byte[]> columnFamilies, long nonceGroup,
45304525
long nonce) throws IOException {

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8829,7 +8829,7 @@ public void onConfigurationChange(Configuration conf) {
88298829
this.storeHotnessProtector.update(conf);
88308830
// update coprocessorHost if the configuration has changed.
88318831
if (
8832-
CoprocessorConfigurationUtil.checkConfigurationChange(getReadOnlyConfiguration(), conf,
8832+
CoprocessorConfigurationUtil.checkConfigurationChange(this.coprocessorHost, conf,
88338833
CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
88348834
CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY)
88358835
) {

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3475,7 +3475,7 @@ public void onConfigurationChange(Configuration newConf) {
34753475

34763476
// update region server coprocessor if the configuration has changed.
34773477
if (
3478-
CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(), newConf,
3478+
CoprocessorConfigurationUtil.checkConfigurationChange(this.rsHost, newConf,
34793479
CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY)
34803480
) {
34813481
LOG.info("Update region server coprocessors because the configuration has changed");

hbase-server/src/main/java/org/apache/hadoop/hbase/util/CoprocessorConfigurationUtil.java

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
*/
1818
package org.apache.hadoop.hbase.util;
1919

20-
import org.apache.commons.lang3.StringUtils;
20+
import java.util.HashSet;
21+
import java.util.Set;
2122
import org.apache.hadoop.conf.Configuration;
23+
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
2224
import org.apache.yetus.audience.InterfaceAudience;
2325

2426
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
27+
import org.apache.hbase.thirdparty.com.google.common.base.Strings;
2528

2629
/**
2730
* Helper class for coprocessor host when configuration changes.
@@ -32,19 +35,65 @@ public final class CoprocessorConfigurationUtil {
3235
private CoprocessorConfigurationUtil() {
3336
}
3437

35-
public static boolean checkConfigurationChange(Configuration oldConfig, Configuration newConfig,
36-
String... configurationKey) {
38+
/**
39+
* Check configuration change by comparing current loaded coprocessors with configuration values.
40+
* This method is useful when the configuration object has been updated but we need to determine
41+
* if coprocessor configuration has actually changed compared to what's currently loaded.
42+
* @param coprocessorHost the coprocessor host to check current loaded coprocessors (can be null)
43+
* @param conf the configuration to check
44+
* @param configurationKey the configuration keys to check
45+
* @return true if configuration has changed, false otherwise
46+
*/
47+
public static boolean checkConfigurationChange(CoprocessorHost<?, ?> coprocessorHost,
48+
Configuration conf, String... configurationKey) {
3749
Preconditions.checkArgument(configurationKey != null, "Configuration Key(s) must be provided");
38-
boolean isConfigurationChange = false;
50+
Preconditions.checkArgument(conf != null, "Configuration must be provided");
51+
52+
if (coprocessorHost == null) {
53+
// If no coprocessor host exists, check if any coprocessors are now configured
54+
return hasCoprocessorsConfigured(conf, configurationKey);
55+
}
56+
57+
// Get currently loaded coprocessor class names
58+
Set<String> currentlyLoaded = coprocessorHost.getCoprocessorClassNames();
59+
60+
// Get coprocessor class names from configuration
61+
Set<String> configuredClasses = new HashSet<>();
62+
for (String key : configurationKey) {
63+
String[] classes = conf.getStrings(key);
64+
if (classes != null) {
65+
for (String className : classes) {
66+
// Handle the className|priority|path format
67+
String[] classNameToken = className.split("\\|");
68+
String actualClassName = classNameToken[0].trim();
69+
if (!Strings.isNullOrEmpty(actualClassName)) {
70+
configuredClasses.add(actualClassName);
71+
}
72+
}
73+
}
74+
}
75+
76+
// Compare the two sets
77+
return !currentlyLoaded.equals(configuredClasses);
78+
}
79+
80+
/**
81+
* Helper method to check if there are any coprocessors configured.
82+
*/
83+
private static boolean hasCoprocessorsConfigured(Configuration conf, String... configurationKey) {
84+
if (
85+
!conf.getBoolean(CoprocessorHost.COPROCESSORS_ENABLED_CONF_KEY,
86+
CoprocessorHost.DEFAULT_COPROCESSORS_ENABLED)
87+
) {
88+
return false;
89+
}
90+
3991
for (String key : configurationKey) {
40-
String oldValue = oldConfig.get(key);
41-
String newValue = newConfig.get(key);
42-
// check if the coprocessor key has any difference
43-
if (!StringUtils.equalsIgnoreCase(oldValue, newValue)) {
44-
isConfigurationChange = true;
45-
break;
92+
String[] coprocessors = conf.getStrings(key);
93+
if (coprocessors != null && coprocessors.length > 0) {
94+
return true;
4695
}
4796
}
48-
return isConfigurationChange;
97+
return false;
4998
}
5099
}

hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerOnlineConfigChange.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,22 @@ public void testStoreConfigurationOnlineChange() {
267267
@Test
268268
public void testCoprocessorConfigurationOnlineChange() {
269269
assertNull(rs1.getRegionServerCoprocessorHost().findCoprocessor(JMXListener.class.getName()));
270-
conf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY, JMXListener.class.getName());
271-
rs1.getConfigurationManager().notifyAllObservers(conf);
270+
// Update configuration directly to simulate dynamic configuration reload
271+
Configuration rsConf = rs1.getConfiguration();
272+
rsConf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY, JMXListener.class.getName());
273+
rs1.getConfigurationManager().notifyAllObservers(rsConf);
272274
assertNotNull(
273275
rs1.getRegionServerCoprocessorHost().findCoprocessor(JMXListener.class.getName()));
274276
}
275277

276278
@Test
277279
public void testCoprocessorConfigurationOnlineChangeOnMaster() {
278280
assertNull(hMaster.getMasterCoprocessorHost().findCoprocessor(JMXListener.class.getName()));
279-
conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, JMXListener.class.getName());
281+
// Update configuration directly to simulate dynamic configuration reload
282+
Configuration masterConf = hMaster.getConfiguration();
283+
masterConf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, JMXListener.class.getName());
280284
assertFalse(hMaster.isInMaintenanceMode());
281-
hMaster.getConfigurationManager().notifyAllObservers(conf);
285+
hMaster.getConfigurationManager().notifyAllObservers(masterConf);
282286
assertNotNull(hMaster.getMasterCoprocessorHost().findCoprocessor(JMXListener.class.getName()));
283287
}
284288

0 commit comments

Comments
 (0)