using Microsoft.Extensions.Options; using System; using System.Collections.Concurrent; using System.Threading.Tasks; namespace StellaOps.Cryptography.Kms; /// /// Google Cloud KMS implementation of . /// public sealed partial class GcpKmsClient : IKmsClient, IDisposable { private readonly IGcpKmsFacade _facade; private readonly TimeProvider _timeProvider; private readonly TimeSpan _metadataCacheDuration; private readonly TimeSpan _publicKeyCacheDuration; private readonly ConcurrentDictionary _metadataCache = new(StringComparer.Ordinal); private readonly ConcurrentDictionary _publicKeyCache = new(StringComparer.Ordinal); private bool _disposed; public GcpKmsClient(IGcpKmsFacade facade, GcpKmsOptions options, TimeProvider? timeProvider = null) { _facade = facade ?? throw new ArgumentNullException(nameof(facade)); ArgumentNullException.ThrowIfNull(options); _timeProvider = timeProvider ?? TimeProvider.System; _metadataCacheDuration = options.MetadataCacheDuration; _publicKeyCacheDuration = options.PublicKeyCacheDuration; } public GcpKmsClient(IGcpKmsFacade facade, IOptions options, TimeProvider timeProvider) : this(facade, options?.Value ?? new GcpKmsOptions(), timeProvider) { } public Task RotateAsync(string keyId, CancellationToken cancellationToken = default) => throw new NotSupportedException("Google Cloud KMS rotation must be managed via Cloud KMS rotation schedules."); public Task RevokeAsync(string keyId, CancellationToken cancellationToken = default) => throw new NotSupportedException("Google Cloud KMS key revocation must be managed via Cloud KMS destroy/disable operations."); public void Dispose() { if (_disposed) { return; } _disposed = true; _facade.Dispose(); } }