Skip to content
Merged
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,12 @@
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.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
Expand Down Expand Up @@ -85,11 +89,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 +117,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 +201,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 +221,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 +341,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 +360,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 +441,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 +538,25 @@ public static <T> T withTracing(
span.end();
}
}

private static ProxyOptions createProxyOptions(Map<String, String> proxyProperties) {
Comment thread
logachev marked this conversation as resolved.
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);
}

return ProxyOptions.create(InetSocketAddress.createUnresolved(host, port));
}
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