From d1935bc9ec5dc8e01387fb932ae292cbe963b0ed Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 23 Feb 2026 05:59:03 -0500 Subject: [PATCH] feat: add jetstream config validation models --- .../JetStream/Models/ConsumerConfig.cs | 18 +++++++++++++ .../JetStream/Models/StreamConfig.cs | 9 +++++++ .../Validation/JetStreamConfigValidator.cs | 26 +++++++++++++++++++ .../JetStreamConfigValidationTests.cs | 15 +++++++++++ 4 files changed, 68 insertions(+) create mode 100644 src/NATS.Server/JetStream/Models/ConsumerConfig.cs create mode 100644 src/NATS.Server/JetStream/Models/StreamConfig.cs create mode 100644 src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs create mode 100644 tests/NATS.Server.Tests/JetStreamConfigValidationTests.cs diff --git a/src/NATS.Server/JetStream/Models/ConsumerConfig.cs b/src/NATS.Server/JetStream/Models/ConsumerConfig.cs new file mode 100644 index 0000000..b7531ee --- /dev/null +++ b/src/NATS.Server/JetStream/Models/ConsumerConfig.cs @@ -0,0 +1,18 @@ +namespace NATS.Server.JetStream.Models; + +public sealed class ConsumerConfig +{ + public string DurableName { get; set; } = string.Empty; + public string? FilterSubject { get; set; } + public AckPolicy AckPolicy { get; set; } = AckPolicy.None; + public int AckWaitMs { get; set; } = 30_000; + public int MaxDeliver { get; set; } = 1; + public bool Push { get; set; } + public int HeartbeatMs { get; set; } +} + +public enum AckPolicy +{ + None, + Explicit, +} diff --git a/src/NATS.Server/JetStream/Models/StreamConfig.cs b/src/NATS.Server/JetStream/Models/StreamConfig.cs new file mode 100644 index 0000000..eccc10f --- /dev/null +++ b/src/NATS.Server/JetStream/Models/StreamConfig.cs @@ -0,0 +1,9 @@ +namespace NATS.Server.JetStream.Models; + +public sealed class StreamConfig +{ + public string Name { get; set; } = string.Empty; + public List Subjects { get; set; } = []; + public int MaxMsgs { get; set; } + public int Replicas { get; set; } = 1; +} diff --git a/src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs b/src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs new file mode 100644 index 0000000..b1a8913 --- /dev/null +++ b/src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs @@ -0,0 +1,26 @@ +using NATS.Server.JetStream.Models; + +namespace NATS.Server.JetStream.Validation; + +public static class JetStreamConfigValidator +{ + public static ValidationResult Validate(StreamConfig config) + => string.IsNullOrWhiteSpace(config.Name) || config.Subjects.Count == 0 + ? ValidationResult.Invalid("name/subjects required") + : ValidationResult.Valid(); +} + +public sealed class ValidationResult +{ + public bool IsValid { get; } + public string Message { get; } + + private ValidationResult(bool isValid, string message) + { + IsValid = isValid; + Message = message; + } + + public static ValidationResult Valid() => new(true, string.Empty); + public static ValidationResult Invalid(string message) => new(false, message); +} diff --git a/tests/NATS.Server.Tests/JetStreamConfigValidationTests.cs b/tests/NATS.Server.Tests/JetStreamConfigValidationTests.cs new file mode 100644 index 0000000..2547006 --- /dev/null +++ b/tests/NATS.Server.Tests/JetStreamConfigValidationTests.cs @@ -0,0 +1,15 @@ +using NATS.Server.JetStream.Models; +using NATS.Server.JetStream.Validation; + +namespace NATS.Server.Tests; + +public class JetStreamConfigValidationTests +{ + [Fact] + public void Stream_requires_name_and_subjects() + { + var config = new StreamConfig { Name = "", Subjects = [] }; + var result = JetStreamConfigValidator.Validate(config); + result.IsValid.ShouldBeFalse(); + } +}