Browse Source

Refactored

pull/235/head
Galip Tolga Erdem 3 years ago
parent
commit
f66ad6c5a2
  1. 1
      gateways/web/src/EShopOnAbp.WebGateway/Aggregations/ILocalizationAggregation.cs
  2. 8
      gateways/web/src/EShopOnAbp.WebGateway/Aggregations/Localization/CachedLocalizationService.cs
  3. 25
      gateways/web/src/EShopOnAbp.WebGateway/Aggregations/Localization/RemoteLocalizationService.cs
  4. 56
      gateways/web/src/EShopOnAbp.WebGateway/Aggregations/LocalizationAggregation.cs
  5. 12
      gateways/web/src/EShopOnAbp.WebGateway/ReverseProxyBuilderExtensions.cs

1
gateways/web/src/EShopOnAbp.WebGateway/Aggregations/ILocalizationAggregation.cs

@ -6,6 +6,7 @@ namespace EShopOnAbp.WebGateway.Aggregations;
public interface ILocalizationAggregation : ITransientDependency
{
public string LocalizationRouteName { get; }
public string LocalizationEndpoint { get; }
public Task<ApplicationLocalizationDto> GetLocalizationAsync(LocalizationRequest input);
}

8
gateways/web/src/EShopOnAbp.WebGateway/Aggregations/Localization/CachedLocalizationService.cs

@ -16,18 +16,12 @@ public class CachedLocalizationService : ISingletonDependency
LocalizationDictionary = new ConcurrentDictionary<string, ApplicationLocalizationDto>(StringComparer.OrdinalIgnoreCase);
}
//TODO:skip url -> Use ServiceName_Culture as cache key
public void AddOrUpdate(string serviceNameWithCulture, ApplicationLocalizationDto localizationInfo)
{
LocalizationDictionary.AddOrUpdate(serviceNameWithCulture, localizationInfo, (key, value) => localizationInfo);
}
public ApplicationLocalizationDto Get(string serviceNameWithCulture)
{
return LocalizationDictionary.TryGetValue(serviceNameWithCulture, out var result) ? result : null;
}
public IDictionary<string, ApplicationLocalizationDto> GetMultipleLocalizationsAsync(string[] serviceNamesWithCulture)
public IDictionary<string, ApplicationLocalizationDto> GetLocalizationsFromCacheAsync(string[] serviceNamesWithCulture)
{
return LocalizationDictionary
.Where(kv => serviceNamesWithCulture.Contains(kv.Key))

25
gateways/web/src/EShopOnAbp.WebGateway/Aggregations/Localization/RemoteLocalizationService.cs

@ -46,7 +46,7 @@ public class RemoteLocalizationService : IRemoteLocalizationService, ITransientD
completedTasks.Add(completedTask.Key, completedTask.Value);
completedResult.Add(completedTask.Key, result);
_logger.LogInformation($"Key: {completedTask.Key}, Value: {result}");
_logger.LogInformation($"Localization Key: {completedTask.Key}, Value: {result}");
}
catch (Exception ex)
{
@ -70,23 +70,14 @@ public class RemoteLocalizationService : IRemoteLocalizationService, ITransientD
private async Task<T> MakeRequestAsync<T>(HttpClient httpClient, string url)
{
try
{
HttpResponseMessage response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
HttpResponseMessage response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
return JsonSerializer.Deserialize<T>(content, options);
}
catch (Exception ex)
string content = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
// Log or handle the exception, and return a default value or throw it again if needed
Console.WriteLine($"Error making request to {url}: {ex.Message}");
throw;
}
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
return JsonSerializer.Deserialize<T>(content, options);
}
}

56
gateways/web/src/EShopOnAbp.WebGateway/Aggregations/LocalizationAggregation.cs

@ -2,7 +2,6 @@
using System.Linq;
using System.Threading.Tasks;
using EShopOnAbp.WebGateway.Aggregations.Localization;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
namespace EShopOnAbp.WebGateway.Aggregations;
@ -10,48 +9,64 @@ namespace EShopOnAbp.WebGateway.Aggregations;
public class LocalizationAggregation : ILocalizationAggregation
{
//Yarp localization route name
public string LocalizationEndpoint { get; } = "EshopOnAbpLocalization";
private readonly ILogger<LocalizationAggregation> _logger;
public string LocalizationRouteName { get; } = "EshopOnAbpLocalization";
public string LocalizationEndpoint { get; } = "api/abp/application-localization";
private readonly CachedLocalizationService _cachedLocalizationService;
private readonly RemoteLocalizationService _remoteLocalizationService;
private readonly IRemoteLocalizationService _remoteLocalizationService;
public LocalizationAggregation(ILogger<LocalizationAggregation> logger, CachedLocalizationService cachedLocalizationService, RemoteLocalizationService remoteLocalizationService)
public LocalizationAggregation(CachedLocalizationService cachedLocalizationService,
IRemoteLocalizationService remoteLocalizationService)
{
_logger = logger;
_cachedLocalizationService = cachedLocalizationService;
_remoteLocalizationService = remoteLocalizationService;
}
public async Task<ApplicationLocalizationDto> GetLocalizationAsync(LocalizationRequest input)
{
// Check the cache service
var cachedLocalization = _cachedLocalizationService.GetMultipleLocalizationsAsync(input.LocalizationEndpoints.Keys.ToArray());
var cachedLocalization = _cachedLocalizationService
.GetLocalizationsFromCacheAsync(input.LocalizationEndpoints.Keys.ToArray());
// Compare cache with input service list
var missingLocalizationKeys = GetMissingLocalizations(cachedLocalization, input.LocalizationEndpoints);
if (missingLocalizationKeys.Count != 0)
{
// Make request to remote localization service
var remoteLocalizationResults = await _remoteLocalizationService
.GetMultipleLocalizationsAsync(input.LocalizationEndpoints
.Where(kv=> missingLocalizationKeys.Contains(kv.Key))
.ToDictionary(k=>k.Key,v=>v.Value));
// Make request to remote localization service to get missing localizations
var remoteLocalizationResults =
await GetLocalizationsFromRemoteAsync(missingLocalizationKeys, input.LocalizationEndpoints);
// Update localization cache
foreach (var result in remoteLocalizationResults)
{
_cachedLocalizationService.AddOrUpdate(result.Key, result.Value);
}
cachedLocalization = _cachedLocalizationService.GetMultipleLocalizationsAsync(input.LocalizationEndpoints.Keys.ToArray());
cachedLocalization = _cachedLocalizationService
.GetLocalizationsFromCacheAsync(input.LocalizationEndpoints.Keys.ToArray());
}
//merge result
ApplicationLocalizationDto mergedResult = MergeLocalizations(cachedLocalization);
//return result
return mergedResult;
}
private List<string> GetMissingLocalizations(IDictionary<string,ApplicationLocalizationDto> serviceNameWithLocalization, Dictionary<string,string> serviceNameWithUrls)
private async Task<Dictionary<string, ApplicationLocalizationDto>> GetLocalizationsFromRemoteAsync(
List<string> missingLocalizationKeys, Dictionary<string, string> localizationEndpoints)
{
return await _remoteLocalizationService
.GetMultipleLocalizationsAsync(localizationEndpoints
.Where(kv => missingLocalizationKeys.Contains(kv.Key))
.ToDictionary(k => k.Key, v => v.Value));
}
private List<string> GetMissingLocalizations(
IDictionary<string, ApplicationLocalizationDto> serviceNameWithLocalization,
Dictionary<string, string> serviceNameWithUrls)
{
List<string> missingKeysInCache = serviceNameWithUrls.Keys.Except(serviceNameWithLocalization.Keys).ToList();
List<string> missingKeysInUrls = serviceNameWithLocalization.Keys.Except(serviceNameWithUrls.Keys).ToList();
@ -59,10 +74,11 @@ public class LocalizationAggregation : ILocalizationAggregation
return missingKeysInCache.Concat(missingKeysInUrls).ToList();
}
private ApplicationLocalizationDto MergeLocalizations(IDictionary<string, ApplicationLocalizationDto> localizationResults)
private ApplicationLocalizationDto MergeLocalizations(
IDictionary<string, ApplicationLocalizationDto> localizationResults)
{
var localizationDto = new ApplicationLocalizationDto();
foreach (var localization in localizationResults)
{
foreach (var resource in localization.Value.Resources)

12
gateways/web/src/EShopOnAbp.WebGateway/ReverseProxyBuilderExtensions.cs

@ -13,8 +13,6 @@ namespace EShopOnAbp.WebGateway;
public static class ReverseProxyBuilderExtensions
{
public static string LocalizationPath = "api/abp/application-localization";
public static ReverseProxyConventionBuilder MapReverseProxyWithLocalization(this IEndpointRouteBuilder endpoints)
{
return endpoints.MapReverseProxy(proxyBuilder =>
@ -24,11 +22,11 @@ public static class ReverseProxyBuilderExtensions
var endpoint = context.GetEndpoint();
var localizationAggregation = context.RequestServices.GetRequiredService<ILocalizationAggregation>();
if (localizationAggregation.LocalizationEndpoint == endpoint?.DisplayName)
if (localizationAggregation.LocalizationRouteName == endpoint?.DisplayName)
{
LocalizationRequest input = CreateLocalizationRequestInput(context);
LocalizationRequest requestInput = CreateLocalizationRequestInput(context, localizationAggregation.LocalizationEndpoint);
var result = await localizationAggregation.GetLocalizationAsync(input);
var result = await localizationAggregation.GetLocalizationAsync(requestInput);
await context.Response.WriteAsync(JsonSerializer.Serialize(result, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
@ -44,14 +42,14 @@ public static class ReverseProxyBuilderExtensions
});
}
private static LocalizationRequest CreateLocalizationRequestInput(HttpContext context)
private static LocalizationRequest CreateLocalizationRequestInput(HttpContext context, string localizationPath)
{
var proxyConfig = context.RequestServices.GetRequiredService<IProxyConfigProvider>();
context.Request.Query.TryGetValue("CultureName", out var cultureName);
var input = new LocalizationRequest(cultureName);
string path = $"{LocalizationPath}?cultureName={cultureName}&onlyDynamics=false";
string path = $"{localizationPath}?cultureName={cultureName}&onlyDynamics=false";
var clusterList = GetClusters(proxyConfig);
foreach (var cluster in clusterList)

Loading…
Cancel
Save