Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion adapter/avro/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion adapter/jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion adapter/orc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion algorithm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>
<artifactId>arrow-algorithm</artifactId>
<name>Arrow Algorithms</name>
Expand Down
2 changes: 1 addition & 1 deletion arrow-variant/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>
<artifactId>arrow-variant</artifactId>
<name>Arrow Variant</name>
Expand Down
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ under the License.

<groupId>org.apache.arrow</groupId>
<artifactId>arrow-bom</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
<packaging>pom</packaging>

<name>Arrow Bill of Materials</name>
Expand Down
2 changes: 1 addition & 1 deletion c/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>

<artifactId>arrow-c-data</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion compression/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>
<artifactId>arrow-compression</artifactId>
<name>Arrow Compression</name>
Expand Down
2 changes: 1 addition & 1 deletion dataset/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-java-root</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>

<artifactId>arrow-dataset</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion flight/flight-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-flight</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>

<artifactId>flight-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,28 @@ public NettyChannelBuilder build() {
"Scheme is not supported: " + location.getUri().getScheme());
}

try {
configureChannel(builder);
} catch (SSLException e) {
throw new RuntimeException(e);
}
return builder;
}

/**
* Build a {@link NettyChannelBuilder} using {@code forTarget()} instead of {@code forAddress()}.
*
* <p>This is required for proxy support: only the DNS resolver path ({@code dns:///host:port})
* invokes the {@link io.grpc.ProxyDetector}. {@code forAddress()} bypasses it entirely.
*/
public NettyChannelBuilder buildForTarget(String target) throws SSLException {
final NettyChannelBuilder builder = NettyChannelBuilder.forTarget(target);
configureChannel(builder);
return builder;
}

/** Apply TLS and message-size configuration to an already-created {@link NettyChannelBuilder}. */
protected void configureChannel(NettyChannelBuilder builder) throws SSLException {
if (this.forceTls || LocationSchemes.GRPC_TLS.equals(location.getUri().getScheme())) {
builder.useTransportSecurity();

Expand All @@ -210,11 +232,8 @@ public NettyChannelBuilder build() {
sslContextBuilder.keyManager(this.clientCertificate, this.clientKey);
}
}
try {
builder.sslContext(sslContextBuilder.build());
} catch (SSLException e) {
throw new RuntimeException(e);
}

builder.sslContext(sslContextBuilder.build());

if (this.overrideHostname != null) {
builder.overrideAuthority(this.overrideHostname);
Expand All @@ -227,6 +246,5 @@ public NettyChannelBuilder build() {
.maxTraceEvents(MAX_CHANNEL_TRACE_EVENTS)
.maxInboundMessageSize(maxInboundMessageSize)
.maxInboundMetadataSize(maxInboundMessageSize);
return builder;
}
}
2 changes: 1 addition & 1 deletion flight/flight-integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-flight</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>

<artifactId>flight-integration-tests</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion flight/flight-sql-jdbc-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ under the License.
<parent>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-flight</artifactId>
<version>19.0.0-SNAPSHOT</version>
<version>19.0.0-iomete.1</version>
</parent>

<artifactId>flight-sql-jdbc-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ private static ArrowFlightSqlClientHandler createNewClientHandler(
.withConnectTimeout(config.getConnectTimeout())
.withDriverVersion(driverVersion)
.withOAuthConfiguration(config.getOauthConfiguration())
.withProxySettings(config.getProxyHost(), config.getProxyPort())
.withProxyBypassPattern(config.getProxyBypassPattern())
.withProxyDisable(config.getProxyDisable())
.build();
} catch (final SQLException e) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.apache.arrow.driver.jdbc.client.utils.ClientAuthenticationUtils;
import org.apache.arrow.driver.jdbc.client.utils.FlightClientCache;
import org.apache.arrow.driver.jdbc.client.utils.FlightLocationQueue;
import org.apache.arrow.driver.jdbc.utils.ArrowFlightProxyDetector;
import org.apache.arrow.flight.CallOption;
import org.apache.arrow.flight.CallStatus;
import org.apache.arrow.flight.CloseSessionRequest;
Expand Down Expand Up @@ -693,6 +694,14 @@ public static final class Builder {

DriverVersion driverVersion;

@VisibleForTesting String proxyHost;

@VisibleForTesting Integer proxyPort;

@VisibleForTesting String proxyBypassPattern;

@VisibleForTesting String proxyDisable;

public Builder() {}

/**
Expand Down Expand Up @@ -1000,6 +1009,63 @@ public Builder withOAuthConfiguration(final OAuthConfiguration oauthConfig) {
return this;
}

/**
* Sets the explicit proxy host and port for this connection.
*
* @param proxyHost the proxy hostname or IP, or {@code null} to clear
* @param proxyPort the proxy port, or {@code null} to clear
* @return this builder instance
*/
public Builder withProxySettings(
@Nullable final String proxyHost, @Nullable final Integer proxyPort) {
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
return this;
}

/**
* Sets the proxy bypass pattern in {@code http.nonProxyHosts} format ({@code |}-separated glob
* patterns).
*
* @param proxyBypassPattern bypass pattern, or {@code null} to clear
* @return this builder instance
*/
public Builder withProxyBypassPattern(@Nullable final String proxyBypassPattern) {
this.proxyBypassPattern = proxyBypassPattern;
return this;
}

/**
* Sets the proxy disable flag. Pass {@code "force"} to disable proxy even when system
* properties or environment variables configure one.
*
* @param proxyDisable disable flag value, or {@code null} to clear
* @return this builder instance
*/
public Builder withProxyDisable(@Nullable final String proxyDisable) {
this.proxyDisable = proxyDisable;
return this;
}

private String getDnsTarget() {
// Validate port is in valid range (0-65535) before passing to gRPC.
// gRPC's DNS resolver validates the port on a background thread, but background thread
// exceptions do not propagate to the caller and prevent proper error handling.
if (port < 0 || port > 65535) {
throw new IllegalArgumentException("port out of range: " + port);
}
// IPv6 addresses need brackets in the URI authority component
String normalizedHost = host.contains(":") && !host.startsWith("[") ? "[" + host + "]" : host;
return "dns:///" + normalizedHost + ":" + port;
}

private NettyChannelBuilder getChannelBuilder(final NettyClientBuilder clientBuilder)
throws IOException {
// forTarget() ensures the DNS resolver is used, which invokes ProxyDetector.
// forAddress() bypasses it entirely.
return clientBuilder.buildForTarget(getDnsTarget());
}

public String getCacheKey() {
return getLocation().toString();
}
Expand Down Expand Up @@ -1075,9 +1141,12 @@ public ArrowFlightSqlClientHandler build() throws SQLException {
}
}

NettyChannelBuilder channelBuilder = clientBuilder.build();
NettyChannelBuilder channelBuilder = getChannelBuilder(clientBuilder);

channelBuilder.userAgent(userAgent);
// Always install — returns null when no proxy is applicable, safe for all connections
channelBuilder.proxyDetector(
new ArrowFlightProxyDetector(proxyHost, proxyPort, proxyBypassPattern, proxyDisable));

if (connectTimeout != null) {
channelBuilder.withOption(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,22 @@ public boolean useClientCache() {
return ArrowFlightConnectionProperty.USE_CLIENT_CACHE.getBoolean(properties);
}

public String getProxyHost() {
return ArrowFlightConnectionProperty.PROXY_HOST.getString(properties);
}

public Integer getProxyPort() {
return ArrowFlightConnectionProperty.PROXY_PORT.getInteger(properties);
}

public String getProxyBypassPattern() {
return ArrowFlightConnectionProperty.PROXY_BYPASS_PATTERN.getString(properties);
}

public String getProxyDisable() {
return ArrowFlightConnectionProperty.PROXY_DISABLE.getString(properties);
}

/**
* Gets the {@link CallOption}s from this {@link ConnectionConfig}.
*
Expand Down Expand Up @@ -284,6 +300,10 @@ public enum ArrowFlightConnectionProperty implements ConnectionProperty {
OAUTH_EXCHANGE_AUDIENCE("oauth.exchange.aud", null, Type.STRING, false),
OAUTH_EXCHANGE_REQUESTED_TOKEN_TYPE(
"oauth.exchange.requestedTokenType", null, Type.STRING, false),
PROXY_HOST("proxyHost", null, Type.STRING, false),
PROXY_PORT("proxyPort", null, Type.NUMBER, false),
PROXY_BYPASS_PATTERN("proxyBypassPattern", null, Type.STRING, false),
PROXY_DISABLE("proxyDisable", null, Type.STRING, false),
;

private final String camelName;
Expand Down
Loading
Loading