toddmeng-db commented on code in PR #2743: URL: https://github.com/apache/arrow-adbc/pull/2743#discussion_r2067009789
########## csharp/src/Drivers/Databricks/Auth/OAuthClientCredentialsProvider.cs: ########## @@ -0,0 +1,232 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +namespace Apache.Arrow.Adbc.Drivers.Databricks.Auth +{ + /// <summary> + /// Service for obtaining OAuth access tokens using the client credentials grant type. + /// </summary> + internal class OAuthClientCredentialsProvider : IDisposable + { + private readonly HttpClient _httpClient; + private readonly string _clientId; + private readonly string _clientSecret; + private readonly string _host; + private readonly string _tokenEndpoint; + private readonly int _timeoutMinutes; + private readonly string? _tenantId; + private readonly string? _accountId; + private readonly SemaphoreSlim _tokenLock = new SemaphoreSlim(1, 1); + private TokenInfo? _cachedToken; + + private class TokenInfo + { + public string? AccessToken { get; set; } + public DateTime ExpiresAt { get; set; } + + public bool IsExpired => DateTime.UtcNow >= ExpiresAt; + + // Add buffer time to refresh token before actual expiration + public bool NeedsRefresh => DateTime.UtcNow >= ExpiresAt.AddMinutes(-5); + } + + /// <summary> + /// Initializes a new instance of the <see cref="OAuthClientCredentialsService"/> class. + /// </summary> + /// <param name="clientId">The OAuth client ID.</param> + /// <param name="clientSecret">The OAuth client secret.</param> + /// <param name="host">The host of the Databricks workspace.</param> + /// <param name="tenantId">The Azure AD tenant ID (optional).</param> + /// <param name="accountId">The Databricks account ID (optional).</param> + /// <param name="timeoutMinutes">The timeout in minutes for HTTP requests.</param> + public OAuthClientCredentialsProvider( + string clientId, + string clientSecret, + string host, + string? tenantId = null, + string? accountId = null, + int timeoutMinutes = 1) + { + _clientId = clientId ?? throw new ArgumentNullException(nameof(clientId)); + _clientSecret = clientSecret ?? throw new ArgumentNullException(nameof(clientSecret)); + _host = host ?? throw new ArgumentNullException(nameof(host)); + _tenantId = tenantId; + _accountId = accountId; + _timeoutMinutes = timeoutMinutes; + _tokenEndpoint = DetermineTokenEndpoint(); + + _httpClient = new HttpClient(); + _httpClient.Timeout = TimeSpan.FromMinutes(_timeoutMinutes); + } + + private string DetermineTokenEndpoint() + { + if (!string.IsNullOrEmpty(_tenantId)) + { + // Use the tenant-specific Azure OIDC token endpoint + return $"https://login.microsoftonline.com/{_tenantId}/oauth2/v2.0/token"; Review Comment: Reverted -- 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: github-unsubscr...@arrow.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org