Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Went back to old commit. :*( #1

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions AzureRedisCachingSystem/Adapters/RedisReader/RedisReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using AzureRedisCachingSystem.Cache.CustomValues;
using AzureRedisCachingSystem.HelperServices.UniqueKey;
using AzureRedisCachingSystem.Services.Abstract;
using Newtonsoft.Json;
using StackExchange.Redis;

namespace AzureRedisCachingSystem.Adapters.RedisReader;

public class RedisReader
{
private readonly IRedisService redisService;
private readonly IMetricsService metricsService;

public RedisReader(IRedisService redisService, IMetricsService metricsService)
{
this.redisService = redisService;
this.metricsService = metricsService;
}

public async Task<CacheValue> 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<CacheValue>(responseValue);

if (cacheValue == null)
throw new Exception("Error occurred while casting type");

await metricsService.HandleCacheHit(key);

return cacheValue;
}

public async Task<CacheValue> ReadFromCacheViaParametersAsync(object parameter)
{
string key = string.Empty;

UniqueKeyService.GenerateUniqueKeyViaParams(ref key, parameter);

return await ReadFromCacheAsync(key);
}
}
59 changes: 59 additions & 0 deletions AzureRedisCachingSystem/Adapters/RedisWriter/RedisWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using AzureRedisCachingSystem.Cache.Entries;
using AzureRedisCachingSystem.Cache.Metrics;
using AzureRedisCachingSystem.Cache.Models.Enums;
using AzureRedisCachingSystem.Services.Abstract;
using System.Configuration;

namespace AzureRedisCachingSystem.Adapters.RedisWriter;

public class RedisWriter
{
private readonly IRedisService redisService;
private readonly IMetricsService metricsService;

public RedisWriter(IRedisService redisService, IMetricsService metricsService)
{
this.redisService = redisService;
this.metricsService = metricsService;
}

public async Task<bool> WriteToCache(CacheEntry entry)
{
if(await redisService.CheckKeyExist(entry.Key))
entry.Key = await HandleKeyConflict(entry.Key);

bool writeResult = await redisService.WriteToRedis(entry);

if (writeResult)
{
CacheMetrics metrics = new CacheMetrics()
{
Key = entry.Key,
CacheHits = 1,
CacheMisses = 0,
LastAccessed = DateTime.UtcNow.ToShortTimeString(),
};

await metricsService.CreateMetrics(metrics);
}

return writeResult;
}

private async Task<string> HandleKeyConflict(string key)
{
string conflictBehaviour = ConfigurationManager.AppSettings["KeyConflictBehaviour"].ToLower();
int x = 0;

if (conflictBehaviour == KeyConflictBehaviours.None.ToString().ToLower())
throw new Exception("Value realated with given key is already exists.. .Try providing another 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;
}
}
6 changes: 6 additions & 0 deletions AzureRedisCachingSystem/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="KeyConflictBehaviour" value="none"/>
</appSettings>
</configuration>
9 changes: 9 additions & 0 deletions AzureRedisCachingSystem/ApplicationModels/Book.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
4 changes: 2 additions & 2 deletions AzureRedisCachingSystem/AzureRedisCachingSystem.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Cosmos" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="MongoDB.Driver" Version="2.28.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
Expand Down
6 changes: 6 additions & 0 deletions AzureRedisCachingSystem/Cache/CustomValues/CacheValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace AzureRedisCachingSystem.Cache.CustomValues;

public class CacheValue
{
public object Value { get; set; }
}
11 changes: 11 additions & 0 deletions AzureRedisCachingSystem/Cache/Entries/CacheEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using AzureRedisCachingSystem.Cache.CustomValues;

namespace AzureRedisCachingSystem.Cache.Entries;

public class CacheEntry
{
public string Key { get; set; }
public CacheValue Value { get; set; }
public DateTime BuildDate { get; set; }
public DateTimeOffset Expire { get; set; }
}
31 changes: 31 additions & 0 deletions AzureRedisCachingSystem/Cache/Metrics/CacheMetrics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
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; }
public string LastAccessed { get; set; }

static CacheMetrics()
{
BsonClassMap.RegisterClassMap<CacheMetrics>(cm =>
{
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
}

public CacheMetrics()
{

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace AzureRedisCachingSystem.Cache.Models.Enums;

public enum KeyConflictBehaviours
{
None = 0,
MakeChanges = 1,
}
84 changes: 84 additions & 0 deletions AzureRedisCachingSystem/Cache/Settings/CacheEntryConfigurer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using AzureRedisCachingSystem.Cache.CustomValues;
using AzureRedisCachingSystem.Cache.Entries;
using AzureRedisCachingSystem.HelperServices.Hash;
using AzureRedisCachingSystem.HelperServices.UniqueKey;

namespace AzureRedisCachingSystem.Cache.Settings;

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)
{
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;
}

public CacheEntryConfigurer SetExpire(DateTimeOffset expire)
{
this.expire = expire;

return this;
}

public CacheEntry BuildCacheEntry()
{
if(!CheckIfSettingsIsConfigured())
{
throw new Exception("Once configure settings before build.");
}

HashIfNeeded();

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;
}

private void HashIfNeeded()
{
if (key.Length > 32)
{
HashService.HashString(ref key);
}
}
#endregion
}
9 changes: 0 additions & 9 deletions AzureRedisCachingSystem/Configurations/CosmosConfig.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace AzureRedisCachingSystem.Configurations;

public class MongoDbConfiguration
{
public string ConnectionString { get; set; }
public string DatabaseName { get; set; }
}
34 changes: 0 additions & 34 deletions AzureRedisCachingSystem/Data/AppDbContext.cs

This file was deleted.

21 changes: 21 additions & 0 deletions AzureRedisCachingSystem/Data/MongoDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using AzureRedisCachingSystem.Cache.Metrics;
using AzureRedisCachingSystem.Configurations;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using Serilog;

namespace AzureRedisCachingSystem.Data;

public class MongoDbContext
{
private readonly IMongoDatabase _database;

public MongoDbContext(IOptions<MongoDbConfiguration> settings)
{
MongoClient client = new MongoClient(settings.Value.ConnectionString);

_database = client.GetDatabase(settings.Value.DatabaseName);
}

public IMongoCollection<CacheMetrics> Metrics => _database.GetCollection<CacheMetrics>("metrics");
}
26 changes: 26 additions & 0 deletions AzureRedisCachingSystem/HelperServices/Hash/HashService.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
Loading