feat 网关继承微服务Swagger
This commit is contained in:
@ -0,0 +1,103 @@
|
||||
using Volo.Abp.Json;
|
||||
|
||||
namespace KonSoft.InternalGateway.Aggregations.Base;
|
||||
|
||||
public abstract class AggregateRemoteServiceBase<TDto> : IAggregateRemoteService<TDto>
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly ILogger<AggregateRemoteServiceBase<TDto>> _logger;
|
||||
protected IJsonSerializer JsonSerializer { get; }
|
||||
|
||||
protected AggregateRemoteServiceBase(IHttpContextAccessor httpContextAccessor, IJsonSerializer jsonSerializer,
|
||||
ILogger<AggregateRemoteServiceBase<TDto>> logger)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
JsonSerializer = jsonSerializer;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, TDto>> GetMultipleAsync(
|
||||
Dictionary<string, string> serviceNameWithUrlDictionary)
|
||||
{
|
||||
Dictionary<string, Task<TDto>> completedTasks = new Dictionary<string, Task<TDto>>();
|
||||
Dictionary<string, Task<TDto>> runningTasks = new Dictionary<string, Task<TDto>>();
|
||||
Dictionary<string, TDto> completedResult = new Dictionary<string, TDto>();
|
||||
|
||||
using (HttpClient httpClient = CreateHttpClient())
|
||||
{
|
||||
foreach (var service in serviceNameWithUrlDictionary)
|
||||
{
|
||||
Task<TDto> requestTask =
|
||||
MakeRequestAsync<TDto>(httpClient, service.Value);
|
||||
runningTasks.Add(service.Key, requestTask);
|
||||
}
|
||||
|
||||
while (runningTasks.Count > 0)
|
||||
{
|
||||
KeyValuePair<string, Task<TDto>> completedTask = await WaitForAnyTaskAsync(runningTasks);
|
||||
|
||||
runningTasks.Remove(completedTask.Key);
|
||||
|
||||
try
|
||||
{
|
||||
TDto result = await completedTask.Value;
|
||||
|
||||
completedTasks.Add(completedTask.Key, completedTask.Value);
|
||||
completedResult.Add(completedTask.Key, result);
|
||||
|
||||
_logger.LogInformation("Localization Key: {0}, Value: {1}", completedTask.Key, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogInformation("Error for the {0}: {1}", completedTask.Key, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return completedResult;
|
||||
}
|
||||
|
||||
private HttpClient CreateHttpClient()
|
||||
{
|
||||
var httpClient = new HttpClient();
|
||||
|
||||
var headers = _httpContextAccessor.HttpContext?.Request.Headers;
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
{
|
||||
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public async Task<T> MakeRequestAsync<T>(HttpClient httpClient, string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = await httpClient.GetAsync(url);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
return JsonSerializer.Deserialize<T>(content);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogInformation("Error making request to {0}: {1}", url, e.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<KeyValuePair<TKey, Task<TValue>>> WaitForAnyTaskAsync<TKey, TValue>(
|
||||
Dictionary<TKey, Task<TValue>> tasks)
|
||||
{
|
||||
var completedTask = Task.WhenAny(tasks.Values);
|
||||
var result = await completedTask;
|
||||
|
||||
var completedTaskPair = tasks.First(kv => kv.Value == result);
|
||||
|
||||
return completedTaskPair;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
namespace KonSoft.InternalGateway.Aggregations.Base;
|
||||
|
||||
public abstract class AggregateServiceBase<TDto>
|
||||
{
|
||||
private readonly IAggregateRemoteService<TDto> _remoteService;
|
||||
|
||||
public AggregateServiceBase(IAggregateRemoteService<TDto> remoteService)
|
||||
{
|
||||
_remoteService = remoteService;
|
||||
}
|
||||
|
||||
public virtual async Task<Dictionary<string, TDto>> GetMultipleFromRemoteAsync(List<string> missingKeys,
|
||||
Dictionary<string, string> endpoints)
|
||||
{
|
||||
return await _remoteService
|
||||
.GetMultipleAsync(endpoints
|
||||
.Where(kv => missingKeys.Contains(kv.Key))
|
||||
.ToDictionary(k => k.Key, v => v.Value));
|
||||
}
|
||||
|
||||
public List<string> GetMissingServiceKeys(
|
||||
IDictionary<string, TDto> serviceNamesWithData,
|
||||
Dictionary<string, string> serviceNamesWithUrls)
|
||||
{
|
||||
List<string> missingKeysInCache = serviceNamesWithUrls.Keys.Except(serviceNamesWithData.Keys).ToList();
|
||||
List<string> missingKeysInUrls = serviceNamesWithData.Keys.Except(serviceNamesWithUrls.Keys).ToList();
|
||||
|
||||
return missingKeysInCache.Concat(missingKeysInUrls).ToList();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace KonSoft.InternalGateway.Aggregations.Base;
|
||||
|
||||
public abstract class CachedServiceBase<TCacheValue> : ICachedServiceBase<TCacheValue>
|
||||
{
|
||||
private readonly IMemoryCache _cache;
|
||||
|
||||
protected MemoryCacheEntryOptions CacheEntryOptions { get; } = new()
|
||||
{
|
||||
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24),
|
||||
SlidingExpiration = TimeSpan.FromHours(4)
|
||||
};
|
||||
|
||||
protected CachedServiceBase(IMemoryCache cache)
|
||||
{
|
||||
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
||||
}
|
||||
|
||||
public void Add(string serviceName, TCacheValue data)
|
||||
{
|
||||
_cache.Set(serviceName, data, CacheEntryOptions);
|
||||
}
|
||||
|
||||
public IDictionary<string, TCacheValue> GetManyAsync(IEnumerable<string> serviceNames)
|
||||
{
|
||||
var result = new Dictionary<string, TCacheValue>();
|
||||
|
||||
foreach (var serviceName in serviceNames)
|
||||
{
|
||||
if (_cache.TryGetValue(serviceName, out TCacheValue data))
|
||||
{
|
||||
result.Add(serviceName, data);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
namespace KonSoft.InternalGateway.Aggregations.Base;
|
||||
|
||||
public interface IAggregateRemoteService<TDto>
|
||||
{
|
||||
Task<Dictionary<string, TDto>> GetMultipleAsync(Dictionary<string, string> serviceNameWithUrlDictionary);
|
||||
Task<T> MakeRequestAsync<T>(HttpClient httpClient, string url);
|
||||
Task<KeyValuePair<TKey, Task<TValue>>> WaitForAnyTaskAsync<TKey, TValue>(Dictionary<TKey, Task<TValue>> tasks);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
namespace KonSoft.InternalGateway.Aggregations.Base;
|
||||
|
||||
public interface ICachedServiceBase<TValue>
|
||||
{
|
||||
void Add(string serviceName, TValue data);
|
||||
IDictionary<string, TValue> GetManyAsync(IEnumerable<string> serviceNames);
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
namespace KonSoft.InternalGateway.Aggregations.Base;
|
||||
|
||||
public interface IRequestInput
|
||||
{
|
||||
Dictionary<string, string> Endpoints { get; }
|
||||
}
|
||||
Reference in New Issue
Block a user