using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway;
using ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb;
using ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer;
using ZB.MOM.WW.OtOpcUa.Runtime.Historian;
namespace ZB.MOM.WW.OtOpcUa.Host.Configuration;
///
/// Maps ServerHistorian:Backend to an . Names are
/// case-insensitive. To add a backend, add one entry to .
/// only constructs the provider; option validation belongs to
/// .
///
public static class HistorianBackendRegistry
{
/// Backend name for the SQL Server historian.
public const string SqlServerBackendName = "SqlServer";
/// Binds the ServerHistorian:SqlServer section (shared by the registry and the validator).
public static SqlServerHistorianOptions BindSqlServer(IConfiguration configuration)
{
var o = new SqlServerHistorianOptions();
configuration.GetSection($"{ServerHistorianOptions.SectionName}:SqlServer").Bind(o);
return o;
}
/// Backend name for the QuestDB historian.
public const string QuestDbBackendName = "QuestDb";
/// Binds the ServerHistorian:QuestDb section (shared by the registry and the validator).
public static QuestDbHistorianOptions BindQuestDb(IConfiguration configuration)
{
var o = new QuestDbHistorianOptions();
configuration.GetSection($"{ServerHistorianOptions.SectionName}:QuestDb").Bind(o);
return o;
}
private static readonly IReadOnlyDictionary> Factories =
new Dictionary>(StringComparer.OrdinalIgnoreCase)
{
[ServerHistorianOptions.GatewayBackendName] = (o, _) => new GatewayHistorianProvider(o),
[SqlServerBackendName] = (o, c) => new SqlServerHistorianProvider(BindSqlServer(c), o.MaxTimeWeightedRawRows),
[QuestDbBackendName] = (o, c) => new QuestDbHistorianProvider(BindQuestDb(c), o.MaxTimeWeightedRawRows),
};
/// The registered backend names, for validation messages.
public static IReadOnlyCollection KnownBackends { get; } = Factories.Keys.ToArray();
/// True when names a registered backend.
public static bool IsKnown(string? backend) =>
!string.IsNullOrWhiteSpace(backend) && Factories.ContainsKey(backend.Trim());
/// Builds the provider for options.Backend; throws if unknown.
public static IHistorianBackendProvider Resolve(ServerHistorianOptions options, IConfiguration configuration)
{
ArgumentNullException.ThrowIfNull(options);
ArgumentNullException.ThrowIfNull(configuration);
if (!IsKnown(options.Backend))
throw new OptionsValidationException(
ServerHistorianOptions.SectionName, typeof(ServerHistorianOptions),
[$"ServerHistorian:Backend '{options.Backend}' is not a known historian backend. Allowed values: {string.Join(", ", KnownBackends)}."]);
return Factories[options.Backend.Trim()](options, configuration);
}
}