feat: port sessions 14-16 — Routes, Leaf Nodes & Gateways
Session 14 (57 features, IDs 2895-2951): - RouteTypes: RouteType enum, Route, RouteInfo, ConnectInfo, ASubs, GossipMode Session 15 (71 features, IDs 1979-2049): - LeafNodeTypes: Leaf, LeafNodeCfg (replaces stub), LeafConnectInfo Session 16 (91 features, IDs 1263-1353): - GatewayTypes: GatewayInterestMode, SrvGateway (replaces stub), GatewayCfg, Gateway, OutSide, InSide, SitAlly, GwReplyMap, GwReplyMapping
This commit is contained in:
185
dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteTypes.cs
Normal file
185
dotnet/src/ZB.MOM.NatsNet.Server/Routes/RouteTypes.cs
Normal file
@@ -0,0 +1,185 @@
|
||||
// Copyright 2013-2025 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/route.go in the NATS server Go source.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using ZB.MOM.NatsNet.Server.Internal;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server;
|
||||
|
||||
// ============================================================================
|
||||
// Session 14: Routes
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Designates whether a route was explicitly configured or discovered via gossip.
|
||||
/// Mirrors Go <c>RouteType</c> iota in route.go.
|
||||
/// Note: Go defines Implicit=0, Explicit=1 — we keep TombStone=2 for future use.
|
||||
/// </summary>
|
||||
public enum RouteType : int
|
||||
{
|
||||
/// <summary>This route was learned from speaking to other routes.</summary>
|
||||
Implicit = 0,
|
||||
/// <summary>This route was explicitly configured.</summary>
|
||||
Explicit = 1,
|
||||
/// <summary>Reserved tombstone marker for removed routes.</summary>
|
||||
TombStone = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gossip mode constants exchanged between route servers.
|
||||
/// Mirrors the const block immediately after <c>routeInfo</c> in route.go.
|
||||
/// Do not change values — they are part of the wire protocol.
|
||||
/// </summary>
|
||||
internal static class GossipMode
|
||||
{
|
||||
public const byte Default = 0;
|
||||
public const byte Disabled = 1;
|
||||
public const byte Override = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Per-connection route state embedded in <see cref="ClientConnection"/> when the
|
||||
/// connection kind is <c>Router</c>.
|
||||
/// Mirrors Go <c>route</c> struct in route.go.
|
||||
/// </summary>
|
||||
internal sealed class Route
|
||||
{
|
||||
/// <summary>Remote server ID string.</summary>
|
||||
public string RemoteId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Remote server name.</summary>
|
||||
public string RemoteName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>True if this server solicited the outbound connection.</summary>
|
||||
public bool DidSolicit { get; set; }
|
||||
|
||||
/// <summary>True if the connection should be retried on failure.</summary>
|
||||
public bool Retry { get; set; }
|
||||
|
||||
/// <summary>Leaf-node origin cluster flag (lnoc).</summary>
|
||||
public bool Lnoc { get; set; }
|
||||
|
||||
/// <summary>Leaf-node origin cluster with unsub support (lnocu).</summary>
|
||||
public bool Lnocu { get; set; }
|
||||
|
||||
/// <summary>Whether this is an explicit or implicit route.</summary>
|
||||
public RouteType RouteType { get; set; }
|
||||
|
||||
/// <summary>Remote URL used to establish the connection.</summary>
|
||||
public Uri? Url { get; set; }
|
||||
|
||||
/// <summary>True if the remote requires authentication.</summary>
|
||||
public bool AuthRequired { get; set; }
|
||||
|
||||
/// <summary>True if the remote requires TLS.</summary>
|
||||
public bool TlsRequired { get; set; }
|
||||
|
||||
/// <summary>True if JetStream is enabled on the remote.</summary>
|
||||
public bool JetStream { get; set; }
|
||||
|
||||
/// <summary>List of client connect URLs advertised by the remote.</summary>
|
||||
public List<string> ConnectUrls { get; set; } = [];
|
||||
|
||||
/// <summary>List of WebSocket connect URLs advertised by the remote.</summary>
|
||||
public List<string> WsConnUrls { get; set; } = [];
|
||||
|
||||
/// <summary>Gateway URL advertised by the remote.</summary>
|
||||
public string GatewayUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Leaf-node URL advertised by the remote.</summary>
|
||||
public string LeafnodeUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Cluster hash used for routing.</summary>
|
||||
public string Hash { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Server ID hash (6 bytes encoded).</summary>
|
||||
public string IdHash { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Index of this route in the <c>s.routes[remoteID]</c> slice.
|
||||
/// Initialized to -1 to indicate the route has not yet been registered.
|
||||
/// </summary>
|
||||
public int PoolIdx { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// When set, this route is pinned to a specific account and the account
|
||||
/// name will not be included in routed protocols.
|
||||
/// </summary>
|
||||
public byte[]? AccName { get; set; }
|
||||
|
||||
/// <summary>True if this is a connection to an old server or one with pooling disabled.</summary>
|
||||
public bool NoPool { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Selected compression mode, which may differ from the server-configured mode.
|
||||
/// </summary>
|
||||
public string Compression { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Transient gossip mode byte sent when initiating an implicit route.
|
||||
/// </summary>
|
||||
public byte GossipMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When set in a pooling scenario, signals that the route should trigger
|
||||
/// creation of the next pooled connection after receiving the first PONG.
|
||||
/// </summary>
|
||||
public RouteInfo? StartNewRoute { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimal descriptor used to create a new route connection, including
|
||||
/// the target URL, its type, and gossip mode.
|
||||
/// Mirrors Go <c>routeInfo</c> struct (the small inner type) in route.go.
|
||||
/// </summary>
|
||||
internal sealed class RouteInfo
|
||||
{
|
||||
public Uri? Url { get; set; }
|
||||
public RouteType RouteType { get; set; }
|
||||
public byte GossipMode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CONNECT protocol payload exchanged between cluster servers.
|
||||
/// Fields map 1-to-1 with the JSON tags in Go's <c>connectInfo</c>.
|
||||
/// Mirrors Go <c>connectInfo</c> struct in route.go.
|
||||
/// </summary>
|
||||
internal sealed class ConnectInfo
|
||||
{
|
||||
[JsonPropertyName("echo")] public bool Echo { get; set; }
|
||||
[JsonPropertyName("verbose")] public bool Verbose { get; set; }
|
||||
[JsonPropertyName("pedantic")] public bool Pedantic { get; set; }
|
||||
[JsonPropertyName("user")] public string User { get; set; } = string.Empty;
|
||||
[JsonPropertyName("pass")] public string Pass { get; set; } = string.Empty;
|
||||
[JsonPropertyName("tls_required")] public bool Tls { get; set; }
|
||||
[JsonPropertyName("headers")] public bool Headers { get; set; }
|
||||
[JsonPropertyName("name")] public string Name { get; set; } = string.Empty;
|
||||
[JsonPropertyName("cluster")] public string Cluster { get; set; } = string.Empty;
|
||||
[JsonPropertyName("cluster_dynamic")] public bool Dynamic { get; set; }
|
||||
[JsonPropertyName("lnoc")] public bool Lnoc { get; set; }
|
||||
[JsonPropertyName("lnocu")] public bool Lnocu { get; set; }
|
||||
[JsonPropertyName("gateway")] public string Gateway { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds a set of subscriptions for a single account, used when fanning out
|
||||
/// route subscription interest.
|
||||
/// Mirrors Go <c>asubs</c> struct in route.go.
|
||||
/// </summary>
|
||||
internal sealed class ASubs
|
||||
{
|
||||
public Account? Account { get; set; }
|
||||
public List<Internal.Subscription> Subs { get; set; } = [];
|
||||
}
|
||||
Reference in New Issue
Block a user