Commit Graph

190 Commits

Author SHA1 Message Date
Joseph Doherty
264b49f96a test: add go jetstream parity runner 2026-02-23 06:24:41 -05:00
Joseph Doherty
6c83f12e5c feat: add reload semantics for cluster and jetstream options 2026-02-23 06:23:34 -05:00
Joseph Doherty
2aa7265db1 feat: enforce account jetstream limits and jwt tiers 2026-02-23 06:21:51 -05:00
Joseph Doherty
ccbcf759a9 feat: implement jsz and live jetstream monitoring 2026-02-23 06:19:41 -05:00
Joseph Doherty
c87661800d feat: add stream replica groups and leader stepdown 2026-02-23 06:17:30 -05:00
Joseph Doherty
23216d0a48 feat: integrate jetstream meta-group placement 2026-02-23 06:16:01 -05:00
Joseph Doherty
005600b9b8 feat: implement raft snapshot catchup 2026-02-23 06:13:08 -05:00
Joseph Doherty
ecc4752c07 feat: implement raft log replication and apply 2026-02-23 06:12:18 -05:00
Joseph Doherty
66ec378bdc feat: implement raft election and term state 2026-02-23 06:11:28 -05:00
Joseph Doherty
f1d3c19594 feat: add jetstream mirror and source orchestration 2026-02-23 06:10:41 -05:00
Joseph Doherty
d3aad48096 feat: enforce jetstream ack and redelivery semantics 2026-02-23 06:09:26 -05:00
Joseph Doherty
fecb51095f feat: implement jetstream push delivery and heartbeat 2026-02-23 06:08:14 -05:00
Joseph Doherty
9a0de19c2d feat: implement jetstream pull consumer fetch 2026-02-23 06:07:02 -05:00
Joseph Doherty
40b940b1fd feat: add jetstream consumer api lifecycle 2026-02-23 06:06:02 -05:00
Joseph Doherty
6825839191 feat: add jetstream publish preconditions and dedupe 2026-02-23 06:05:01 -05:00
Joseph Doherty
d73e7e2f88 feat: enforce jetstream retention and limits 2026-02-23 06:04:23 -05:00
Joseph Doherty
95691fa9e7 feat: route publishes to jetstream with puback 2026-02-23 06:03:24 -05:00
Joseph Doherty
5f530de2e4 feat: add jetstream stream lifecycle api 2026-02-23 06:02:07 -05:00
Joseph Doherty
788f4254b0 feat: implement jetstream filestore recovery baseline 2026-02-23 06:00:42 -05:00
Joseph Doherty
64e3b1bd49 feat: implement jetstream memstore core behavior 2026-02-23 06:00:10 -05:00
Joseph Doherty
cae09f9091 feat: define jetstream storage interfaces 2026-02-23 05:59:39 -05:00
Joseph Doherty
d1935bc9ec feat: add jetstream config validation models 2026-02-23 05:59:03 -05:00
Joseph Doherty
6d23e89fe8 feat: add jetstream api router and error envelope 2026-02-23 05:58:34 -05:00
Joseph Doherty
7fe15d7ce1 feat: add route propagation and bootstrap js gateway leaf services 2026-02-23 05:55:45 -05:00
Joseph Doherty
5f98e53d62 feat: add route handshake lifecycle 2026-02-23 05:46:59 -05:00
Joseph Doherty
44d426a7c5 feat: parse cluster and jetstream config blocks 2026-02-23 05:43:04 -05:00
Joseph Doherty
d9f157d9e4 feat: add client kind command matrix parity 2026-02-23 05:41:42 -05:00
Joseph Doherty
1ebf283a8c Merge branch 'feature/websocket'
# Conflicts:
#	differences.md
2026-02-23 05:28:34 -05:00
Joseph Doherty
18a6d0f478 fix: address code review findings for WebSocket implementation
- Convert WsReadInfo from mutable struct to class (prevents silent copy bugs)
- Add handshake timeout enforcement via CancellationToken in WsUpgrade
- Use buffered reading (512 bytes) in ReadHttpRequestAsync instead of byte-at-a-time
- Add IAsyncDisposable to WsConnection for proper async cleanup
- Simplify redundant mask bit check in WsReadInfo
- Remove unused WsGuid and CompressLastBlock dead code from WsConstants
- Document single-reader assumption on WsConnection read-side state
2026-02-23 05:27:36 -05:00
Joseph Doherty
02a474a91e docs: add JetStream full parity design 2026-02-23 05:25:09 -05:00
Joseph Doherty
c8a89c9de2 docs: update mqtt connection type design with config parsing scope 2026-02-23 05:18:47 -05:00
Joseph Doherty
5fd2cf040d docs: update differences.md to reflect WebSocket implementation 2026-02-23 05:18:03 -05:00
Joseph Doherty
ca88036126 feat: integrate WebSocket accept loop into NatsServer and NatsClient
Add WebSocket listener support to NatsServer alongside the existing TCP
listener. When WebSocketOptions.Port >= 0, the server binds a second
socket, performs HTTP upgrade via WsUpgrade.TryUpgradeAsync, wraps the
connection in WsConnection for transparent frame/deframe, and hands it
to the standard NatsClient pipeline.

Changes:
- NatsClient: add IsWebSocket and WsInfo properties
- NatsServer: add RunWebSocketAcceptLoopAsync and AcceptWebSocketClientAsync,
  WS listener lifecycle in StartAsync/ShutdownAsync/Dispose
- NatsOptions: change WebSocketOptions.Port default from 0 to -1 (disabled)
- WsConnection.ReadAsync: fix premature end-of-stream when ReadFrames
  returns no payloads by looping until data is available
- Add WsIntegration tests (connect, ping, pub/sub over WebSocket)
- Add WsConnection masked frame and end-of-stream unit tests
2026-02-23 05:16:57 -05:00
Joseph Doherty
4b3890f046 docs: add implementation plan for SYSTEM/ACCOUNT connection types
16 tasks across 6 layers: ClientKind + INatsClient + InternalClient,
event infrastructure, event publishing, request-reply services,
import/export model, and response routing with latency tracking.
2026-02-23 05:12:02 -05:00
Joseph Doherty
e0abce66da docs: add mqtt connection type design 2026-02-23 05:08:44 -05:00
Joseph Doherty
a0926c3a50 docs: add design doc for SYSTEM and ACCOUNT connection types
Covers 6 implementation layers: ClientKind enum + INatsClient interface,
event infrastructure with Channel<T>, system event publishing, request-reply
monitoring services, import/export model with ACCOUNT client, and response
routing with latency tracking.
2026-02-23 05:03:17 -05:00
Joseph Doherty
6d0a4d259e feat: add WsConnection Stream wrapper for transparent framing 2026-02-23 04:58:56 -05:00
Joseph Doherty
ad336167b9 docs: update differences.md to reflect config parsing and hot reload implementation 2026-02-23 04:58:53 -05:00
Joseph Doherty
684ee222ad feat: integrate config file loading and SIGHUP hot reload
Wire up the config parsing infrastructure into the server:
- NatsServer: add ReloadConfig() with digest-based change detection,
  diff/validate, CLI override preservation, and side-effect triggers
- Program.cs: two-pass CLI parsing — load config file first, then
  apply CLI args on top with InCmdLine tracking for reload precedence
- SIGHUP handler upgraded from stub warning to actual reload
- Remove config file "not yet supported" warning from StartAsync
- Add integration tests for config loading, CLI overrides, and
  reload validation
2026-02-23 04:57:34 -05:00
Joseph Doherty
fe304dfe01 fix: review fixes for WsReadInfo and WsUpgrade
- WsReadInfo: validate 64-bit frame payload length against maxPayload
  before casting to int (prevents overflow/memory exhaustion)
- WsReadInfo: always send close response per RFC 6455 Section 5.5.1,
  including for empty close frames
- WsUpgrade: restrict no-masking to leaf node connections only (browser
  clients must always mask frames)
2026-02-23 04:55:53 -05:00
Joseph Doherty
d21243bc8a feat: add config reloader with diff, validate, and CLI merge
Port of Go server/reload.go option interface and diffing logic. Compares
NatsOptions property-by-property to detect changes, tags each with category
flags (logging, auth, TLS, non-reloadable), validates that non-reloadable
options (Host, Port, ServerName) are not changed at runtime, and provides
MergeCliOverrides to ensure CLI flags always take precedence over config
file values during hot reload.
2026-02-23 04:53:25 -05:00
Joseph Doherty
1c948b5b0f feat: add WebSocket HTTP upgrade handshake 2026-02-23 04:53:21 -05:00
Joseph Doherty
bd29c529a8 feat: add WebSocket frame reader state machine 2026-02-23 04:51:54 -05:00
Joseph Doherty
4e9c415fd2 Merge branch 'feature/remaining-gaps' 2026-02-23 04:48:39 -05:00
Joseph Doherty
1a1aa9d642 fix: use byte-length for close message truncation, add exception-safe disposal
- CreateCloseMessage now operates on UTF-8 byte length (matching Go's
  len(body) behavior) instead of character length, with proper UTF-8
  boundary detection during truncation
- WsCompression.Compress now uses try/finally for exception-safe disposal
  of DeflateStream and MemoryStream
2026-02-23 04:47:57 -05:00
Joseph Doherty
8a2ded8e48 feat: add config processor mapping parsed config to NatsOptions
Port of Go server/opts.go processConfigFileLine switch. Maps parsed
NATS config dictionaries to NatsOptions fields including:
- Core options (port, host, server_name, limits, ping, write_deadline)
- Logging (debug, trace, logfile, log rotation)
- Authorization (single user, users array with permissions)
- TLS (cert/key/ca, verify, pinned_certs, handshake_first)
- Monitoring (http_port, https_port, http/https listen, base_path)
- Lifecycle (lame_duck_duration/grace_period)
- Server tags, file paths, system account options

Includes error collection (not fail-fast), duration parsing (ms/s/m/h
strings and numeric seconds), host:port listen parsing, and 56 tests
covering all config sections plus validation edge cases.
2026-02-23 04:47:54 -05:00
Joseph Doherty
6fcc9d1fd5 docs: update differences.md to reflect all remaining lower-priority gaps resolved
Mark JWT auth, OCSP, subject mapping, Windows Service, per-subsystem
log control, per-client trace, per-account stats, TLS cert expiry,
permission templates, bearer tokens, and user revocation as implemented.
2026-02-23 04:47:41 -05:00
Joseph Doherty
d5a0274fc9 feat: wire subject transforms into NatsServer message delivery path 2026-02-23 04:45:08 -05:00
Joseph Doherty
5219f77f9b fix: add include depth limit, fix PopContext guard, add SetValue fallback
- Add MaxIncludeDepth = 10 constant and thread _includeDepth through ParserState
  constructors, ProcessInclude, ParseFile (private overload), and ParseEnvValue
  to prevent StackOverflowException from recursive includes
- Fix PopContext to check _ctxs.Count <= 1 instead of == 0 so the root context
  is never popped, replacing silent crash with clear InvalidOperationException
- Add else throw in SetValue so unknown context types surface as bugs rather
  than silently dropping values
2026-02-23 04:42:37 -05:00
Joseph Doherty
d49bc5b0d7 feat: add WebSocket permessage-deflate compression
Implement WsCompression with Compress/Decompress methods per RFC 7692.
Key .NET adaptation: Flush() without Dispose() on DeflateStream to produce
the correct sync flush marker that can be stripped and re-appended.
2026-02-23 04:42:31 -05:00