using StellaOps.Plugin.Abstractions.Capabilities; using StellaOps.Plugin.Abstractions.Context; using StellaOps.Router.Common.Abstractions; namespace StellaOps.Router.Plugin.Unified; /// /// Adapts ITransportServer to ITransportServerInstance. /// internal sealed class TransportServerAdapter : ITransportServerInstance { private readonly ITransportServer _inner; private readonly IPluginLogger _logger; private bool _isRunning; private bool _disposed; /// /// Gets the server identifier. /// public string ServerId { get; } /// public bool IsRunning => _isRunning; /// public TransportEndpoint LocalEndpoint { get; } /// public int ActiveConnections { get { // Try to get connection count from the inner server if it exposes this // Otherwise return 0 as we cannot determine this var serverType = _inner.GetType(); var countProperty = serverType.GetProperty("ConnectionCount"); if (countProperty != null) { return (int)(countProperty.GetValue(_inner) ?? 0); } return 0; } } /// /// Creates a new server adapter. /// public TransportServerAdapter( ITransportServer inner, string serverId, TransportEndpoint endpoint, IPluginLogger logger) { _inner = inner ?? throw new ArgumentNullException(nameof(inner)); ServerId = serverId; LocalEndpoint = endpoint; _logger = logger; } /// public async Task StartAsync(CancellationToken ct) { ObjectDisposedException.ThrowIf(_disposed, this); if (_isRunning) { return; } await _inner.StartAsync(ct); _isRunning = true; _logger.Info("Transport server {ServerId} started on {Host}:{Port}", ServerId, LocalEndpoint.Host, LocalEndpoint.Port); } /// public async Task StopAsync(CancellationToken ct) { if (!_isRunning) { return; } await _inner.StopAsync(ct); _isRunning = false; _logger.Info("Transport server {ServerId} stopped", ServerId); } /// public async ValueTask DisposeAsync() { if (_disposed) { return; } _disposed = true; if (_isRunning) { await StopAsync(CancellationToken.None); } if (_inner is IAsyncDisposable asyncDisposable) { await asyncDisposable.DisposeAsync(); } else if (_inner is IDisposable disposable) { disposable.Dispose(); } } }