using ZB.MOM.WW.Configuration;
using ZB.MOM.WW.OtOpcUa.OpcUaServer;
namespace ZB.MOM.WW.OtOpcUa.Host.Configuration;
///
/// Fail-fast startup validator for , built on the
/// shared ZB.MOM.WW.Configuration . The C#
/// defaults are all valid, so a host with no explicit "OpcUa" section passes untouched;
/// the validator exists to reject explicit prod/env overrides before the OPC UA SDK boots.
/// Identity/transport essentials (ApplicationName, ApplicationUri,
/// PublicHostname, PkiStoreRoot, OpcUaPort) must be present/valid and at
/// least one security profile must be enabled. Optional fields — ApplicationConfigPath,
/// PeerApplicationUris, AutoAcceptUntrustedClientCertificates, and
/// ProductUri — are intentionally not validated. Failure messages carry the real
/// "OpcUa:" section prefix matching the bound configuration section.
///
public sealed class OpcUaApplicationHostOptionsValidator : OptionsValidatorBase
{
///
protected override void Validate(ValidationBuilder builder, OpcUaApplicationHostOptions o)
{
builder.Required(o.ApplicationName, "OpcUa:ApplicationName");
builder.Required(o.ApplicationUri, "OpcUa:ApplicationUri");
builder.Required(o.PublicHostname, "OpcUa:PublicHostname");
builder.Required(o.PkiStoreRoot, "OpcUa:PkiStoreRoot");
builder.Port(o.OpcUaPort, "OpcUa:OpcUaPort");
// EnabledSecurityProfiles is declared as IList — that interface does not derive from
// IReadOnlyCollection, so it can't bind to MinCount's IReadOnlyCollection parameter
// directly. ToList() bridges to the shared primitive while preserving the count (and message).
builder.MinCount(o.EnabledSecurityProfiles?.ToList(), 1, "OpcUa:EnabledSecurityProfiles");
}
}