This is an automated email from the ASF dual-hosted git repository.
tuglu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new b7ac0bf7a3d fix: make BrokerDynamicConfig backwards-compatible (#19120)
b7ac0bf7a3d is described below
commit b7ac0bf7a3de85933d3b932fc80ce8bc9af157eb
Author: jtuglu1 <[email protected]>
AuthorDate: Tue Mar 10 02:43:15 2026 -0700
fix: make BrokerDynamicConfig backwards-compatible (#19120)
Make BrokerDynamicConfig backwards-compatible. By default, brokers who poll
coordinators without the broker dynamic config endpoint (and receive a 404)
will return an empty BrokerDynamicConfig.
---
.../client/coordinator/CoordinatorClient.java | 1 +
.../client/coordinator/CoordinatorClientImpl.java | 27 +++++++++++------
.../coordinator/CoordinatorClientImplTest.java | 35 ++++++++++++++++++++++
3 files changed, 54 insertions(+), 9 deletions(-)
diff --git
a/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java
b/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java
index 3d7118c1981..fb23fadf489 100644
---
a/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java
+++
b/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java
@@ -105,6 +105,7 @@ public interface CoordinatorClient
/**
* Gets the latest broker dynamic config from the Coordinator.
* Brokers use this to fetch their configuration from the Coordinator on
startup.
+ * Returns an empty {@link BrokerDynamicConfig} when querying older
coordinators to ensure backwards-compatibility.
* <p>
* API: {@code GET /druid/coordinator/v1/broker/config}
*/
diff --git
a/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClientImpl.java
b/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClientImpl.java
index 039835181f9..ab0545bf345 100644
---
a/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClientImpl.java
+++
b/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClientImpl.java
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import org.apache.druid.client.BootstrapSegmentsResponse;
import org.apache.druid.client.ImmutableSegmentLoadInfo;
import org.apache.druid.client.JsonParserIterator;
@@ -37,6 +38,7 @@ import
org.apache.druid.java.util.http.client.response.StringFullResponseHandler
import org.apache.druid.query.SegmentDescriptor;
import org.apache.druid.query.lookup.LookupExtractorFactoryContainer;
import org.apache.druid.query.lookup.LookupUtils;
+import org.apache.druid.rpc.HttpResponseException;
import org.apache.druid.rpc.IgnoreHttpResponseHandler;
import org.apache.druid.rpc.RequestBuilder;
import org.apache.druid.rpc.ServiceClient;
@@ -257,16 +259,23 @@ public class CoordinatorClientImpl implements
CoordinatorClient
@Override
public ListenableFuture<BrokerDynamicConfig> getBrokerDynamicConfig()
{
- return FutureUtils.transform(
- client.asyncRequest(
- new RequestBuilder(HttpMethod.GET,
"/druid/coordinator/v1/broker/config"),
- new BytesFullResponseHandler()
+ // Older coordinators may not support this endpoint; fall back to an empty
config on 404.
+ return Futures.catching(
+ FutureUtils.transform(
+ client.asyncRequest(
+ new RequestBuilder(HttpMethod.GET,
"/druid/coordinator/v1/broker/config"),
+ new BytesFullResponseHandler()
+ ),
+ holder -> JacksonUtils.readValue(jsonMapper, holder.getContent(),
BrokerDynamicConfig.class)
),
- holder -> JacksonUtils.readValue(
- jsonMapper,
- holder.getContent(),
- BrokerDynamicConfig.class
- )
+ HttpResponseException.class,
+ e -> {
+ if (e != null && e.getResponse().getStatus().getCode() == 404) {
+ return BrokerDynamicConfig.builder().build();
+ }
+ throw new RuntimeException(e);
+ },
+ MoreExecutors.directExecutor()
);
}
diff --git
a/server/src/test/java/org/apache/druid/client/coordinator/CoordinatorClientImplTest.java
b/server/src/test/java/org/apache/druid/client/coordinator/CoordinatorClientImplTest.java
index a25ad98ec1b..d915ece0c2e 100644
---
a/server/src/test/java/org/apache/druid/client/coordinator/CoordinatorClientImplTest.java
+++
b/server/src/test/java/org/apache/druid/client/coordinator/CoordinatorClientImplTest.java
@@ -49,6 +49,8 @@ import org.apache.druid.rpc.RequestBuilder;
import org.apache.druid.segment.column.ColumnType;
import org.apache.druid.segment.column.RowSignature;
import org.apache.druid.segment.metadata.DataSourceInformation;
+import org.apache.druid.server.QueryBlocklistRule;
+import org.apache.druid.server.broker.BrokerDynamicConfig;
import org.apache.druid.server.compaction.CompactionStatusResponse;
import org.apache.druid.server.coordination.DruidServerMetadata;
import org.apache.druid.server.coordination.ServerType;
@@ -832,4 +834,37 @@ public class CoordinatorClientImplTest
Assert.assertNull(coordinatorClient.updateRulesForDatasource("xyz",
rules).get());
}
+
+ @Test
+ public void test_getBrokerDynamicConfig() throws Exception
+ {
+ final BrokerDynamicConfig brokerDynamicConfig =
BrokerDynamicConfig.builder().withQueryBlocklist(
+ List.of(
+ new QueryBlocklistRule("test", Set.of("dataSource"), null, null)
+ )
+ ).build();
+
+ serviceClient.expectAndRespond(
+ new RequestBuilder(HttpMethod.GET,
"/druid/coordinator/v1/broker/config"),
+ HttpResponseStatus.OK,
+ ImmutableMap.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON),
+ jsonMapper.writeValueAsBytes(brokerDynamicConfig)
+ );
+ Assert.assertEquals(brokerDynamicConfig,
coordinatorClient.getBrokerDynamicConfig().get());
+ }
+
+ @Test
+ public void
test_getBrokerDynamicConfig_backwardsCompatibleCoordinatorRequest() throws
Exception
+ {
+ serviceClient.expectAndThrow(
+ new RequestBuilder(HttpMethod.GET,
"/druid/coordinator/v1/broker/config"),
+ new HttpResponseException(
+ new StringFullResponseHolder(
+ new DefaultHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.NOT_FOUND),
+ StandardCharsets.UTF_8
+ )
+ )
+ );
+ Assert.assertEquals(BrokerDynamicConfig.builder().build(),
coordinatorClient.getBrokerDynamicConfig().get());
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]