feat: port sessions 12 & 13 — Events/Monitoring/MsgTrace + Config Reload
Session 12 (218 features, IDs 854-950, 2166-2251, 2405-2439): - EventTypes: system subjects, event message types, InternalState, ConnectEventMsg, DisconnectEventMsg, AccountNumConns, ServerIdentity, DataStats - MonitorTypes: Connz, ConnInfo, ConnzOptions, ConnState, ProxyInfo, TlsPeerCert - MonitorSortOptions: SortOpt, ConnInfos, all 13 sort comparers - MsgTraceTypes: IMsgTrace, MsgTraceBase + 6 concrete types, custom JSON converter Session 13 (89 features, IDs 2800-2888): - ReloadOptions: IReloadOption interface, NoopReloadOption base, 50 option classes covering logging, TLS, auth, cluster, JetStream, MQTT, OCSP, misc
This commit is contained in:
778
dotnet/src/ZB.MOM.NatsNet.Server/Events/EventTypes.cs
Normal file
778
dotnet/src/ZB.MOM.NatsNet.Server/Events/EventTypes.cs
Normal file
@@ -0,0 +1,778 @@
|
||||
// Copyright 2018-2026 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Adapted from server/events.go in the NATS server Go source.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using ZB.MOM.NatsNet.Server.Auth.CertificateIdentityProvider;
|
||||
using ZB.MOM.NatsNet.Server.Internal;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server;
|
||||
|
||||
// ============================================================================
|
||||
// System subject constants
|
||||
// Mirrors the const block at the top of server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// System-account subject templates and constants used for internal NATS server
|
||||
/// event routing. All format-string fields use <see cref="string.Format"/> with
|
||||
/// the appropriate server/account ID substituted at call time.
|
||||
/// Mirrors the const block in server/events.go.
|
||||
/// </summary>
|
||||
public static class SystemSubjects
|
||||
{
|
||||
// Account lookup / claims
|
||||
public const string AccLookupReqSubj = "$SYS.REQ.ACCOUNT.{0}.CLAIMS.LOOKUP";
|
||||
public const string AccPackReqSubj = "$SYS.REQ.CLAIMS.PACK";
|
||||
public const string AccListReqSubj = "$SYS.REQ.CLAIMS.LIST";
|
||||
public const string AccClaimsReqSubj = "$SYS.REQ.CLAIMS.UPDATE";
|
||||
public const string AccDeleteReqSubj = "$SYS.REQ.CLAIMS.DELETE";
|
||||
|
||||
// Connection events
|
||||
public const string ConnectEventSubj = "$SYS.ACCOUNT.{0}.CONNECT";
|
||||
public const string DisconnectEventSubj = "$SYS.ACCOUNT.{0}.DISCONNECT";
|
||||
|
||||
// Direct request routing
|
||||
public const string AccDirectReqSubj = "$SYS.REQ.ACCOUNT.{0}.{1}";
|
||||
public const string AccPingReqSubj = "$SYS.REQ.ACCOUNT.PING.{0}";
|
||||
|
||||
// Account update events (both old and new forms kept for backward compatibility)
|
||||
public const string AccUpdateEventSubjOld = "$SYS.ACCOUNT.{0}.CLAIMS.UPDATE";
|
||||
public const string AccUpdateEventSubjNew = "$SYS.REQ.ACCOUNT.{0}.CLAIMS.UPDATE";
|
||||
|
||||
public const string ConnsRespSubj = "$SYS._INBOX_.{0}";
|
||||
public const string AccConnsEventSubjNew = "$SYS.ACCOUNT.{0}.SERVER.CONNS";
|
||||
public const string AccConnsEventSubjOld = "$SYS.SERVER.ACCOUNT.{0}.CONNS"; // backward compat
|
||||
|
||||
// Server lifecycle events
|
||||
public const string LameDuckEventSubj = "$SYS.SERVER.{0}.LAMEDUCK";
|
||||
public const string ShutdownEventSubj = "$SYS.SERVER.{0}.SHUTDOWN";
|
||||
|
||||
// Client control
|
||||
public const string ClientKickReqSubj = "$SYS.REQ.SERVER.{0}.KICK";
|
||||
public const string ClientLdmReqSubj = "$SYS.REQ.SERVER.{0}.LDM";
|
||||
|
||||
// Auth error events
|
||||
public const string AuthErrorEventSubj = "$SYS.SERVER.{0}.CLIENT.AUTH.ERR";
|
||||
public const string AuthErrorAccountEventSubj = "$SYS.ACCOUNT.CLIENT.AUTH.ERR";
|
||||
|
||||
// Stats
|
||||
public const string ServerStatsSubj = "$SYS.SERVER.{0}.STATSZ";
|
||||
public const string ServerDirectReqSubj = "$SYS.REQ.SERVER.{0}.{1}";
|
||||
public const string ServerPingReqSubj = "$SYS.REQ.SERVER.PING.{0}";
|
||||
public const string ServerStatsPingReqSubj = "$SYS.REQ.SERVER.PING"; // deprecated; use STATSZ variant
|
||||
public const string ServerReloadReqSubj = "$SYS.REQ.SERVER.{0}.RELOAD";
|
||||
|
||||
// Leaf node
|
||||
public const string LeafNodeConnectEventSubj = "$SYS.ACCOUNT.{0}.LEAFNODE.CONNECT"; // internal only
|
||||
|
||||
// Latency
|
||||
public const string RemoteLatencyEventSubj = "$SYS.LATENCY.M2.{0}";
|
||||
public const string InboxRespSubj = "$SYS._INBOX.{0}.{1}";
|
||||
|
||||
// User info
|
||||
public const string UserDirectInfoSubj = "$SYS.REQ.USER.INFO";
|
||||
public const string UserDirectReqSubj = "$SYS.REQ.USER.{0}.INFO";
|
||||
|
||||
// Subscription count
|
||||
public const string AccNumSubsReqSubj = "$SYS.REQ.ACCOUNT.NSUBS";
|
||||
|
||||
// Debug
|
||||
public const string AccSubsSubj = "$SYS.DEBUG.SUBSCRIBERS";
|
||||
|
||||
// OCSP peer events
|
||||
public const string OcspPeerRejectEventSubj = "$SYS.SERVER.{0}.OCSP.PEER.CONN.REJECT";
|
||||
public const string OcspPeerChainlinkInvalidEventSubj = "$SYS.SERVER.{0}.OCSP.PEER.LINK.INVALID";
|
||||
|
||||
// Parsing constants (token indexes / counts)
|
||||
public const int AccLookupReqTokens = 6;
|
||||
public const int ShutdownEventTokens = 4;
|
||||
public const int ServerSubjectIndex = 2;
|
||||
public const int AccUpdateTokensNew = 6;
|
||||
public const int AccUpdateTokensOld = 5;
|
||||
public const int AccUpdateAccIdxOld = 2;
|
||||
public const int AccReqTokens = 5;
|
||||
public const int AccReqAccIndex = 3;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Advisory message type schema URI constants
|
||||
// Mirrors the const string variables near each struct in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
public static class EventMsgTypes
|
||||
{
|
||||
public const string ConnectEventMsgType = "io.nats.server.advisory.v1.client_connect";
|
||||
public const string DisconnectEventMsgType = "io.nats.server.advisory.v1.client_disconnect";
|
||||
public const string OcspPeerRejectEventMsgType = "io.nats.server.advisory.v1.ocsp_peer_reject";
|
||||
public const string OcspPeerChainlinkInvalidEventMsgType = "io.nats.server.advisory.v1.ocsp_peer_link_invalid";
|
||||
public const string AccountNumConnsMsgType = "io.nats.server.advisory.v1.account_connections";
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Heartbeat / rate-limit intervals (mirrors package-level vars in events.go)
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Default timing constants for server event heartbeats and rate limiting.
|
||||
/// Mirrors Go package-level <c>var</c> declarations in events.go.
|
||||
/// </summary>
|
||||
public static class EventIntervals
|
||||
{
|
||||
/// <summary>Default HB interval for events. Mirrors Go <c>eventsHBInterval = 30s</c>.</summary>
|
||||
public static readonly TimeSpan EventsHbInterval = TimeSpan.FromSeconds(30);
|
||||
|
||||
/// <summary>Default HB interval for stats. Mirrors Go <c>statsHBInterval = 10s</c>.</summary>
|
||||
public static readonly TimeSpan StatsHbInterval = TimeSpan.FromSeconds(10);
|
||||
|
||||
/// <summary>Minimum interval between statsz publishes. Mirrors Go <c>defaultStatszRateLimit = 1s</c>.</summary>
|
||||
public static readonly TimeSpan DefaultStatszRateLimit = TimeSpan.FromSeconds(1);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SysMsgHandler — delegate for internal system message dispatch
|
||||
// Mirrors Go <c>sysMsgHandler</c> func type in events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Callback invoked when an internal system message is dispatched.
|
||||
/// Mirrors Go <c>sysMsgHandler</c> in server/events.go.
|
||||
/// </summary>
|
||||
public delegate void SysMsgHandler(
|
||||
Subscription sub,
|
||||
NatsClient client,
|
||||
Account acc,
|
||||
string subject,
|
||||
string reply,
|
||||
byte[] hdr,
|
||||
byte[] msg);
|
||||
|
||||
// ============================================================================
|
||||
// InSysMsg — queued internal system message
|
||||
// Mirrors Go <c>inSysMsg</c> struct in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Holds a system message queued for internal delivery, avoiding the
|
||||
/// route/gateway path.
|
||||
/// Mirrors Go <c>inSysMsg</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
internal sealed class InSysMsg
|
||||
{
|
||||
public Subscription? Sub { get; set; }
|
||||
public NatsClient? Client { get; set; }
|
||||
public Account? Acc { get; set; }
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public string Reply { get; set; } = string.Empty;
|
||||
public byte[]? Hdr { get; set; }
|
||||
public byte[]? Msg { get; set; }
|
||||
public SysMsgHandler? Cb { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// InternalState — server internal/sys state
|
||||
// Mirrors Go <c>internal</c> struct in server/events.go.
|
||||
// Uses Monitor lock (lock(this)) in place of Go's embedded sync.Mutex.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Holds all internal state used by the server's system-account event
|
||||
/// machinery: account reference, client, send/receive queues, timers,
|
||||
/// reply handlers, and heartbeat configuration.
|
||||
/// Mirrors Go <c>internal</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
internal sealed class InternalState
|
||||
{
|
||||
// ---- identity / sequencing ----
|
||||
public Account? Account { get; set; }
|
||||
public NatsClient? Client { get; set; }
|
||||
public ulong Seq { get; set; }
|
||||
public int Sid { get; set; }
|
||||
|
||||
// ---- remote server tracking ----
|
||||
/// <summary>Map of server ID → serverUpdate. Mirrors Go <c>servers map[string]*serverUpdate</c>.</summary>
|
||||
public Dictionary<string, ServerUpdate> Servers { get; set; } = new();
|
||||
|
||||
// ---- timers ----
|
||||
/// <summary>Sweeper timer. Mirrors Go <c>sweeper *time.Timer</c>.</summary>
|
||||
public System.Threading.Timer? Sweeper { get; set; }
|
||||
|
||||
/// <summary>Stats heartbeat timer. Mirrors Go <c>stmr *time.Timer</c>.</summary>
|
||||
public System.Threading.Timer? StatsMsgTimer { get; set; }
|
||||
|
||||
// ---- reply handlers ----
|
||||
/// <summary>
|
||||
/// Pending reply subject → handler map.
|
||||
/// Mirrors Go <c>replies map[string]msgHandler</c>.
|
||||
/// </summary>
|
||||
public Dictionary<string, Action<Subscription, NatsClient, Account, string, string, byte[], byte[]>> Replies { get; set; } = new();
|
||||
|
||||
// ---- queues ----
|
||||
/// <summary>Outbound message send queue. Mirrors Go <c>sendq *ipQueue[*pubMsg]</c>.</summary>
|
||||
public IpQueue<PubMsg>? SendQueue { get; set; }
|
||||
|
||||
/// <summary>Inbound receive queue. Mirrors Go <c>recvq *ipQueue[*inSysMsg]</c>.</summary>
|
||||
public IpQueue<InSysMsg>? RecvQueue { get; set; }
|
||||
|
||||
/// <summary>Priority receive queue for STATSZ/Pings. Mirrors Go <c>recvqp *ipQueue[*inSysMsg]</c>.</summary>
|
||||
public IpQueue<InSysMsg>? RecvQueuePriority { get; set; }
|
||||
|
||||
/// <summary>Reset channel used to restart the send loop. Mirrors Go <c>resetCh chan struct{}</c>.</summary>
|
||||
public System.Threading.Channels.Channel<bool>? ResetChannel { get; set; }
|
||||
|
||||
// ---- durations ----
|
||||
/// <summary>Maximum time before an orphaned server entry is removed. Mirrors Go <c>orphMax</c>.</summary>
|
||||
public TimeSpan OrphanMax { get; set; }
|
||||
|
||||
/// <summary>Interval at which orphan checks run. Mirrors Go <c>chkOrph</c>.</summary>
|
||||
public TimeSpan CheckOrphan { get; set; }
|
||||
|
||||
/// <summary>Interval between statsz publishes. Mirrors Go <c>statsz</c>.</summary>
|
||||
public TimeSpan StatszInterval { get; set; }
|
||||
|
||||
/// <summary>Client-facing statsz interval. Mirrors Go <c>cstatsz</c>.</summary>
|
||||
public TimeSpan ClientStatszInterval { get; set; }
|
||||
|
||||
// ---- misc ----
|
||||
/// <summary>Short hash used for shared-inbox routing. Mirrors Go <c>shash string</c>.</summary>
|
||||
public string ShortHash { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Inbox prefix for this server's internal client. Mirrors Go <c>inboxPre string</c>.</summary>
|
||||
public string InboxPrefix { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Subscription for remote stats. Mirrors Go <c>remoteStatsSub *subscription</c>.</summary>
|
||||
public Subscription? RemoteStatsSub { get; set; }
|
||||
|
||||
/// <summary>Time of the last statsz publish. Mirrors Go <c>lastStatsz time.Time</c>.</summary>
|
||||
public DateTime LastStatsz { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ServerUpdate — remote server heartbeat tracking
|
||||
// Mirrors Go <c>serverUpdate</c> struct in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the sequence number and last-seen timestamp of a remote server's
|
||||
/// system heartbeat. Used to detect orphaned servers.
|
||||
/// Mirrors Go <c>serverUpdate</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
internal sealed class ServerUpdate
|
||||
{
|
||||
/// <summary>Last sequence number received from the remote server.</summary>
|
||||
public ulong Seq { get; set; }
|
||||
|
||||
/// <summary>Wall-clock time of the last heartbeat.</summary>
|
||||
public DateTime LTime { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PubMsg — internally-queued outbound publish message
|
||||
// Mirrors Go <c>pubMsg</c> struct in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Holds an outbound message that the server wants to publish via the internal
|
||||
/// send loop, avoiding direct route/gateway writes.
|
||||
/// Mirrors Go <c>pubMsg</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
internal sealed class PubMsg
|
||||
{
|
||||
public NatsClient? Client { get; set; }
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public string Reply { get; set; } = string.Empty;
|
||||
public ServerInfo? Si { get; set; }
|
||||
public byte[]? Hdr { get; set; }
|
||||
public object? Msg { get; set; }
|
||||
|
||||
/// <summary>Compression type. TODO: session 12 — wire up compressionType enum.</summary>
|
||||
public int Oct { get; set; }
|
||||
|
||||
public bool Echo { get; set; }
|
||||
public bool Last { get; set; }
|
||||
|
||||
// TODO: session 12 — add pool return helper (returnToPool).
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// DataStats — message/byte counter pair (sent or received)
|
||||
// Mirrors Go <c>DataStats</c> struct in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Reports how many messages and bytes were sent or received.
|
||||
/// Optionally breaks out gateway, route, and leaf-node traffic.
|
||||
/// Mirrors Go <c>DataStats</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class DataStats
|
||||
{
|
||||
[JsonPropertyName("msgs")]
|
||||
public long Msgs { get; set; }
|
||||
|
||||
[JsonPropertyName("bytes")]
|
||||
public long Bytes { get; set; }
|
||||
|
||||
[JsonPropertyName("gateways")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public MsgBytes? Gateways { get; set; }
|
||||
|
||||
[JsonPropertyName("routes")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public MsgBytes? Routes { get; set; }
|
||||
|
||||
[JsonPropertyName("leafs")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public MsgBytes? Leafs { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MsgBytes — simple message+byte pair used inside DataStats
|
||||
// Mirrors Go <c>MsgBytes</c> struct in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// A simple pair of message and byte counts, used as a nested breakdown
|
||||
/// inside <see cref="DataStats"/>.
|
||||
/// Mirrors Go <c>MsgBytes</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class MsgBytes
|
||||
{
|
||||
[JsonPropertyName("msgs")]
|
||||
public long Msgs { get; set; }
|
||||
|
||||
[JsonPropertyName("bytes")]
|
||||
public long Bytes { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// RouteStat / GatewayStat — per-route and per-gateway stat snapshots
|
||||
// Mirrors Go <c>RouteStat</c> and <c>GatewayStat</c> in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Statistics snapshot for a single cluster route connection.
|
||||
/// Mirrors Go <c>RouteStat</c> in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class RouteStat
|
||||
{
|
||||
[JsonPropertyName("rid")]
|
||||
public ulong Id { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("sent")]
|
||||
public DataStats Sent { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("received")]
|
||||
public DataStats Received { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("pending")]
|
||||
public int Pending { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statistics snapshot for a gateway connection.
|
||||
/// Mirrors Go <c>GatewayStat</c> in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class GatewayStat
|
||||
{
|
||||
[JsonPropertyName("gwid")]
|
||||
public ulong Id { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("sent")]
|
||||
public DataStats Sent { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("received")]
|
||||
public DataStats Received { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("inbound_connections")]
|
||||
public int NumInbound { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ServerStatsMsg — periodic stats advisory published on $SYS.SERVER.{id}.STATSZ
|
||||
// Mirrors Go <c>ServerStatsMsg</c> struct in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Periodic advisory message containing the current server statistics.
|
||||
/// Mirrors Go <c>ServerStatsMsg</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class ServerStatsMsg
|
||||
{
|
||||
[JsonPropertyName("server")]
|
||||
public ServerInfo Server { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("statsz")]
|
||||
public ServerStatsAdvisory Stats { get; set; } = new();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ServerStatsAdvisory — the statsz payload inside ServerStatsMsg
|
||||
// Mirrors Go <c>ServerStats</c> struct (advisory form) in server/events.go.
|
||||
// NOTE: distinct from the internal ServerStats in NatsServerTypes.cs.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// The JSON-serialisable statistics payload included inside <see cref="ServerStatsMsg"/>.
|
||||
/// Mirrors Go <c>ServerStats</c> struct (advisory form) in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class ServerStatsAdvisory
|
||||
{
|
||||
[JsonPropertyName("start")]
|
||||
public DateTime Start { get; set; }
|
||||
|
||||
[JsonPropertyName("mem")]
|
||||
public long Mem { get; set; }
|
||||
|
||||
[JsonPropertyName("cores")]
|
||||
public int Cores { get; set; }
|
||||
|
||||
[JsonPropertyName("cpu")]
|
||||
public double Cpu { get; set; }
|
||||
|
||||
[JsonPropertyName("connections")]
|
||||
public int Connections { get; set; }
|
||||
|
||||
[JsonPropertyName("total_connections")]
|
||||
public ulong TotalConnections { get; set; }
|
||||
|
||||
[JsonPropertyName("active_accounts")]
|
||||
public int ActiveAccounts { get; set; }
|
||||
|
||||
[JsonPropertyName("subscriptions")]
|
||||
public uint NumSubs { get; set; }
|
||||
|
||||
[JsonPropertyName("sent")]
|
||||
public DataStats Sent { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("received")]
|
||||
public DataStats Received { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("slow_consumers")]
|
||||
public long SlowConsumers { get; set; }
|
||||
|
||||
[JsonPropertyName("slow_consumer_stats")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SlowConsumersStats? SlowConsumersStats { get; set; }
|
||||
|
||||
[JsonPropertyName("stale_connections")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public long StaleConnections { get; set; }
|
||||
|
||||
[JsonPropertyName("stale_connection_stats")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public StaleConnectionStats? StaleConnectionStats { get; set; }
|
||||
|
||||
[JsonPropertyName("stalled_clients")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public long StalledClients { get; set; }
|
||||
|
||||
[JsonPropertyName("routes")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<RouteStat>? Routes { get; set; }
|
||||
|
||||
[JsonPropertyName("gateways")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<GatewayStat>? Gateways { get; set; }
|
||||
|
||||
[JsonPropertyName("active_servers")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public int ActiveServers { get; set; }
|
||||
|
||||
/// <summary>JetStream stats. TODO: session 19 — wire JetStreamVarz type.</summary>
|
||||
[JsonPropertyName("jetstream")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public object? JetStream { get; set; }
|
||||
|
||||
[JsonPropertyName("gomemlimit")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public long MemLimit { get; set; }
|
||||
|
||||
[JsonPropertyName("gomaxprocs")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public int MaxProcs { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SlowConsumersStats / StaleConnectionStats — advisory-layer per-kind counters
|
||||
// These are the JSON-serialisable variants used in ServerStatsAdvisory.
|
||||
// The internal atomic counters live in NatsServerTypes.cs (SlowConsumerStats /
|
||||
// StaleConnectionStats with different casing).
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Per-kind slow-consumer counters included in stats advisories.
|
||||
/// Mirrors Go <c>SlowConsumersStats</c> in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class SlowConsumersStats
|
||||
{
|
||||
[JsonPropertyName("clients")]
|
||||
public ulong Clients { get; set; }
|
||||
|
||||
[JsonPropertyName("routes")]
|
||||
public ulong Routes { get; set; }
|
||||
|
||||
[JsonPropertyName("gateways")]
|
||||
public ulong Gateways { get; set; }
|
||||
|
||||
[JsonPropertyName("leafs")]
|
||||
public ulong Leafs { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Per-kind stale-connection counters included in stats advisories.
|
||||
/// Mirrors Go <c>StaleConnectionStats</c> in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class StaleConnectionStats
|
||||
{
|
||||
[JsonPropertyName("clients")]
|
||||
public ulong Clients { get; set; }
|
||||
|
||||
[JsonPropertyName("routes")]
|
||||
public ulong Routes { get; set; }
|
||||
|
||||
[JsonPropertyName("gateways")]
|
||||
public ulong Gateways { get; set; }
|
||||
|
||||
[JsonPropertyName("leafs")]
|
||||
public ulong Leafs { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ConnectEventMsg / DisconnectEventMsg — client lifecycle advisories
|
||||
// Mirrors Go structs in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Advisory published on <c>$SYS.ACCOUNT.{acc}.CONNECT</c> when a new
|
||||
/// client connection is established within a tracked account.
|
||||
/// Mirrors Go <c>ConnectEventMsg</c> in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class ConnectEventMsg : TypedEvent
|
||||
{
|
||||
[JsonPropertyName("server")]
|
||||
public ServerInfo Server { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("client")]
|
||||
public ClientInfo Client { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advisory published on <c>$SYS.ACCOUNT.{acc}.DISCONNECT</c> when a
|
||||
/// previously-tracked client connection closes.
|
||||
/// Mirrors Go <c>DisconnectEventMsg</c> in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class DisconnectEventMsg : TypedEvent
|
||||
{
|
||||
[JsonPropertyName("server")]
|
||||
public ServerInfo Server { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("client")]
|
||||
public ClientInfo Client { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("sent")]
|
||||
public DataStats Sent { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("received")]
|
||||
public DataStats Received { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("reason")]
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OCSPPeerRejectEventMsg / OCSPPeerChainlinkInvalidEventMsg
|
||||
// Mirrors Go structs in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Advisory published when a peer TLS handshake is rejected due to OCSP
|
||||
/// invalidation of the peer's leaf certificate.
|
||||
/// Mirrors Go <c>OCSPPeerRejectEventMsg</c> in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class OcspPeerRejectEventMsg : TypedEvent
|
||||
{
|
||||
[JsonPropertyName("kind")]
|
||||
public string Kind { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("peer")]
|
||||
public CertInfo Peer { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("server")]
|
||||
public ServerInfo Server { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("reason")]
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advisory published when a certificate in a valid TLS chain is found to be
|
||||
/// OCSP-invalid during a peer handshake. Both the invalid link and the
|
||||
/// peer's leaf cert are included.
|
||||
/// Mirrors Go <c>OCSPPeerChainlinkInvalidEventMsg</c> in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class OcspPeerChainlinkInvalidEventMsg : TypedEvent
|
||||
{
|
||||
[JsonPropertyName("link")]
|
||||
public CertInfo Link { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("peer")]
|
||||
public CertInfo Peer { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("server")]
|
||||
public ServerInfo Server { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("reason")]
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// AccountNumConns / AccountStat — account connection count advisories
|
||||
// Mirrors Go structs in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Advisory heartbeat published when the connection count for a tracked
|
||||
/// account changes, or on a periodic schedule.
|
||||
/// Mirrors Go <c>AccountNumConns</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class AccountNumConns : TypedEvent
|
||||
{
|
||||
[JsonPropertyName("server")]
|
||||
public ServerInfo Server { get; set; } = new();
|
||||
|
||||
// Embedded AccountStat fields are inlined via composition.
|
||||
[JsonPropertyName("acc")]
|
||||
public string Account { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("conns")]
|
||||
public int Conns { get; set; }
|
||||
|
||||
[JsonPropertyName("leafnodes")]
|
||||
public int LeafNodes { get; set; }
|
||||
|
||||
[JsonPropertyName("total_conns")]
|
||||
public int TotalConns { get; set; }
|
||||
|
||||
[JsonPropertyName("num_subscriptions")]
|
||||
public uint NumSubs { get; set; }
|
||||
|
||||
[JsonPropertyName("sent")]
|
||||
public DataStats Sent { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("received")]
|
||||
public DataStats Received { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("slow_consumers")]
|
||||
public long SlowConsumers { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statistic data common to <see cref="AccountNumConns"/> and account-level
|
||||
/// monitoring responses.
|
||||
/// Mirrors Go <c>AccountStat</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class AccountStat
|
||||
{
|
||||
[JsonPropertyName("acc")]
|
||||
public string Account { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("conns")]
|
||||
public int Conns { get; set; }
|
||||
|
||||
[JsonPropertyName("leafnodes")]
|
||||
public int LeafNodes { get; set; }
|
||||
|
||||
[JsonPropertyName("total_conns")]
|
||||
public int TotalConns { get; set; }
|
||||
|
||||
[JsonPropertyName("num_subscriptions")]
|
||||
public uint NumSubs { get; set; }
|
||||
|
||||
[JsonPropertyName("sent")]
|
||||
public DataStats Sent { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("received")]
|
||||
public DataStats Received { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("slow_consumers")]
|
||||
public long SlowConsumers { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal request payload sent when this server first starts tracking an
|
||||
/// account, asking peer servers for their local connection counts.
|
||||
/// Mirrors Go <c>accNumConnsReq</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
internal sealed class AccNumConnsReq
|
||||
{
|
||||
[JsonPropertyName("server")]
|
||||
public ServerInfo Server { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("acc")]
|
||||
public string Account { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ServerCapability / ServerID — server identity and capability flags
|
||||
// Mirrors Go types in server/events.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Bit-flag capability set for a remote server.
|
||||
/// Mirrors Go <c>ServerCapability uint64</c> in server/events.go.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ServerCapability : ulong
|
||||
{
|
||||
/// <summary>No capabilities.</summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>Server has JetStream enabled. Mirrors Go <c>JetStreamEnabled</c>.</summary>
|
||||
JetStreamEnabled = 1UL << 0,
|
||||
|
||||
/// <summary>New stream snapshot capability. Mirrors Go <c>BinaryStreamSnapshot</c>.</summary>
|
||||
BinaryStreamSnapshot = 1UL << 1,
|
||||
|
||||
/// <summary>Move NRG traffic out of system account. Mirrors Go <c>AccountNRG</c>.</summary>
|
||||
AccountNrg = 1UL << 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimal static identity for a remote server (name, host, ID).
|
||||
/// Mirrors Go <c>ServerID</c> struct in server/events.go.
|
||||
/// </summary>
|
||||
public sealed class ServerIdentity
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("host")]
|
||||
public string Host { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public string Id { get; set; } = string.Empty;
|
||||
}
|
||||
Reference in New Issue
Block a user