gemini-code-assist[bot] commented on code in PR #38846:
URL: https://github.com/apache/beam/pull/38846#discussion_r3373382536


##########
sdks/java/extensions/opentelemetry-gcp-auth-extension/src/main/java/org/apache/beam/sdk/extensions/opentelemetry/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java:
##########
@@ -96,150 +108,132 @@ public class GcpAuthAutoConfigurationCustomizerProvider
    * enable GCP integration.
    *
    * @param autoConfiguration the AutoConfigurationCustomizer to customize.
+   * @throws GoogleAuthException if there's an error retrieving Google 
Application Default
+   *     Credentials.
+   * @throws io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException if 
required options are
+   *     not configured through environment variables or system properties.
    */
   @Override
   public void customize(@Nonnull AutoConfigurationCustomizer 
autoConfiguration) {
+    GoogleCredentials credentials;
+    try {
+      credentials = GoogleCredentials.getApplicationDefault();
+    } catch (IOException e) {
+      throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
+    }
     autoConfiguration
-        .addSpanExporterCustomizer(this::customizeSpanExporter)
-        .addMetricExporterCustomizer(this::customizeMetricExporter)
-        .addResourceCustomizer(this::customizeResource);
+        .addSpanExporterCustomizer(
+            (spanExporter, configProperties) ->
+                customizeSpanExporter(spanExporter, credentials, 
configProperties))
+        .addMetricExporterCustomizer(
+            (metricExporter, configProperties) ->
+                customizeMetricExporter(metricExporter, credentials, 
configProperties))
+        .addResourceCustomizer(
+            (resource, configProperties) ->
+                customizeResource(resource, credentials, configProperties));
   }

Review Comment:
   ![critical](https://www.gstatic.com/codereviewagent/critical.svg)
   
   Eagerly loading `GoogleCredentials.getApplicationDefault()` inside the 
`customize` method will throw a `GoogleAuthException` during OpenTelemetry SDK 
initialization if GCP Application Default Credentials are not configured. This 
happens even if the user has explicitly disabled GCP authentication (e.g., by 
setting the signal type to `none`) or is not targeting GCP endpoints, because 
this customizer is loaded via SPI on startup.
   
   To fix this, we should defer the loading of credentials using a lazy 
`Supplier` so that they are only retrieved when a GCP-targeted signal is 
actually processed.
   
   ```java
     @Override
     public void customize(@Nonnull AutoConfigurationCustomizer 
autoConfiguration) {
       java.util.function.Supplier<GoogleCredentials> credentialsSupplier =
           new java.util.function.Supplier<>() {
             private GoogleCredentials credentials;
   
             @Override
             public synchronized GoogleCredentials get() {
               if (credentials == null) {
                 try {
                   credentials = GoogleCredentials.getApplicationDefault();
                 } catch (IOException e) {
                   throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, 
e);
                 }
               }
               return credentials;
             }
           };
       autoConfiguration
           .addSpanExporterCustomizer(
               (spanExporter, configProperties) ->
                   customizeSpanExporter(spanExporter, credentialsSupplier, 
configProperties))
           .addMetricExporterCustomizer(
               (metricExporter, configProperties) ->
                   customizeMetricExporter(metricExporter, credentialsSupplier, 
configProperties))
           .addResourceCustomizer(
               (resource, configProperties) ->
                   customizeResource(resource, credentialsSupplier, 
configProperties));
     }
   ```



##########
sdks/java/extensions/opentelemetry-gcp-auth-extension/src/main/java/org/apache/beam/sdk/extensions/opentelemetry/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java:
##########
@@ -96,150 +108,132 @@ public class GcpAuthAutoConfigurationCustomizerProvider
    * enable GCP integration.
    *
    * @param autoConfiguration the AutoConfigurationCustomizer to customize.
+   * @throws GoogleAuthException if there's an error retrieving Google 
Application Default
+   *     Credentials.
+   * @throws io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException if 
required options are
+   *     not configured through environment variables or system properties.
    */
   @Override
   public void customize(@Nonnull AutoConfigurationCustomizer 
autoConfiguration) {
+    GoogleCredentials credentials;
+    try {
+      credentials = GoogleCredentials.getApplicationDefault();
+    } catch (IOException e) {
+      throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
+    }
     autoConfiguration
-        .addSpanExporterCustomizer(this::customizeSpanExporter)
-        .addMetricExporterCustomizer(this::customizeMetricExporter)
-        .addResourceCustomizer(this::customizeResource);
+        .addSpanExporterCustomizer(
+            (spanExporter, configProperties) ->
+                customizeSpanExporter(spanExporter, credentials, 
configProperties))
+        .addMetricExporterCustomizer(
+            (metricExporter, configProperties) ->
+                customizeMetricExporter(metricExporter, credentials, 
configProperties))
+        .addResourceCustomizer(
+            (resource, configProperties) ->
+                customizeResource(resource, credentials, configProperties));
   }
 
   @Override
   public int order() {
     return Integer.MAX_VALUE - 1;
   }
 
-  private synchronized GoogleCredentials getCredentials() {
-    if (credentials == null) {
-      try {
-        credentials = GoogleCredentials.getApplicationDefault();
-      } catch (IOException e) {
-        throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
-      }
-    }
-    return credentials;
-  }
-
-  private SpanExporter customizeSpanExporter(
-      SpanExporter exporter, ConfigProperties configProperties) {
+  private static SpanExporter customizeSpanExporter(
+      SpanExporter exporter, GoogleCredentials credentials, ConfigProperties 
configProperties) {
     if (isSignalTargeted(SIGNAL_TYPE_TRACES, configProperties)) {
-      return addAuthorizationHeaders(exporter, configProperties);
+      return addAuthorizationHeaders(exporter, credentials, configProperties);
+    } else if (!hasSignal(SIGNAL_TYPE_NONE, configProperties)) {
+      String[] params = {SIGNAL_TYPE_TRACES, 
SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
+      logger.log(
+          Level.WARNING,
+          "GCP Authentication Extension is not configured for signal type: 
{0}. {1}",
+          params);
     }
     return exporter;
   }

Review Comment:
   ![critical](https://www.gstatic.com/codereviewagent/critical.svg)
   
   Update `customizeSpanExporter` to accept a lazy 
`Supplier<GoogleCredentials>` instead of eagerly loaded `GoogleCredentials`.
   
   ```java
     private static SpanExporter customizeSpanExporter(
         SpanExporter exporter,
         java.util.function.Supplier<GoogleCredentials> credentialsSupplier,
         ConfigProperties configProperties) {
       if (isSignalTargeted(SIGNAL_TYPE_TRACES, configProperties)) {
         return addAuthorizationHeaders(exporter, credentialsSupplier.get(), 
configProperties);
       } else if (!hasSignal(SIGNAL_TYPE_NONE, configProperties)) {
         String[] params = {SIGNAL_TYPE_TRACES, 
SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
         logger.log(
             Level.WARNING,
             "GCP Authentication Extension is not configured for signal type: 
{0}. {1}",
             params);
       }
       return exporter;
     }
   ```



##########
sdks/java/extensions/opentelemetry-gcp-auth-extension/src/main/java/org/apache/beam/sdk/extensions/opentelemetry/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java:
##########
@@ -262,16 +256,13 @@ private Map<String, String> 
getRequiredHeaderMap(ConfigProperties configProperti
   }
 
   // Updates the current resource with the attributes required for ingesting 
OTLP data on GCP.
-  private Resource customizeResource(Resource resource, ConfigProperties 
configProperties) {
-    if (!isAnySignalTargeted(configProperties)) {
-      return resource;
-    }
-
+  private static Resource customizeResource(
+      Resource resource, GoogleCredentials credentials, ConfigProperties 
configProperties) {
     String gcpProjectId;
     try {
       gcpProjectId = 
ConfigurableOption.GOOGLE_CLOUD_PROJECT.getConfiguredValue(configProperties);
     } catch (ConfigurationException e) {
-      gcpProjectId = getCredentials().getProjectId();
+      gcpProjectId = credentials.getProjectId();
       if (gcpProjectId == null || gcpProjectId.isEmpty()) {
         throw e;
       }

Review Comment:
   ![critical](https://www.gstatic.com/codereviewagent/critical.svg)
   
   In addition to accepting a lazy `Supplier<GoogleCredentials>`, we must 
restore the check to verify if any signal is targeted for GCP authentication 
before attempting to customize the resource. Without this check, 
`customizeResource` will always run and throw a `ConfigurationException` if the 
GCP project ID is missing, even if the user has explicitly disabled GCP 
authentication (e.g., by setting the signal type to `none`).
   
   ```java
     private static Resource customizeResource(
         Resource resource,
         java.util.function.Supplier<GoogleCredentials> credentialsSupplier,
         ConfigProperties configProperties) {
       if (!isSignalTargeted(SIGNAL_TYPE_TRACES, configProperties)
           && !isSignalTargeted(SIGNAL_TYPE_METRICS, configProperties)) {
         return resource;
       }
       String gcpProjectId;
       try {
         gcpProjectId = 
ConfigurableOption.GOOGLE_CLOUD_PROJECT.getConfiguredValue(configProperties);
       } catch (ConfigurationException e) {
         gcpProjectId = credentialsSupplier.get().getProjectId();
         if (gcpProjectId == null || gcpProjectId.isEmpty()) {
           throw e;
         }
   ```



##########
sdks/java/extensions/opentelemetry-gcp-auth-extension/src/main/java/org/apache/beam/sdk/extensions/opentelemetry/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java:
##########
@@ -96,150 +108,132 @@ public class GcpAuthAutoConfigurationCustomizerProvider
    * enable GCP integration.
    *
    * @param autoConfiguration the AutoConfigurationCustomizer to customize.
+   * @throws GoogleAuthException if there's an error retrieving Google 
Application Default
+   *     Credentials.
+   * @throws io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException if 
required options are
+   *     not configured through environment variables or system properties.
    */
   @Override
   public void customize(@Nonnull AutoConfigurationCustomizer 
autoConfiguration) {
+    GoogleCredentials credentials;
+    try {
+      credentials = GoogleCredentials.getApplicationDefault();
+    } catch (IOException e) {
+      throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
+    }
     autoConfiguration
-        .addSpanExporterCustomizer(this::customizeSpanExporter)
-        .addMetricExporterCustomizer(this::customizeMetricExporter)
-        .addResourceCustomizer(this::customizeResource);
+        .addSpanExporterCustomizer(
+            (spanExporter, configProperties) ->
+                customizeSpanExporter(spanExporter, credentials, 
configProperties))
+        .addMetricExporterCustomizer(
+            (metricExporter, configProperties) ->
+                customizeMetricExporter(metricExporter, credentials, 
configProperties))
+        .addResourceCustomizer(
+            (resource, configProperties) ->
+                customizeResource(resource, credentials, configProperties));
   }
 
   @Override
   public int order() {
     return Integer.MAX_VALUE - 1;
   }
 
-  private synchronized GoogleCredentials getCredentials() {
-    if (credentials == null) {
-      try {
-        credentials = GoogleCredentials.getApplicationDefault();
-      } catch (IOException e) {
-        throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
-      }
-    }
-    return credentials;
-  }
-
-  private SpanExporter customizeSpanExporter(
-      SpanExporter exporter, ConfigProperties configProperties) {
+  private static SpanExporter customizeSpanExporter(
+      SpanExporter exporter, GoogleCredentials credentials, ConfigProperties 
configProperties) {
     if (isSignalTargeted(SIGNAL_TYPE_TRACES, configProperties)) {
-      return addAuthorizationHeaders(exporter, configProperties);
+      return addAuthorizationHeaders(exporter, credentials, configProperties);
+    } else if (!hasSignal(SIGNAL_TYPE_NONE, configProperties)) {
+      String[] params = {SIGNAL_TYPE_TRACES, 
SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
+      logger.log(
+          Level.WARNING,
+          "GCP Authentication Extension is not configured for signal type: 
{0}. {1}",
+          params);
     }
     return exporter;
   }
 
-  private MetricExporter customizeMetricExporter(
-      MetricExporter exporter, ConfigProperties configProperties) {
+  private static MetricExporter customizeMetricExporter(
+      MetricExporter exporter, GoogleCredentials credentials, ConfigProperties 
configProperties) {
     if (isSignalTargeted(SIGNAL_TYPE_METRICS, configProperties)) {
-      return addAuthorizationHeaders(exporter, configProperties);
+      return addAuthorizationHeaders(exporter, credentials, configProperties);
+    } else if (!hasSignal(SIGNAL_TYPE_NONE, configProperties)) {
+      String[] params = {SIGNAL_TYPE_METRICS, 
SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
+      logger.log(
+          Level.WARNING,
+          "GCP Authentication Extension is not configured for signal type: 
{0}. {1}",
+          params);
     }
     return exporter;
   }

Review Comment:
   ![critical](https://www.gstatic.com/codereviewagent/critical.svg)
   
   Update `customizeMetricExporter` to accept a lazy 
`Supplier<GoogleCredentials>` instead of eagerly loaded `GoogleCredentials`.
   
   ```suggestion
     private static MetricExporter customizeMetricExporter(
         MetricExporter exporter,
         java.util.function.Supplier<GoogleCredentials> credentialsSupplier,
         ConfigProperties configProperties) {
       if (isSignalTargeted(SIGNAL_TYPE_METRICS, configProperties)) {
         return addAuthorizationHeaders(exporter, credentialsSupplier.get(), 
configProperties);
       } else if (!hasSignal(SIGNAL_TYPE_NONE, configProperties)) {
         String[] params = {SIGNAL_TYPE_METRICS, 
SIGNAL_TARGET_WARNING_FIX_SUGGESTION};
         logger.log(
             Level.WARNING,
             "GCP Authentication Extension is not configured for signal type: 
{0}. {1}",
             params);
       }
       return exporter;
     }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to