From 05d269786822cb85381263da272a2bc69eb085bf Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 12:29:31 +0400 Subject: [PATCH 01/22] Redis cixardanin --- .../AzureRedisCachingSystem.csproj | 1 + .../Configurations/CosmosConfig.cs | 9 ----- .../Configurations/MongoDbConfiguration.cs | 7 ++++ AzureRedisCachingSystem/Data/AppDbContext.cs | 34 ------------------- .../Data/MongoDbContext.cs | 19 +++++++++++ AzureRedisCachingSystem/Models/Faculty.cs | 8 ----- .../Models/ModelFilters/BaseEntity.cs | 6 ---- AzureRedisCachingSystem/Models/User.cs | 15 -------- AzureRedisCachingSystem/Program.cs | 15 +------- AzureRedisCachingSystem/appsettings.json | 15 ++++---- 10 files changed, 35 insertions(+), 94 deletions(-) delete mode 100644 AzureRedisCachingSystem/Configurations/CosmosConfig.cs create mode 100644 AzureRedisCachingSystem/Configurations/MongoDbConfiguration.cs delete mode 100644 AzureRedisCachingSystem/Data/AppDbContext.cs create mode 100644 AzureRedisCachingSystem/Data/MongoDbContext.cs delete mode 100644 AzureRedisCachingSystem/Models/Faculty.cs delete mode 100644 AzureRedisCachingSystem/Models/ModelFilters/BaseEntity.cs delete mode 100644 AzureRedisCachingSystem/Models/User.cs diff --git a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj index e9f06c5..6e89ede 100644 --- a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj +++ b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj @@ -13,6 +13,7 @@ + diff --git a/AzureRedisCachingSystem/Configurations/CosmosConfig.cs b/AzureRedisCachingSystem/Configurations/CosmosConfig.cs deleted file mode 100644 index e0c4f99..0000000 --- a/AzureRedisCachingSystem/Configurations/CosmosConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AzureRedisCachingSystem.Configurations; - -public class CosmosConfig -{ - public string ConnectionString { get; set; } - public string Uri { get; set; } - public string Key { get; set; } - public string DataBaseName { get; set; } -} diff --git a/AzureRedisCachingSystem/Configurations/MongoDbConfiguration.cs b/AzureRedisCachingSystem/Configurations/MongoDbConfiguration.cs new file mode 100644 index 0000000..e22d717 --- /dev/null +++ b/AzureRedisCachingSystem/Configurations/MongoDbConfiguration.cs @@ -0,0 +1,7 @@ +namespace AzureRedisCachingSystem.Configurations; + +public class MongoDbConfiguration +{ + public string ConnectionString { get; set; } + public string DatabaseName { get; set; } +} diff --git a/AzureRedisCachingSystem/Data/AppDbContext.cs b/AzureRedisCachingSystem/Data/AppDbContext.cs deleted file mode 100644 index 06a4758..0000000 --- a/AzureRedisCachingSystem/Data/AppDbContext.cs +++ /dev/null @@ -1,34 +0,0 @@ -using AzureRedisCachingSystem.Configurations; -using AzureRedisCachingSystem.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; - -namespace AzureRedisCachingSystem.Data; - -public class AppDbContext : DbContext -{ - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseCosmos( - "https://eminaccount.documents.azure.com:443/", - "BriCfVzHHeNZYeH8JfsEV7ANZeu59EZIBFoBcbWqo4SGO9v4UyEhK7dhhEzJXVm17Va7GCPEVq44ACDbmL8Pxg==", - "databasefyp" - ); - - base.OnConfiguring(optionsBuilder); - } - - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().ToContainer("Users"); - modelBuilder.Entity().ToContainer("Books"); - modelBuilder.Entity().ToContainer("Faculties"); - - base.OnModelCreating(modelBuilder); - } - - public DbSet Users { get; set; } - public DbSet Books { get; set; } - public DbSet Faculties { get; set; } -} diff --git a/AzureRedisCachingSystem/Data/MongoDbContext.cs b/AzureRedisCachingSystem/Data/MongoDbContext.cs new file mode 100644 index 0000000..9508d86 --- /dev/null +++ b/AzureRedisCachingSystem/Data/MongoDbContext.cs @@ -0,0 +1,19 @@ +using AzureRedisCachingSystem.Configurations; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using MongoDB.Driver; +using Serilog; + +namespace AzureRedisCachingSystem.Data; + +public class MongoDbContext +{ + private readonly IMongoDatabase _database; + + public MongoDbContext(IOptions options) + { + MongoClient client = new MongoClient(options.Value.ConnectionString); + + _database = client.GetDatabase(options.Value.DatabaseName); + } +} diff --git a/AzureRedisCachingSystem/Models/Faculty.cs b/AzureRedisCachingSystem/Models/Faculty.cs deleted file mode 100644 index 82d5ae2..0000000 --- a/AzureRedisCachingSystem/Models/Faculty.cs +++ /dev/null @@ -1,8 +0,0 @@ -using AzureRedisCachingSystem.Models.Common; - -namespace AzureRedisCachingSystem.Models; - -public class Faculty : BaseEntity -{ - public string Name { get; set; } -} diff --git a/AzureRedisCachingSystem/Models/ModelFilters/BaseEntity.cs b/AzureRedisCachingSystem/Models/ModelFilters/BaseEntity.cs deleted file mode 100644 index 6976ded..0000000 --- a/AzureRedisCachingSystem/Models/ModelFilters/BaseEntity.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AzureRedisCachingSystem.Models.Common; - -public class BaseEntity -{ - public string Id { get; set; } -} diff --git a/AzureRedisCachingSystem/Models/User.cs b/AzureRedisCachingSystem/Models/User.cs deleted file mode 100644 index c93ee88..0000000 --- a/AzureRedisCachingSystem/Models/User.cs +++ /dev/null @@ -1,15 +0,0 @@ -using AzureRedisCachingSystem.Models.Common; - -namespace AzureRedisCachingSystem.Models; - -public class User : BaseEntity -{ - - public string Name { get; set; } - public string Surname { get; set; } - public string Email { get; set; } - public int Age { get; set; } - public string PhoneNumber { get; set; } - public string FacultyId { get; set; } -} - diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 217af7a..4618f90 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,21 +1,8 @@ -using AzureRedisCachingSystem.Data; -using AzureRedisCachingSystem.Models.Misc; -using AzureRedisCachingSystem.Repositories.Abstract; -using AzureRedisCachingSystem.Repositories; -using AzureRedisCachingSystem.Services; -using Serilog; -using AzureRedisCachingSystem.Models.Cache; -using AzureRedisCachingSystem.Models; -using AzureRedisCachingSystem.Models.ModelFilters; -using Microsoft.Extensions.Caching.Memory; -using AzureRedisCachingSystem.Services.Abstract; - -class Program +class Program { static async Task Main(string[] args) { Console.WriteLine("Hello, World!"); } - } \ No newline at end of file diff --git a/AzureRedisCachingSystem/appsettings.json b/AzureRedisCachingSystem/appsettings.json index 95fb767..1b31a4e 100644 --- a/AzureRedisCachingSystem/appsettings.json +++ b/AzureRedisCachingSystem/appsettings.json @@ -1,11 +1,10 @@ { - "ConnectionStrings": { - "Redis": "sinam.redis.cache.windows.net:6380,password=r2P0T6tS2butiQfMxac4BWXkhiI61XQqwAzCaB3Zrgk=,ssl=True,abortConnect=False" + "Redis": { + "ConnectionString": "localhost:6379" }, - "Cosmos": { - "ConnectionString": "AccountEndpoint=https://eminaccount.documents.azure.com:443/;AccountKey=BriCfVzHHeNZYeH8JfsEV7ANZeu59EZIBFoBcbWqo4SGO9v4UyEhK7dhhEzJXVm17Va7GCPEVq44ACDbmL8Pxg==;", - "Uri": "https://eminaccount.documents.azure.com:443/", - "Key": "BriCfVzHHeNZYeH8JfsEV7ANZeu59EZIBFoBcbWqo4SGO9v4UyEhK7dhhEzJXVm17Va7GCPEVq44ACDbmL8Pxg==", - "DataBaseName": "databasefyp" + + "MongoDB": { + "ConnectionString": "mongodb://localhost:27017", + "DatabaseName": "cachesystemdatabase" } -} +} \ No newline at end of file From 36015983e63d3f37e927997715e0308c2ab0a863 Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 14:17:11 +0400 Subject: [PATCH 02/22] Stage Commit [] --- .../Data/MongoDbContext.cs | 9 +- AzureRedisCachingSystem/Models/Book.cs | 13 +- .../Models/Cache/Abstract/BaseCacheObject.cs | 129 +----------------- .../Models/Cache/CacheObject.cs | 22 +-- AzureRedisCachingSystem/Program.cs | 14 +- .../Abstract/ICacheObjectRepository.cs | 2 +- .../Repositories/CacheObjectRepository.cs | 2 +- .../Services/AppService.cs | 36 ----- .../Services/MongoCachingService.cs | 29 ---- .../Services/RedisCachingService.cs | 62 +++------ AzureRedisCachingSystem/appsettings.json | 2 +- 11 files changed, 47 insertions(+), 273 deletions(-) delete mode 100644 AzureRedisCachingSystem/Services/AppService.cs delete mode 100644 AzureRedisCachingSystem/Services/MongoCachingService.cs diff --git a/AzureRedisCachingSystem/Data/MongoDbContext.cs b/AzureRedisCachingSystem/Data/MongoDbContext.cs index 9508d86..82cbe2c 100644 --- a/AzureRedisCachingSystem/Data/MongoDbContext.cs +++ b/AzureRedisCachingSystem/Data/MongoDbContext.cs @@ -1,4 +1,5 @@ using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using MongoDB.Driver; @@ -10,10 +11,12 @@ public class MongoDbContext { private readonly IMongoDatabase _database; - public MongoDbContext(IOptions options) + public MongoDbContext(string conStr, string dbname) { - MongoClient client = new MongoClient(options.Value.ConnectionString); + MongoClient client = new MongoClient(conStr); - _database = client.GetDatabase(options.Value.DatabaseName); + _database = client.GetDatabase(dbname); } + + public IMongoCollection Books { get; set; } } diff --git a/AzureRedisCachingSystem/Models/Book.cs b/AzureRedisCachingSystem/Models/Book.cs index d86f930..dd30f47 100644 --- a/AzureRedisCachingSystem/Models/Book.cs +++ b/AzureRedisCachingSystem/Models/Book.cs @@ -1,17 +1,8 @@ -using AzureRedisCachingSystem.Models.Common; - + namespace AzureRedisCachingSystem.Models; -public class Book : BaseEntity +public class Book { - public Book(string title, string description, string authorFullName, int price) - { - Title = title; - Description = description; - AuthorFullName = authorFullName; - Price = price; - } - public string Title { get; set; } public string Description { get; set; } public string AuthorFullName { get; set; } diff --git a/AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs b/AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs index 081cf00..389924c 100644 --- a/AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs +++ b/AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs @@ -7,165 +7,48 @@ namespace AzureRedisCachingSystem.Models.Cache.Abstract { - /// - /// Abstract base class for cache objects, providing methods for cache management. - /// public abstract class BaseCacheObject { - /// - /// Gets or sets the cache value. - /// - public KValue Value { get; set; } - - /// - /// Gets or sets the cache expiration duration. - /// - public DateTimeOffset ExpireDuration { get; set; } - - /// - /// Gets or sets the unique cache key. - /// public StringBuilder UniqueKey { get; set; } + public KValue Value { get; set; } - /// - /// The cache service used for caching operations. - /// - public IMemoryCaching CacheService { get; } - - private bool _watch; - protected bool _hashFlag; protected readonly IMemoryCaching _cacheService; protected readonly IHashService _hashService; - /// - /// Initializes a new instance of the class. - /// - /// The cache service. - /// The hash service. - /// Thrown when is null. + protected BaseCacheObject(IMemoryCaching cacheService, IHashService hashService) { _cacheService = cacheService ?? throw new ArgumentNullException(nameof(cacheService)); _hashService = hashService; UniqueKey = new StringBuilder(); - _watch = false; - _hashFlag = true; // default } - /// - /// Builds the cache by setting the cache data and logs the result. - /// - /// The current instance of . - public async Task BuildCache() - { - long elapsedMilliseconds = 0; - - if (_watch) - { - var stopwatch = System.Diagnostics.Stopwatch.StartNew(); - bool result = await _cacheService.SetCacheData(UniqueKey.ToString(), Value, ExpireDuration); - stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; - - Log.Information($"Build Cache method result: {result} ({elapsedMilliseconds} ms)"); - } - else - { - bool result = await _cacheService.SetCacheData(UniqueKey.ToString(), Value, ExpireDuration); - Log.Information($"Build Cache method result: {result}"); - } + public async Task BuildCache(DateTimeOffset expire) + { + bool result = await _cacheService.SetCacheData(UniqueKey.ToString(), Value, expire); return this; } - /// - /// Sets the cache key. - /// - /// The key to set. - /// The current instance of . public BaseCacheObject SetKey(string key) { UniqueKey.Clear().Append(key); return this; } - /// - /// Sets the cache value. - /// - /// The value to set. - /// The current instance of . + public BaseCacheObject SetValue(object value) { Value = new KValue(value); return this; } - /// - /// Asynchronously retrieves the cached value for the given key. - /// - /// The type of the cached value. - /// The key to retrieve the value for. If null, uses the current . - /// A task representing the asynchronous operation, with a result. public async Task> GetValueAsync(string key = null) { key ??= UniqueKey.ToString(); KValue value = await _cacheService.GetCacheData>(key); return value; } - - /// - /// Sets the cache expiration duration in seconds. - /// - /// The expiration duration in seconds. - /// The current instance of . - public BaseCacheObject SetDurationWithSeconds(int seconds) - { - ExpireDuration = DateTimeOffset.UtcNow.AddSeconds(seconds); - return this; - } - - /// - /// Sets the cache expiration duration in minutes. - /// - /// The expiration duration in minutes. - /// The current instance of . - public BaseCacheObject SetDurationWithMinutes(int minutes) - { - ExpireDuration = DateTimeOffset.UtcNow.AddMinutes(minutes); - return this; - } - - /// - /// Sets the cache expiration duration in months. - /// - /// The expiration duration in months. - /// The current instance of . - public BaseCacheObject SetDurationWithMonths(int months) - { - ExpireDuration = DateTimeOffset.UtcNow.AddMonths(months); - return this; - } - - /// - /// Activates the timer for measuring cache build duration. - /// - /// The current instance of . - public BaseCacheObject ActivateTimer() - { - _watch = true; - return this; - } - - /// - /// Sets the flag for hashing before caching. - /// - /// True to enable hashing, false to disable. - /// The current instance of . - public BaseCacheObject HashBefore(bool flag = true) - { - _hashFlag = flag; - return this; - } } } diff --git a/AzureRedisCachingSystem/Models/Cache/CacheObject.cs b/AzureRedisCachingSystem/Models/Cache/CacheObject.cs index f47c79a..99d8cba 100644 --- a/AzureRedisCachingSystem/Models/Cache/CacheObject.cs +++ b/AzureRedisCachingSystem/Models/Cache/CacheObject.cs @@ -1,38 +1,23 @@ using AzureRedisCachingSystem.Models.Cache.Abstract; using AzureRedisCachingSystem.Services.Abstract; using Serilog; -using System; using System.Text; namespace AzureRedisCachingSystem.Models.Cache { - /// - /// Represents a cache object with a generic type parameter. - /// - /// The type of the parameter used to set cache object properties. public class CacheObject : BaseCacheObject { - /// - /// Initializes a new instance of the class. - /// - /// The cache service. - /// The hash service. public CacheObject(IMemoryCaching cacheService, IHashService hashService) : base(cacheService, hashService) { } - /// - /// Sets parameters for the cache object using the specified parameter. - /// - /// The parameter object used to set cache object properties. - /// The current instance of . - /// Thrown when is null. public CacheObject SetParams(T parameter) { if (parameter == null) throw new ArgumentNullException(nameof(parameter)); var properties = parameter.GetType().GetProperties(); + foreach (var prop in properties) { var value = prop.GetValue(parameter); @@ -45,10 +30,7 @@ public CacheObject SetParams(T parameter) UniqueKey.Append($"{prop.Name.ToLower()}:{value?.ToString().ToLower()}&*"); } - if (_hashFlag) - { - UniqueKey = new StringBuilder(_hashService.HashString(UniqueKey.ToString())); - } + UniqueKey = new StringBuilder(_hashService.HashString(UniqueKey.ToString())); Log.Information("Params set to cache object"); diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 4618f90..f780319 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,8 +1,18 @@ -class Program +using AzureRedisCachingSystem.Data; +using AzureRedisCachingSystem.Repositories; +using AzureRedisCachingSystem.Repositories.Abstract; + +class Program { static async Task Main(string[] args) { - Console.WriteLine("Hello, World!"); + ICacheObjectRepository repo = new CacheObjectRepository(); + + MongoDbContext context = new MongoDbContext("mongodb://localhost:27017", "myappdb"); + + var response = await repo.BookCacheObject.GetValueAsync(); + + Console.WriteLine(response); } } \ No newline at end of file diff --git a/AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs b/AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs index d3fc874..78fa516 100644 --- a/AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs +++ b/AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs @@ -5,5 +5,5 @@ namespace AzureRedisCachingSystem.Repositories.Abstract; public interface ICacheObjectRepository { - BaseCacheObject UserCacheObject { get; set; } + BaseCacheObject BookCacheObject { get; set; } } diff --git a/AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs b/AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs index ed7bea5..0282274 100644 --- a/AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs +++ b/AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs @@ -10,6 +10,6 @@ namespace AzureRedisCachingSystem.Repositories { public class CacheObjectRepository : ICacheObjectRepository { - public BaseCacheObject UserCacheObject { get; set; } + public BaseCacheObject BookCacheObject { get; set; } } } diff --git a/AzureRedisCachingSystem/Services/AppService.cs b/AzureRedisCachingSystem/Services/AppService.cs deleted file mode 100644 index 592b1d2..0000000 --- a/AzureRedisCachingSystem/Services/AppService.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Serilog; - -namespace AzureRedisCachingSystem.Services -{ - /// - /// Provides static methods for application configuration and logging setup. - /// - public static class AppService - { - /// - /// Retrieves the Redis connection string from the application's configuration file. - /// - /// The Redis connection string. - public static string GetConnectionString() - { - var configuration = new ConfigurationBuilder() - .SetBasePath(AppContext.BaseDirectory) - .AddJsonFile("appsettings.json", optional: true) - .Build(); - - return configuration.GetConnectionString("Redis"); - } - - /// - /// Configures the logging settings for the application using Serilog. - /// - public static void ConfigureLogging() - { - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Debug() - .WriteTo.Console() - .CreateLogger(); - } - } -} diff --git a/AzureRedisCachingSystem/Services/MongoCachingService.cs b/AzureRedisCachingSystem/Services/MongoCachingService.cs deleted file mode 100644 index 8e8e3bb..0000000 --- a/AzureRedisCachingSystem/Services/MongoCachingService.cs +++ /dev/null @@ -1,29 +0,0 @@ -using AzureRedisCachingSystem.Services.Abstract; - -namespace AzureRedisCachingSystem.Services; - -public class MongoCachingService : IMemoryCaching -{ - public MongoCachingService(string connectionString) - { } - - public Task CheckIfExist(string Key) - { - throw new NotImplementedException(); - } - - public Task GetCacheData(string key) - { - throw new NotImplementedException(); - } - - public Task RemoveData(string key) - { - throw new NotImplementedException(); - } - - public Task SetCacheData(string key, T value, DateTimeOffset expireTime) - { - throw new NotImplementedException(); - } -} diff --git a/AzureRedisCachingSystem/Services/RedisCachingService.cs b/AzureRedisCachingSystem/Services/RedisCachingService.cs index 9dccf57..610d872 100644 --- a/AzureRedisCachingSystem/Services/RedisCachingService.cs +++ b/AzureRedisCachingSystem/Services/RedisCachingService.cs @@ -1,4 +1,6 @@ -using AzureRedisCachingSystem.Services.Abstract; +using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.Services.Abstract; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using StackExchange.Redis; using System; @@ -6,75 +8,43 @@ namespace AzureRedisCachingSystem.Services { - /// - /// Implements using Redis as the caching mechanism. - /// + public class RedisCachingService : IMemoryCaching { - private readonly IDatabase _db; - private readonly IConnectionMultiplexer _connection; + private readonly IDatabase database; - /// - /// Initializes a new instance of the class with the specified Redis connection string. - /// - /// The Redis connection string. - public RedisCachingService(string connectionString) + public RedisCachingService(string connectionStr) { - _connection = ConnectionMultiplexer.Connect(connectionString); - _db = _connection.GetDatabase(); + ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(connectionStr); + database = redis.GetDatabase(); } - /// - /// Asynchronously retrieves the cache data for the specified key. - /// - /// The type of the cached value. - /// The key to retrieve the cache data for. - /// A task representing the asynchronous operation, with the cached value as the result. public async Task GetCacheData(string key) { - var value = await _db.StringGetAsync(key); + var value = await database.StringGetAsync(key); if (!string.IsNullOrEmpty(value)) return JsonConvert.DeserializeObject(value); return default; } - - /// - /// Asynchronously removes the cache data for the specified key. - /// - /// The key to remove the cache data for. - /// A task representing the asynchronous operation, with a boolean indicating success or failure. public async Task RemoveData(string key) { - var exists = await _db.KeyExistsAsync(key); + var exists = await database.KeyExistsAsync(key); if (exists) - return await _db.KeyDeleteAsync(key); + return await database.KeyDeleteAsync(key); return false; } - - /// - /// Asynchronously sets the cache data for the specified key with an expiration time. - /// - /// The type of the value to cache. - /// The key to set the cache data for. - /// The value to cache. - /// The expiration time for the cache data. - /// A task representing the asynchronous operation, with a boolean indicating whether the data was set successfully. + public async Task SetCacheData(string key, T value, DateTimeOffset expireTime) { TimeSpan timeToLive = expireTime.DateTime.Subtract(DateTime.UtcNow); - var isSet = await _db.StringSetAsync(key, JsonConvert.SerializeObject(value)); - await _db.KeyExpireAsync(key, timeToLive); + var isSet = await database.StringSetAsync(key, JsonConvert.SerializeObject(value)); + await database.KeyExpireAsync(key, timeToLive); return isSet; } - - /// - /// Asynchronously checks if the cache data for the specified key exists. - /// - /// The key to check for existence. - /// A task representing the asynchronous operation, with a boolean indicating whether the key exists. + public async Task CheckIfExist(string key) { - return await _db.KeyExistsAsync(key); + return await database.KeyExistsAsync(key); } } } diff --git a/AzureRedisCachingSystem/appsettings.json b/AzureRedisCachingSystem/appsettings.json index 1b31a4e..c47a649 100644 --- a/AzureRedisCachingSystem/appsettings.json +++ b/AzureRedisCachingSystem/appsettings.json @@ -5,6 +5,6 @@ "MongoDB": { "ConnectionString": "mongodb://localhost:27017", - "DatabaseName": "cachesystemdatabase" + "DatabaseName": "myappdb" } } \ No newline at end of file From b625d26b4dc831a6890a03f28fc191d6fb8de58e Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 15:02:30 +0400 Subject: [PATCH 03/22] Uje deli oluram yavas yavas --- .../Adapters/RedisWriter/RedisWriter.cs | 11 +++ .../AzureRedisCachingSystem.csproj | 4 ++ .../Cache/CustomValues/CacheValue.cs | 6 ++ .../Cache/Entries/CacheEntry.cs | 9 +++ .../Cache/Settings/CacheEntryConfigurer.cs | 12 ++++ .../HelperServices/Json/JsonService.cs | 17 +++++ AzureRedisCachingSystem/Models/Book.cs | 10 --- .../Models/Cache/Abstract/BaseCacheObject.cs | 54 --------------- .../Models/Cache/CacheObject.cs | 40 ----------- AzureRedisCachingSystem/Models/Misc/KValue.cs | 25 ------- .../Models/ModelFilters/UserModelFilter.cs | 14 ---- AzureRedisCachingSystem/Program.cs | 13 +--- .../Abstract/ICacheObjectRepository.cs | 9 --- .../Repositories/CacheObjectRepository.cs | 15 ---- .../Services/Abstract/IHashService.cs | 6 -- .../Services/Abstract/IMemoryCaching.cs | 10 --- .../Services/Abstract/IRedisService.cs | 8 +++ .../Services/HashService.cs | 68 ------------------- .../Services/RedisCachingService.cs | 50 -------------- .../Services/RedisService.cs | 31 +++++++++ 20 files changed, 100 insertions(+), 312 deletions(-) create mode 100644 AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs create mode 100644 AzureRedisCachingSystem/Cache/CustomValues/CacheValue.cs create mode 100644 AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs create mode 100644 AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs create mode 100644 AzureRedisCachingSystem/HelperServices/Json/JsonService.cs delete mode 100644 AzureRedisCachingSystem/Models/Book.cs delete mode 100644 AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs delete mode 100644 AzureRedisCachingSystem/Models/Cache/CacheObject.cs delete mode 100644 AzureRedisCachingSystem/Models/Misc/KValue.cs delete mode 100644 AzureRedisCachingSystem/Models/ModelFilters/UserModelFilter.cs delete mode 100644 AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs delete mode 100644 AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs delete mode 100644 AzureRedisCachingSystem/Services/Abstract/IHashService.cs delete mode 100644 AzureRedisCachingSystem/Services/Abstract/IMemoryCaching.cs create mode 100644 AzureRedisCachingSystem/Services/Abstract/IRedisService.cs delete mode 100644 AzureRedisCachingSystem/Services/HashService.cs delete mode 100644 AzureRedisCachingSystem/Services/RedisCachingService.cs create mode 100644 AzureRedisCachingSystem/Services/RedisService.cs diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs new file mode 100644 index 0000000..f330efd --- /dev/null +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -0,0 +1,11 @@ +using AzureRedisCachingSystem.Cache.Entries; + +namespace AzureRedisCachingSystem.Adapters.RedisWriter; + +public class RedisWriter +{ + public Task WriteToCache(CacheEntry entry) + { + + } +} diff --git a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj index 6e89ede..be7f693 100644 --- a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj +++ b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj @@ -27,4 +27,8 @@ + + + + diff --git a/AzureRedisCachingSystem/Cache/CustomValues/CacheValue.cs b/AzureRedisCachingSystem/Cache/CustomValues/CacheValue.cs new file mode 100644 index 0000000..87eb24d --- /dev/null +++ b/AzureRedisCachingSystem/Cache/CustomValues/CacheValue.cs @@ -0,0 +1,6 @@ +namespace AzureRedisCachingSystem.Cache.CustomValues; + +public class CacheValue +{ + public object Value { get; set; } +} diff --git a/AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs b/AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs new file mode 100644 index 0000000..5777e6d --- /dev/null +++ b/AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs @@ -0,0 +1,9 @@ +using AzureRedisCachingSystem.Cache.CustomValues; + +namespace AzureRedisCachingSystem.Cache.Entries; + +public class CacheEntry +{ + public string Key { get; set; } + public CacheValue Value { get; set; } +} diff --git a/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs b/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs new file mode 100644 index 0000000..952868b --- /dev/null +++ b/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs @@ -0,0 +1,12 @@ +using AzureRedisCachingSystem.Cache.CustomValues; +using AzureRedisCachingSystem.Cache.Entries; + +namespace AzureRedisCachingSystem.Cache.Settings; + +public class CacheEntryConfigurer +{ + private string key; + private CacheValue value; + + +} diff --git a/AzureRedisCachingSystem/HelperServices/Json/JsonService.cs b/AzureRedisCachingSystem/HelperServices/Json/JsonService.cs new file mode 100644 index 0000000..3ff61af --- /dev/null +++ b/AzureRedisCachingSystem/HelperServices/Json/JsonService.cs @@ -0,0 +1,17 @@ +using AzureRedisCachingSystem.Cache.Entries; +using Newtonsoft.Json; + +namespace AzureRedisCachingSystem.HelperServices.Json; + +public static class JsonService +{ + public static string SerializeEntry(CacheEntry entry) + { + string entryJsonString = JsonConvert.SerializeObject(entry); + + if (string.IsNullOrEmpty(entryJsonString)) + throw new Exception("Error occured while attemp on serializing object"); + + return entryJsonString; + } +} diff --git a/AzureRedisCachingSystem/Models/Book.cs b/AzureRedisCachingSystem/Models/Book.cs deleted file mode 100644 index dd30f47..0000000 --- a/AzureRedisCachingSystem/Models/Book.cs +++ /dev/null @@ -1,10 +0,0 @@ - -namespace AzureRedisCachingSystem.Models; - -public class Book -{ - public string Title { get; set; } - public string Description { get; set; } - public string AuthorFullName { get; set; } - public int Price { get; set; } -} diff --git a/AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs b/AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs deleted file mode 100644 index 389924c..0000000 --- a/AzureRedisCachingSystem/Models/Cache/Abstract/BaseCacheObject.cs +++ /dev/null @@ -1,54 +0,0 @@ -using AzureRedisCachingSystem.Models.Misc; -using AzureRedisCachingSystem.Services.Abstract; -using Serilog; -using System; -using System.Text; -using System.Threading.Tasks; - -namespace AzureRedisCachingSystem.Models.Cache.Abstract -{ - public abstract class BaseCacheObject - { - public StringBuilder UniqueKey { get; set; } - public KValue Value { get; set; } - - protected readonly IMemoryCaching _cacheService; - protected readonly IHashService _hashService; - - - protected BaseCacheObject(IMemoryCaching cacheService, IHashService hashService) - { - _cacheService = cacheService ?? throw new ArgumentNullException(nameof(cacheService)); - _hashService = hashService; - - UniqueKey = new StringBuilder(); - } - - - public async Task BuildCache(DateTimeOffset expire) - { - bool result = await _cacheService.SetCacheData(UniqueKey.ToString(), Value, expire); - return this; - } - - public BaseCacheObject SetKey(string key) - { - UniqueKey.Clear().Append(key); - return this; - } - - - public BaseCacheObject SetValue(object value) - { - Value = new KValue(value); - return this; - } - - public async Task> GetValueAsync(string key = null) - { - key ??= UniqueKey.ToString(); - KValue value = await _cacheService.GetCacheData>(key); - return value; - } - } -} diff --git a/AzureRedisCachingSystem/Models/Cache/CacheObject.cs b/AzureRedisCachingSystem/Models/Cache/CacheObject.cs deleted file mode 100644 index 99d8cba..0000000 --- a/AzureRedisCachingSystem/Models/Cache/CacheObject.cs +++ /dev/null @@ -1,40 +0,0 @@ -using AzureRedisCachingSystem.Models.Cache.Abstract; -using AzureRedisCachingSystem.Services.Abstract; -using Serilog; -using System.Text; - -namespace AzureRedisCachingSystem.Models.Cache -{ - public class CacheObject : BaseCacheObject - { - public CacheObject(IMemoryCaching cacheService, IHashService hashService) - : base(cacheService, hashService) - { - } - - public CacheObject SetParams(T parameter) - { - if (parameter == null) throw new ArgumentNullException(nameof(parameter)); - - var properties = parameter.GetType().GetProperties(); - - foreach (var prop in properties) - { - var value = prop.GetValue(parameter); - - if (value is DateTime dateTimeValue) - { - value = dateTimeValue.ToString("M/d/yyyy"); - } - - UniqueKey.Append($"{prop.Name.ToLower()}:{value?.ToString().ToLower()}&*"); - } - - UniqueKey = new StringBuilder(_hashService.HashString(UniqueKey.ToString())); - - Log.Information("Params set to cache object"); - - return this; - } - } -} diff --git a/AzureRedisCachingSystem/Models/Misc/KValue.cs b/AzureRedisCachingSystem/Models/Misc/KValue.cs deleted file mode 100644 index 61b9520..0000000 --- a/AzureRedisCachingSystem/Models/Misc/KValue.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace AzureRedisCachingSystem.Models.Misc -{ - /// - /// Represents a value with a generic type. - /// - /// The type of the value. - public class KValue - { - /// - /// Gets or sets the value. - /// - public T Value { get; set; } - - /// - /// Initializes a new instance of the class with the specified value. - /// - /// The value to initialize the instance with. - public KValue(T value) - { - Value = value; - } - - // Other properties or methods can be added here if needed - } -} diff --git a/AzureRedisCachingSystem/Models/ModelFilters/UserModelFilter.cs b/AzureRedisCachingSystem/Models/ModelFilters/UserModelFilter.cs deleted file mode 100644 index 455af7b..0000000 --- a/AzureRedisCachingSystem/Models/ModelFilters/UserModelFilter.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace AzureRedisCachingSystem.Models.ModelFilters; - -public class UserModelFilter -{ - public string Id { get; set; } - public string Name { get; set; } - public string Surname { get; set; } - public string Email { get; set; } - public int Age { get; set; } - public string PhoneNumber { get; set; } - public string FacultyId { get; set; } - public DateTime From { get; set; } - public DateTime To { get; set; } -} diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index f780319..249a9da 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,18 +1,9 @@ -using AzureRedisCachingSystem.Data; -using AzureRedisCachingSystem.Repositories; -using AzureRedisCachingSystem.Repositories.Abstract; - + class Program { static async Task Main(string[] args) { - ICacheObjectRepository repo = new CacheObjectRepository(); - - MongoDbContext context = new MongoDbContext("mongodb://localhost:27017", "myappdb"); - - var response = await repo.BookCacheObject.GetValueAsync(); - - Console.WriteLine(response); + } } \ No newline at end of file diff --git a/AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs b/AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs deleted file mode 100644 index 78fa516..0000000 --- a/AzureRedisCachingSystem/Repositories/Abstract/ICacheObjectRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using AzureRedisCachingSystem.Models.Cache; -using AzureRedisCachingSystem.Models.Cache.Abstract; - -namespace AzureRedisCachingSystem.Repositories.Abstract; - -public interface ICacheObjectRepository -{ - BaseCacheObject BookCacheObject { get; set; } -} diff --git a/AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs b/AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs deleted file mode 100644 index 0282274..0000000 --- a/AzureRedisCachingSystem/Repositories/CacheObjectRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -using AzureRedisCachingSystem.Models; -using AzureRedisCachingSystem.Models.Cache; -using AzureRedisCachingSystem.Models.Cache.Abstract; -using AzureRedisCachingSystem.Models.Misc; -using AzureRedisCachingSystem.Repositories.Abstract; -using AzureRedisCachingSystem.Services; -using Microsoft.EntityFrameworkCore; - -namespace AzureRedisCachingSystem.Repositories -{ - public class CacheObjectRepository : ICacheObjectRepository - { - public BaseCacheObject BookCacheObject { get; set; } - } -} diff --git a/AzureRedisCachingSystem/Services/Abstract/IHashService.cs b/AzureRedisCachingSystem/Services/Abstract/IHashService.cs deleted file mode 100644 index bd65147..0000000 --- a/AzureRedisCachingSystem/Services/Abstract/IHashService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AzureRedisCachingSystem.Services.Abstract; - -public interface IHashService -{ - string HashString(string input); -} diff --git a/AzureRedisCachingSystem/Services/Abstract/IMemoryCaching.cs b/AzureRedisCachingSystem/Services/Abstract/IMemoryCaching.cs deleted file mode 100644 index 67dbd9c..0000000 --- a/AzureRedisCachingSystem/Services/Abstract/IMemoryCaching.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace AzureRedisCachingSystem.Services.Abstract; - -public interface IMemoryCaching -{ - Task GetCacheData(string key); - Task RemoveData(string key); - Task SetCacheData(string key, T value, DateTimeOffset expireTime); - Task CheckIfExist(string Key); - -} diff --git a/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs b/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs new file mode 100644 index 0000000..f64a5e4 --- /dev/null +++ b/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs @@ -0,0 +1,8 @@ +using AzureRedisCachingSystem.Cache.Entries; + +namespace AzureRedisCachingSystem.Services.Abstract; + +public interface IRedisService +{ + Task WriteToRedis(CacheEntry entry); +} diff --git a/AzureRedisCachingSystem/Services/HashService.cs b/AzureRedisCachingSystem/Services/HashService.cs deleted file mode 100644 index 65025b7..0000000 --- a/AzureRedisCachingSystem/Services/HashService.cs +++ /dev/null @@ -1,68 +0,0 @@ -using AzureRedisCachingSystem.Services.Abstract; -using System; -using System.Security.Cryptography; -using System.Text; - -namespace AzureRedisCachingSystem.Services -{ - /// - /// Provides hashing services for strings using MD5 algorithm. - /// - public class HashService : IHashService - { - /// - /// Computes the MD5 hash of the given input string and returns it as a hexadecimal string. - /// - /// The input string to hash. - /// The hexadecimal representation of the MD5 hash. - /// Thrown when the input string is null or empty. - /// Thrown when an error occurs during hashing. - /// Thrown when an unexpected error occurs. - public string HashString(string input) - { - if (string.IsNullOrEmpty(input)) - { - throw new ArgumentException("Input cannot be null or empty.", nameof(input)); - } - - try - { - using var md5 = MD5.Create(); - byte[] inputBytes = Encoding.UTF8.GetBytes(input); - byte[] hashBytes = md5.ComputeHash(inputBytes); - return ConvertToHexString(hashBytes); - } - catch (CryptographicException ex) - { - throw new InvalidOperationException("An error occurred while computing the hash.", ex); - } - catch (Exception ex) - { - throw new ApplicationException("An unexpected error occurred.", ex); - } - } - - /// - /// Converts the given byte array to its hexadecimal string representation. - /// - /// The byte array to convert. - /// The hexadecimal string representation of the byte array. - /// Thrown when an error occurs during conversion. - private string ConvertToHexString(byte[] bytes) - { - try - { - var sb = new StringBuilder(); - foreach (byte b in bytes) - { - sb.Append(b.ToString("x2")); - } - return sb.ToString(); - } - catch (Exception ex) - { - throw new ApplicationException("An error occurred while converting bytes to hex string.", ex); - } - } - } -} diff --git a/AzureRedisCachingSystem/Services/RedisCachingService.cs b/AzureRedisCachingSystem/Services/RedisCachingService.cs deleted file mode 100644 index 610d872..0000000 --- a/AzureRedisCachingSystem/Services/RedisCachingService.cs +++ /dev/null @@ -1,50 +0,0 @@ -using AzureRedisCachingSystem.Configurations; -using AzureRedisCachingSystem.Services.Abstract; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using StackExchange.Redis; -using System; -using System.Threading.Tasks; - -namespace AzureRedisCachingSystem.Services -{ - - public class RedisCachingService : IMemoryCaching - { - private readonly IDatabase database; - - public RedisCachingService(string connectionStr) - { - ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(connectionStr); - database = redis.GetDatabase(); - } - - public async Task GetCacheData(string key) - { - var value = await database.StringGetAsync(key); - if (!string.IsNullOrEmpty(value)) - return JsonConvert.DeserializeObject(value); - return default; - } - public async Task RemoveData(string key) - { - var exists = await database.KeyExistsAsync(key); - if (exists) - return await database.KeyDeleteAsync(key); - return false; - } - - public async Task SetCacheData(string key, T value, DateTimeOffset expireTime) - { - TimeSpan timeToLive = expireTime.DateTime.Subtract(DateTime.UtcNow); - var isSet = await database.StringSetAsync(key, JsonConvert.SerializeObject(value)); - await database.KeyExpireAsync(key, timeToLive); - return isSet; - } - - public async Task CheckIfExist(string key) - { - return await database.KeyExistsAsync(key); - } - } -} diff --git a/AzureRedisCachingSystem/Services/RedisService.cs b/AzureRedisCachingSystem/Services/RedisService.cs new file mode 100644 index 0000000..032bc92 --- /dev/null +++ b/AzureRedisCachingSystem/Services/RedisService.cs @@ -0,0 +1,31 @@ +using AzureRedisCachingSystem.Cache.Entries; +using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.HelperServices.Json; +using AzureRedisCachingSystem.Services.Abstract; +using Microsoft.Extensions.Options; +using StackExchange.Redis; + +namespace AzureRedisCachingSystem.Services; + +public class RedisService : IRedisService +{ + private readonly IDatabase database; + + public RedisService(IOptions settings) + { + ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(settings.Value.ConnectionString); + + database = redis.GetDatabase(); + } + + public async Task WriteToRedis(CacheEntry entry) + { + RedisKey key = entry.Key; + + RedisValue value = JsonService.SerializeEntry(entry); + + bool setResult = await database.StringSetAsync(key, value); + + return setResult; + } +} From 002786f0b307eee9e8f5d0fd7cfd3b16867195eb Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 15:48:52 +0400 Subject: [PATCH 04/22] 30 manat olar --- .../Adapters/RedisWriter/RedisWriter.cs | 16 ++++-- .../AzureRedisCachingSystem.csproj | 1 + .../Cache/Entries/CacheEntry.cs | 2 + .../Cache/Settings/CacheEntryConfigurer.cs | 53 +++++++++++++++++++ .../Data/MongoDbContext.cs | 3 +- AzureRedisCachingSystem/Program.cs | 32 ++++++++--- .../Services/RedisService.cs | 8 ++- 7 files changed, 101 insertions(+), 14 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index f330efd..968a32a 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -1,11 +1,21 @@ using AzureRedisCachingSystem.Cache.Entries; +using AzureRedisCachingSystem.Services.Abstract; namespace AzureRedisCachingSystem.Adapters.RedisWriter; public class RedisWriter -{ - public Task WriteToCache(CacheEntry entry) +{ + private readonly IRedisService redisService; + + public RedisWriter(IRedisService redisService) { - + this.redisService = redisService; + } + + public async Task WriteToCache(CacheEntry entry) + { + bool writeResult = await redisService.WriteToRedis(entry); + + return writeResult; } } diff --git a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj index be7f693..3031c3e 100644 --- a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj +++ b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj @@ -13,6 +13,7 @@ + diff --git a/AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs b/AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs index 5777e6d..5b6c72f 100644 --- a/AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs +++ b/AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs @@ -6,4 +6,6 @@ public class CacheEntry { public string Key { get; set; } public CacheValue Value { get; set; } + public DateTime BuildDate { get; set; } + public DateTimeOffset Expire { get; set; } } diff --git a/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs b/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs index 952868b..833eafe 100644 --- a/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs +++ b/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs @@ -7,6 +7,59 @@ public class CacheEntryConfigurer { private string key; private CacheValue value; + private DateTimeOffset expire; + public CacheEntryConfigurer SetKey(string key) + { + this.key = key; + return this; + } + + public CacheEntryConfigurer SetValue(CacheValue value) + { + this.value = value; + + return this; + } + + public CacheEntryConfigurer SetParams(object filterParameter) + { + return this; + } + + public CacheEntryConfigurer SetExpire(DateTimeOffset expire) + { + this.expire = expire; + + return this; + } + + public CacheEntry BuildCacheEntry() + { + if(!CheckIfSettingsIsConfigured()) + { + throw new Exception("Once configure settings before build."); + } + + CacheEntry cacheEntry = new CacheEntry() + { + Key = key, + Value = value, + BuildDate = DateTime.Now, + Expire = expire, + }; + + return cacheEntry; + } + + #region Helper Methods + private bool CheckIfSettingsIsConfigured() + { + if (this.value == null || this.key == null) + return false; + + return true; + } + #endregion } diff --git a/AzureRedisCachingSystem/Data/MongoDbContext.cs b/AzureRedisCachingSystem/Data/MongoDbContext.cs index 82cbe2c..bc0c9a0 100644 --- a/AzureRedisCachingSystem/Data/MongoDbContext.cs +++ b/AzureRedisCachingSystem/Data/MongoDbContext.cs @@ -1,5 +1,4 @@ using AzureRedisCachingSystem.Configurations; -using AzureRedisCachingSystem.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using MongoDB.Driver; @@ -18,5 +17,5 @@ public MongoDbContext(string conStr, string dbname) _database = client.GetDatabase(dbname); } - public IMongoCollection Books { get; set; } + //public IMongoCollection Books { get; set; } } diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 249a9da..b34a93e 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,9 +1,25 @@ - -class Program +using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.Services; +using AzureRedisCachingSystem.Services.Abstract; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +//////////////////////////////////////// Dependency Injection + +var host = Host.CreateDefaultBuilder(args) +.ConfigureAppConfiguration((context, config) => { - static async Task Main(string[] args) - { - - } -} - \ No newline at end of file +config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); +}) +.ConfigureServices((context, services) => +{ +services.Configure(context.Configuration.GetSection("Redis")); +services.AddScoped(); +}) +.Build(); + +//////////////////////////////////////// Application + + + diff --git a/AzureRedisCachingSystem/Services/RedisService.cs b/AzureRedisCachingSystem/Services/RedisService.cs index 032bc92..599d852 100644 --- a/AzureRedisCachingSystem/Services/RedisService.cs +++ b/AzureRedisCachingSystem/Services/RedisService.cs @@ -21,11 +21,17 @@ public RedisService(IOptions settings) public async Task WriteToRedis(CacheEntry entry) { RedisKey key = entry.Key; - RedisValue value = JsonService.SerializeEntry(entry); bool setResult = await database.StringSetAsync(key, value); + if (setResult is true) + { + TimeSpan expiryTime = entry.Expire - DateTimeOffset.Now; + await database.KeyExpireAsync(key, expiryTime); + } + return setResult; } + } From 4a364bb91e5af69c421b5f1bb28c00c46ece83ca Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 16:12:48 +0400 Subject: [PATCH 05/22] Stage Commit [] --- .../UniqueKey/UniqueKeyService.cs | 18 ++++++++++++++++++ AzureRedisCachingSystem/Program.cs | 14 ++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs diff --git a/AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs b/AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs new file mode 100644 index 0000000..024f1b6 --- /dev/null +++ b/AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs @@ -0,0 +1,18 @@ +using System.Reflection; + +namespace AzureRedisCachingSystem.HelperServices.UniqueKey; + +public static class UniqueKeyService +{ + public static void GenerateUniqueKeyViaParams(string key,object parameter) + { + PropertyInfo[] properties = parameter.GetType().GetProperties(); + + foreach (var prop in properties) + { + object value = prop.GetValue(parameter); + + key += $"{prop.Name.ToLower()}:{value.ToString().Replace(" ", "")}"; + } + } +} diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index b34a93e..2217329 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,4 +1,8 @@ -using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.Adapters.RedisWriter; +using AzureRedisCachingSystem.Cache.CustomValues; +using AzureRedisCachingSystem.Cache.Entries; +using AzureRedisCachingSystem.Cache.Settings; +using AzureRedisCachingSystem.Configurations; using AzureRedisCachingSystem.Services; using AzureRedisCachingSystem.Services.Abstract; using Microsoft.Extensions.Configuration; @@ -10,16 +14,14 @@ var host = Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { -config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); }) .ConfigureServices((context, services) => { -services.Configure(context.Configuration.GetSection("Redis")); -services.AddScoped(); + services.Configure(context.Configuration.GetSection("Redis")); + services.AddScoped(); }) .Build(); //////////////////////////////////////// Application - - From cc092e4aa1d7bf6c2a86860f094b9041a17da4bc Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 16:45:08 +0400 Subject: [PATCH 06/22] SetParams Working, helper services --- .../ApplicationModels/Book.cs | 9 ++++ .../Cache/Settings/CacheEntryConfigurer.cs | 19 +++++++ .../HelperServices/Hash/HashService.cs | 26 +++++++++ .../UniqueKey/UniqueKeyService.cs | 2 +- AzureRedisCachingSystem/Program.cs | 53 ++++++++++++++++++- .../Services/RedisService.cs | 2 + 6 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 AzureRedisCachingSystem/ApplicationModels/Book.cs create mode 100644 AzureRedisCachingSystem/HelperServices/Hash/HashService.cs diff --git a/AzureRedisCachingSystem/ApplicationModels/Book.cs b/AzureRedisCachingSystem/ApplicationModels/Book.cs new file mode 100644 index 0000000..fbb6b81 --- /dev/null +++ b/AzureRedisCachingSystem/ApplicationModels/Book.cs @@ -0,0 +1,9 @@ +namespace AzureRedisCachingSystem.ApplicationModels; + +public class Book +{ + public string Id { get; set; } + public string Title { get; set; } + public DateTime PublishDate { get; set; } + public int Price { get; set; } +} diff --git a/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs b/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs index 833eafe..987fb5a 100644 --- a/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs +++ b/AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs @@ -1,5 +1,7 @@ using AzureRedisCachingSystem.Cache.CustomValues; using AzureRedisCachingSystem.Cache.Entries; +using AzureRedisCachingSystem.HelperServices.Hash; +using AzureRedisCachingSystem.HelperServices.UniqueKey; namespace AzureRedisCachingSystem.Cache.Settings; @@ -25,6 +27,13 @@ public CacheEntryConfigurer SetValue(CacheValue value) public CacheEntryConfigurer SetParams(object filterParameter) { + if(key is not null) + { + throw new Exception("You cannot define params after setting key manually. Try removing key"); + } + + UniqueKeyService.GenerateUniqueKeyViaParams(ref key , filterParameter); + return this; } @@ -42,6 +51,8 @@ public CacheEntry BuildCacheEntry() throw new Exception("Once configure settings before build."); } + HashIfNeeded(); + CacheEntry cacheEntry = new CacheEntry() { Key = key, @@ -61,5 +72,13 @@ private bool CheckIfSettingsIsConfigured() return true; } + + private void HashIfNeeded() + { + if (key.Length > 32) + { + HashService.HashString(ref key); + } + } #endregion } diff --git a/AzureRedisCachingSystem/HelperServices/Hash/HashService.cs b/AzureRedisCachingSystem/HelperServices/Hash/HashService.cs new file mode 100644 index 0000000..e3c1387 --- /dev/null +++ b/AzureRedisCachingSystem/HelperServices/Hash/HashService.cs @@ -0,0 +1,26 @@ +using System.Security.Cryptography; +using System.Text; + +namespace AzureRedisCachingSystem.HelperServices.Hash; + +public static class HashService +{ + public static void HashString(ref string input) + { + using (var sha256 = SHA256.Create()) + { + byte[] bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(input)); + + var truncatedBytes = new byte[16]; + Array.Copy(bytes, truncatedBytes, 16); + + var sb = new StringBuilder(); + foreach (var b in truncatedBytes) + { + sb.Append(b.ToString("x2")); + } + + input = sb.ToString(); + } + } +} diff --git a/AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs b/AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs index 024f1b6..e9155d8 100644 --- a/AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs +++ b/AzureRedisCachingSystem/HelperServices/UniqueKey/UniqueKeyService.cs @@ -4,7 +4,7 @@ namespace AzureRedisCachingSystem.HelperServices.UniqueKey; public static class UniqueKeyService { - public static void GenerateUniqueKeyViaParams(string key,object parameter) + public static void GenerateUniqueKeyViaParams(ref string key,object parameter) { PropertyInfo[] properties = parameter.GetType().GetProperties(); diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 2217329..8ece826 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,4 +1,5 @@ using AzureRedisCachingSystem.Adapters.RedisWriter; +using AzureRedisCachingSystem.ApplicationModels; using AzureRedisCachingSystem.Cache.CustomValues; using AzureRedisCachingSystem.Cache.Entries; using AzureRedisCachingSystem.Cache.Settings; @@ -23,5 +24,55 @@ }) .Build(); -//////////////////////////////////////// Application +//////////////////////////////////////// Fake data +List books = new List() +{ + new Book + { + Id = Guid.NewGuid().ToString(), + Price = 15, + PublishDate = DateTime.Now, + Title = "Nagil 101" + }, + new Book + { + Id = Guid.NewGuid().ToString(), + Price = 15, + PublishDate = DateTime.Now, + Title = "Nagil 101" + }, + new Book + { + Id = Guid.NewGuid().ToString(), + Price = 15, + PublishDate = DateTime.Now, + Title = "Nagil 101" + }, + new Book + { + Id = Guid.NewGuid().ToString(), + Price = 15, + PublishDate = DateTime.Now, + Title = "Nagil 101" + + }, +}; + +/////////////////////////////////////// Application + +RedisWriter writerAdapter = new RedisWriter(host.Services.GetRequiredService()); + +CacheEntry entry = new CacheEntryConfigurer() + .SetValue(new CacheValue() { Value = 15 }) + .SetParams(new Book() + { + Id = Guid.NewGuid().ToString(), + Price = 15, + PublishDate = DateTime.Now, + Title = "Naqillar alemi", + }) + .SetExpire(DateTimeOffset.UtcNow.AddMinutes(2)) + .BuildCacheEntry(); + +await writerAdapter.WriteToCache(entry); diff --git a/AzureRedisCachingSystem/Services/RedisService.cs b/AzureRedisCachingSystem/Services/RedisService.cs index 599d852..0a9ee90 100644 --- a/AzureRedisCachingSystem/Services/RedisService.cs +++ b/AzureRedisCachingSystem/Services/RedisService.cs @@ -23,6 +23,8 @@ public async Task WriteToRedis(CacheEntry entry) RedisKey key = entry.Key; RedisValue value = JsonService.SerializeEntry(entry); + + bool setResult = await database.StringSetAsync(key, value); if (setResult is true) From c8d7be186a2d094b177dd088a5a592f51487aec9 Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 16:48:38 +0400 Subject: [PATCH 07/22] Simple bug fixed --- AzureRedisCachingSystem/HelperServices/Json/JsonService.cs | 5 +++-- AzureRedisCachingSystem/Program.cs | 4 ++-- AzureRedisCachingSystem/Services/RedisService.cs | 4 +--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/AzureRedisCachingSystem/HelperServices/Json/JsonService.cs b/AzureRedisCachingSystem/HelperServices/Json/JsonService.cs index 3ff61af..3f3c529 100644 --- a/AzureRedisCachingSystem/HelperServices/Json/JsonService.cs +++ b/AzureRedisCachingSystem/HelperServices/Json/JsonService.cs @@ -1,11 +1,12 @@ -using AzureRedisCachingSystem.Cache.Entries; +using AzureRedisCachingSystem.Cache.CustomValues; +using AzureRedisCachingSystem.Cache.Entries; using Newtonsoft.Json; namespace AzureRedisCachingSystem.HelperServices.Json; public static class JsonService { - public static string SerializeEntry(CacheEntry entry) + public static string SerializeValue(CacheValue entry) { string entryJsonString = JsonConvert.SerializeObject(entry); diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 8ece826..d690738 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -64,7 +64,7 @@ RedisWriter writerAdapter = new RedisWriter(host.Services.GetRequiredService()); CacheEntry entry = new CacheEntryConfigurer() - .SetValue(new CacheValue() { Value = 15 }) + .SetValue(new CacheValue() { Value = books }) .SetParams(new Book() { Id = Guid.NewGuid().ToString(), @@ -72,7 +72,7 @@ PublishDate = DateTime.Now, Title = "Naqillar alemi", }) - .SetExpire(DateTimeOffset.UtcNow.AddMinutes(2)) + .SetExpire(DateTimeOffset.UtcNow.AddMonths(2)) .BuildCacheEntry(); await writerAdapter.WriteToCache(entry); diff --git a/AzureRedisCachingSystem/Services/RedisService.cs b/AzureRedisCachingSystem/Services/RedisService.cs index 0a9ee90..eedbe89 100644 --- a/AzureRedisCachingSystem/Services/RedisService.cs +++ b/AzureRedisCachingSystem/Services/RedisService.cs @@ -21,9 +21,7 @@ public RedisService(IOptions settings) public async Task WriteToRedis(CacheEntry entry) { RedisKey key = entry.Key; - RedisValue value = JsonService.SerializeEntry(entry); - - + RedisValue value = JsonService.SerializeValue(entry.Value); bool setResult = await database.StringSetAsync(key, value); From c4a1e774a36ed2d62f1d8bf5bf9e54c9d47a9f93 Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 17:05:12 +0400 Subject: [PATCH 08/22] Stage Commit [] --- .../Adapters/RedisReader/RedisReader.cs | 31 +++++++++++++++++++ .../AzureRedisCachingSystem.csproj | 4 --- AzureRedisCachingSystem/Program.cs | 21 +++++-------- .../Services/Abstract/IRedisService.cs | 2 ++ .../Services/RedisService.cs | 3 ++ 5 files changed, 44 insertions(+), 17 deletions(-) create mode 100644 AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs diff --git a/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs b/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs new file mode 100644 index 0000000..7e033dc --- /dev/null +++ b/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs @@ -0,0 +1,31 @@ +using AzureRedisCachingSystem.Cache.CustomValues; +using AzureRedisCachingSystem.Services.Abstract; +using Newtonsoft.Json; +using StackExchange.Redis; + +namespace AzureRedisCachingSystem.Adapters.RedisReader; + +public class RedisReader +{ + private readonly IRedisService redisService; + + public RedisReader(IRedisService redisService) + { + this.redisService = redisService; + } + + public async Task ReadFromCacheAsync(string key) + { + RedisValue responseValue = await redisService.ReadFromRedis(key); + + if (!responseValue.HasValue) + throw new Exception("Cannot find value related with given key"); + + var obj = JsonConvert.DeserializeObject(responseValue); + + if (obj is CacheValue) + throw new Exception("Error occured while casting type"); + + return obj as CacheValue; + } +} diff --git a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj index 3031c3e..7a413f2 100644 --- a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj +++ b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj @@ -28,8 +28,4 @@ - - - - diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index d690738..559cbb0 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -61,18 +61,13 @@ /////////////////////////////////////// Application -RedisWriter writerAdapter = new RedisWriter(host.Services.GetRequiredService()); +try +{ + +} +catch (Exception exception) +{ + Console.WriteLine(exception.Message); +} -CacheEntry entry = new CacheEntryConfigurer() - .SetValue(new CacheValue() { Value = books }) - .SetParams(new Book() - { - Id = Guid.NewGuid().ToString(), - Price = 15, - PublishDate = DateTime.Now, - Title = "Naqillar alemi", - }) - .SetExpire(DateTimeOffset.UtcNow.AddMonths(2)) - .BuildCacheEntry(); -await writerAdapter.WriteToCache(entry); diff --git a/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs b/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs index f64a5e4..b15c41b 100644 --- a/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs +++ b/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs @@ -1,8 +1,10 @@ using AzureRedisCachingSystem.Cache.Entries; +using StackExchange.Redis; namespace AzureRedisCachingSystem.Services.Abstract; public interface IRedisService { Task WriteToRedis(CacheEntry entry); + Task ReadFromRedis(string key); } diff --git a/AzureRedisCachingSystem/Services/RedisService.cs b/AzureRedisCachingSystem/Services/RedisService.cs index eedbe89..3e9359b 100644 --- a/AzureRedisCachingSystem/Services/RedisService.cs +++ b/AzureRedisCachingSystem/Services/RedisService.cs @@ -18,6 +18,9 @@ public RedisService(IOptions settings) database = redis.GetDatabase(); } + public async Task ReadFromRedis(string key) + => await database.StringGetAsync(key); + public async Task WriteToRedis(CacheEntry entry) { RedisKey key = entry.Key; From 68086001ec58e00d98286908df34d1b5b41213f3 Mon Sep 17 00:00:00 2001 From: novru Date: Wed, 7 Aug 2024 17:20:17 +0400 Subject: [PATCH 09/22] Bitdi axirki prosda uje men gijd*** olmusam --- .../Adapters/RedisReader/RedisReader.cs | 20 +++++++--- AzureRedisCachingSystem/Program.cs | 40 +++++++++++++++---- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs b/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs index 7e033dc..cd979ba 100644 --- a/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs +++ b/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs @@ -1,4 +1,5 @@ using AzureRedisCachingSystem.Cache.CustomValues; +using AzureRedisCachingSystem.HelperServices.UniqueKey; using AzureRedisCachingSystem.Services.Abstract; using Newtonsoft.Json; using StackExchange.Redis; @@ -21,11 +22,20 @@ public async Task ReadFromCacheAsync(string key) if (!responseValue.HasValue) throw new Exception("Cannot find value related with given key"); - var obj = JsonConvert.DeserializeObject(responseValue); + CacheValue cacheValue = JsonConvert.DeserializeObject(responseValue); - if (obj is CacheValue) - throw new Exception("Error occured while casting type"); + if (cacheValue == null) + throw new Exception("Error occurred while casting type"); - return obj as CacheValue; - } + return cacheValue; + } + + public async Task ReadFromCacheViaParametersAsync(object parameter) + { + string key = string.Empty; + + UniqueKeyService.GenerateUniqueKeyViaParams(ref key, parameter); + + return await ReadFromCacheAsync(key); + } } diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 559cbb0..afa3631 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,4 +1,5 @@ -using AzureRedisCachingSystem.Adapters.RedisWriter; +using AzureRedisCachingSystem.Adapters.RedisReader; +using AzureRedisCachingSystem.Adapters.RedisWriter; using AzureRedisCachingSystem.ApplicationModels; using AzureRedisCachingSystem.Cache.CustomValues; using AzureRedisCachingSystem.Cache.Entries; @@ -61,13 +62,36 @@ /////////////////////////////////////// Application -try -{ +//RedisWriter writerAdapter = new RedisWriter(host.Services.GetRequiredService()); -} -catch (Exception exception) -{ - Console.WriteLine(exception.Message); -} +//CacheValue bookCacheValue = new CacheValue() +//{ +// Value = 31697252, +//}; + +//CacheEntry bookCache = new CacheEntryConfigurer() +// .SetKey("Salamqaqa") +// .SetValue(bookCacheValue) +// .SetExpire(DateTimeOffset.UtcNow.AddSeconds(100)) +// .BuildCacheEntry(); + +//await writerAdapter.WriteToCache(bookCache); + +////////////////////////////////////// Read sample + +// cc8687825c8a2556c011e8f6a77f81a0 + +//try +//{ +// RedisReader reader = new RedisReader(host.Services.GetRequiredService()); + +// CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); + +// Console.WriteLine(responseValue.Value); +//} +//catch (Exception exception) +//{ +// Console.WriteLine(exception.Message); +//} From b00272c792216fcf43c883379966a9273466cd9f Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 09:56:09 +0400 Subject: [PATCH 10/22] New CACHE METRICS SERVICE BLYA --- .../Cache/Metrics/CacheMetrics.cs | 9 ++++ .../Data/MongoDbContext.cs | 5 +- AzureRedisCachingSystem/Program.cs | 7 +-- .../Services/Abstract/IMetricsService.cs | 9 ++++ .../Services/MetricsService.cs | 46 +++++++++++++++++++ 5 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs create mode 100644 AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs create mode 100644 AzureRedisCachingSystem/Services/MetricsService.cs diff --git a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs new file mode 100644 index 0000000..cd79477 --- /dev/null +++ b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs @@ -0,0 +1,9 @@ +namespace AzureRedisCachingSystem.Cache.Metrics; + +public class CacheMetrics +{ + public string Key { get; set; } + public int CacheHits { get; set; } + public int CacheMisses { get; set; } + public DateTime LastAccessed { get; set; } +} diff --git a/AzureRedisCachingSystem/Data/MongoDbContext.cs b/AzureRedisCachingSystem/Data/MongoDbContext.cs index bc0c9a0..345e1a0 100644 --- a/AzureRedisCachingSystem/Data/MongoDbContext.cs +++ b/AzureRedisCachingSystem/Data/MongoDbContext.cs @@ -1,4 +1,5 @@ -using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.Cache.Metrics; +using AzureRedisCachingSystem.Configurations; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using MongoDB.Driver; @@ -17,5 +18,5 @@ public MongoDbContext(string conStr, string dbname) _database = client.GetDatabase(dbname); } - //public IMongoCollection Books { get; set; } + public IMongoCollection Metrics { get; set; } } diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index afa3631..6091fa0 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,9 +1,4 @@ -using AzureRedisCachingSystem.Adapters.RedisReader; -using AzureRedisCachingSystem.Adapters.RedisWriter; -using AzureRedisCachingSystem.ApplicationModels; -using AzureRedisCachingSystem.Cache.CustomValues; -using AzureRedisCachingSystem.Cache.Entries; -using AzureRedisCachingSystem.Cache.Settings; +using AzureRedisCachingSystem.ApplicationModels; using AzureRedisCachingSystem.Configurations; using AzureRedisCachingSystem.Services; using AzureRedisCachingSystem.Services.Abstract; diff --git a/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs b/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs new file mode 100644 index 0000000..84b0b71 --- /dev/null +++ b/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs @@ -0,0 +1,9 @@ +namespace AzureRedisCachingSystem.Services.Abstract; + +public interface IMetricsService +{ + Task CraeteMetrics(); + Task HandleCacheHit(); + Task HandleCacheMiss(); + Task RemoveMetrics(); +} diff --git a/AzureRedisCachingSystem/Services/MetricsService.cs b/AzureRedisCachingSystem/Services/MetricsService.cs new file mode 100644 index 0000000..684cf87 --- /dev/null +++ b/AzureRedisCachingSystem/Services/MetricsService.cs @@ -0,0 +1,46 @@ +using AzureRedisCachingSystem.Cache.Metrics; +using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.Data; +using AzureRedisCachingSystem.Services.Abstract; +using Microsoft.Extensions.Options; +using MongoDB.Driver; +using System.Threading.Tasks; + +namespace AzureRedisCachingSystem.Services +{ + public class MetricsService : IMetricsService + { + private readonly MongoDbContext context; + + public MetricsService(MongoDbContext context) + { + this.context = context; + } + + public async Task CreateMetrics(CacheMetrics metrics) + => await context.Metrics.InsertOneAsync(metrics); + + public async Task HandleCacheHit(string key) + { + var filter = Builders.Filter.Eq(m => m.Key, key); + var update = Builders.Update.Inc(m => m.CacheHits, 1) + .Set(m => m.LastAccessed, DateTime.UtcNow); + + var result = await context.Metrics.UpdateOneAsync(filter, update); + + return result.ModifiedCount > 0; + } + + public async Task HandleCacheMiss() + { + return true; + } + + public async Task RemoveMetrics() + { + var result = await context.Metrics.DeleteManyAsync(FilterDefinition.Empty); + + return result.DeletedCount > 0; + } + } +} From 3ce28c584e616f68038c26bb00327d1b3eeebd95 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 10:32:00 +0400 Subject: [PATCH 11/22] Metrics implemented to project. need for testing --- .../Adapters/RedisReader/RedisReader.cs | 9 +++- .../Adapters/RedisWriter/RedisWriter.cs | 18 ++++++- AzureRedisCachingSystem/Program.cs | 51 +++++++++++-------- .../Services/Abstract/IMetricsService.cs | 10 ++-- .../Services/MetricsService.cs | 4 +- AzureRedisCachingSystem/appsettings.json | 2 +- 6 files changed, 63 insertions(+), 31 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs b/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs index cd979ba..ff70a88 100644 --- a/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs +++ b/AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs @@ -9,10 +9,12 @@ namespace AzureRedisCachingSystem.Adapters.RedisReader; public class RedisReader { private readonly IRedisService redisService; + private readonly IMetricsService metricsService; - public RedisReader(IRedisService redisService) + public RedisReader(IRedisService redisService, IMetricsService metricsService) { this.redisService = redisService; + this.metricsService = metricsService; } public async Task ReadFromCacheAsync(string key) @@ -20,13 +22,18 @@ public async Task ReadFromCacheAsync(string key) RedisValue responseValue = await redisService.ReadFromRedis(key); if (!responseValue.HasValue) + { + await metricsService.HandleCacheMiss(key); throw new Exception("Cannot find value related with given key"); + } CacheValue cacheValue = JsonConvert.DeserializeObject(responseValue); if (cacheValue == null) throw new Exception("Error occurred while casting type"); + await metricsService.HandleCacheHit(key); + return cacheValue; } diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index 968a32a..ed80c47 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -1,4 +1,5 @@ using AzureRedisCachingSystem.Cache.Entries; +using AzureRedisCachingSystem.Cache.Metrics; using AzureRedisCachingSystem.Services.Abstract; namespace AzureRedisCachingSystem.Adapters.RedisWriter; @@ -6,16 +7,31 @@ namespace AzureRedisCachingSystem.Adapters.RedisWriter; public class RedisWriter { private readonly IRedisService redisService; + private readonly IMetricsService metricsService; - public RedisWriter(IRedisService redisService) + public RedisWriter(IRedisService redisService, IMetricsService metricsService) { this.redisService = redisService; + this.metricsService = metricsService; } public async Task WriteToCache(CacheEntry entry) { bool writeResult = await redisService.WriteToRedis(entry); + if(writeResult) + { + CacheMetrics metrics = new CacheMetrics() + { + Key = entry.Key, + CacheHits = 1, + CacheMisses = 0, + LastAccessed = DateTime.UtcNow, + }; + + await metricsService.CraeteMetrics(metrics); + } + return writeResult; } } diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 6091fa0..220053a 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -1,4 +1,9 @@ -using AzureRedisCachingSystem.ApplicationModels; +using AzureRedisCachingSystem.Adapters.RedisReader; +using AzureRedisCachingSystem.Adapters.RedisWriter; +using AzureRedisCachingSystem.ApplicationModels; +using AzureRedisCachingSystem.Cache.CustomValues; +using AzureRedisCachingSystem.Cache.Entries; +using AzureRedisCachingSystem.Cache.Settings; using AzureRedisCachingSystem.Configurations; using AzureRedisCachingSystem.Services; using AzureRedisCachingSystem.Services.Abstract; @@ -17,6 +22,7 @@ { services.Configure(context.Configuration.GetSection("Redis")); services.AddScoped(); + services.AddScoped(); }) .Build(); @@ -29,6 +35,7 @@ Id = Guid.NewGuid().ToString(), Price = 15, PublishDate = DateTime.Now, + Title = "Nagil 101" }, new Book @@ -57,36 +64,36 @@ /////////////////////////////////////// Application -//RedisWriter writerAdapter = new RedisWriter(host.Services.GetRequiredService()); +RedisWriter writerAdapter = new RedisWriter(host.Services.GetRequiredService(), host.Services.GetRequiredService()); -//CacheValue bookCacheValue = new CacheValue() -//{ -// Value = 31697252, -//}; +CacheValue bookCacheValue = new CacheValue() +{ + Value = 31697252, +}; -//CacheEntry bookCache = new CacheEntryConfigurer() -// .SetKey("Salamqaqa") -// .SetValue(bookCacheValue) -// .SetExpire(DateTimeOffset.UtcNow.AddSeconds(100)) -// .BuildCacheEntry(); +CacheEntry bookCache = new CacheEntryConfigurer() + .SetKey("Salamqaqa") + .SetValue(bookCacheValue) + .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) + .BuildCacheEntry(); -//await writerAdapter.WriteToCache(bookCache); +await writerAdapter.WriteToCache(bookCache); ////////////////////////////////////// Read sample // cc8687825c8a2556c011e8f6a77f81a0 -//try -//{ -// RedisReader reader = new RedisReader(host.Services.GetRequiredService()); +try +{ + RedisReader reader = new RedisReader(host.Services.GetRequiredService(), host.Services.GetRequiredService()); -// CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); + CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); -// Console.WriteLine(responseValue.Value); -//} -//catch (Exception exception) -//{ -// Console.WriteLine(exception.Message); -//} + Console.WriteLine(responseValue.Value); +} +catch (Exception exception) +{ + Console.WriteLine(exception.Message); +} diff --git a/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs b/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs index 84b0b71..9ef3881 100644 --- a/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs +++ b/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs @@ -1,9 +1,11 @@ -namespace AzureRedisCachingSystem.Services.Abstract; +using AzureRedisCachingSystem.Cache.Metrics; + +namespace AzureRedisCachingSystem.Services.Abstract; public interface IMetricsService { - Task CraeteMetrics(); - Task HandleCacheHit(); - Task HandleCacheMiss(); + Task CraeteMetrics(CacheMetrics metrics); + Task HandleCacheHit(string key); + Task HandleCacheMiss(string key); Task RemoveMetrics(); } diff --git a/AzureRedisCachingSystem/Services/MetricsService.cs b/AzureRedisCachingSystem/Services/MetricsService.cs index 684cf87..fac2431 100644 --- a/AzureRedisCachingSystem/Services/MetricsService.cs +++ b/AzureRedisCachingSystem/Services/MetricsService.cs @@ -17,7 +17,7 @@ public MetricsService(MongoDbContext context) this.context = context; } - public async Task CreateMetrics(CacheMetrics metrics) + public async Task CraeteMetrics(CacheMetrics metrics) => await context.Metrics.InsertOneAsync(metrics); public async Task HandleCacheHit(string key) @@ -31,7 +31,7 @@ public async Task HandleCacheHit(string key) return result.ModifiedCount > 0; } - public async Task HandleCacheMiss() + public async Task HandleCacheMiss(string key) { return true; } diff --git a/AzureRedisCachingSystem/appsettings.json b/AzureRedisCachingSystem/appsettings.json index c47a649..2d3efe0 100644 --- a/AzureRedisCachingSystem/appsettings.json +++ b/AzureRedisCachingSystem/appsettings.json @@ -5,6 +5,6 @@ "MongoDB": { "ConnectionString": "mongodb://localhost:27017", - "DatabaseName": "myappdb" + "DatabaseName": "cachemetrics" } } \ No newline at end of file From c8bdf8aa7335c9d9cde09421013a14cdbd769fd4 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 10:56:09 +0400 Subject: [PATCH 12/22] Statement for key conflict --- .../Adapters/RedisWriter/RedisWriter.cs | 8 ++++++++ AzureRedisCachingSystem/Data/MongoDbContext.cs | 8 ++++---- AzureRedisCachingSystem/Program.cs | 14 +++++++++++--- .../Services/Abstract/IRedisService.cs | 1 + AzureRedisCachingSystem/Services/RedisService.cs | 3 +++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index ed80c47..39881b1 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -17,6 +17,8 @@ public RedisWriter(IRedisService redisService, IMetricsService metricsService) public async Task WriteToCache(CacheEntry entry) { + await HandleKeyConflict(entry.Key); + bool writeResult = await redisService.WriteToRedis(entry); if(writeResult) @@ -34,4 +36,10 @@ public async Task WriteToCache(CacheEntry entry) return writeResult; } + + private async Task HandleKeyConflict(string key) + { + if(await redisService.CheckKeyExist(key)) + throw new Exception("Value with given key is already existing.."); + } } diff --git a/AzureRedisCachingSystem/Data/MongoDbContext.cs b/AzureRedisCachingSystem/Data/MongoDbContext.cs index 345e1a0..f416650 100644 --- a/AzureRedisCachingSystem/Data/MongoDbContext.cs +++ b/AzureRedisCachingSystem/Data/MongoDbContext.cs @@ -11,12 +11,12 @@ public class MongoDbContext { private readonly IMongoDatabase _database; - public MongoDbContext(string conStr, string dbname) + public MongoDbContext(IOptions settings) { - MongoClient client = new MongoClient(conStr); + MongoClient client = new MongoClient(settings.Value.ConnectionString); - _database = client.GetDatabase(dbname); + _database = client.GetDatabase(settings.Value.DatabaseName); } - public IMongoCollection Metrics { get; set; } + public IMongoCollection Metrics => _database.GetCollection("metrics"); } diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 220053a..be95fc2 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -5,6 +5,7 @@ using AzureRedisCachingSystem.Cache.Entries; using AzureRedisCachingSystem.Cache.Settings; using AzureRedisCachingSystem.Configurations; +using AzureRedisCachingSystem.Data; using AzureRedisCachingSystem.Services; using AzureRedisCachingSystem.Services.Abstract; using Microsoft.Extensions.Configuration; @@ -21,8 +22,10 @@ .ConfigureServices((context, services) => { services.Configure(context.Configuration.GetSection("Redis")); + services.Configure(context.Configuration.GetSection("MongoDB")); services.AddScoped(); services.AddScoped(); + services.AddSingleton(); }) .Build(); @@ -64,7 +67,12 @@ /////////////////////////////////////// Application -RedisWriter writerAdapter = new RedisWriter(host.Services.GetRequiredService(), host.Services.GetRequiredService()); +IRedisService redisService = host.Services.GetRequiredService(); +IMetricsService metricsService = host.Services.GetRequiredService(); + +/////////////////////////////////////// Write sample + +RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); CacheValue bookCacheValue = new CacheValue() { @@ -79,13 +87,13 @@ await writerAdapter.WriteToCache(bookCache); -////////////////////////////////////// Read sample +/////////////////////////////////////// Read sample // cc8687825c8a2556c011e8f6a77f81a0 try { - RedisReader reader = new RedisReader(host.Services.GetRequiredService(), host.Services.GetRequiredService()); + RedisReader reader = new RedisReader(redisService,metricsService); CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); diff --git a/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs b/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs index b15c41b..99a33a6 100644 --- a/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs +++ b/AzureRedisCachingSystem/Services/Abstract/IRedisService.cs @@ -7,4 +7,5 @@ public interface IRedisService { Task WriteToRedis(CacheEntry entry); Task ReadFromRedis(string key); + Task CheckKeyExist(string key); } diff --git a/AzureRedisCachingSystem/Services/RedisService.cs b/AzureRedisCachingSystem/Services/RedisService.cs index 3e9359b..c6b905b 100644 --- a/AzureRedisCachingSystem/Services/RedisService.cs +++ b/AzureRedisCachingSystem/Services/RedisService.cs @@ -18,6 +18,9 @@ public RedisService(IOptions settings) database = redis.GetDatabase(); } + public async Task CheckKeyExist(string key) + => await database.KeyExistsAsync(key); + public async Task ReadFromRedis(string key) => await database.StringGetAsync(key); From 2cabc62f4632909bd5156d2f319b68aee7522fc3 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 11:18:38 +0400 Subject: [PATCH 13/22] Stage Commit [] --- AzureRedisCachingSystem/App.config | 6 ++++ AzureRedisCachingSystem/Program.cs | 34 ++++++------------- .../Services/MetricsService.cs | 6 +++- 3 files changed, 22 insertions(+), 24 deletions(-) create mode 100644 AzureRedisCachingSystem/App.config diff --git a/AzureRedisCachingSystem/App.config b/AzureRedisCachingSystem/App.config new file mode 100644 index 0000000..24161a4 --- /dev/null +++ b/AzureRedisCachingSystem/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index be95fc2..7906cf1 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -72,36 +72,24 @@ /////////////////////////////////////// Write sample -RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); +//RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); -CacheValue bookCacheValue = new CacheValue() -{ - Value = 31697252, -}; +//CacheValue bookCacheValue = new CacheValue() { Value = 31 }; -CacheEntry bookCache = new CacheEntryConfigurer() - .SetKey("Salamqaqa") - .SetValue(bookCacheValue) - .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) - .BuildCacheEntry(); +//CacheEntry bookCache = new CacheEntryConfigurer() +// .SetKey("Salamqaqa") +// .SetValue(bookCacheValue) +// .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) +// .BuildCacheEntry(); -await writerAdapter.WriteToCache(bookCache); +//await writerAdapter.WriteToCache(bookCache); /////////////////////////////////////// Read sample // cc8687825c8a2556c011e8f6a77f81a0 -try -{ - RedisReader reader = new RedisReader(redisService,metricsService); - - CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); - - Console.WriteLine(responseValue.Value); -} -catch (Exception exception) -{ - Console.WriteLine(exception.Message); -} +RedisReader reader = new RedisReader(redisService, metricsService); +CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); +Console.WriteLine(responseValue.Value); \ No newline at end of file diff --git a/AzureRedisCachingSystem/Services/MetricsService.cs b/AzureRedisCachingSystem/Services/MetricsService.cs index fac2431..1ae56db 100644 --- a/AzureRedisCachingSystem/Services/MetricsService.cs +++ b/AzureRedisCachingSystem/Services/MetricsService.cs @@ -33,7 +33,11 @@ public async Task HandleCacheHit(string key) public async Task HandleCacheMiss(string key) { - return true; + var filter = Builders.Filter.Eq(m => m.Key, key); + + DeleteResult result = await context.Metrics.DeleteOneAsync(filter); + + return result.DeletedCount > 0; } public async Task RemoveMetrics() From 39750362705086143eb9bcb77e04f62af2a93787 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 11:30:32 +0400 Subject: [PATCH 14/22] Stage commit [] --- .../Adapters/RedisWriter/RedisWriter.cs | 15 +++++++++++-- AzureRedisCachingSystem/App.config | 2 +- AzureRedisCachingSystem/Program.cs | 22 +++++++++---------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index 39881b1..603262a 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -1,6 +1,7 @@ using AzureRedisCachingSystem.Cache.Entries; using AzureRedisCachingSystem.Cache.Metrics; using AzureRedisCachingSystem.Services.Abstract; +using System.Configuration; namespace AzureRedisCachingSystem.Adapters.RedisWriter; @@ -39,7 +40,17 @@ public async Task WriteToCache(CacheEntry entry) private async Task HandleKeyConflict(string key) { - if(await redisService.CheckKeyExist(key)) - throw new Exception("Value with given key is already existing.."); + string conflictBehaviour = ConfigurationManager.AppSettings["KeyConflictBehaviour"]; + int x = 0; + + if (conflictBehaviour == "none") + throw new Exception("Value realated with given key is already exists.. .Try providing another key."); + + else if (conflictBehaviour == "makeChanges") + while (await redisService.CheckKeyExist(key)) + key += x++.ToString(); + + else + throw new Exception("Unkown Conflict Behaviour error"); } } diff --git a/AzureRedisCachingSystem/App.config b/AzureRedisCachingSystem/App.config index 24161a4..72944a8 100644 --- a/AzureRedisCachingSystem/App.config +++ b/AzureRedisCachingSystem/App.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 7906cf1..97406e3 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -72,24 +72,24 @@ /////////////////////////////////////// Write sample -//RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); +RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); -//CacheValue bookCacheValue = new CacheValue() { Value = 31 }; +CacheValue bookCacheValue = new CacheValue() { Value = 31 }; -//CacheEntry bookCache = new CacheEntryConfigurer() -// .SetKey("Salamqaqa") -// .SetValue(bookCacheValue) -// .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) -// .BuildCacheEntry(); +CacheEntry bookCache = new CacheEntryConfigurer() + .SetKey("Salamqaqa") + .SetValue(bookCacheValue) + .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) + .BuildCacheEntry(); -//await writerAdapter.WriteToCache(bookCache); +await writerAdapter.WriteToCache(bookCache); /////////////////////////////////////// Read sample // cc8687825c8a2556c011e8f6a77f81a0 -RedisReader reader = new RedisReader(redisService, metricsService); +//RedisReader reader = new RedisReader(redisService, metricsService); -CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); +//CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); -Console.WriteLine(responseValue.Value); \ No newline at end of file +//Console.WriteLine(responseValue.Value); \ No newline at end of file From 4a4af2deda92b72eb65b2492f5402311ec4831a9 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 11:40:59 +0400 Subject: [PATCH 15/22] Changes on RedisWriter, bug fixed --- AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index 603262a..d40ba12 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -18,7 +18,7 @@ public RedisWriter(IRedisService redisService, IMetricsService metricsService) public async Task WriteToCache(CacheEntry entry) { - await HandleKeyConflict(entry.Key); + entry.Key = await HandleKeyConflict(entry.Key); bool writeResult = await redisService.WriteToRedis(entry); @@ -38,7 +38,7 @@ public async Task WriteToCache(CacheEntry entry) return writeResult; } - private async Task HandleKeyConflict(string key) + private async Task HandleKeyConflict(string key) { string conflictBehaviour = ConfigurationManager.AppSettings["KeyConflictBehaviour"]; int x = 0; @@ -52,5 +52,7 @@ private async Task HandleKeyConflict(string key) else throw new Exception("Unkown Conflict Behaviour error"); + + return key; } } From 1799100281764ded1ef6cc4639d9b45fb119ef65 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 11:48:23 +0400 Subject: [PATCH 16/22] Bugs fixed, progress for making code clean --- AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs | 3 ++- AzureRedisCachingSystem/App.config | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index d40ba12..4406fd5 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -18,7 +18,8 @@ public RedisWriter(IRedisService redisService, IMetricsService metricsService) public async Task WriteToCache(CacheEntry entry) { - entry.Key = await HandleKeyConflict(entry.Key); + if(await redisService.CheckKeyExist(entry.Key)) + entry.Key = await HandleKeyConflict(entry.Key); bool writeResult = await redisService.WriteToRedis(entry); diff --git a/AzureRedisCachingSystem/App.config b/AzureRedisCachingSystem/App.config index 72944a8..cf32728 100644 --- a/AzureRedisCachingSystem/App.config +++ b/AzureRedisCachingSystem/App.config @@ -1,6 +1,6 @@  - + \ No newline at end of file From fb2d6db2425b65b06d41cb197bf0f7bf72ada570 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 12:08:14 +0400 Subject: [PATCH 17/22] String bug fixed --- .../Adapters/RedisWriter/RedisWriter.cs | 7 ++++--- AzureRedisCachingSystem/AzureRedisCachingSystem.csproj | 2 -- .../Cache/Models/Enums/KeyConflictBehaviours.cs | 7 +++++++ AzureRedisCachingSystem/Data/MongoDbContext.cs | 1 - 4 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 AzureRedisCachingSystem/Cache/Models/Enums/KeyConflictBehaviours.cs diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index 4406fd5..c9242ef 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -1,5 +1,6 @@ using AzureRedisCachingSystem.Cache.Entries; using AzureRedisCachingSystem.Cache.Metrics; +using AzureRedisCachingSystem.Cache.Models.Enums; using AzureRedisCachingSystem.Services.Abstract; using System.Configuration; @@ -41,13 +42,13 @@ public async Task WriteToCache(CacheEntry entry) private async Task HandleKeyConflict(string key) { - string conflictBehaviour = ConfigurationManager.AppSettings["KeyConflictBehaviour"]; + string conflictBehaviour = ConfigurationManager.AppSettings["KeyConflictBehaviour"].ToLower(); int x = 0; - if (conflictBehaviour == "none") + if (conflictBehaviour == KeyConflictBehaviours.None.ToString().ToLower()) throw new Exception("Value realated with given key is already exists.. .Try providing another key."); - else if (conflictBehaviour == "makeChanges") + else if (conflictBehaviour == KeyConflictBehaviours.MakeChanges.ToString().ToLower()) while (await redisService.CheckKeyExist(key)) key += x++.ToString(); diff --git a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj index 7a413f2..80db486 100644 --- a/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj +++ b/AzureRedisCachingSystem/AzureRedisCachingSystem.csproj @@ -8,8 +8,6 @@ - - diff --git a/AzureRedisCachingSystem/Cache/Models/Enums/KeyConflictBehaviours.cs b/AzureRedisCachingSystem/Cache/Models/Enums/KeyConflictBehaviours.cs new file mode 100644 index 0000000..b75cc63 --- /dev/null +++ b/AzureRedisCachingSystem/Cache/Models/Enums/KeyConflictBehaviours.cs @@ -0,0 +1,7 @@ +namespace AzureRedisCachingSystem.Cache.Models.Enums; + +public enum KeyConflictBehaviours +{ + None = 0, + MakeChanges = 1, +} diff --git a/AzureRedisCachingSystem/Data/MongoDbContext.cs b/AzureRedisCachingSystem/Data/MongoDbContext.cs index f416650..e73d021 100644 --- a/AzureRedisCachingSystem/Data/MongoDbContext.cs +++ b/AzureRedisCachingSystem/Data/MongoDbContext.cs @@ -1,6 +1,5 @@ using AzureRedisCachingSystem.Cache.Metrics; using AzureRedisCachingSystem.Configurations; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using MongoDB.Driver; using Serilog; From 0395bcaf98231972ff53f8ae956991c828b11cc0 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 12:36:48 +0400 Subject: [PATCH 18/22] Stage Commit [] --- .../Adapters/RedisWriter/RedisWriter.cs | 5 +++-- AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs | 9 ++++++++- .../Services/Abstract/IMetricsService.cs | 2 +- AzureRedisCachingSystem/Services/MetricsService.cs | 10 ++++++++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index c9242ef..cd05cf4 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -24,7 +24,7 @@ public async Task WriteToCache(CacheEntry entry) bool writeResult = await redisService.WriteToRedis(entry); - if(writeResult) + if (writeResult) { CacheMetrics metrics = new CacheMetrics() { @@ -32,9 +32,10 @@ public async Task WriteToCache(CacheEntry entry) CacheHits = 1, CacheMisses = 0, LastAccessed = DateTime.UtcNow, + Id = Guid.NewGuid().ToString() }; - await metricsService.CraeteMetrics(metrics); + await metricsService.CreateMetrics(metrics); } return writeResult; diff --git a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs index cd79477..a28d423 100644 --- a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs +++ b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs @@ -1,7 +1,14 @@ -namespace AzureRedisCachingSystem.Cache.Metrics; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace AzureRedisCachingSystem.Cache.Metrics; public class CacheMetrics { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string Id { get; set; } + public string Key { get; set; } public int CacheHits { get; set; } public int CacheMisses { get; set; } diff --git a/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs b/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs index 9ef3881..3b17f3d 100644 --- a/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs +++ b/AzureRedisCachingSystem/Services/Abstract/IMetricsService.cs @@ -4,7 +4,7 @@ namespace AzureRedisCachingSystem.Services.Abstract; public interface IMetricsService { - Task CraeteMetrics(CacheMetrics metrics); + Task CreateMetrics(CacheMetrics metrics); Task HandleCacheHit(string key); Task HandleCacheMiss(string key); Task RemoveMetrics(); diff --git a/AzureRedisCachingSystem/Services/MetricsService.cs b/AzureRedisCachingSystem/Services/MetricsService.cs index 1ae56db..a2d2376 100644 --- a/AzureRedisCachingSystem/Services/MetricsService.cs +++ b/AzureRedisCachingSystem/Services/MetricsService.cs @@ -17,8 +17,14 @@ public MetricsService(MongoDbContext context) this.context = context; } - public async Task CraeteMetrics(CacheMetrics metrics) - => await context.Metrics.InsertOneAsync(metrics); + public async Task CreateMetrics(CacheMetrics metrics) + { + FilterDefinition filter = Builders.Filter.Eq(m => m.Key, metrics.Key); + CacheMetrics existingMetrics = await context.Metrics.Find(filter).FirstOrDefaultAsync(); + + if (existingMetrics == null) + await context.Metrics.InsertOneAsync(metrics); + } public async Task HandleCacheHit(string key) { From a0da4d08b4f267521cdec88150f0c76a236d9e41 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 12:47:20 +0400 Subject: [PATCH 19/22] Stage Commit [] Bugs existing --- .../Adapters/RedisWriter/RedisWriter.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index cd05cf4..276d17b 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -32,7 +32,7 @@ public async Task WriteToCache(CacheEntry entry) CacheHits = 1, CacheMisses = 0, LastAccessed = DateTime.UtcNow, - Id = Guid.NewGuid().ToString() + Id = Generate24CharacterId() }; await metricsService.CreateMetrics(metrics); @@ -52,10 +52,24 @@ private async Task HandleKeyConflict(string key) else if (conflictBehaviour == KeyConflictBehaviours.MakeChanges.ToString().ToLower()) while (await redisService.CheckKeyExist(key)) key += x++.ToString(); - else throw new Exception("Unkown Conflict Behaviour error"); return key; } + + + #region Helper Methods + private string Generate24CharacterId() + { + Guid guid = Guid.NewGuid(); + string base64Guid = Convert.ToBase64String(guid.ToByteArray()) + .Replace("=", "") + .Replace("+", "") + .Replace("/", "") + .Substring(0, 22); + + return base64Guid.PadRight(24, '0'); + } + #endregion } From 84e7084e72107a1249a1bf7e00627b59006b6c65 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 12:51:23 +0400 Subject: [PATCH 20/22] object id error fixed with mongo id generator --- .../Adapters/RedisWriter/RedisWriter.cs | 16 ---------------- .../Cache/Metrics/CacheMetrics.cs | 11 +++++++++++ 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index 276d17b..842f878 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -32,7 +32,6 @@ public async Task WriteToCache(CacheEntry entry) CacheHits = 1, CacheMisses = 0, LastAccessed = DateTime.UtcNow, - Id = Generate24CharacterId() }; await metricsService.CreateMetrics(metrics); @@ -57,19 +56,4 @@ private async Task HandleKeyConflict(string key) return key; } - - - #region Helper Methods - private string Generate24CharacterId() - { - Guid guid = Guid.NewGuid(); - string base64Guid = Convert.ToBase64String(guid.ToByteArray()) - .Replace("=", "") - .Replace("+", "") - .Replace("/", "") - .Substring(0, 22); - - return base64Guid.PadRight(24, '0'); - } - #endregion } diff --git a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs index a28d423..6b18666 100644 --- a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs +++ b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs @@ -1,4 +1,5 @@ using MongoDB.Bson; +using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Attributes; namespace AzureRedisCachingSystem.Cache.Metrics; @@ -13,4 +14,14 @@ public class CacheMetrics public int CacheHits { get; set; } public int CacheMisses { get; set; } public DateTime LastAccessed { get; set; } + + public CacheMetrics() + { + BsonClassMap.RegisterClassMap(cm => + { + cm.AutoMap(); + cm.SetIgnoreExtraElements(true); + + }); + } } From 1ed8d010814cbc6a2a9abcbf95c046bf04965659 Mon Sep 17 00:00:00 2001 From: novru Date: Thu, 8 Aug 2024 14:24:26 +0400 Subject: [PATCH 21/22] Finish --- .../Adapters/RedisWriter/RedisWriter.cs | 2 +- .../Cache/Metrics/CacheMetrics.cs | 3 +-- AzureRedisCachingSystem/Program.cs | 22 +++++++++---------- .../Services/MetricsService.cs | 2 +- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs index 842f878..c911bb8 100644 --- a/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs +++ b/AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs @@ -31,7 +31,7 @@ public async Task WriteToCache(CacheEntry entry) Key = entry.Key, CacheHits = 1, CacheMisses = 0, - LastAccessed = DateTime.UtcNow, + LastAccessed = DateTime.UtcNow.ToShortTimeString(), }; await metricsService.CreateMetrics(metrics); diff --git a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs index 6b18666..8809fc0 100644 --- a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs +++ b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs @@ -13,7 +13,7 @@ public class CacheMetrics public string Key { get; set; } public int CacheHits { get; set; } public int CacheMisses { get; set; } - public DateTime LastAccessed { get; set; } + public string LastAccessed { get; set; } public CacheMetrics() { @@ -21,7 +21,6 @@ public CacheMetrics() { cm.AutoMap(); cm.SetIgnoreExtraElements(true); - }); } } diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 97406e3..7906cf1 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -72,24 +72,24 @@ /////////////////////////////////////// Write sample -RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); +//RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); -CacheValue bookCacheValue = new CacheValue() { Value = 31 }; +//CacheValue bookCacheValue = new CacheValue() { Value = 31 }; -CacheEntry bookCache = new CacheEntryConfigurer() - .SetKey("Salamqaqa") - .SetValue(bookCacheValue) - .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) - .BuildCacheEntry(); +//CacheEntry bookCache = new CacheEntryConfigurer() +// .SetKey("Salamqaqa") +// .SetValue(bookCacheValue) +// .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) +// .BuildCacheEntry(); -await writerAdapter.WriteToCache(bookCache); +//await writerAdapter.WriteToCache(bookCache); /////////////////////////////////////// Read sample // cc8687825c8a2556c011e8f6a77f81a0 -//RedisReader reader = new RedisReader(redisService, metricsService); +RedisReader reader = new RedisReader(redisService, metricsService); -//CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); +CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); -//Console.WriteLine(responseValue.Value); \ No newline at end of file +Console.WriteLine(responseValue.Value); \ No newline at end of file diff --git a/AzureRedisCachingSystem/Services/MetricsService.cs b/AzureRedisCachingSystem/Services/MetricsService.cs index a2d2376..966b5dd 100644 --- a/AzureRedisCachingSystem/Services/MetricsService.cs +++ b/AzureRedisCachingSystem/Services/MetricsService.cs @@ -30,7 +30,7 @@ public async Task HandleCacheHit(string key) { var filter = Builders.Filter.Eq(m => m.Key, key); var update = Builders.Update.Inc(m => m.CacheHits, 1) - .Set(m => m.LastAccessed, DateTime.UtcNow); + .Set(m => m.LastAccessed, DateTime.UtcNow.ToShortTimeString()); var result = await context.Metrics.UpdateOneAsync(filter, update); From bf6b08fbf3799613745535b991c704decf058e73 Mon Sep 17 00:00:00 2001 From: novru Date: Fri, 9 Aug 2024 10:45:14 +0400 Subject: [PATCH 22/22] Testings, all working --- .../Cache/Metrics/CacheMetrics.cs | 15 ++++++++---- AzureRedisCachingSystem/Program.cs | 24 +++++++++---------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs index 8809fc0..ebfff94 100644 --- a/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs +++ b/AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs @@ -7,15 +7,15 @@ namespace AzureRedisCachingSystem.Cache.Metrics; public class CacheMetrics { [BsonId] - [BsonRepresentation(BsonType.ObjectId)] + [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; } public string Key { get; set; } - public int CacheHits { get; set; } - public int CacheMisses { get; set; } - public string LastAccessed { get; set; } + public int CacheHits { get; set; } + public int CacheMisses { get; set; } + public string LastAccessed { get; set; } - public CacheMetrics() + static CacheMetrics() { BsonClassMap.RegisterClassMap(cm => { @@ -23,4 +23,9 @@ public CacheMetrics() cm.SetIgnoreExtraElements(true); }); } + + public CacheMetrics() + { + + } } diff --git a/AzureRedisCachingSystem/Program.cs b/AzureRedisCachingSystem/Program.cs index 7906cf1..e613972 100644 --- a/AzureRedisCachingSystem/Program.cs +++ b/AzureRedisCachingSystem/Program.cs @@ -72,24 +72,24 @@ /////////////////////////////////////// Write sample -//RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); +RedisWriter writerAdapter = new RedisWriter(redisService, metricsService); -//CacheValue bookCacheValue = new CacheValue() { Value = 31 }; +CacheValue bookCacheValue = new CacheValue() { Value = 31 }; -//CacheEntry bookCache = new CacheEntryConfigurer() -// .SetKey("Salamqaqa") -// .SetValue(bookCacheValue) -// .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) -// .BuildCacheEntry(); - -//await writerAdapter.WriteToCache(bookCache); +CacheEntry bookCache = new CacheEntryConfigurer() + .SetKey("Salamqaqa") + .SetValue(bookCacheValue) + .SetExpire(DateTimeOffset.UtcNow.AddHours(1)) + .BuildCacheEntry(); + +await writerAdapter.WriteToCache(bookCache); /////////////////////////////////////// Read sample // cc8687825c8a2556c011e8f6a77f81a0 -RedisReader reader = new RedisReader(redisService, metricsService); +//RedisReader reader = new RedisReader(redisService, metricsService); -CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); +//CacheValue responseValue = await reader.ReadFromCacheAsync("Salamqaqa"); -Console.WriteLine(responseValue.Value); \ No newline at end of file +//Console.WriteLine(responseValue.Value); \ No newline at end of file