This is an automated email from the ASF dual-hosted git repository.
sigram pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 62aace94a13 SOLR-18412: CrossDC - ZooKeeper /crossdc.properties no
longer overrides solr.crossdc.kafka.* sysprops or env vars (#4884)
62aace94a13 is described below
commit 62aace94a13f1f2a6831e6b189393ceecb9195d4
Author: Andrzej BiaĆecki <[email protected]>
AuthorDate: Wed Sep 9 11:31:27 2026 +0200
SOLR-18412: CrossDC - ZooKeeper /crossdc.properties no longer overrides
solr.crossdc.kafka.* sysprops or env vars (#4884)
---
changelog/unreleased/SOLR-18412.yml | 8 +++
.../solr/crossdc/common/KafkaCrossDcConf.java | 13 +++-
.../apache/solr/crossdc/common/ConfUtilTest.java | 81 ++++++++++++++++++++++
3 files changed, 100 insertions(+), 2 deletions(-)
diff --git a/changelog/unreleased/SOLR-18412.yml
b/changelog/unreleased/SOLR-18412.yml
new file mode 100644
index 00000000000..6fdc63a806f
--- /dev/null
+++ b/changelog/unreleased/SOLR-18412.yml
@@ -0,0 +1,8 @@
+title: CrossDC - ZooKeeper /crossdc.properties no longer overrides
solr.crossdc.kafka.* sysprops or env vars
+type: fixed
+authors:
+ - name: Andrzej Bialecki
+ nick: ab
+links:
+ - name: SOLR-18412
+ url: https://issues.apache.org/jira/browse/SOLR-18412
diff --git
a/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java
b/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java
index 88db372683e..64dfc2cae7a 100644
---
a/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java
+++
b/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java
@@ -295,8 +295,17 @@ public class KafkaCrossDcConf extends CrossDcConf {
}
zkPropsUnprocessed.forEach(
(key, val) -> {
- if (properties.get(key) == null) {
- properties.put((String) key, val);
+ String strKey = (String) key;
+ String targetKey = strKey;
+ if (strKey.startsWith(ConfUtil.KAFKA_ENV_PREFIX)) {
+ targetKey = ConfUtil.normalizeKafkaEnvKey(strKey);
+ } else if (strKey.startsWith(ConfUtil.KAFKA_PROP_PREFIX)) {
+ targetKey = ConfUtil.normalizeKafkaSysPropKey(strKey);
+ }
+ // A JVM system property or env var pass-through override always
takes precedence
+ // over the same property coming from ZooKeeper's
/crossdc.properties.
+ if (properties.get(targetKey) == null) {
+ properties.put(targetKey, val);
}
});
}
diff --git
a/solr/modules/cross-dc/src/test/org/apache/solr/crossdc/common/ConfUtilTest.java
b/solr/modules/cross-dc/src/test/org/apache/solr/crossdc/common/ConfUtilTest.java
index 6afcc35ae2a..05591e8f8d5 100644
---
a/solr/modules/cross-dc/src/test/org/apache/solr/crossdc/common/ConfUtilTest.java
+++
b/solr/modules/cross-dc/src/test/org/apache/solr/crossdc/common/ConfUtilTest.java
@@ -426,6 +426,87 @@ public class ConfUtilTest extends SolrTestCaseJ4 {
assertEquals("lz4",
conf.getAdditionalProperties().get("compression.type"));
}
+ @Test
+ public void testFillProperties_ZkOnlyKafkaPrefixPropIsNormalized() throws
Exception {
+ Map<String, Object> properties = new HashMap<>();
+
+ System.setProperty(KafkaCrossDcConf.BOOTSTRAP_SERVERS, "sys-kafka:9092");
+ System.setProperty(KafkaCrossDcConf.TOPIC_NAME, "sys-topic");
+
+ Properties zkProps = new Properties();
+ zkProps.setProperty("solr.crossdc.kafka.compression.type", "zk-value");
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(baos,
StandardCharsets.UTF_8);
+ zkProps.store(writer, null);
+ writer.close();
+ byte[] zkData = baos.toByteArray();
+
+ when(mockZkClient.exists(anyString())).thenReturn(true);
+ when(mockZkClient.getData(anyString(), isNull(),
isNull())).thenReturn(zkData);
+
+ ConfUtil.fillProperties(mockZkClient, properties);
+
+ // ZK value lands under the normalized key, not the raw
solr.crossdc.kafka.* key.
+ assertEquals("zk-value", properties.get("compression.type"));
+ assertNull(properties.get("solr.crossdc.kafka.compression.type"));
+ }
+
+ @Test
+ public void testFillProperties_KafkaPrefixSysPropPrecedenceOverZk() throws
Exception {
+ Map<String, Object> properties = new HashMap<>();
+
+ System.setProperty(KafkaCrossDcConf.BOOTSTRAP_SERVERS, "sys-kafka:9092");
+ System.setProperty(KafkaCrossDcConf.TOPIC_NAME, "sys-topic");
+ System.setProperty("solr.crossdc.kafka.compression.type", "sys-value");
+
+ Properties zkProps = new Properties();
+ zkProps.setProperty("solr.crossdc.kafka.compression.type", "zk-value");
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(baos,
StandardCharsets.UTF_8);
+ zkProps.store(writer, null);
+ writer.close();
+ byte[] zkData = baos.toByteArray();
+
+ when(mockZkClient.exists(anyString())).thenReturn(true);
+ when(mockZkClient.getData(anyString(), isNull(),
isNull())).thenReturn(zkData);
+
+ ConfUtil.fillProperties(mockZkClient, properties);
+
+ assertEquals("sys-value", properties.get("compression.type"));
+ }
+
+ @Test
+ public void testFillProperties_SysPropPrecedenceOverDoubleZk() throws
Exception {
+ Map<String, Object> properties = new HashMap<>();
+
+ System.setProperty(KafkaCrossDcConf.BOOTSTRAP_SERVERS, "sys-kafka:9092");
+ System.setProperty(KafkaCrossDcConf.TOPIC_NAME, "sys-topic");
+ System.setProperty("solr.crossdc.kafka.compression.type", "sys-value");
+
+ // First call, as Consumer.start() does, with no ZK client yet.
+ ConfUtil.fillProperties(null, properties);
+ assertEquals("sys-value", properties.get("compression.type"));
+
+ Properties zkProps = new Properties();
+ zkProps.setProperty("solr.crossdc.kafka.compression.type", "zk-value");
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(baos,
StandardCharsets.UTF_8);
+ zkProps.store(writer, null);
+ writer.close();
+ byte[] zkData = baos.toByteArray();
+
+ when(mockZkClient.exists(anyString())).thenReturn(true);
+ when(mockZkClient.getData(anyString(), isNull(),
isNull())).thenReturn(zkData);
+
+ // Second call, now with the real ZK client, as Consumer.start() does.
+ ConfUtil.fillProperties(mockZkClient, properties);
+
+ assertEquals("sys-value", properties.get("compression.type"));
+ }
+
// we can't easily modify envvars, test just the key conversion in properties
@Test
public void testUnderscoreToDotsConversion() {