Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
List<ConnectionProperty> queryProperties;
Map<String, String> authProperties;
Map<String, String> overrideProperties;
Map<String, String> proxyProperties;
Credentials credentials;
boolean useStatelessQueryMode;
int numBufferedRows;
Expand Down Expand Up @@ -299,7 +300,7 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
String.valueOf(ds.getRequestGoogleDriveScope()),
BigQueryJdbcUrlUtility.REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME);

Map<String, String> proxyProperties =
this.proxyProperties =
BigQueryJdbcProxyUtility.parseProxyProperties(ds, this.connectionClassName);

this.sslTrustStorePath = ds.getSSLTrustStorePath();
Expand Down Expand Up @@ -1204,14 +1205,20 @@ private OpenTelemetry getOpenTelemetryInstance() {
this.customOpenTelemetry,
this.gcpTelemetryCredentials,
effectiveProjectId,
this.credentials);
this.credentials,
this.proxyProperties);

boolean hasExternalOtel = this.customOpenTelemetry != null || this.useGlobalOpenTelemetry;
Logging localLoggingClient = null;
if (this.enableGcpLogExporter && !hasExternalOtel) {
localLoggingClient =
BigQueryJdbcOpenTelemetry.createLoggingClient(
true, null, this.gcpTelemetryCredentials, effectiveProjectId, this.credentials);
true,
null,
this.gcpTelemetryCredentials,
effectiveProjectId,
this.credentials,
this.headerProvider);
}

if (this.enableGcpLogExporter || hasExternalOtel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.cloud.bigquery.jdbc;

import com.google.api.gax.rpc.HeaderProvider;
import com.google.auth.Credentials;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.bigquery.exception.BigQueryJdbcRuntimeException;
Expand All @@ -32,9 +33,16 @@
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
Expand Down Expand Up @@ -85,11 +93,25 @@ private static final class SdkCacheKey {
private final String projectId;
private final String credentialsHashOrPath;
private final boolean enableTrace;

SdkCacheKey(String projectId, String credentialsHashOrPath, boolean enableTrace) {
private final String proxyHost;
private final String proxyPort;

SdkCacheKey(
String projectId,
String credentialsHashOrPath,
boolean enableTrace,
Map<String, String> proxyProperties) {
this.projectId = projectId;
this.credentialsHashOrPath = credentialsHashOrPath;
this.enableTrace = enableTrace;
this.proxyHost =
proxyProperties != null
? proxyProperties.get(BigQueryJdbcUrlUtility.PROXY_HOST_PROPERTY_NAME)
: null;
this.proxyPort =
proxyProperties != null
? proxyProperties.get(BigQueryJdbcUrlUtility.PROXY_PORT_PROPERTY_NAME)
: null;
}

@Override
Expand All @@ -99,12 +121,14 @@ public boolean equals(Object o) {
SdkCacheKey that = (SdkCacheKey) o;
return enableTrace == that.enableTrace
&& Objects.equals(projectId, that.projectId)
&& Objects.equals(credentialsHashOrPath, that.credentialsHashOrPath);
&& Objects.equals(credentialsHashOrPath, that.credentialsHashOrPath)
&& Objects.equals(proxyHost, that.proxyHost)
&& Objects.equals(proxyPort, that.proxyPort);
}

@Override
public int hashCode() {
return Objects.hash(projectId, credentialsHashOrPath, enableTrace);
return Objects.hash(projectId, credentialsHashOrPath, enableTrace, proxyHost, proxyPort);
}
}

Expand Down Expand Up @@ -181,7 +205,8 @@ public static Logging createLoggingClient(
OpenTelemetry customOpenTelemetry,
String effectiveCredentials,
String effectiveProjectId,
Credentials fallbackCredentials) {
Credentials fallbackCredentials,
HeaderProvider headerProvider) {

if (!enableGcpLogExporter || customOpenTelemetry != null) {
return null;
Expand All @@ -200,6 +225,9 @@ public static Logging createLoggingClient(
if (credentials != null) {
loggingOptionsBuilder.setCredentials(credentials);
}
if (headerProvider != null) {
loggingOptionsBuilder.setHeaderProvider(headerProvider);
}
return loggingOptionsBuilder.build().getService();
} catch (Exception e) {
throw new BigQueryJdbcRuntimeException("Failed to initialize Logging client", e);
Expand Down Expand Up @@ -317,7 +345,8 @@ public static OpenTelemetry getOpenTelemetry(
OpenTelemetry customOpenTelemetry,
String gcpTelemetryCredentials,
String gcpTelemetryProjectId,
Credentials fallbackCredentials) {
Credentials fallbackCredentials,
Map<String, String> proxyProperties) {

if (customOpenTelemetry != null) {
return customOpenTelemetry;
Expand All @@ -335,7 +364,8 @@ public static OpenTelemetry getOpenTelemetry(
new SdkCacheKey(
gcpTelemetryProjectId,
getCredentialsIdentifier(gcpTelemetryCredentials),
enableGcpTraceExporter);
enableGcpTraceExporter,
proxyProperties);
CachedSdk fastCheck = sdkCache.get(key);
if (fastCheck != null) {
CachedSdk result =
Expand Down Expand Up @@ -415,11 +445,17 @@ public static OpenTelemetry getOpenTelemetry(
final Credentials finalCredentials = credentials;

if (spanExporter instanceof OtlpHttpSpanExporter) {
return ((OtlpHttpSpanExporter) spanExporter)
.toBuilder()
.setHeaders(
() -> getAuthHeaders(finalCredentials, gcpTelemetryProjectId))
.build();
OtlpHttpSpanExporterBuilder builder =
((OtlpHttpSpanExporter) spanExporter).toBuilder();
builder.setHeaders(
() -> getAuthHeaders(finalCredentials, gcpTelemetryProjectId));

ProxyOptions proxyOptions = createProxyOptions(proxyProperties);
if (proxyOptions != null) {
builder.setProxy(proxyOptions);
}

return builder.build();
}
if (spanExporter instanceof OtlpGrpcSpanExporter) {
return ((OtlpGrpcSpanExporter) spanExporter)
Expand Down Expand Up @@ -506,4 +542,37 @@ public static <T> T withTracing(
span.end();
}
}

private static ProxyOptions createProxyOptions(Map<String, String> proxyProperties) {
if (proxyProperties == null) {
return null;
}

final String host = proxyProperties.get(BigQueryJdbcUrlUtility.PROXY_HOST_PROPERTY_NAME);
final String portStr = proxyProperties.get(BigQueryJdbcUrlUtility.PROXY_PORT_PROPERTY_NAME);
if (host == null || host.isEmpty() || portStr == null || portStr.isEmpty()) {
return null;
}

int port;
try {
port = Integer.parseInt(portStr);
} catch (NumberFormatException e) {
throw new BigQueryJdbcRuntimeException("Invalid proxy port number: " + portStr, e);
}

ProxySelector proxySelector =
new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
return Collections.singletonList(
new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved(host, port)));
}

@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {}
};
Comment thread
keshavdandeva marked this conversation as resolved.

return ProxyOptions.create(proxySelector);
}
Comment thread
keshavdandeva marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ public void testOpenTelemetryPrecedenceHierarchy(
.when(
() ->
BigQueryJdbcOpenTelemetry.createLoggingClient(
anyBoolean(), any(), any(), any(), any()))
anyBoolean(), any(), any(), any(), any(), any()))
.thenReturn(mockLogging);

// Stub getOpenTelemetry to return the expected mock based on inputs
Expand All @@ -634,6 +634,7 @@ public void testOpenTelemetryPrecedenceHierarchy(
hasCustom ? eq(mockCustomOtel) : isNull(),
any(),
any(),
any(),
any()))
.thenAnswer(
invocation -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void testGetOpenTelemetry_withCustomSdk_returnsCustom() {

OpenTelemetry result =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, false, false, mockCustomOtel, null, null, null);
false, false, false, mockCustomOtel, null, null, null, null);

assertThat(result).isSameInstanceAs(mockCustomOtel);
}
Expand All @@ -64,15 +64,16 @@ public void testGetOpenTelemetry_withCustomSdkAndFlags_returnsCustom() {
// Custom SDK always takes precedence over individual flags
OpenTelemetry result =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, true, mockCustomOtel, null, null, null);
false, true, true, mockCustomOtel, null, null, null, null);

assertThat(result).isSameInstanceAs(mockCustomOtel);
}

@Test
public void testGetOpenTelemetry_noFlags_returnsNoop() {
OpenTelemetry result =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(false, false, false, null, null, null, null);
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, false, false, null, null, null, null, null);

assertThat(result).isSameInstanceAs(OpenTelemetry.noop());
}
Expand All @@ -88,10 +89,10 @@ public void testGetTracer_respectsScopeName() {
public void testGetOpenTelemetry_cachesSdkInstances() {
OpenTelemetry result1 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, false, null, null, "project1", null);
false, true, false, null, null, "project1", null, null);
OpenTelemetry result2 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, false, null, null, "project1", null);
false, true, false, null, null, "project1", null, null);

assertThat(result1).isSameInstanceAs(result2);
}
Expand All @@ -100,40 +101,43 @@ public void testGetOpenTelemetry_cachesSdkInstances() {
public void testGetOpenTelemetry_createsNewInstanceForDifferentKey() {
OpenTelemetry result1 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, false, null, null, "project1", null);
false, true, false, null, null, "project1", null, null);
OpenTelemetry result2 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, false, null, null, "project2", null);
false, true, false, null, null, "project2", null, null);

assertThat(result1).isNotSameInstanceAs(result2);
}

@Test
public void testGetOpenTelemetry_createsNewInstanceForDifferentTraceFlag() {
OpenTelemetry result1 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(false, true, true, null, null, "project1", null);
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, true, null, null, "project1", null, null);
OpenTelemetry result2 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, false, true, null, null, "project1", null);
false, false, true, null, null, "project1", null, null);

assertThat(result1).isNotSameInstanceAs(result2);
}

@Test
public void testGetOpenTelemetry_ignoresEnableLogFlagInCacheKey() {
OpenTelemetry result1 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(false, true, true, null, null, "project1", null);
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, true, null, null, "project1", null, null);
OpenTelemetry result2 =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
false, true, false, null, null, "project1", null);
false, true, false, null, null, "project1", null, null);

assertThat(result1).isSameInstanceAs(result2);
}

@Test
public void testGetOpenTelemetry_withUseGlobalOTel_returnsGlobal() {
OpenTelemetry result =
BigQueryJdbcOpenTelemetry.getOpenTelemetry(true, false, false, null, null, null, null);
BigQueryJdbcOpenTelemetry.getOpenTelemetry(
true, false, false, null, null, null, null, null);

assertThat(result).isSameInstanceAs(GlobalOpenTelemetry.get());
}
Expand Down
Loading
Loading