CurtHagenlocher commented on code in PR #3022:
URL: https://github.com/apache/arrow-adbc/pull/3022#discussion_r2183649197


##########
csharp/src/Drivers/BigQuery/BigQueryParameters.cs:
##########
@@ -68,5 +69,10 @@ internal class BigQueryConstants
 
         // default value per 
https://pkg.go.dev/cloud.google.com/go/bigquery#section-readme
         public const string DetectProjectId = "*detect-project-id*";
+
+        // What ODBC uses

Review Comment:
   Consider amending the comment to explain why we would use the same value as 
ODBC (versus e.g. `_bqadbc_temp_tables`).



##########
csharp/src/Drivers/BigQuery/RetryManager.cs:
##########
@@ -67,7 +73,9 @@ public static async Task<T> ExecuteWithRetriesAsync<T>(
                     {
                         if (tokenProtectedResource.TokenRequiresUpdate(ex) == 
true)
                         {
+                            activity?.AddBigQueryTag("update_token.status", 
"Required");
                             await tokenProtectedResource.UpdateToken();
+                            activity?.AddBigQueryTag("update_token.status", 
"Completed");

Review Comment:
   What's the behavior when adding the same tag twice? It keeps the most recent 
one or it keeps all of them?



##########
csharp/src/Drivers/BigQuery/BigQueryConnection.cs:
##########
@@ -36,16 +38,17 @@ namespace Apache.Arrow.Adbc.Drivers.BigQuery
     /// <summary>
     /// BigQuery-specific implementation of <see cref="AdbcConnection"/>
     /// </summary>
-    public class BigQueryConnection : AdbcConnection, ITokenProtectedResource
+    public class BigQueryConnection : TracingConnection, 
ITokenProtectedResource
     {
         readonly Dictionary<string, string> properties;
         readonly HttpClient httpClient;
         bool includePublicProjectIds = false;
         const string infoDriverName = "ADBC BigQuery Driver";
-        const string infoDriverVersion = "1.0.1";
         const string infoVendorName = "BigQuery";
-        const string infoDriverArrowVersion = "19.0.0";
-        const string publicProjectId = "bigquery-public-data";
+        readonly string? infoDriverArrowVersion;
+
+        private static readonly string s_assemblyName = 
BigQueryUtils.GetAssemblyName(typeof(BigQueryStatement));
+        private static readonly string s_assemblyVersion = 
BigQueryUtils.GetAssemblyVersion(typeof(BigQueryStatement));

Review Comment:
   Instead of capturing these three times in `BigQueryConnection`, 
`BigQueryStatement` and `BigQueryStatement.MultiArrowReader`, consider storing 
them in just `BigQueryUtils` and referencing them from there.



##########
csharp/src/Drivers/BigQuery/BigQueryUtils.cs:
##########
@@ -33,5 +34,11 @@ public static bool TokenRequiresUpdate(Exception ex)
 
             return result;
         }
+
+        internal static string GetAssemblyName(Type type) => 
type.Assembly.GetName().Name!;
+
+        internal static string GetAssemblyVersion(Type type) => 
FileVersionInfo.GetVersionInfo(type.Assembly.Location).ProductVersion ?? 
string.Empty;
+
+        internal static bool TracingToFile() { return false; }

Review Comment:
   Consider making a property instead of a method.



##########
csharp/src/Drivers/BigQuery/BigQueryStatement.cs:
##########
@@ -355,112 +388,215 @@ private QueryOptions ValidateOptions()
                     if (firstProjectId != null)
                     {
                         options.ProjectId = firstProjectId;
+                        activity?.AddBigQueryTag("detected_client_project_id", 
firstProjectId);
+                        // need to reopen the Client with the projectId 
specified
+                        this.bigQueryConnection.Open(firstProjectId);
                     }
                 }
             }
 
             if (Options == null || Options.Count == 0)
                 return options;
 
+            string largeResultDatasetId = 
BigQueryConstants.DefaultLargeDatasetId;
+
             foreach (KeyValuePair<string, string> keyValuePair in Options)
             {
-                if (keyValuePair.Key == BigQueryParameters.AllowLargeResults)
+                switch (keyValuePair.Key)
                 {
-                    options.AllowLargeResults = true ? 
keyValuePair.Value.ToLower().Equals("true") : false;
-                }
-                if (keyValuePair.Key == 
BigQueryParameters.LargeResultsDestinationTable)
-                {
-                    string destinationTable = keyValuePair.Value;
+                    case BigQueryParameters.AllowLargeResults:
+                        options.AllowLargeResults = true ? 
keyValuePair.Value.ToLower().Equals("true") : false;

Review Comment:
   There are two existing and one new instance of `s.ToLower().Equals("true")` 
in this file, which is strictly worse than `s.Equals("true", 
StringComparer.OrdinalIgnoreCase)`.



##########
csharp/src/Drivers/BigQuery/BigQueryConnection.cs:
##########
@@ -282,89 +331,97 @@ public override IArrowArrayStream 
GetInfo(IReadOnlyList<AdbcInfoCode> codes)
                         ),
                         true
                     )
-                },
-                new int[] { 0, 1, 2, 3, 4, 5 }.ToArray(),
-                UnionMode.Dense);
+                    },
+                    new int[] { 0, 1, 2, 3, 4, 5 }.ToArray(),
+                    UnionMode.Dense);
 
-            if (codes.Count == 0)
-            {
-                codes = infoSupportedCodes;
-            }
+                if (codes.Count == 0)
+                {
+                    codes = infoSupportedCodes;
+                }
 
-            UInt32Array.Builder infoNameBuilder = new UInt32Array.Builder();
-            ArrowBuffer.Builder<byte> typeBuilder = new 
ArrowBuffer.Builder<byte>();
-            ArrowBuffer.Builder<int> offsetBuilder = new 
ArrowBuffer.Builder<int>();
-            StringArray.Builder stringInfoBuilder = new StringArray.Builder();
-            int nullCount = 0;
-            int arrayLength = codes.Count;
+                UInt32Array.Builder infoNameBuilder = new 
UInt32Array.Builder();
+                ArrowBuffer.Builder<byte> typeBuilder = new 
ArrowBuffer.Builder<byte>();
+                ArrowBuffer.Builder<int> offsetBuilder = new 
ArrowBuffer.Builder<int>();
+                StringArray.Builder stringInfoBuilder = new 
StringArray.Builder();
+                int nullCount = 0;
+                int arrayLength = codes.Count;
 
-            foreach (AdbcInfoCode code in codes)
-            {
-                switch (code)
+                foreach (AdbcInfoCode code in codes)
                 {
-                    case AdbcInfoCode.DriverName:
-                        infoNameBuilder.Append((UInt32)code);
-                        typeBuilder.Append(strValTypeID);
-                        offsetBuilder.Append(stringInfoBuilder.Length);
-                        stringInfoBuilder.Append(infoDriverName);
-                        break;
-                    case AdbcInfoCode.DriverVersion:
-                        infoNameBuilder.Append((UInt32)code);
-                        typeBuilder.Append(strValTypeID);
-                        offsetBuilder.Append(stringInfoBuilder.Length);
-                        stringInfoBuilder.Append(infoDriverVersion);
-                        break;
-                    case AdbcInfoCode.DriverArrowVersion:
-                        infoNameBuilder.Append((UInt32)code);
-                        typeBuilder.Append(strValTypeID);
-                        offsetBuilder.Append(stringInfoBuilder.Length);
-                        stringInfoBuilder.Append(infoDriverArrowVersion);
-                        break;
-                    case AdbcInfoCode.VendorName:
-                        infoNameBuilder.Append((UInt32)code);
-                        typeBuilder.Append(strValTypeID);
-                        offsetBuilder.Append(stringInfoBuilder.Length);
-                        stringInfoBuilder.Append(infoVendorName);
-                        break;
-                    default:
-                        infoNameBuilder.Append((UInt32)code);
-                        typeBuilder.Append(strValTypeID);
-                        offsetBuilder.Append(stringInfoBuilder.Length);
-                        stringInfoBuilder.AppendNull();
-                        nullCount++;
-                        break;
+                    string tagKey = 
SemanticConventions.Db.Operation.Parameter(code.ToString().ToLowerInvariant());
+                    Func<object?> tagValue = () => null;
+                    switch (code)
+                    {
+                        case AdbcInfoCode.DriverName:
+                            infoNameBuilder.Append((UInt32)code);
+                            typeBuilder.Append(strValTypeID);
+                            offsetBuilder.Append(stringInfoBuilder.Length);
+                            stringInfoBuilder.Append(infoDriverName);
+                            tagValue = () => infoDriverName;

Review Comment:
   Why does it makes sense to capture these as delegates instead of just 
recording the object value?



##########
csharp/test/Drivers/BigQuery/DriverTests.cs:
##########
@@ -291,7 +291,7 @@ public void CanExecuteQuery()
                 AdbcConnection adbcConnection = 
GetAdbcConnection(environment.Name);
 
                 AdbcStatement statement = adbcConnection.CreateStatement();
-                statement.SqlQuery = environment.Query;
+                statement.SqlQuery = "select * from 
mashuptest-154002.NWIND.AdbcAllTypes"; // environment.Query;

Review Comment:
   Should this be reverted?



##########
csharp/src/Drivers/BigQuery/BigQueryStatement.cs:
##########
@@ -302,25 +331,27 @@ private IArrowType GetType(TableFieldSchema field, 
IArrowType type)
             return type;
         }
 
-        private IArrowReader? 
ReadChunkWithRetries(TokenProtectedReadClientManger clientMgr, string 
streamName)
+        private IArrowReader? 
ReadChunkWithRetries(TokenProtectedReadClientManger clientMgr, string 
streamName, Activity? activity)
         {
-            Func<Task<IArrowReader?>> func = () => 
Task.FromResult<IArrowReader?>(ReadChunk(clientMgr, streamName));
-            return 
RetryManager.ExecuteWithRetriesAsync<IArrowReader?>(clientMgr, func, 
MaxRetryAttempts, RetryDelayMs).GetAwaiter().GetResult();
+            Func<Task<IArrowReader?>> func = () => 
Task.FromResult<IArrowReader?>(ReadChunk(clientMgr, streamName, activity));
+            return 
RetryManager.ExecuteWithRetriesAsync<IArrowReader?>(clientMgr, func, activity, 
MaxRetryAttempts, RetryDelayMs).GetAwaiter().GetResult();
         }
 
-        private static IArrowReader? ReadChunk(TokenProtectedReadClientManger 
clientMgr, string streamName)
+        private static IArrowReader? ReadChunk(TokenProtectedReadClientManger 
clientMgr, string streamName, Activity? activity)
         {
-            return ReadChunk(clientMgr.ReadClient, streamName);
+            return ReadChunk(clientMgr.ReadClient, streamName, activity);
         }
 
-        private static IArrowReader? ReadChunk(BigQueryReadClient client, 
string streamName)
+        private static IArrowReader? ReadChunk(BigQueryReadClient client, 
string streamName, Activity? activity)
         {
             // Ideally we wouldn't need to indirect through a stream, but the 
necessary APIs in Arrow
             // are internal. (TODO: consider changing Arrow).
+            activity?.AddBigQueryTag("read_stream", streamName);

Review Comment:
   Is the stream name system-generated or can it expose an arbitrary user 
identifier?
   
   I'll stop asking this question, but might apply to other things like the 
destination table.



##########
csharp/src/Drivers/BigQuery/BigQueryConnection.cs:
##########
@@ -36,16 +38,17 @@ namespace Apache.Arrow.Adbc.Drivers.BigQuery
     /// <summary>
     /// BigQuery-specific implementation of <see cref="AdbcConnection"/>
     /// </summary>
-    public class BigQueryConnection : AdbcConnection, ITokenProtectedResource
+    public class BigQueryConnection : TracingConnection, 
ITokenProtectedResource
     {
         readonly Dictionary<string, string> properties;
         readonly HttpClient httpClient;
         bool includePublicProjectIds = false;
         const string infoDriverName = "ADBC BigQuery Driver";
-        const string infoDriverVersion = "1.0.1";
         const string infoVendorName = "BigQuery";
-        const string infoDriverArrowVersion = "19.0.0";
-        const string publicProjectId = "bigquery-public-data";
+        readonly string? infoDriverArrowVersion;

Review Comment:
   Why is this an instance field while the next two are static fields?



##########
csharp/src/Drivers/BigQuery/BigQueryConnection.cs:
##########
@@ -97,136 +104,176 @@ public BigQueryConnection(IReadOnlyDictionary<string, 
string> properties)
 
         internal int RetryDelayMs { get; private set; } = 200;
 
+        public override string AssemblyVersion => s_assemblyVersion;
+
+        public override string AssemblyName => s_assemblyName;
+
         /// <summary>
         /// Initializes the internal BigQuery connection
         /// </summary>
+        /// <param name="projectId">A project ID that has been specified by 
the caller, not a user.</param>
         /// <exception cref="ArgumentException"></exception>
-        internal BigQueryClient Open()
+        internal BigQueryClient Open(string? projectId = null)
         {
-            string? projectId = null;
-            string? billingProjectId = null;
-            TimeSpan? clientTimeout = null;
-
-            // if the caller doesn't specify a projectId, use the default
-            if (!this.properties.TryGetValue(BigQueryParameters.ProjectId, out 
projectId))
-                projectId = BigQueryConstants.DetectProjectId;
-
-            // in some situations, the publicProjectId gets passed and causes 
an error when we try to create a query job:
-            //     Google.GoogleApiException : The service bigquery has thrown 
an exception. HttpStatusCode is Forbidden.
-            //     Access Denied: Project bigquery-public-data: User does not 
have bigquery.jobs.create permission in
-            //     project bigquery-public-data.
-            // so if that is the case, treat it as if we need to detect the 
projectId
-            if (projectId.Equals(publicProjectId, 
StringComparison.OrdinalIgnoreCase))
-                projectId = BigQueryConstants.DetectProjectId;
-
-            // the billing project can be null if it's not specified
-            this.properties.TryGetValue(BigQueryParameters.BillingProjectId, 
out billingProjectId);
-
-            if 
(this.properties.TryGetValue(BigQueryParameters.IncludePublicProjectId, out 
string? result))
+            return this.TraceActivity(activity =>
             {
-                if (!string.IsNullOrEmpty(result))
-                    this.includePublicProjectIds = Convert.ToBoolean(result);
-            }
+                string? billingProjectId = null;
+                TimeSpan? clientTimeout = null;
 
-            if (this.properties.TryGetValue(BigQueryParameters.ClientTimeout, 
out string? timeoutSeconds) &&
-                int.TryParse(timeoutSeconds, out int seconds))
-            {
-                clientTimeout = TimeSpan.FromSeconds(seconds);
-            }
+                if (string.IsNullOrEmpty(projectId))
+                {
+                    // if the caller doesn't specify a projectId, use the 
default
+                    if 
(!this.properties.TryGetValue(BigQueryParameters.ProjectId, out projectId))
+                    {
+                        projectId = BigQueryConstants.DetectProjectId;
+                    }
+                    else
+                    {
+                        
activity?.AddBigQueryParameterTag(BigQueryParameters.ProjectId, projectId);
+                    }
 
-            SetCredential();
+                    // in some situations, the publicProjectId gets passed and 
causes an error when we try to create a query job:
+                    //     Google.GoogleApiException : The service bigquery 
has thrown an exception. HttpStatusCode is Forbidden.
+                    //     Access Denied: Project bigquery-public-data: User 
does not have bigquery.jobs.create permission in
+                    //     project bigquery-public-data.
+                    // so if that is the case, treat it as if we need to 
detect the projectId
+                    if (projectId.Equals(BigQueryConstants.PublicProjectId, 
StringComparison.OrdinalIgnoreCase))
+                    {
+                        projectId = BigQueryConstants.DetectProjectId;
+                        
activity?.AddBigQueryTag("change_public_projectId_to_detect_project_id", 
projectId);
+                    }
+                }
 
-            BigQueryClientBuilder bigQueryClientBuilder = new 
BigQueryClientBuilder()
-            {
-                ProjectId = projectId,
-                QuotaProject = billingProjectId,
-                GoogleCredential = Credential
-            };
+                // the billing project can be null if it's not specified
+                if 
(this.properties.TryGetValue(BigQueryParameters.BillingProjectId, out 
billingProjectId))
+                {
+                    
activity?.AddBigQueryParameterTag((BigQueryParameters.BillingProjectId), 
billingProjectId);
+                }
+
+                if 
(this.properties.TryGetValue(BigQueryParameters.IncludePublicProjectId, out 
string? result))
+                {
+                    if (!string.IsNullOrEmpty(result))
+                    {
+                        this.includePublicProjectIds = 
Convert.ToBoolean(result);
+                        
activity?.AddBigQueryParameterTag(BigQueryParameters.IncludePublicProjectId, 
this.includePublicProjectIds);
+                    }
+                }
 
-            BigQueryClient client = bigQueryClientBuilder.Build();
+                if 
(this.properties.TryGetValue(BigQueryParameters.ClientTimeout, out string? 
timeoutSeconds) &&
+                    int.TryParse(timeoutSeconds, out int seconds))
+                {
+                    clientTimeout = TimeSpan.FromSeconds(seconds);
+                    
activity?.AddBigQueryParameterTag(BigQueryParameters.ClientTimeout, seconds);
+                }
 
-            if (clientTimeout.HasValue)
-            {
-                client.Service.HttpClient.Timeout = clientTimeout.Value;
-            }
+                SetCredential();
+
+                BigQueryClientBuilder bigQueryClientBuilder = new 
BigQueryClientBuilder()
+                {
+                    ProjectId = projectId,
+                    QuotaProject = billingProjectId,
+                    GoogleCredential = Credential
+                };
 
-            Client = client;
-            return client;
+                BigQueryClient client = bigQueryClientBuilder.Build();
+
+                if (clientTimeout.HasValue)
+                {
+                    client.Service.HttpClient.Timeout = clientTimeout.Value;
+                }
+
+                Client = client;
+                return client;
+            });
         }
 
         internal void SetCredential()
         {
-            string? clientId = null;
-            string? clientSecret = null;
-            string? refreshToken = null;
-            string? accessToken = null;
-            string? audienceUri = null;
-            string? authenticationType = null;
-
-            string tokenEndpoint = BigQueryConstants.TokenEndpoint;
+            this.TraceActivity(activity =>
+            {
+                string? clientId = null;
+                string? clientSecret = null;
+                string? refreshToken = null;
+                string? accessToken = null;
+                string? audienceUri = null;
+                string? authenticationType = null;
 
-            if 
(!this.properties.TryGetValue(BigQueryParameters.AuthenticationType, out 
authenticationType))
-                throw new ArgumentException($"The 
{BigQueryParameters.AuthenticationType} parameter is not present");
+                string tokenEndpoint = BigQueryConstants.TokenEndpoint;
 
-            if 
(this.properties.TryGetValue(BigQueryParameters.AuthenticationType, out string? 
newAuthenticationType))
-            {
-                if (!string.IsNullOrEmpty(newAuthenticationType))
-                    authenticationType = newAuthenticationType;
+                if 
(!this.properties.TryGetValue(BigQueryParameters.AuthenticationType, out 
authenticationType))
+                {
+                    throw new ArgumentException($"The 
{BigQueryParameters.AuthenticationType} parameter is not present");
+                }
 
-                if 
(!authenticationType.Equals(BigQueryConstants.UserAuthenticationType, 
StringComparison.OrdinalIgnoreCase) &&
-                    
!authenticationType.Equals(BigQueryConstants.ServiceAccountAuthenticationType, 
StringComparison.OrdinalIgnoreCase) &&
-                    
!authenticationType.Equals(BigQueryConstants.EntraIdAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
+                if 
(this.properties.TryGetValue(BigQueryParameters.AuthenticationType, out string? 
newAuthenticationType))
                 {
-                    throw new ArgumentException($"The 
{BigQueryParameters.AuthenticationType} parameter can only be 
`{BigQueryConstants.UserAuthenticationType}`, 
`{BigQueryConstants.ServiceAccountAuthenticationType}` or 
`{BigQueryConstants.EntraIdAuthenticationType}`");
+                    if (!string.IsNullOrEmpty(newAuthenticationType))
+                        authenticationType = newAuthenticationType;
+
+                    if 
(!authenticationType.Equals(BigQueryConstants.UserAuthenticationType, 
StringComparison.OrdinalIgnoreCase) &&
+                        
!authenticationType.Equals(BigQueryConstants.ServiceAccountAuthenticationType, 
StringComparison.OrdinalIgnoreCase) &&
+                        
!authenticationType.Equals(BigQueryConstants.EntraIdAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
+                    {
+                        throw new ArgumentException($"The 
{BigQueryParameters.AuthenticationType} parameter can only be 
`{BigQueryConstants.UserAuthenticationType}`, 
`{BigQueryConstants.ServiceAccountAuthenticationType}` or 
`{BigQueryConstants.EntraIdAuthenticationType}`");
+                    }
+                    else
+                    {
+                        
activity?.AddBigQueryParameterTag((BigQueryParameters.AuthenticationType), 
authenticationType);
+                    }
                 }
-            }
 
-            if (!string.IsNullOrEmpty(authenticationType) && 
authenticationType.Equals(BigQueryConstants.UserAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
-            {
-                if (!this.properties.TryGetValue(BigQueryParameters.ClientId, 
out clientId))
-                    throw new ArgumentException($"The 
{BigQueryParameters.ClientId} parameter is not present");
+                if (!string.IsNullOrEmpty(authenticationType) && 
authenticationType.Equals(BigQueryConstants.UserAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
+                {
+                    if 
(!this.properties.TryGetValue(BigQueryParameters.ClientId, out clientId))
+                        throw new ArgumentException($"The 
{BigQueryParameters.ClientId} parameter is not present");
 
-                if 
(!this.properties.TryGetValue(BigQueryParameters.ClientSecret, out 
clientSecret))
-                    throw new ArgumentException($"The 
{BigQueryParameters.ClientSecret} parameter is not present");
+                    if 
(!this.properties.TryGetValue(BigQueryParameters.ClientSecret, out 
clientSecret))
+                        throw new ArgumentException($"The 
{BigQueryParameters.ClientSecret} parameter is not present");
 
-                if 
(!this.properties.TryGetValue(BigQueryParameters.RefreshToken, out 
refreshToken))
-                    throw new ArgumentException($"The 
{BigQueryParameters.RefreshToken} parameter is not present");
+                    if 
(!this.properties.TryGetValue(BigQueryParameters.RefreshToken, out 
refreshToken))
+                        throw new ArgumentException($"The 
{BigQueryParameters.RefreshToken} parameter is not present");
 
-                Credential = 
ApplyScopes(GoogleCredential.FromAccessToken(GetAccessToken(clientId, 
clientSecret, refreshToken, tokenEndpoint)));
-            }
-            else if (!string.IsNullOrEmpty(authenticationType) && 
authenticationType.Equals(BigQueryConstants.EntraIdAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
-            {
-                if 
(!this.properties.TryGetValue(BigQueryParameters.AccessToken, out accessToken))
-                    throw new ArgumentException($"The 
{BigQueryParameters.AccessToken} parameter is not present");
+                    Credential = 
ApplyScopes(GoogleCredential.FromAccessToken(GetAccessToken(clientId, 
clientSecret, refreshToken, tokenEndpoint)));
+                }
+                else if (!string.IsNullOrEmpty(authenticationType) && 
authenticationType.Equals(BigQueryConstants.EntraIdAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
+                {
+                    if 
(!this.properties.TryGetValue(BigQueryParameters.AccessToken, out accessToken))
+                        throw new ArgumentException($"The 
{BigQueryParameters.AccessToken} parameter is not present");
 
-                if 
(!this.properties.TryGetValue(BigQueryParameters.AudienceUri, out audienceUri))
-                    throw new ArgumentException($"The 
{BigQueryParameters.AudienceUri} parameter is not present");
+                    if 
(!this.properties.TryGetValue(BigQueryParameters.AudienceUri, out audienceUri))
+                        throw new ArgumentException($"The 
{BigQueryParameters.AudienceUri} parameter is not present");
 
-                Credential = 
ApplyScopes(GoogleCredential.FromAccessToken(TradeEntraIdTokenForBigQueryToken(audienceUri,
 accessToken)));
-            }
-            else if (!string.IsNullOrEmpty(authenticationType) && 
authenticationType.Equals(BigQueryConstants.ServiceAccountAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
-            {
-                string? json = string.Empty;
+                    Credential = 
ApplyScopes(GoogleCredential.FromAccessToken(TradeEntraIdTokenForBigQueryToken(audienceUri,
 accessToken)));
+                }
+                else if (!string.IsNullOrEmpty(authenticationType) && 
authenticationType.Equals(BigQueryConstants.ServiceAccountAuthenticationType, 
StringComparison.OrdinalIgnoreCase))
+                {
+                    string? json = string.Empty;
 
-                if 
(!this.properties.TryGetValue(BigQueryParameters.JsonCredential, out json))
-                    throw new ArgumentException($"The 
{BigQueryParameters.JsonCredential} parameter is not present");
+                    if 
(!this.properties.TryGetValue(BigQueryParameters.JsonCredential, out json))
+                        throw new ArgumentException($"The 
{BigQueryParameters.JsonCredential} parameter is not present");
 
-                Credential = ApplyScopes(GoogleCredential.FromJson(json));
-            }
-            else
-            {
-                throw new ArgumentException($"{authenticationType} is not a 
valid authenticationType");
-            }
+                    Credential = ApplyScopes(GoogleCredential.FromJson(json));
+                }
+                else
+                {
+                    throw new ArgumentException($"{authenticationType} is not 
a valid authenticationType");
+                }
+            });
         }
 
         public override void SetOption(string key, string value)
         {
-            this.properties[key] = value;
-
-            if (key.Equals(BigQueryParameters.AccessToken))
+            this.TraceActivity(activity =>
             {
-                UpdateClientToken();
-            }
+                activity?.AddTag(key + ".set", value);

Review Comment:
   It seems like a bad idea to log an access token under any circumstances. Are 
there other sensitive option values we should also avoid logging (or tie to 
`BigQueryUtils.TracingToFile`, which looks like a proxy for "is safe to log 
sensitive information")?



-- 
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