in src/Services/Azure/Subscription/SubscriptionService.cs [11:111]
public class SubscriptionService(ICacheService cacheService, ITenantService tenantService)
: BaseAzureService(tenantService), ISubscriptionService
{
private readonly ICacheService _cacheService = cacheService ?? throw new ArgumentNullException(nameof(cacheService));
private const string CACHE_KEY = "subscriptions";
private const string SUBSCRIPTION_CACHE_KEY = "subscription";
private static readonly TimeSpan CACHE_DURATION = TimeSpan.FromHours(12);
public async Task<List<ArgumentOption>> GetSubscriptions(string? tenant = null, RetryPolicyArguments? retryPolicy = null)
{
// Try to get from cache first
var cacheKey = string.IsNullOrEmpty(tenant) ? CACHE_KEY : $"{CACHE_KEY}_{tenant}";
var cachedResults = await _cacheService.GetAsync<List<ArgumentOption>>(cacheKey, CACHE_DURATION);
if (cachedResults != null)
{
return cachedResults;
}
// If not in cache, fetch from Azure
var armClient = await CreateArmClientAsync(tenant, retryPolicy);
var subscriptions = armClient.GetSubscriptions();
var results = new List<ArgumentOption>();
foreach (var subscription in subscriptions)
{
results.Add(new ArgumentOption
{
Name = subscription.Data.DisplayName,
Id = subscription.Data.SubscriptionId
});
}
// Cache the results
await _cacheService.SetAsync(cacheKey, results, CACHE_DURATION);
return results;
}
public async Task<SubscriptionResource> GetSubscription(string subscription, string? tenant = null, RetryPolicyArguments? retryPolicy = null)
{
ValidateRequiredParameters(subscription);
// Get the subscription ID first, whether the input is a name or ID
var subscriptionId = await GetSubscriptionId(subscription, tenant, retryPolicy);
// Use subscription ID for cache key
var cacheKey = string.IsNullOrEmpty(tenant)
? $"{SUBSCRIPTION_CACHE_KEY}_{subscriptionId}"
: $"{SUBSCRIPTION_CACHE_KEY}_{subscriptionId}_{tenant}";
var cachedSubscription = await _cacheService.GetAsync<SubscriptionResource>(cacheKey, CACHE_DURATION);
if (cachedSubscription != null)
{
return cachedSubscription;
}
var armClient = await CreateArmClientAsync(tenant, retryPolicy);
var response = await armClient.GetSubscriptionResource(SubscriptionResource.CreateResourceIdentifier(subscriptionId)).GetAsync();
if (response?.Value == null)
{
throw new Exception($"Could not retrieve subscription {subscription}");
}
// Cache the result using subscription ID
await _cacheService.SetAsync(cacheKey, response.Value, CACHE_DURATION);
return response.Value;
}
public bool IsSubscriptionId(string subscription, string? tenant = null)
{
return Guid.TryParse(subscription, out _);
}
public async Task<string> GetSubscriptionIdByName(string subscriptionName, string? tenant = null, RetryPolicyArguments? retryPolicy = null)
{
var subscriptions = await GetSubscriptions(tenant, retryPolicy);
var subscription = subscriptions.FirstOrDefault(s => s.Name.Equals(subscriptionName, StringComparison.OrdinalIgnoreCase)) ??
throw new Exception($"Could not find subscription with name {subscriptionName}");
return subscription.Id;
}
public async Task<string> GetSubscriptionNameById(string subscriptionId, string? tenant = null, RetryPolicyArguments? retryPolicy = null)
{
var subscriptions = await GetSubscriptions(tenant, retryPolicy);
var subscription = subscriptions.FirstOrDefault(s => s.Id.Equals(subscriptionId, StringComparison.OrdinalIgnoreCase)) ??
throw new Exception($"Could not find subscription with ID {subscriptionId}");
return subscription.Name;
}
private async Task<string> GetSubscriptionId(string subscription, string? tenant, RetryPolicyArguments? retryPolicy)
{
if (IsSubscriptionId(subscription))
{
return subscription;
}
return await GetSubscriptionIdByName(subscription, tenant, retryPolicy);
}
}