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); } }