using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Opc.Ua; using Opc.Ua.Server; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; using ZB.MOM.WW.OtOpcUa.Core.Hosting; using ZB.MOM.WW.OtOpcUa.Core.OpcUa; namespace ZB.MOM.WW.OtOpcUa.Server.OpcUa; /// /// subclass that wires one per /// registered driver from . Anonymous endpoint on /// opc.tcp://0.0.0.0:4840, no security — PR 16 minimum-viable scope; LDAP + security /// profiles are deferred to their own PR on top of this. /// public sealed class OtOpcUaServer : StandardServer { private readonly DriverHost _driverHost; private readonly ILoggerFactory _loggerFactory; private readonly List _driverNodeManagers = new(); public OtOpcUaServer(DriverHost driverHost, ILoggerFactory loggerFactory) { _driverHost = driverHost; _loggerFactory = loggerFactory; } /// /// Read-only snapshot of the driver node managers materialized at server start. Used by /// the generic-driver-node-manager-driven discovery flow after the server starts — the /// host walks each entry and invokes /// GenericDriverNodeManager.BuildAddressSpaceAsync(manager) passing the manager /// as its own . /// public IReadOnlyList DriverNodeManagers => _driverNodeManagers; protected override MasterNodeManager CreateMasterNodeManager(IServerInternal server, ApplicationConfiguration configuration) { foreach (var driverId in _driverHost.RegisteredDriverIds) { var driver = _driverHost.GetDriver(driverId); if (driver is null) continue; var logger = _loggerFactory.CreateLogger(); var manager = new DriverNodeManager(server, configuration, driver, logger); _driverNodeManagers.Add(manager); } return new MasterNodeManager(server, configuration, null, _driverNodeManagers.ToArray()); } protected override ServerProperties LoadServerProperties() => new() { ManufacturerName = "OtOpcUa", ProductName = "OtOpcUa.Server", ProductUri = "urn:OtOpcUa:Server", SoftwareVersion = "2.0.0", BuildNumber = "0", BuildDate = DateTime.UtcNow, }; }