diff --git a/WotBlitzStatisticsPro.Blazor/graphql/schema.graphql b/WotBlitzStatisticsPro.Blazor/graphql/schema.graphql
index 7ad93a5..7d2573b 100644
--- a/WotBlitzStatisticsPro.Blazor/graphql/schema.graphql
+++ b/WotBlitzStatisticsPro.Blazor/graphql/schema.graphql
@@ -24,7 +24,7 @@ type Mutation {
"Updates the necessary dictionaries in database.\n\n\n**Returns:**\nInformation about what was updated."
updateDictionaries("Determines what dictionaries should be updated." updateDictionariesRequest: UpdateDictionariesRequestInput!): [UpdateDictionariesResponseItem!]!
"Gathers all account information"
- gatherAccountInformation("Account region" realmType: RealmType! "AccountId" accountId: Long! "Request language" requestLanguage: RequestLanguage!): AccountInfoResponse!
+ gatherAccountInformation("Account region" realmType: RealmType! "AccountId" accountId: Long! "Request language" requestLanguage: RequestLanguage!): DateTime!
"This method accepts GitHub oauth code, and returns JWT token with GutHub user as claim"
gitHubAuthenticate("OAuth code can be generated by this URL https:\/\/github.com\/login\/oauth\/authorize?client_id={yourClientId}" oauthCode: String!): String!
}
diff --git a/WotBlitzStatisticsPro.GraphQl/Mutation/WotBlitzStatisticsMutation.cs b/WotBlitzStatisticsPro.GraphQl/Mutation/WotBlitzStatisticsMutation.cs
index 645e8d7..15e9b19 100644
--- a/WotBlitzStatisticsPro.GraphQl/Mutation/WotBlitzStatisticsMutation.cs
+++ b/WotBlitzStatisticsPro.GraphQl/Mutation/WotBlitzStatisticsMutation.cs
@@ -1,4 +1,5 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
using HotChocolate;
using HotChocolate.AspNetCore.Authorization;
using HotChocolate.Types;
@@ -43,7 +44,7 @@ namespace WotBlitzStatisticsPro.GraphQl.Mutation
/// Request language
/// Wargaming authentication token
///
- public Task GatherAccountInformation(
+ public Task GatherAccountInformation(
RealmType realmType,
long accountId,
RequestLanguage requestLanguage,
diff --git a/WotBlitzStatisticsPro.GraphQl/Program.cs b/WotBlitzStatisticsPro.GraphQl/Program.cs
index 5548266..afeeb1b 100644
--- a/WotBlitzStatisticsPro.GraphQl/Program.cs
+++ b/WotBlitzStatisticsPro.GraphQl/Program.cs
@@ -1,5 +1,9 @@
+using System;
+using System.IO;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
+using Serilog;
namespace WotBlitzStatisticsPro.GraphQl
{
@@ -7,12 +11,36 @@ namespace WotBlitzStatisticsPro.GraphQl
{
public static void Main(string[] args)
{
- CreateHostBuilder(args).Build().Run();
+ var configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json")
+ .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
+ .AddEnvironmentVariables()
+ .Build();
+
+ Log.Logger = new LoggerConfiguration()
+ .ReadFrom.Configuration(configuration)
+ .CreateLogger();
+
+ try
+ {
+ Log.Information("Starting web host");
+ CreateHostBuilder(args).Build().Run();
+ }
+ catch (Exception ex)
+ {
+ Log.Fatal(ex, "Host terminated unexpectedly");
+ }
+ finally
+ {
+ Log.CloseAndFlush();
+ }
}
- public static IHostBuilder CreateHostBuilder(string[] args) =>
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
+ .UseSerilog()
+ .ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
diff --git a/WotBlitzStatisticsPro.GraphQl/Query/WotBlitzStatisticsQuery.cs b/WotBlitzStatisticsPro.GraphQl/Query/WotBlitzStatisticsQuery.cs
index e2f5bc3..3dcc365 100644
--- a/WotBlitzStatisticsPro.GraphQl/Query/WotBlitzStatisticsQuery.cs
+++ b/WotBlitzStatisticsPro.GraphQl/Query/WotBlitzStatisticsQuery.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using HotChocolate.Types;
+using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.Logic;
diff --git a/WotBlitzStatisticsPro.GraphQl/Startup.cs b/WotBlitzStatisticsPro.GraphQl/Startup.cs
index b6622fa..b1731c9 100644
--- a/WotBlitzStatisticsPro.GraphQl/Startup.cs
+++ b/WotBlitzStatisticsPro.GraphQl/Startup.cs
@@ -14,6 +14,7 @@ using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
+using Serilog;
using WotBlitzStatisticsPro.Common;
using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.GraphQl.GitHubOauth;
@@ -37,7 +38,10 @@ namespace WotBlitzStatisticsPro.GraphQl
public void ConfigureServices(IServiceCollection services)
{
- var wgApiConfig = new WargamingApiSettings();
+ //services.AddLogging(loggingBuilder =>
+ // loggingBuilder.AddSerilog(dispose: true));
+
+ var wgApiConfig = new WargamingApiSettings();
Configuration.GetSection("WargamingApi").Bind(wgApiConfig);
var mongoConfig = new MongoSettings();
diff --git a/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj b/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj
index 8b0f42b..4663a2c 100644
--- a/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj
+++ b/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj
@@ -17,6 +17,7 @@
+
diff --git a/WotBlitzStatisticsPro.GraphQl/appsettings.Development.json b/WotBlitzStatisticsPro.GraphQl/appsettings.Development.json
index 8983e0f..d5a3436 100644
--- a/WotBlitzStatisticsPro.GraphQl/appsettings.Development.json
+++ b/WotBlitzStatisticsPro.GraphQl/appsettings.Development.json
@@ -1,9 +1,25 @@
{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "Serilog": {
+ "Using": [ "Serilog.Sinks.Console" ],
+ "MinimumLevel": {
+ "Default": "Debug",
+ "Override": {
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information",
+ "System": "Warning"
+ }
+
+ },
+ "WriteTo": [
+ { "Name": "Console" }
+ ],
+ "Enrich": [ "FromLogContext" ]
}
- }
}
diff --git a/WotBlitzStatisticsPro.GraphQl/appsettings.Production.json b/WotBlitzStatisticsPro.GraphQl/appsettings.Production.json
new file mode 100644
index 0000000..1d1fae0
--- /dev/null
+++ b/WotBlitzStatisticsPro.GraphQl/appsettings.Production.json
@@ -0,0 +1,17 @@
+{
+ "Serilog": {
+ "Using": [ "Serilog.Sinks.Console" ],
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information",
+ "System": "Warning"
+ }
+ },
+ "WriteTo": [
+ { "Name": "Console" }
+ ],
+ "Enrich": [ "FromLogContext" ]
+ }
+}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.GraphQl/appsettings.json b/WotBlitzStatisticsPro.GraphQl/appsettings.json
index ad559c2..59cb4b7 100644
--- a/WotBlitzStatisticsPro.GraphQl/appsettings.json
+++ b/WotBlitzStatisticsPro.GraphQl/appsettings.json
@@ -14,9 +14,30 @@
"Mongo": {
"ConnectionString": "*",
"DatabaseName": "*"
- },
+ },
"GitHubOAuth": {
"ClientId": "YourClientId",
- "ClientSecret": "YourSecret"
- }
-}
+ "ClientSecret": "YourSecret"
+ },
+ "Serilog": {
+ "Using": [ "Serilog.Sinks.Console" ],
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information",
+ "System": "Warning"
+ }
+ },
+ "WriteTo": [
+ {
+ "Name": "Console",
+ "Args": {
+ "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
+ "outputTemplate": "{Timestamp:HH:mm:ss.fff} [{Level:u3}] {Message:lj} |{SourceContext}|{NewLine}{Exception}"
+ }
+ }
+ ],
+ "Enrich": [ "FromLogContext" ]
+ }
+}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs
index 65601ff..f0aa607 100644
--- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs
+++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs
@@ -4,6 +4,7 @@ using AutoMapper;
using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.DataAccess.Model.Accounts;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
+using WotBlitzStatisticsPro.Logic.Model;
using WotBlitzStatisticsPro.Logic.Pipeline;
using WotBlitzStatisticsPro.WgApiClient;
using WotBlitzStatisticsPro.WgApiClient.Model;
@@ -15,19 +16,36 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
private readonly IWargamingApiClient _wargamingApi;
private readonly IMapper _mapper;
private readonly ILogger _logger;
+ private readonly StatisticsCache _cache;
public GetAccountInfoOperation(
IWargamingApiClient wargamingApi,
IMapper mapper,
- ILogger logger)
+ ILogger logger,
+ StatisticsCache cache)
{
_wargamingApi = wargamingApi;
_mapper = mapper;
_logger = logger;
+ _cache = cache;
}
public async Task Invoke(IOperationContext context, Func? next)
{
+ // Store info to AccountInfo and in AccountInfoHistory
+ var contextData = context.Get();
+
+ var cache = _cache.GetAccountData(context.Request.AccountId);
+ if (cache != null)
+ {
+ contextData.AccountInfo = cache.AccountInfo;
+ contextData.AccountInfoHistory = cache.AccountInfoHistory;
+ _logger.LogInformation($"Account data for account {context.Request.AccountId} got from cache");
+
+ if (next != null) await next.Invoke(context);
+ return;
+ }
+
var accountInfo = await
_wargamingApi.GetPlayerAccountInfo(context.Request.AccountId, context.Request.RealmType, context.Request.RequestLanguage, context.Request.AuthenticationToken);
@@ -38,14 +56,14 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
return;
}
- // Store info to AccountInfo and in AccountInfoHistory
- var contextData = context.Get();
contextData.AccountInfo = _mapper.Map(accountInfo);
contextData.AccountInfo.Realm = context.Request.RealmType;
contextData.AccountInfoHistory = new AccountInfoHistory(context.Request.AccountId, contextData.AccountInfo.LastBattleTime);
_mapper.Map(accountInfo.Statistics?.All, contextData.AccountInfoHistory);
+ _cache.SetAccountData(context.Request.AccountId, new AccountDataCache(contextData.AccountInfo, contextData.AccountInfoHistory));
+
if (next != null) await next.Invoke(context);
}
}
diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs
index ccb1851..86fd343 100644
--- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs
+++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs
@@ -6,6 +6,7 @@ using AutoMapper;
using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.DataAccess.Model.Accounts;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
+using WotBlitzStatisticsPro.Logic.Model;
using WotBlitzStatisticsPro.Logic.Pipeline;
using WotBlitzStatisticsPro.WgApiClient;
@@ -16,21 +17,36 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
private readonly IWargamingTanksApiClient _wargamingApi;
private readonly IMapper _mapper;
private readonly ILogger _logger;
+ private readonly StatisticsCache _cache;
public GetTanksInfoOperation(
IWargamingTanksApiClient wargamingApi,
IMapper mapper,
- ILogger logger)
+ ILogger logger,
+ StatisticsCache cache)
{
_wargamingApi = wargamingApi;
_mapper = mapper;
_logger = logger;
+ _cache = cache;
}
public async Task Invoke(IOperationContext context, Func? next)
{
var contextData = context.Get();
+ var cache = _cache.GetTanksData(context.Request.AccountId);
+ if (cache != null)
+ {
+ contextData.Tanks = cache.TankInfo;
+ contextData.TanksHistory = cache.TankInfoHistory;
+ _logger.LogInformation($"Account tanks data for account {context.Request.AccountId} got from cache");
+
+ if (next != null) await next.Invoke(context);
+ return;
+ }
+
+
var tanksInfo = await
_wargamingApi.GetPlayerAccountTanksInfo(context.Request.AccountId, context.Request.RealmType, context.Request.RequestLanguage);
@@ -54,6 +70,8 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
contextData.TanksHistory[stat.TankId] = stat;
});
+ _cache.SetTanksData(context.Request.AccountId, new TanksDataCache(contextData.Tanks, contextData.TanksHistory));
+
if (next != null) await next.Invoke(context);
}
}
diff --git a/WotBlitzStatisticsPro.Logic/IWargamingAccounts.cs b/WotBlitzStatisticsPro.Logic/IWargamingAccounts.cs
index 8c57f63..4bf0b67 100644
--- a/WotBlitzStatisticsPro.Logic/IWargamingAccounts.cs
+++ b/WotBlitzStatisticsPro.Logic/IWargamingAccounts.cs
@@ -8,7 +8,7 @@ namespace WotBlitzStatisticsPro.Logic
{
Task GatherAccountInformation(RealmType realm, long accountId, RequestLanguage requestLanguage);
- Task GatherAndSaveAccountInformation(RealmType realm, long accountId, RequestLanguage requestLanguage, string wargamingToken);
+ Task GatherAndSaveAccountInformation(RealmType realm, long accountId, RequestLanguage requestLanguage, string wargamingToken);
Task GetAccountInfoHistory(RealmType realm, long accountId, DateTime startDate,
RequestLanguage requestLanguage);
diff --git a/WotBlitzStatisticsPro.Logic/Model/AccountDataCache.cs b/WotBlitzStatisticsPro.Logic/Model/AccountDataCache.cs
new file mode 100644
index 0000000..593383f
--- /dev/null
+++ b/WotBlitzStatisticsPro.Logic/Model/AccountDataCache.cs
@@ -0,0 +1,17 @@
+using WotBlitzStatisticsPro.DataAccess.Model.Accounts;
+
+namespace WotBlitzStatisticsPro.Logic.Model
+{
+ public class AccountDataCache
+ {
+ public AccountDataCache(AccountInfo accountInfo, AccountInfoHistory accountInfoHistory)
+ {
+ AccountInfo = accountInfo;
+ AccountInfoHistory = accountInfoHistory;
+ }
+
+ public AccountInfo AccountInfo { get; }
+
+ public AccountInfoHistory AccountInfoHistory { get; }
+ }
+}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Logic/Model/CacheItem.cs b/WotBlitzStatisticsPro.Logic/Model/CacheItem.cs
new file mode 100644
index 0000000..01e35ee
--- /dev/null
+++ b/WotBlitzStatisticsPro.Logic/Model/CacheItem.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace WotBlitzStatisticsPro.Logic.Model
+{
+ public class CacheItem
+ {
+ private const int ExpirationTimeoutInMinutes = 60;
+ private DateTime? _lastRefreshed = null;
+
+ private T? _itemData = default(T);
+
+ public long AccountId { get; set; }
+
+ public bool IsExpired => _lastRefreshed != null &&
+ (DateTime.Now - _lastRefreshed.Value).TotalMinutes > ExpirationTimeoutInMinutes;
+
+ public T? Data
+ {
+ get => _itemData;
+ set
+ {
+ _itemData = value;
+ _lastRefreshed = DateTime.Now;
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Logic/Model/StatisticsCache.cs b/WotBlitzStatisticsPro.Logic/Model/StatisticsCache.cs
new file mode 100644
index 0000000..634e781
--- /dev/null
+++ b/WotBlitzStatisticsPro.Logic/Model/StatisticsCache.cs
@@ -0,0 +1,84 @@
+using System.Collections.Generic;
+
+namespace WotBlitzStatisticsPro.Logic.Model
+{
+ public class StatisticsCache
+ {
+ private readonly Dictionary> _accountsCache = new();
+ private readonly Dictionary> _tanksCache = new();
+
+ public AccountDataCache? GetAccountData(long accountId)
+ {
+ if (!_accountsCache.ContainsKey(accountId) || _accountsCache[accountId].IsExpired)
+ {
+ return null;
+ }
+
+ return _accountsCache[accountId].Data;
+ }
+
+ public TanksDataCache? GetTanksData(long accountId)
+ {
+ if (!_tanksCache.ContainsKey(accountId) || _tanksCache[accountId].IsExpired)
+ {
+ return null;
+ }
+
+ return _tanksCache[accountId].Data;
+ }
+
+ public void SetAccountData(long accountId, AccountDataCache data)
+ {
+ if (!_accountsCache.ContainsKey(accountId))
+ {
+ _accountsCache.Add(accountId, new CacheItem());
+ ClearExpiredAccounts();
+ }
+ _accountsCache[accountId].Data = data;
+ }
+
+ public void SetTanksData(long accountId, TanksDataCache data)
+ {
+ if (!_tanksCache.ContainsKey(accountId))
+ {
+ _tanksCache.Add(accountId, new CacheItem());
+ ClearExpiredTanks();
+ }
+ _tanksCache[accountId].Data = data;
+ }
+
+ private void ClearExpiredAccounts()
+ {
+ var expired = new List();
+ foreach (var cacheItem in _accountsCache)
+ {
+ if (cacheItem.Value.IsExpired)
+ {
+ expired.Add(cacheItem.Key);
+ }
+ }
+
+ foreach (var expiredKey in expired)
+ {
+ _accountsCache.Remove(expiredKey);
+ }
+ }
+
+ private void ClearExpiredTanks()
+ {
+ var expired = new List();
+ foreach (var cacheItem in _tanksCache)
+ {
+ if (cacheItem.Value.IsExpired)
+ {
+ expired.Add(cacheItem.Key);
+ }
+ }
+
+ foreach (var expiredKey in expired)
+ {
+ _accountsCache.Remove(expiredKey);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Logic/Model/TanksDataCache.cs b/WotBlitzStatisticsPro.Logic/Model/TanksDataCache.cs
new file mode 100644
index 0000000..d419a32
--- /dev/null
+++ b/WotBlitzStatisticsPro.Logic/Model/TanksDataCache.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using WotBlitzStatisticsPro.DataAccess.Model.Accounts;
+
+namespace WotBlitzStatisticsPro.Logic.Model
+{
+ public class TanksDataCache
+ {
+ public TanksDataCache(List tankInfo, Dictionary tankInfoHistory)
+ {
+ TankInfo = tankInfo;
+ TankInfoHistory = tankInfoHistory;
+ }
+
+ public List TankInfo { get; }
+
+ public Dictionary TankInfoHistory { get; }
+ }
+}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs b/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs
index 0421b1e..26ee05e 100644
--- a/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs
+++ b/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs
@@ -5,6 +5,7 @@ using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations;
+using WotBlitzStatisticsPro.Logic.Calculations;
using WotBlitzStatisticsPro.Logic.Pipeline;
namespace WotBlitzStatisticsPro.Logic
@@ -58,7 +59,7 @@ namespace WotBlitzStatisticsPro.Logic
return contextData?.Response ?? new AccountInfoResponse();
}
- public async Task GatherAndSaveAccountInformation(
+ public async Task GatherAndSaveAccountInformation(
RealmType realm,
long accountId,
RequestLanguage requestLanguage,
@@ -78,7 +79,6 @@ namespace WotBlitzStatisticsPro.Logic
.AddOperation()
.AddOperation()
.AddOperation()
- .AddOperation()
;
var firstOperation = pipeline.Build();
@@ -95,7 +95,7 @@ namespace WotBlitzStatisticsPro.Logic
throw;
}
- return contextData?.Response ?? new AccountInfoResponse();
+ return contextData?.AccountInfo?.LastBattleTime.ToDateTime() ?? new DateTime(1970,1,1);
}
public async Task GetAccountInfoHistory(RealmType realm, long accountId, DateTime startDate, RequestLanguage requestLanguage)
diff --git a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs
index 915eefb..dee84f1 100644
--- a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs
+++ b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs
@@ -7,6 +7,7 @@ using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.DataAccess;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations;
using WotBlitzStatisticsPro.Logic.Dictionaries;
+using WotBlitzStatisticsPro.Logic.Model;
using WotBlitzStatisticsPro.Logic.Pipeline;
using WotBlitzStatisticsPro.WgApiClient;
@@ -19,6 +20,7 @@ namespace WotBlitzStatisticsPro.Logic
public static void ConfigureServices(IServiceCollection services)
{
+ services.AddSingleton();
ConfigureDictionariesFactory(services);
ConfigureOperationsFactory(services);
WotBlitzStatisticsDataAccessInstaller.ConfigureServices(services);
diff --git a/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetAccountInfoOperationTest.cs b/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetAccountInfoOperationTest.cs
index ba9f1a6..35b9805 100644
--- a/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetAccountInfoOperationTest.cs
+++ b/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetAccountInfoOperationTest.cs
@@ -9,6 +9,7 @@ using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations;
+using WotBlitzStatisticsPro.Logic.Model;
namespace WotBlitzStatisticsPro.Tests.OperationStepsTests
{
@@ -17,16 +18,19 @@ namespace WotBlitzStatisticsPro.Tests.OperationStepsTests
{
private GetAccountInfoOperation _operation;
private AccountInformationPipelineContextData _contextData;
+ private StatisticsCache _cache;
[SetUp]
public void Init()
{
InitAutoMapper();
InitWgApiClient();
+ _cache = new StatisticsCache();
_operation = new GetAccountInfoOperation(
WargamingApiClient,
Mapper,
- (new Mock>()).Object);
+ (new Mock>()).Object,
+ _cache);
_contextData = new AccountInformationPipelineContextData();
}
@@ -51,6 +55,21 @@ namespace WotBlitzStatisticsPro.Tests.OperationStepsTests
var expectedAccountInfoHistory =
await File.ReadAllTextAsync(GetFixturePath("MappedAccountHistory.json"));
accountInfoHistorySerialized.Should().Be(expectedAccountInfoHistory);
+
+ // ToDo: Check cache
+ Assert.Fail("Implement test");
+ }
+
+ [Test]
+ public async Task ShouldGetAndSaveAccountInfoInformationIfCacheExpired()
+ {
+ Assert.Fail("Implement test");
+ }
+
+ [Test]
+ public async Task ShouldReadDataFromCacheIfItIsNotEmpty()
+ {
+ Assert.Fail("Implement test");
}
}
}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetTanksInfoOperationTest.cs b/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetTanksInfoOperationTest.cs
index 3d6d7e1..54c7344 100644
--- a/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetTanksInfoOperationTest.cs
+++ b/WotBlitzStatisticsPro.Tests/OperationStepsTests/GetTanksInfoOperationTest.cs
@@ -8,6 +8,7 @@ using NUnit.Framework;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations;
+using WotBlitzStatisticsPro.Logic.Model;
namespace WotBlitzStatisticsPro.Tests.OperationStepsTests
{
@@ -16,16 +17,21 @@ namespace WotBlitzStatisticsPro.Tests.OperationStepsTests
{
private GetTanksInfoOperation _operation;
private AccountInformationPipelineContextData _contextData;
+ private StatisticsCache _cache;
+
[SetUp]
public void Init()
{
InitAutoMapper();
InitWgApiClient();
+ _cache = new StatisticsCache();
+
_operation = new GetTanksInfoOperation(
WargamingTanksApiClient,
Mapper,
- (new Mock>()).Object);
+ (new Mock>()).Object,
+ _cache);
_contextData = new AccountInformationPipelineContextData();
}
@@ -50,6 +56,21 @@ namespace WotBlitzStatisticsPro.Tests.OperationStepsTests
var expectedTanksHistory =
await File.ReadAllTextAsync(GetFixturePath("MappedTanksHistory.json"));
tanksHistorySerialized.Should().Be(expectedTanksHistory);
+
+ // ToDo: Check cache
+ Assert.Fail("Implement test");
+ }
+
+ [Test]
+ public async Task ShouldGetAndSaveTankInfoInformationIfCacheExpired()
+ {
+ Assert.Fail("Implement test");
+ }
+
+ [Test]
+ public async Task ShouldReadDataFromCacheIfItIsNotEmpty()
+ {
+ Assert.Fail("Implement test");
}
}
diff --git a/WotBlitzStatisticsPro.Tests/OperationStepsTests/OperationsStepsTestBase.cs b/WotBlitzStatisticsPro.Tests/OperationStepsTests/OperationsStepsTestBase.cs
index be3607f..d44a680 100644
--- a/WotBlitzStatisticsPro.Tests/OperationStepsTests/OperationsStepsTestBase.cs
+++ b/WotBlitzStatisticsPro.Tests/OperationStepsTests/OperationsStepsTestBase.cs
@@ -7,6 +7,7 @@ using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using AutoMapper;
+using Microsoft.Extensions.Logging;
using Moq;
using Moq.Protected;
using Newtonsoft.Json;
@@ -97,7 +98,10 @@ namespace WotBlitzStatisticsPro.Tests.OperationStepsTests
ItExpr.IsAny())
.ReturnsAsync(tanksInfoResponse);
- var client = new WargamingApiClient(new HttpClient(handlerMock.Object), settingsMock.Object);
+ var client = new WargamingApiClient(
+ new HttpClient(handlerMock.Object),
+ settingsMock.Object,
+ (new Mock>()).Object);
WargamingApiClient = client;
WargamingTanksApiClient = client;
}
diff --git a/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs
index 830cc9d..e917fe9 100644
--- a/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs
+++ b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs
@@ -6,6 +6,7 @@ using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.Common;
using WotBlitzStatisticsPro.Common.Model;
@@ -19,14 +20,17 @@ namespace WotBlitzStatisticsPro.WgApiClient
private readonly HttpClient _httpClient;
private readonly IWargamingApiSettings _wargamingApiSettings;
+ private readonly ILogger _logger;
- public WagramingApiClientBase(
+ public WagramingApiClientBase(
HttpClient httpClient,
- IWargamingApiSettings wargamingApiSettings)
+ IWargamingApiSettings wargamingApiSettings,
+ ILogger logger)
{
_httpClient = httpClient;
_wargamingApiSettings = wargamingApiSettings;
- _blitzApiUrls[RealmType.Eu] = "https://api.wotblitz.eu/wotb/";
+ _logger = logger;
+ _blitzApiUrls[RealmType.Eu] = "https://api.wotblitz.eu/wotb/";
_blitzApiUrls[RealmType.Ru] = "https://api.wotblitz.ru/wotb/";
_blitzApiUrls[RealmType.Na] = "https://api.wotblitz.com/wotb/";
_blitzApiUrls[RealmType.Asia] = "https://api.wotblitz.asia/wotb/";
@@ -53,6 +57,9 @@ namespace WotBlitzStatisticsPro.WgApiClient
var responseString = await response.Content.ReadAsStringAsync();
var responseBody = JsonConvert.DeserializeObject>(responseString);
+
+ _logger.LogInformation($"HTTP GET {uri} - {responseBody.Status}");
+
switch (responseBody.Status)
{
case "ok":
diff --git a/WotBlitzStatisticsPro.WgApiClient/WargamingAchievementsApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/WargamingAchievementsApiClient.cs
index 11caa26..83becbb 100644
--- a/WotBlitzStatisticsPro.WgApiClient/WargamingAchievementsApiClient.cs
+++ b/WotBlitzStatisticsPro.WgApiClient/WargamingAchievementsApiClient.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.Common;
using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.WgApiClient.Model;
@@ -10,7 +11,10 @@ namespace WotBlitzStatisticsPro.WgApiClient
public class WargamingAchievementsApiClient: WagramingApiClientBase,
IWargamingAchievementsApiClient
{
- public WargamingAchievementsApiClient(HttpClient httpClient, IWargamingApiSettings wargamingApiSettings) : base(httpClient, wargamingApiSettings)
+ public WargamingAchievementsApiClient(
+ HttpClient httpClient,
+ IWargamingApiSettings wargamingApiSettings,
+ ILogger logger) : base(httpClient, wargamingApiSettings, logger)
{
}
diff --git a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs
index fbc8b8e..2e2ab6f 100644
--- a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs
+++ b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.Common;
using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.WgApiClient.Model;
@@ -15,7 +16,8 @@ namespace WotBlitzStatisticsPro.WgApiClient
{
public WargamingApiClient(
HttpClient httpClient,
- IWargamingApiSettings wargamingApiSettings) : base(httpClient, wargamingApiSettings)
+ IWargamingApiSettings wargamingApiSettings,
+ ILogger logger) : base(httpClient, wargamingApiSettings, logger)
{
}
diff --git a/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj b/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj
index 04a9ff5..9bfd599 100644
--- a/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj
+++ b/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj
@@ -6,6 +6,7 @@
+