using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Config; namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy; /// /// In-process .NET 10 Galaxy driver — the v2 replacement for the Galaxy.Host / /// Galaxy.Proxy pair. PR 4.0 ships the project skeleton with /// bodies that wire to a future IGalaxyGatewayClient abstraction. Capability /// interfaces (browse, read, write, subscribe, history routing, host probes) land in /// PRs 4.1–4.7; the wiring sequence keeps every intermediate state buildable so the /// Galaxy:Backend flag (PR 4.W) can flip between legacy-host and mxgateway /// for parity testing. /// /// /// This driver is registered as a Tier A in-process driver alongside Modbus / S7 / etc. /// The legacy GalaxyProxyDriver (Driver.Galaxy.Proxy) coexists until PR 7.2; /// registers under driver-type name /// "GalaxyMxGateway" so both paths can be live simultaneously during parity testing. /// public sealed class GalaxyDriver : IDriver, IDisposable { private readonly string _driverInstanceId; private readonly GalaxyDriverOptions _options; private readonly ILogger _logger; private DriverHealth _health = new(DriverState.Unknown, null, null); private bool _disposed; public GalaxyDriver( string driverInstanceId, GalaxyDriverOptions options, ILogger? logger = null) { _driverInstanceId = !string.IsNullOrWhiteSpace(driverInstanceId) ? driverInstanceId : throw new ArgumentException("Driver instance id required.", nameof(driverInstanceId)); _options = options ?? throw new ArgumentNullException(nameof(options)); _logger = logger ?? NullLogger.Instance; } /// public string DriverInstanceId => _driverInstanceId; /// public string DriverType => GalaxyDriverFactoryExtensions.DriverTypeName; /// Test-visible options snapshot. internal GalaxyDriverOptions Options => _options; /// public Task InitializeAsync(string driverConfigJson, CancellationToken cancellationToken) { ObjectDisposedException.ThrowIf(_disposed, this); // PR 4.0 skeleton — capability bodies (PRs 4.1-4.7) replace this stub with real // MxGatewayClient session opening. The skeleton keeps the IDriver shape buildable // so the Galaxy:Backend flag (PR 4.W) can register the driver factory now. _logger.LogInformation( "GalaxyDriver {InstanceId} initializing — endpoint={Endpoint} clientName={ClientName} (skeleton; real gateway connect in PR 4.1+)", _driverInstanceId, _options.Gateway.Endpoint, _options.MxAccess.ClientName); _health = new DriverHealth(DriverState.Healthy, DateTime.UtcNow, null); return Task.CompletedTask; } /// public Task ReinitializeAsync(string driverConfigJson, CancellationToken cancellationToken) { // In-place config reapply. PR 4.5's reconnect supervisor will swap the // gateway-client options under the lock; for the skeleton we just refresh health. ObjectDisposedException.ThrowIf(_disposed, this); _health = new DriverHealth(DriverState.Healthy, DateTime.UtcNow, null); return Task.CompletedTask; } /// public Task ShutdownAsync(CancellationToken cancellationToken) { if (_disposed) return Task.CompletedTask; _logger.LogInformation("GalaxyDriver {InstanceId} shutting down", _driverInstanceId); _health = new DriverHealth(DriverState.Unknown, _health.LastSuccessfulRead, null); return Task.CompletedTask; } /// public DriverHealth GetHealth() => _health; /// public long GetMemoryFootprint() => 0; // PR 4.4 sets this from SubscriptionRegistry size. /// public Task FlushOptionalCachesAsync(CancellationToken cancellationToken) => Task.CompletedTask; public void Dispose() { if (_disposed) return; _disposed = true; // No owned IDisposables until PR 4.2's GalaxyMxSession lands. } }