using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using ZB.MOM.WW.OtOpcUa.Core.Hosting; namespace ZB.MOM.WW.OtOpcUa.Server; /// /// BackgroundService that owns the OPC UA server lifecycle (decision #30, replacing TopShelf). /// Bootstraps config, starts the , and runs until stopped. /// Phase 1 scope: bootstrap-only — the OPC UA transport layer that serves endpoints stays in /// the legacy Host until the Phase 2 cutover. /// public sealed class OpcUaServerService( NodeBootstrap bootstrap, DriverHost driverHost, ILogger logger) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { logger.LogInformation("OtOpcUa.Server starting"); var result = await bootstrap.LoadCurrentGenerationAsync(stoppingToken); logger.LogInformation("Bootstrap complete: source={Source} generation={Gen}", result.Source, result.GenerationId); // Phase 1: no drivers are wired up at bootstrap — Galaxy still lives in legacy Host. // Phase 2 will register drivers here based on the fetched generation. logger.LogInformation("OtOpcUa.Server running. Hosted drivers: {Count}", driverHost.RegisteredDriverIds.Count); try { await Task.Delay(Timeout.InfiniteTimeSpan, stoppingToken); } catch (OperationCanceledException) { logger.LogInformation("OtOpcUa.Server stopping"); } } public override async Task StopAsync(CancellationToken cancellationToken) { await base.StopAsync(cancellationToken); await driverHost.DisposeAsync(); } }