84 lines
2.3 KiB
C#
84 lines
2.3 KiB
C#
using System.Collections.Concurrent;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Yarp.ReverseProxy.Configuration;
|
|
using YarpGateway.Data;
|
|
using YarpGateway.Models;
|
|
|
|
namespace YarpGateway.Config;
|
|
|
|
public class DatabaseRouteConfigProvider
|
|
{
|
|
private readonly IDbContextFactory<GatewayDbContext> _dbContextFactory;
|
|
private readonly ConcurrentDictionary<string, RouteConfig> _routes = new();
|
|
private readonly SemaphoreSlim _lock = new(1, 1);
|
|
private readonly ILogger<DatabaseRouteConfigProvider> _logger;
|
|
|
|
public DatabaseRouteConfigProvider(
|
|
IDbContextFactory<GatewayDbContext> dbContextFactory,
|
|
ILogger<DatabaseRouteConfigProvider> logger
|
|
)
|
|
{
|
|
_dbContextFactory = dbContextFactory;
|
|
_logger = logger;
|
|
_ = LoadConfigAsync();
|
|
}
|
|
|
|
public IReadOnlyList<RouteConfig> GetRoutes()
|
|
{
|
|
return _routes.Values.ToList().AsReadOnly();
|
|
}
|
|
|
|
public async Task ReloadAsync()
|
|
{
|
|
await _lock.WaitAsync();
|
|
try
|
|
{
|
|
await LoadConfigInternalAsync();
|
|
}
|
|
finally
|
|
{
|
|
_lock.Release();
|
|
}
|
|
}
|
|
|
|
private async Task LoadConfigAsync()
|
|
{
|
|
await LoadConfigInternalAsync();
|
|
}
|
|
|
|
private async Task LoadConfigInternalAsync()
|
|
{
|
|
await using var dbContext = _dbContextFactory.CreateDbContext();
|
|
|
|
var routes = await dbContext
|
|
.TenantRoutes.Where(r => r.Status == 1 && !r.IsDeleted)
|
|
.ToListAsync();
|
|
|
|
var newRoutes = new ConcurrentDictionary<string, RouteConfig>();
|
|
|
|
foreach (var route in routes)
|
|
{
|
|
var config = new RouteConfig
|
|
{
|
|
RouteId = route.Id.ToString(),
|
|
ClusterId = route.ClusterId,
|
|
Match = new RouteMatch { Path = route.PathPattern },
|
|
Metadata = new Dictionary<string, string>
|
|
{
|
|
["TenantCode"] = route.TenantCode,
|
|
["ServiceName"] = route.ServiceName,
|
|
},
|
|
};
|
|
newRoutes[route.Id.ToString()] = config;
|
|
}
|
|
|
|
_routes.Clear();
|
|
foreach (var route in newRoutes)
|
|
{
|
|
_routes[route.Key] = route.Value;
|
|
}
|
|
|
|
_logger.LogInformation("Loaded {Count} routes from database", _routes.Count);
|
|
}
|
|
}
|