Compare commits
	
		
			10 Commits
		
	
	
		
			73b909f780
			...
			developmen
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2ede7baae6 | |||
| c42fb5eb00 | |||
| dbc21959eb | |||
| a97e4e2219 | |||
| 35965591f5 | |||
| 38b63455d4 | |||
| fbfa21f89a | |||
| e3cdf1fb32 | |||
| 351cc28181 | |||
| 4e6bf79656 | 
| @@ -22,7 +22,7 @@ namespace Core.Blueprint.KeyVault | ||||
|         /// <returns> | ||||
|         /// A <see cref="Tuple"/> containing a status message and a boolean indicating whether the secret was successfully deleted. | ||||
|         /// </returns> | ||||
|         ValueTask<Tuple<string, bool>> DeleteSecretAsync(string secretName, CancellationToken cancellationToken); | ||||
|         ValueTask<(string Message, bool Deleted)> DeleteSecretAsync(string secretName, CancellationToken cancellationToken); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Retrieves a secret from Azure Key Vault. | ||||
| @@ -33,7 +33,7 @@ namespace Core.Blueprint.KeyVault | ||||
|         /// A <see cref="Tuple"/> containing the <see cref="KeyVaultResponse"/> with secret details  | ||||
|         /// and an optional error message if the secret was not found. | ||||
|         /// </returns> | ||||
|         ValueTask<Tuple<KeyVaultResponse, string?>> GetSecretAsync(string secretName, CancellationToken cancellationToken); | ||||
|         ValueTask<(KeyVaultResponse Secret, string? Message)> GetSecretAsync(string secretName, CancellationToken cancellationToken); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Updates an existing secret in Azure Key Vault. If the secret does not exist, an error is returned. | ||||
| @@ -43,6 +43,6 @@ namespace Core.Blueprint.KeyVault | ||||
|         /// <returns> | ||||
|         /// A <see cref="Tuple"/> containing the updated <see cref="KeyVaultResponse"/> and an optional error message if the secret was not found. | ||||
|         /// </returns> | ||||
|         ValueTask<Tuple<KeyVaultResponse, string>> UpdateSecretAsync(KeyVaultRequest newSecret, CancellationToken cancellationToken); | ||||
|         ValueTask<(KeyVaultResponse Secret, string? Message)> UpdateSecretAsync(KeyVaultRequest newSecret, CancellationToken cancellationToken); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| using Azure.Security.KeyVault.Secrets; | ||||
| using VaultSharp; | ||||
| using VaultSharp.V1.AuthMethods.Token; | ||||
| using Core.Blueprint.KeyVault.Configuration; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using System.Net.Http.Json; | ||||
| using VaultSharp; | ||||
| using VaultSharp.Core; | ||||
| using VaultSharp.V1.AuthMethods.Token; | ||||
|  | ||||
| namespace Core.Blueprint.KeyVault; | ||||
|  | ||||
| @@ -67,7 +67,7 @@ public sealed class KeyVaultProvider : IKeyVaultProvider | ||||
|     /// <returns> | ||||
|     /// A <see cref="Tuple"/> containing a status message and a boolean indicating whether the secret was successfully deleted. | ||||
|     /// </returns> | ||||
|     public async ValueTask<Tuple<string, bool>> DeleteSecretAsync(string secretName, CancellationToken cancellationToken) | ||||
|     public async ValueTask<(string Message, bool Deleted)> DeleteSecretAsync(string secretName, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (environment == "Local") | ||||
|         { | ||||
| @@ -88,7 +88,7 @@ public sealed class KeyVaultProvider : IKeyVaultProvider | ||||
|     /// <summary> | ||||
|     /// Retrieves a secret from Azure Key Vault or HashiCorp Vault. | ||||
|     /// </summary> | ||||
|     public async ValueTask<Tuple<KeyVaultResponse, string?>> GetSecretAsync(string secretName, CancellationToken cancellationToken) | ||||
|     public async ValueTask<(KeyVaultResponse Secret, string? Message)> GetSecretAsync(string secretName, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (environment == "Local") | ||||
|         { | ||||
| @@ -108,7 +108,7 @@ public sealed class KeyVaultProvider : IKeyVaultProvider | ||||
|             } | ||||
|             catch (VaultSharp.Core.VaultApiException ex) when (ex.HttpStatusCode == System.Net.HttpStatusCode.NotFound) | ||||
|             { | ||||
|                 return new(new KeyVaultResponse(), "Key Not Found"); | ||||
|                 return new(new KeyVaultResponse { }, "Key Not Found"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -126,7 +126,7 @@ public sealed class KeyVaultProvider : IKeyVaultProvider | ||||
|     /// <summary> | ||||
|     /// Updates an existing secret in Azure Key Vault or HashiCorp Vault. If the secret does not exist, an error is returned. | ||||
|     /// </summary> | ||||
|     public async ValueTask<Tuple<KeyVaultResponse, string>> UpdateSecretAsync(KeyVaultRequest newSecret, CancellationToken cancellationToken) | ||||
|     public async ValueTask<(KeyVaultResponse Secret, string? Message)> UpdateSecretAsync(KeyVaultRequest newSecret, CancellationToken cancellationToken) | ||||
|     { | ||||
|         var existingSecret = await this.GetSecretAsync(newSecret.Name, cancellationToken); | ||||
|         if (!string.IsNullOrEmpty(existingSecret.Item2)) | ||||
|   | ||||
| @@ -13,6 +13,8 @@ namespace Core.Blueprint.Logging | ||||
|     /// </summary> | ||||
|     public static class MimeTypes | ||||
|     { | ||||
|         public const string ApplicationVersion = "1.0"; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// The service application/json mime type. | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -104,11 +104,13 @@ namespace Core.Blueprint.Mongo | ||||
|         void ReplaceOne(TDocument document); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Asynchronously replaces an existing document with a new one. | ||||
|         /// Asynchronously replaces an existing document in the collection and returns the updated version. | ||||
|         /// </summary> | ||||
|         /// <param name="document">The document to replace the existing one.</param> | ||||
|         /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> | ||||
|         Task ReplaceOneAsync(TDocument document); | ||||
|         /// <param name="document">The document with the updated data. Its _Id is used to locate the existing document.</param> | ||||
|         /// <returns> | ||||
|         /// The updated document if the replacement was successful; otherwise, <c>null</c> if no matching document was found. | ||||
|         /// </returns> | ||||
|         Task<TDocument?> ReplaceOneAsync(TDocument document); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Deletes a single document by the provided filter expression. | ||||
|   | ||||
| @@ -175,16 +175,27 @@ namespace Core.Blueprint.Mongo | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Asynchronously replaces an existing document in the collection. | ||||
|         /// Asynchronously replaces an existing document in the collection and returns the updated version. | ||||
|         /// </summary> | ||||
|         /// <param name="document">The document with the updated data.</param> | ||||
|         /// <returns>A task that represents the asynchronous operation.</returns> | ||||
|         public virtual async Task ReplaceOneAsync(TDocument document) | ||||
|         /// <param name="document">The document with the updated data. Its _Id is used to locate the existing document.</param> | ||||
|         /// <returns> | ||||
|         /// The updated document if the replacement was successful; otherwise, <c>null</c> if no matching document was found. | ||||
|         /// </returns> | ||||
|         public virtual async Task<TDocument?> ReplaceOneAsync(TDocument document) | ||||
|         { | ||||
|             var filter = Builders<TDocument>.Filter.Eq(doc => doc._Id, document._Id); | ||||
|             await _collection.FindOneAndReplaceAsync(filter, document); | ||||
|  | ||||
|             var options = new FindOneAndReplaceOptions<TDocument> | ||||
|             { | ||||
|                 ReturnDocument = ReturnDocument.After // return the updated document | ||||
|             }; | ||||
|  | ||||
|             var result = await _collection.FindOneAndReplaceAsync(filter, document, options); | ||||
|  | ||||
|             return result; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Deletes a single document from the collection based on the provided filter expression. | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -27,7 +27,7 @@ namespace Core.Blueprint.Redis.Configuration | ||||
|  | ||||
|             // Register RedisCacheProvider | ||||
|             services.AddSingleton<IRedisCacheProvider>(provider => | ||||
|                 new RedisCacheProvider(redisConnectionString, provider.GetRequiredService<ILogger<RedisCacheProvider>>())); | ||||
|                 new RedisCacheProvider(redisConnectionString, provider.GetRequiredService<ILogger<RedisCacheProvider>>(), configuration)); | ||||
|  | ||||
|             // Get CacheSettings and register with the ICacheSettings interface | ||||
|             var cacheSettings = configuration.GetSection("CacheSettings").Get<CacheSettings>(); | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using Azure.Identity; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using StackExchange.Redis; | ||||
| using System.Text.Json; | ||||
| @@ -12,6 +13,7 @@ namespace Core.Blueprint.Redis | ||||
|     { | ||||
|         private IDatabase _cacheDatabase = null!; | ||||
|         private readonly ILogger<RedisCacheProvider> _logger; | ||||
|         private readonly bool _useRedis; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes a new instance of the <see cref="RedisCacheProvider"/> class. | ||||
| @@ -19,34 +21,52 @@ namespace Core.Blueprint.Redis | ||||
|         /// <param name="connectionString">The Redis connection string.</param> | ||||
|         /// <param name="logger">The logger instance for logging operations.</param> | ||||
|         /// <exception cref="ArgumentNullException">Thrown when connection string is null or empty.</exception> | ||||
|         public RedisCacheProvider(string connectionString, ILogger<RedisCacheProvider> logger) | ||||
|         public RedisCacheProvider(string connectionString, ILogger<RedisCacheProvider> logger, IConfiguration configuration) | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(connectionString)) | ||||
|                 throw new ArgumentNullException(nameof(connectionString), "Redis connection string cannot be null or empty."); | ||||
|  | ||||
|             _logger = logger; | ||||
|             _useRedis = configuration.GetValue<bool>("UseRedisCache", false); | ||||
|             _cacheDatabase = InitializeRedisAsync(connectionString).GetAwaiter().GetResult(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes and establishes a connection to Redis using the provided connection string. | ||||
|         /// Initializes and establishes a connection to Redis based on the environment. | ||||
|         /// Uses a local connection in development, and Azure with token credentials in other environments. | ||||
|         /// </summary> | ||||
|         /// <param name="connectionString">The Redis connection string.</param> | ||||
|         /// <returns>An <see cref="IDatabase"/> instance representing the Redis cache database.</returns> | ||||
|         /// <exception cref="Exception">Thrown when the connection to Redis fails.</exce | ||||
|         async Task<IDatabase> InitializeRedisAsync(string connectionString) | ||||
|         /// <exception cref="Exception">Thrown when the connection to Redis fails.</exception> | ||||
|         async Task<IDatabase?> InitializeRedisAsync(string connectionString) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var configurationOptions = await ConfigurationOptions.Parse($"{connectionString}") | ||||
|                     .ConfigureForAzureWithTokenCredentialAsync(new DefaultAzureCredential()); | ||||
|                 if (_useRedis) | ||||
|                 { | ||||
|                     var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty; | ||||
|                     ConnectionMultiplexer connectionMultiplexer; | ||||
|  | ||||
|                 configurationOptions.AbortOnConnectFail = false; | ||||
|                 var connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(configurationOptions); | ||||
|                     if (environment.Equals("Local", StringComparison.OrdinalIgnoreCase)) | ||||
|                     { | ||||
|                         connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(connectionString); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         var configurationOptions = await ConfigurationOptions.Parse(connectionString) | ||||
|                             .ConfigureForAzureWithTokenCredentialAsync(new DefaultAzureCredential()); | ||||
|  | ||||
|                 _logger.LogInformation("Successfully connected to Redis."); | ||||
|                         configurationOptions.AbortOnConnectFail = false; | ||||
|  | ||||
|                 return connectionMultiplexer.GetDatabase(); | ||||
|                         connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(configurationOptions); | ||||
|                     } | ||||
|  | ||||
|                     _logger.LogInformation("Successfully connected to Redis."); | ||||
|  | ||||
|                     return connectionMultiplexer.GetDatabase(); | ||||
|                 } | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
| @@ -65,15 +85,21 @@ namespace Core.Blueprint.Redis | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var value = await _cacheDatabase.StringGetAsync(key); | ||||
|                 if (value.IsNullOrEmpty) | ||||
|                 if (_useRedis is not false) | ||||
|                 { | ||||
|                     _logger.LogInformation($"Cache miss for key: {key}"); | ||||
|                     return default; | ||||
|                     var value = await _cacheDatabase.StringGetAsync(key); | ||||
|  | ||||
|                     if (value.IsNullOrEmpty) | ||||
|                     { | ||||
|                         _logger.LogInformation($"Cache miss for key: {key}"); | ||||
|                         return default; | ||||
|                     } | ||||
|  | ||||
|                     _logger.LogInformation($"Cache hit for key: {key}"); | ||||
|                     return JsonSerializer.Deserialize<TEntity>(value); | ||||
|                 } | ||||
|  | ||||
|                 _logger.LogInformation($"Cache hit for key: {key}"); | ||||
|                 return JsonSerializer.Deserialize<TEntity>(value); | ||||
|                 return default; | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
| @@ -92,9 +118,12 @@ namespace Core.Blueprint.Redis | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var json = JsonSerializer.Serialize(value); | ||||
|                 await _cacheDatabase.StringSetAsync(key, json, expiry); | ||||
|                 _logger.LogInformation($"Cache item set with key: {key}"); | ||||
|                 if (_useRedis is not false) | ||||
|                 { | ||||
|                     var json = JsonSerializer.Serialize(value); | ||||
|                     await _cacheDatabase.StringSetAsync(key, json, expiry); | ||||
|                     _logger.LogInformation($"Cache item set with key: {key}"); | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
| @@ -111,8 +140,11 @@ namespace Core.Blueprint.Redis | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await _cacheDatabase.KeyDeleteAsync(key); | ||||
|                 _logger.LogInformation($"Cache item removed with key: {key}"); | ||||
|                 if (_useRedis is not false) | ||||
|                 { | ||||
|                     await _cacheDatabase.KeyDeleteAsync(key); | ||||
|                     _logger.LogInformation($"Cache item removed with key: {key}"); | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
| @@ -130,9 +162,13 @@ namespace Core.Blueprint.Redis | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var exists = await _cacheDatabase.KeyExistsAsync(key); | ||||
|                 _logger.LogInformation($"Cache item exists check for key: {key} - {exists}"); | ||||
|                 return exists; | ||||
|                 if (_useRedis is not false) | ||||
|                 { | ||||
|                     var exists = await _cacheDatabase.KeyExistsAsync(key); | ||||
|                     _logger.LogInformation($"Cache item exists check for key: {key} - {exists}"); | ||||
|                 } | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
| @@ -150,15 +186,18 @@ namespace Core.Blueprint.Redis | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var value = await _cacheDatabase.StringGetAsync(key); | ||||
|                 if (!value.IsNullOrEmpty) | ||||
|                 if (_useRedis is not false) | ||||
|                 { | ||||
|                     await _cacheDatabase.StringSetAsync(key, value, expiry); | ||||
|                     _logger.LogInformation($"Cache item refreshed with key: {key}"); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     _logger.LogWarning($"Cache item with key: {key} does not exist, cannot refresh"); | ||||
|                     var value = await _cacheDatabase.StringGetAsync(key); | ||||
|                     if (!value.IsNullOrEmpty) | ||||
|                     { | ||||
|                         await _cacheDatabase.StringSetAsync(key, value, expiry); | ||||
|                         _logger.LogInformation($"Cache item refreshed with key: {key}"); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         _logger.LogWarning($"Cache item with key: {key} does not exist, cannot refresh"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|   | ||||
| @@ -20,15 +20,12 @@ namespace Core.Blueprint.SQLServer.Configuration | ||||
|         { | ||||
|             var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty; | ||||
|  | ||||
|             if (environment != "Local") | ||||
|             { | ||||
|                 var chainedCredentials = new ChainedTokenCredential( | ||||
|                     new ManagedIdentityCredential(), | ||||
|                     new SharedTokenCacheCredential(), | ||||
|                     new VisualStudioCredential(), | ||||
|                     new VisualStudioCodeCredential() | ||||
|                 ); | ||||
|             } | ||||
|  | ||||
|             services.AddScoped(typeof(IEntityRepository<,>), typeof(EntityRepository<,>)); | ||||
|  | ||||
|   | ||||
							
								
								
									
										9
									
								
								nuget.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								nuget.config
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <configuration> | ||||
|   <packageSources> | ||||
|     <!-- Tu BaGet primero --> | ||||
|     <add key="BaGet" value="https://nuget.dream-views.com/v3/index.json" protocolVersion="3" /> | ||||
|     <!-- NuGet oficial como fallback (si quieres) --> | ||||
|     <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /> | ||||
|   </packageSources> | ||||
| </configuration> | ||||
		Reference in New Issue
	
	Block a user