From b960474e2ac79d3ac0f73969e738c6c91cca4dbb Mon Sep 17 00:00:00 2001 From: Yukang-Lian Date: Thu, 27 Aug 2026 20:19:21 +0800 Subject: [PATCH] [fix](arrow-flight-sql) Advertise TLS result endpoints ### What problem does this PR solve? Issue Number: N/A Related PR: selectdb/selectdb-core#10971 Problem Summary: When unified TLS enables the Arrow Flight protocol, the Flight SQL server still advertises backend result endpoints with the grpc+tcp scheme. Clients follow that plaintext endpoint and fail to retrieve results from a TLS-enabled backend. Select the advertised grpc+tls scheme from the same enable_tls and tls_excluded_protocols settings that start the Arrow Flight TLS server. ### Release note Arrow Flight SQL now advertises TLS backend result endpoints when Arrow Flight TLS is enabled. ### Check List (For Author) - Test: Unit Test: ./run-fe-ut.sh --run org.apache.doris.service.arrowflight.DorisFlightSqlProducerTest (5 passed) - Behavior changed: Yes. Backend result endpoints use grpc+tls when Arrow Flight TLS is active and remain grpc+tcp otherwise. - Does this need documentation: No --- .../arrowflight/DorisFlightSqlProducer.java | 16 +++++++-- .../DorisFlightSqlProducerTest.java | 34 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducer.java b/fe/fe-core/src/main/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducer.java index e64690a54cb10f..dca585da0250bc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducer.java @@ -20,6 +20,7 @@ package org.apache.doris.service.arrowflight; +import org.apache.doris.common.Config; import org.apache.doris.common.util.DebugUtil; import org.apache.doris.common.util.Util; import org.apache.doris.mysql.MysqlCommand; @@ -29,6 +30,7 @@ import org.apache.doris.service.arrowflight.results.FlightSqlResultCacheEntry; import org.apache.doris.service.arrowflight.sessions.FlightSessionsManager; import org.apache.doris.thrift.TUniqueId; +import org.apache.doris.tls.server.TlsProtocolSet; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; @@ -120,6 +122,14 @@ public DorisFlightSqlProducer(final Location location, FlightSessionsManager fli .withSqlQuotedIdentifierCase(SqlSupportedCaseSensitivity.SQL_CASE_SENSITIVITY_CASE_INSENSITIVE); } + public static Location createAdvertisedLocation(String host, int port) { + if (Config.enable_tls + && TlsProtocolSet.isProtocolIncluded(TlsProtocolSet.Protocol.ARROWFLIGHT)) { + return Location.forGrpcTls(host, port); + } + return Location.forGrpcInsecure(host, port); + } + private static ByteBuffer serializeMetadata(final Schema schema) { final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { @@ -262,14 +272,14 @@ private FlightInfo executeQueryStatement(String peerIdentity, ConnectContext con // If it is different from the Doris BE node randomly routed by nginx, // data forwarding needs to be done inside the Doris BE node. if (endpointLoc.getResultPublicAccessAddr().isSetPort()) { - location = Location.forGrpcInsecure(endpointLoc.getResultPublicAccessAddr().hostname, + location = createAdvertisedLocation(endpointLoc.getResultPublicAccessAddr().hostname, endpointLoc.getResultPublicAccessAddr().port); } else { - location = Location.forGrpcInsecure(endpointLoc.getResultPublicAccessAddr().hostname, + location = createAdvertisedLocation(endpointLoc.getResultPublicAccessAddr().hostname, endpointLoc.getResultFlightServerAddr().port); } } else { - location = Location.forGrpcInsecure(endpointLoc.getResultFlightServerAddr().hostname, + location = createAdvertisedLocation(endpointLoc.getResultFlightServerAddr().hostname, endpointLoc.getResultFlightServerAddr().port); } // By default, the query results of all BE nodes will be aggregated to one BE node. diff --git a/fe/fe-core/src/test/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducerTest.java b/fe/fe-core/src/test/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducerTest.java index eede12688517be..a67f4718acf977 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducerTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/service/arrowflight/DorisFlightSqlProducerTest.java @@ -17,6 +17,7 @@ package org.apache.doris.service.arrowflight; +import org.apache.doris.common.Config; import org.apache.doris.common.FeConstants; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.StmtExecutor; @@ -45,18 +46,51 @@ public class DorisFlightSqlProducerTest { private boolean prevRunningUnitTest; + private boolean prevEnableTls; + private String prevTlsExcludedProtocols; @Before public void setUp() { // FlightSqlConnectContext.init() only reaches Env when this is false; keep it true so the // context can be built without a running FE. prevRunningUnitTest = FeConstants.runningUnitTest; + prevEnableTls = Config.enable_tls; + prevTlsExcludedProtocols = Config.tls_excluded_protocols; FeConstants.runningUnitTest = true; + Config.enable_tls = false; + Config.tls_excluded_protocols = ""; } @After public void tearDown() { FeConstants.runningUnitTest = prevRunningUnitTest; + Config.enable_tls = prevEnableTls; + Config.tls_excluded_protocols = prevTlsExcludedProtocols; + } + + @Test + public void testAdvertisedLocationUsesTlsWhenArrowFlightTlsIsEnabled() { + Config.enable_tls = true; + + Assert.assertEquals("grpc+tls", + DorisFlightSqlProducer.createAdvertisedLocation("be.example.com", 8050).getUri().getScheme()); + } + + @Test + public void testAdvertisedLocationUsesPlaintextWhenTlsIsDisabled() { + Config.enable_tls = false; + + Assert.assertEquals("grpc+tcp", + DorisFlightSqlProducer.createAdvertisedLocation("be.example.com", 8050).getUri().getScheme()); + } + + @Test + public void testAdvertisedLocationUsesPlaintextWhenArrowFlightTlsIsExcluded() { + Config.enable_tls = true; + Config.tls_excluded_protocols = "arrowflight"; + + Assert.assertEquals("grpc+tcp", + DorisFlightSqlProducer.createAdvertisedLocation("be.example.com", 8050).getUri().getScheme()); } /**