2323import static org .junit .jupiter .api .Assertions .assertTrue ;
2424
2525import com .google .api .gax .core .FixedCredentialsProvider ;
26+ import com .google .api .gax .grpc .InstantiatingGrpcChannelProvider ;
2627import com .google .api .gax .paging .Page ;
28+ import com .google .api .gax .rpc .TransportChannelProvider ;
2729import com .google .auth .oauth2 .GoogleCredentials ;
2830import com .google .cloud .ServiceOptions ;
2931import com .google .cloud .bigquery .jdbc .BigQueryConnection ;
3638import com .google .devtools .cloudtrace .v1 .Trace ;
3739import com .google .devtools .cloudtrace .v1 .TraceSpan ;
3840import com .google .gson .JsonObject ;
41+ import io .grpc .HttpConnectProxiedSocketAddress ;
42+ import io .grpc .ProxiedSocketAddress ;
43+ import io .grpc .ProxyDetector ;
44+ import io .opentelemetry .api .trace .Span ;
45+ import io .opentelemetry .api .trace .SpanContext ;
46+ import io .opentelemetry .api .trace .TraceFlags ;
47+ import io .opentelemetry .api .trace .TraceState ;
48+ import io .opentelemetry .context .Scope ;
49+ import io .opentelemetry .sdk .trace .IdGenerator ;
3950import java .io .File ;
51+ import java .net .InetSocketAddress ;
52+ import java .net .SocketAddress ;
4053import java .nio .charset .StandardCharsets ;
4154import java .nio .file .Files ;
4255import java .sql .Connection ;
4558import java .sql .Statement ;
4659import java .util .ArrayList ;
4760import java .util .List ;
61+ import org .junit .jupiter .api .Tag ;
4862import org .junit .jupiter .api .Test ;
4963
5064public class ITOpenTelemetryTest extends ITBase {
@@ -53,6 +67,7 @@ public class ITOpenTelemetryTest extends ITBase {
5367 private static final String CONNECTION_URL = connectionUrl ;
5468
5569 @ Test
70+ @ Tag ("known_issue" )
5671 public void testExecute_withOpenTelemetryGcpExporter () throws Exception {
5772
5873 // Step 1: Connect with GCP Exporters enabled via DataSource
@@ -124,8 +139,8 @@ public void testExecute_withOpenTelemetryGcpExporter() throws Exception {
124139 }
125140
126141 @ Test
142+ @ Tag ("known_issue" )
127143 public void testExecute_withErrorCorrelation () throws Exception {
128-
129144 // Step 1: Connect with GCP Exporters enabled via DataSource
130145 DataSource ds = DataSource .fromUrl (CONNECTION_URL );
131146 ds .setEnableGcpTraceExporter (true );
@@ -168,6 +183,7 @@ public void testExecute_withErrorCorrelation() throws Exception {
168183 }
169184
170185 @ Test
186+ @ Tag ("known_issue" )
171187 public void testExecute_withCustomCredentialsJson () throws Exception {
172188 JsonObject authJson = getAuthJson ();
173189 DataSource ds = DataSource .fromUrl (CONNECTION_URL );
@@ -179,6 +195,7 @@ public void testExecute_withCustomCredentialsJson() throws Exception {
179195 }
180196
181197 @ Test
198+ @ Tag ("known_issue" )
182199 public void testExecute_withCustomCredentialsFilePath () throws Exception {
183200 JsonObject authJson = getAuthJson ();
184201 File tempFile = File .createTempFile ("auth" , ".json" );
@@ -194,6 +211,7 @@ public void testExecute_withCustomCredentialsFilePath() throws Exception {
194211 }
195212
196213 @ Test
214+ @ Tag ("known_issue" )
197215 public void testExecute_withHttpProtocol () throws Exception {
198216 JsonObject authJson = getAuthJson ();
199217 System .setProperty ("otel.exporter.otlp.protocol" , "http/protobuf" );
@@ -211,6 +229,7 @@ public void testExecute_withHttpProtocol() throws Exception {
211229 }
212230
213231 @ Test
232+ @ Tag ("known_issue" )
214233 public void testExecute_withGrpcProtocol () throws Exception {
215234 JsonObject authJson = getAuthJson ();
216235 System .setProperty ("otel.exporter.otlp.protocol" , "grpc" );
@@ -227,6 +246,39 @@ public void testExecute_withGrpcProtocol() throws Exception {
227246 }
228247 }
229248
249+ @ Test
250+ public void testExecute_withHttpProtocol_andDirectTraceVerification () throws Exception {
251+ JsonObject authJson = getAuthJson ();
252+ System .setProperty ("otel.exporter.otlp.protocol" , "http/protobuf" );
253+
254+ try {
255+ DataSource ds = DataSource .fromUrl (CONNECTION_URL );
256+ ds .setEnableGcpTraceExporter (true );
257+ ds .setGcpTelemetryProjectId (PROJECT_ID );
258+ ds .setGcpTelemetryCredentials (authJson .toString ());
259+
260+ String traceId = IdGenerator .random ().generateTraceId ();
261+ String spanId = IdGenerator .random ().generateSpanId ();
262+ SpanContext parentContext =
263+ SpanContext .create (traceId , spanId , TraceFlags .getSampled (), TraceState .getDefault ());
264+
265+ try (Scope scope = Span .wrap (parentContext ).makeCurrent ()) {
266+ try (Connection connection = ds .getConnection ();
267+ Statement statement = connection .createStatement ()) {
268+ String query = "SELECT 1;" ;
269+ try (ResultSet rs = statement .executeQuery (query )) {
270+ assertTrue (rs .next ());
271+ }
272+ }
273+ }
274+
275+ Trace trace = verifyAndFetchTrace (traceId );
276+ assertNotNull (trace , "Trace must be found in Cloud Trace API: " + traceId );
277+ } finally {
278+ System .clearProperty ("otel.exporter.otlp.protocol" );
279+ }
280+ }
281+
230282 private void verifyTraceDelivery (DataSource ds ) throws Exception {
231283 ds .setEnableGcpLogExporter (true );
232284 ds .setLogLevel ("5" );
@@ -293,18 +345,42 @@ private Trace verifyAndFetchTrace(String traceId) throws Exception {
293345
294346 GoogleCredentials credentials = getCredentials ();
295347
296- TraceServiceSettings settings =
348+ TraceServiceSettings . Builder settingsBuilder =
297349 TraceServiceSettings .newBuilder ()
298- .setCredentialsProvider (FixedCredentialsProvider .create (credentials ))
299- .build ();
350+ .setCredentialsProvider (FixedCredentialsProvider .create (credentials ));
351+
352+ DataSource ds = DataSource .fromUrl (CONNECTION_URL );
353+ String proxyHost = ds .getProxyHost ();
354+ String proxyPortStr = ds .getProxyPort ();
355+ if (proxyHost != null && proxyPortStr != null ) {
356+ settingsBuilder .setTransportChannelProvider (
357+ createProxyTransportChannelProvider (proxyHost , Integer .parseInt (proxyPortStr )));
358+ }
300359
301- try (TraceServiceClient traceClient = TraceServiceClient .create (settings )) {
360+ try (TraceServiceClient traceClient = TraceServiceClient .create (settingsBuilder . build () )) {
302361 Trace trace = fetchTraceWithRetry (traceClient , PROJECT_ID , hexTraceId );
303362 assertNotNull (trace , "Trace must be found in Cloud Trace API: " + hexTraceId );
304363 return trace ;
305364 }
306365 }
307366
367+ private TransportChannelProvider createProxyTransportChannelProvider (String host , int port ) {
368+ return InstantiatingGrpcChannelProvider .newBuilder ()
369+ .setChannelConfigurator (
370+ builder ->
371+ builder .proxyDetector (
372+ new ProxyDetector () {
373+ @ Override
374+ public ProxiedSocketAddress proxyFor (SocketAddress socketAddress ) {
375+ return HttpConnectProxiedSocketAddress .newBuilder ()
376+ .setProxyAddress (new InetSocketAddress (host , port ))
377+ .setTargetAddress ((InetSocketAddress ) socketAddress )
378+ .build ();
379+ }
380+ }))
381+ .build ();
382+ }
383+
308384 private <T > T pollWithRetry (java .util .concurrent .Callable <T > task ) throws InterruptedException {
309385 int attempts = 0 ;
310386 int maxAttempts = 10 ;
0 commit comments