diff --git a/src/NATS.Server/Monitoring/Varz.cs b/src/NATS.Server/Monitoring/Varz.cs index 3e85374..dda7234 100644 --- a/src/NATS.Server/Monitoring/Varz.cs +++ b/src/NATS.Server/Monitoring/Varz.cs @@ -355,8 +355,29 @@ public sealed class MqttOptsVarz [JsonPropertyName("port")] public int Port { get; set; } + [JsonPropertyName("no_auth_user")] + public string NoAuthUser { get; set; } = ""; + + [JsonPropertyName("auth_timeout")] + public double AuthTimeout { get; set; } + + [JsonPropertyName("tls_map")] + public bool TlsMap { get; set; } + [JsonPropertyName("tls_timeout")] public double TlsTimeout { get; set; } + + [JsonPropertyName("tls_pinned_certs")] + public string[] TlsPinnedCerts { get; set; } = []; + + [JsonPropertyName("js_domain")] + public string JsDomain { get; set; } = ""; + + [JsonPropertyName("ack_wait")] + public long AckWait { get; set; } + + [JsonPropertyName("max_ack_pending")] + public ushort MaxAckPending { get; set; } } /// diff --git a/src/NATS.Server/Monitoring/VarzHandler.cs b/src/NATS.Server/Monitoring/VarzHandler.cs index 3bdbe6d..290139c 100644 --- a/src/NATS.Server/Monitoring/VarzHandler.cs +++ b/src/NATS.Server/Monitoring/VarzHandler.cs @@ -121,6 +121,7 @@ public sealed class VarzHandler : IDisposable Subscriptions = _server.SubList.Count, ConfigLoadTime = _server.StartTime, HttpReqStats = stats.HttpReqStats.ToDictionary(kv => kv.Key, kv => (ulong)kv.Value), + Mqtt = BuildMqttVarz(), }; } finally @@ -134,6 +135,27 @@ public sealed class VarzHandler : IDisposable _varzMu.Dispose(); } + private MqttOptsVarz BuildMqttVarz() + { + var mqtt = _options.Mqtt; + if (mqtt is null) + return new MqttOptsVarz(); + + return new MqttOptsVarz + { + Host = mqtt.Host, + Port = mqtt.Port, + NoAuthUser = mqtt.NoAuthUser ?? "", + AuthTimeout = mqtt.AuthTimeout, + TlsMap = mqtt.TlsMap, + TlsTimeout = mqtt.TlsTimeout, + TlsPinnedCerts = mqtt.TlsPinnedCerts?.ToArray() ?? [], + JsDomain = mqtt.JsDomain ?? "", + AckWait = (long)mqtt.AckWait.TotalNanoseconds, + MaxAckPending = mqtt.MaxAckPending, + }; + } + /// /// Formats a TimeSpan as a human-readable uptime string matching Go server format. /// diff --git a/tests/NATS.Server.Tests/MonitorTests.cs b/tests/NATS.Server.Tests/MonitorTests.cs index d4dad6c..bb1356a 100644 --- a/tests/NATS.Server.Tests/MonitorTests.cs +++ b/tests/NATS.Server.Tests/MonitorTests.cs @@ -271,6 +271,23 @@ public class MonitorTests : IAsyncLifetime response.StatusCode.ShouldBe(HttpStatusCode.OK); } + [Fact] + public async Task Varz_includes_mqtt_section() + { + var response = await _http.GetAsync($"http://127.0.0.1:{_monitorPort}/varz"); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + + var varz = await response.Content.ReadFromJsonAsync(); + varz.ShouldNotBeNull(); + varz.Mqtt.ShouldNotBeNull(); + varz.Mqtt.Host.ShouldBe(""); + varz.Mqtt.Port.ShouldBe(0); + varz.Mqtt.NoAuthUser.ShouldBe(""); + varz.Mqtt.JsDomain.ShouldBe(""); + varz.Mqtt.AckWait.ShouldBe(0L); + varz.Mqtt.MaxAckPending.ShouldBe((ushort)0); + } + private static int GetFreePort() { using var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);