From e35cba80a274acec75bceb05acb009afa5b6a560 Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Tue, 24 Feb 2026 10:48:20 +0700 Subject: [PATCH 1/9] feat: add support for gRPC client interceptors in ClientConfig --- .../v3/client/config/ClientConfig.java | 33 ++++++++++++++- .../v3/client/internal/FlightSqlClient.java | 4 ++ .../client/internal/FlightSqlClientTest.java | 41 +++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/influxdb/v3/client/config/ClientConfig.java b/src/main/java/com/influxdb/v3/client/config/ClientConfig.java index 7e0e8ac7..ce53c6f0 100644 --- a/src/main/java/com/influxdb/v3/client/config/ClientConfig.java +++ b/src/main/java/com/influxdb/v3/client/config/ClientConfig.java @@ -28,6 +28,7 @@ import java.time.Duration; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Properties; @@ -36,6 +37,8 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import io.grpc.ClientInterceptor; + import com.influxdb.v3.client.write.WriteOptions; import com.influxdb.v3.client.write.WritePrecision; @@ -68,6 +71,7 @@ *
  • headers - headers to be added to requests
  • *
  • sslRootsFilePath - path to the stored certificates file in PEM format
  • *
  • disableGRPCCompression - disables the default gRPC compression header
  • + *
  • interceptors - list of client interceptors will be used in query api
  • * *

    * If you want to create a client with custom configuration, you can use following code: @@ -115,6 +119,7 @@ public final class ClientConfig { private final Map headers; private final String sslRootsFilePath; private final boolean disableGRPCCompression; + private final List interceptors; /** * Deprecated use {@link #proxyUrl}. @@ -329,6 +334,15 @@ public boolean getDisableGRPCCompression() { return disableGRPCCompression; } + /** + * Gets a list of client interceptors. + * + * @return a list of client interceptors. + */ + public List getInterceptors() { + return interceptors; + } + /** * Validates the configuration properties. */ @@ -366,7 +380,8 @@ public boolean equals(final Object o) { && Objects.equals(authenticator, that.authenticator) && Objects.equals(headers, that.headers) && Objects.equals(sslRootsFilePath, that.sslRootsFilePath) - && disableGRPCCompression == that.disableGRPCCompression; + && disableGRPCCompression == that.disableGRPCCompression + && Objects.equals(interceptors, that.interceptors); } @Override @@ -375,7 +390,7 @@ public int hashCode() { database, writePrecision, gzipThreshold, writeNoSync, timeout, writeTimeout, queryTimeout, allowHttpRedirects, disableServerCertificateValidation, proxy, proxyUrl, authenticator, headers, - defaultTags, sslRootsFilePath, disableGRPCCompression); + defaultTags, sslRootsFilePath, disableGRPCCompression, interceptors); } @Override @@ -429,6 +444,7 @@ public static final class Builder { private Map headers; private String sslRootsFilePath; private boolean disableGRPCCompression; + private List interceptors; /** * Sets the URL of the InfluxDB server. @@ -723,6 +739,18 @@ public Builder disableGRPCCompression(final boolean disableGRPCCompression) { return this; } + /** + * Sets a list of interceptors will be used for query api. + * + * @param interceptors a list of ClientInterceptor + * @return this + */ + @Nonnull + public Builder interceptors(final List interceptors) { + this.interceptors = interceptors; + return this; + } + /** * Build an instance of {@code ClientConfig}. * @@ -897,5 +925,6 @@ private ClientConfig(@Nonnull final Builder builder) { headers = builder.headers; sslRootsFilePath = builder.sslRootsFilePath; disableGRPCCompression = builder.disableGRPCCompression; + interceptors = builder.interceptors; } } diff --git a/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java b/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java index d80c7e87..3b43415b 100644 --- a/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java +++ b/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java @@ -176,6 +176,10 @@ private FlightClient createFlightClient(@Nonnull final ClientConfig config) { .with(Codec.Identity.NONE, false)); } + if (config.getInterceptors() != null && !config.getInterceptors().isEmpty()) { + nettyChannelBuilder.intercept(config.getInterceptors()); + } + return FlightGrpcUtils.createFlightClient(new RootAllocator(Long.MAX_VALUE), nettyChannelBuilder.build()); } diff --git a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java index a6873c56..861313dc 100644 --- a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java +++ b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java @@ -24,11 +24,20 @@ import java.net.InetSocketAddress; import java.net.URISyntaxException; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.stream.IntStream; import java.util.stream.Stream; +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingClientCall; +import io.grpc.ForwardingClientCallListener; import io.grpc.HttpConnectProxiedSocketAddress; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; import io.grpc.ProxyDetector; import io.grpc.internal.GrpcUtil; import org.apache.arrow.flight.CallHeaders; @@ -108,6 +117,38 @@ public void callHeaders() throws Exception { } } + @Test + public void setHeaderInInterceptor() throws Exception { + ClientInterceptor interceptor = new ClientInterceptor() { + @Override + public ClientCall interceptCall(MethodDescriptor method, CallOptions callOptions, Channel next) { + ClientCall call = next.newCall(method, callOptions); + return new ForwardingClientCall.SimpleForwardingClientCall(call) { + @Override + public void start(Listener responseListener, Metadata headers) { + Metadata.Key key = Metadata.Key.of("some-header", Metadata.ASCII_STRING_MARSHALLER); + headers.put(key, "This is from interceptor"); + super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener(responseListener) { + }, headers); + } + }; + } + }; + + ClientConfig clientConfig = new ClientConfig.Builder() + .host(server.getLocation().getUri().toString()) + .token("my-token".toCharArray()) + .interceptors(List.of(interceptor)) + .build(); + + try (FlightSqlClient flightSqlClient = new FlightSqlClient(clientConfig); + var data = executeQuery(flightSqlClient, Map.of(), Map.of())) { + Assertions.assertThat(data.count()).isEqualTo(rowCount); + final Map receivedHeaders = headerFactory.getLastInstance().getHeaders(); + Assertions.assertThat(receivedHeaders.get("some-header")).isEqualTo("This is from interceptor"); + } + } + @Test public void callHeadersWithoutToken() throws Exception { ClientConfig clientConfig = new ClientConfig.Builder() From d36ed6b1abe18f42da4cdd6edf1e6e0d70240d50 Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Tue, 24 Feb 2026 10:50:18 +0700 Subject: [PATCH 2/9] chore: update CHANGELOG with interceptor support for Flight client --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37978503..50769a30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## 1.9.0 [unreleased] +### Features + +1. [#360](https://github.com/InfluxCommunity/influxdb3-java/pull/360): Support passing interceptors to the Flight client. + ## 1.8.0 [2026-02-19] ### Features From 07ba9a3ef37fb7281ff5b1e8f2f105ff40b09756 Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Tue, 24 Feb 2026 10:56:38 +0700 Subject: [PATCH 3/9] refactor: improve readability in FlightSqlClientTest interceptor test --- .../v3/client/internal/FlightSqlClientTest.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java index 861313dc..6ae56021 100644 --- a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java +++ b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java @@ -121,14 +121,21 @@ public void callHeaders() throws Exception { public void setHeaderInInterceptor() throws Exception { ClientInterceptor interceptor = new ClientInterceptor() { @Override - public ClientCall interceptCall(MethodDescriptor method, CallOptions callOptions, Channel next) { + public ClientCall interceptCall( + final MethodDescriptor method, + final CallOptions callOptions, + final Channel next + ) { ClientCall call = next.newCall(method, callOptions); return new ForwardingClientCall.SimpleForwardingClientCall(call) { @Override public void start(Listener responseListener, Metadata headers) { - Metadata.Key key = Metadata.Key.of("some-header", Metadata.ASCII_STRING_MARSHALLER); + Metadata.Key key = Metadata.Key.of( + "some-header", + Metadata.ASCII_STRING_MARSHALLER); headers.put(key, "This is from interceptor"); - super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener(responseListener) { + super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener + (responseListener) { }, headers); } }; From 5c877707133e26458d9d09eefed915b876de5243 Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Tue, 24 Feb 2026 11:01:02 +0700 Subject: [PATCH 4/9] refactor: simplify generics and improve formatting in interceptor test --- .../influxdb/v3/client/internal/FlightSqlClientTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java index 6ae56021..95625f94 100644 --- a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java +++ b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java @@ -127,14 +127,15 @@ public ClientCall interceptCall( final Channel next ) { ClientCall call = next.newCall(method, callOptions); - return new ForwardingClientCall.SimpleForwardingClientCall(call) { + return new ForwardingClientCall.SimpleForwardingClientCall<>(call) { @Override - public void start(Listener responseListener, Metadata headers) { + public void start(final Listener responseListener, final Metadata headers) { Metadata.Key key = Metadata.Key.of( "some-header", - Metadata.ASCII_STRING_MARSHALLER); + Metadata.ASCII_STRING_MARSHALLER + ); headers.put(key, "This is from interceptor"); - super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener + super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<> (responseListener) { }, headers); } From 45979672860c29b785766e58fc0018eb945833e0 Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Tue, 24 Feb 2026 11:08:57 +0700 Subject: [PATCH 5/9] refactor: extract response listener in FlightSqlClientTest interceptor test --- .../com/influxdb/v3/client/internal/FlightSqlClientTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java index 95625f94..0d3d1860 100644 --- a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java +++ b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java @@ -135,9 +135,10 @@ public void start(final Listener responseListener, final Metadata headers Metadata.ASCII_STRING_MARSHALLER ); headers.put(key, "This is from interceptor"); - super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<> + var respListener = new ForwardingClientCallListener.SimpleForwardingClientCallListener<> (responseListener) { - }, headers); + }; + super.start(respListener, headers); } }; } From a26d719e86acdfd58f9d527d59031a22ad811ad4 Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Tue, 24 Feb 2026 11:15:24 +0700 Subject: [PATCH 6/9] refactor: reformat response listener instantiation in FlightSqlClientTest --- .../com/influxdb/v3/client/internal/FlightSqlClientTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java index 0d3d1860..10796206 100644 --- a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java +++ b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java @@ -135,8 +135,9 @@ public void start(final Listener responseListener, final Metadata headers Metadata.ASCII_STRING_MARSHALLER ); headers.put(key, "This is from interceptor"); - var respListener = new ForwardingClientCallListener.SimpleForwardingClientCallListener<> - (responseListener) { + var respListener = new ForwardingClientCallListener.SimpleForwardingClientCallListener<>( + responseListener + ) { }; super.start(respListener, headers); } From 4b3c5bfccf94e821c012f864183ec06189375acb Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Tue, 24 Feb 2026 11:26:39 +0700 Subject: [PATCH 7/9] refactor: remove unnecessary interceptor list emptiness check in FlightSqlClient --- .../java/com/influxdb/v3/client/internal/FlightSqlClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java b/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java index 3b43415b..9880e7f2 100644 --- a/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java +++ b/src/main/java/com/influxdb/v3/client/internal/FlightSqlClient.java @@ -176,7 +176,7 @@ private FlightClient createFlightClient(@Nonnull final ClientConfig config) { .with(Codec.Identity.NONE, false)); } - if (config.getInterceptors() != null && !config.getInterceptors().isEmpty()) { + if (config.getInterceptors() != null) { nettyChannelBuilder.intercept(config.getInterceptors()); } From 47263b465ecefa4c03d72d87b08f32be7fa781ba Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Thu, 26 Feb 2026 13:53:03 +0700 Subject: [PATCH 8/9] refactor: annotate interceptor methods with @Nullable and improve related comments --- .../java/com/influxdb/v3/client/config/ClientConfig.java | 7 ++++--- .../influxdb/v3/client/internal/FlightSqlClientTest.java | 6 +----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/influxdb/v3/client/config/ClientConfig.java b/src/main/java/com/influxdb/v3/client/config/ClientConfig.java index ce53c6f0..4326f3a5 100644 --- a/src/main/java/com/influxdb/v3/client/config/ClientConfig.java +++ b/src/main/java/com/influxdb/v3/client/config/ClientConfig.java @@ -71,7 +71,7 @@ *

  • headers - headers to be added to requests
  • *
  • sslRootsFilePath - path to the stored certificates file in PEM format
  • *
  • disableGRPCCompression - disables the default gRPC compression header
  • - *
  • interceptors - list of client interceptors will be used in query api
  • + *
  • interceptors - list of client interceptors to be used in the query API
  • * *

    * If you want to create a client with custom configuration, you can use following code: @@ -339,6 +339,7 @@ public boolean getDisableGRPCCompression() { * * @return a list of client interceptors. */ + @Nullable public List getInterceptors() { return interceptors; } @@ -740,13 +741,13 @@ public Builder disableGRPCCompression(final boolean disableGRPCCompression) { } /** - * Sets a list of interceptors will be used for query api. + * Sets a list of interceptors to be used for the query API. * * @param interceptors a list of ClientInterceptor * @return this */ @Nonnull - public Builder interceptors(final List interceptors) { + public Builder interceptors(@Nullable final List interceptors) { this.interceptors = interceptors; return this; } diff --git a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java index 10796206..cca14e95 100644 --- a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java +++ b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java @@ -135,11 +135,7 @@ public void start(final Listener responseListener, final Metadata headers Metadata.ASCII_STRING_MARSHALLER ); headers.put(key, "This is from interceptor"); - var respListener = new ForwardingClientCallListener.SimpleForwardingClientCallListener<>( - responseListener - ) { - }; - super.start(respListener, headers); + super.start(responseListener, headers); } }; } From ec695872b0a75cbb4072ba44a94357932bc694d4 Mon Sep 17 00:00:00 2001 From: NguyenHoangSon96 Date: Thu, 26 Feb 2026 13:57:53 +0700 Subject: [PATCH 9/9] refactor: remove unused ForwardingClientCallListener import in FlightSqlClientTest --- .../com/influxdb/v3/client/internal/FlightSqlClientTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java index cca14e95..ab326c90 100644 --- a/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java +++ b/src/test/java/com/influxdb/v3/client/internal/FlightSqlClientTest.java @@ -34,7 +34,6 @@ import io.grpc.ClientCall; import io.grpc.ClientInterceptor; import io.grpc.ForwardingClientCall; -import io.grpc.ForwardingClientCallListener; import io.grpc.HttpConnectProxiedSocketAddress; import io.grpc.Metadata; import io.grpc.MethodDescriptor;