feat: add jetstream stream lifecycle api
This commit is contained in:
91
src/NATS.Server/JetStream/Api/Handlers/StreamApiHandlers.cs
Normal file
91
src/NATS.Server/JetStream/Api/Handlers/StreamApiHandlers.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System.Text.Json;
|
||||
using NATS.Server.JetStream.Models;
|
||||
|
||||
namespace NATS.Server.JetStream.Api.Handlers;
|
||||
|
||||
public static class StreamApiHandlers
|
||||
{
|
||||
private const string CreatePrefix = "$JS.API.STREAM.CREATE.";
|
||||
private const string InfoPrefix = "$JS.API.STREAM.INFO.";
|
||||
|
||||
public static JetStreamApiResponse HandleCreate(string subject, ReadOnlySpan<byte> payload, StreamManager streamManager)
|
||||
{
|
||||
var streamName = ExtractTrailingToken(subject, CreatePrefix);
|
||||
if (streamName == null)
|
||||
return JetStreamApiResponse.NotFound(subject);
|
||||
|
||||
var config = ParseConfig(payload);
|
||||
if (string.IsNullOrWhiteSpace(config.Name))
|
||||
config.Name = streamName;
|
||||
|
||||
if (config.Subjects.Count == 0)
|
||||
config.Subjects.Add(streamName.ToLowerInvariant() + ".>");
|
||||
|
||||
return streamManager.CreateOrUpdate(config);
|
||||
}
|
||||
|
||||
public static JetStreamApiResponse HandleInfo(string subject, StreamManager streamManager)
|
||||
{
|
||||
var streamName = ExtractTrailingToken(subject, InfoPrefix);
|
||||
if (streamName == null)
|
||||
return JetStreamApiResponse.NotFound(subject);
|
||||
|
||||
return streamManager.GetInfo(streamName);
|
||||
}
|
||||
|
||||
private static string? ExtractTrailingToken(string subject, string prefix)
|
||||
{
|
||||
if (!subject.StartsWith(prefix, StringComparison.Ordinal))
|
||||
return null;
|
||||
|
||||
var token = subject[prefix.Length..].Trim();
|
||||
return token.Length == 0 ? null : token;
|
||||
}
|
||||
|
||||
private static StreamConfig ParseConfig(ReadOnlySpan<byte> payload)
|
||||
{
|
||||
if (payload.IsEmpty)
|
||||
return new StreamConfig();
|
||||
|
||||
try
|
||||
{
|
||||
using var doc = JsonDocument.Parse(payload.ToArray());
|
||||
var root = doc.RootElement;
|
||||
var config = new StreamConfig();
|
||||
|
||||
if (root.TryGetProperty("name", out var nameEl))
|
||||
config.Name = nameEl.GetString() ?? string.Empty;
|
||||
|
||||
if (root.TryGetProperty("subjects", out var subjectsEl))
|
||||
{
|
||||
if (subjectsEl.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
foreach (var item in subjectsEl.EnumerateArray())
|
||||
{
|
||||
var value = item.GetString();
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
config.Subjects.Add(value);
|
||||
}
|
||||
}
|
||||
else if (subjectsEl.ValueKind == JsonValueKind.String)
|
||||
{
|
||||
var value = subjectsEl.GetString();
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
config.Subjects.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (root.TryGetProperty("max_msgs", out var maxMsgsEl) && maxMsgsEl.TryGetInt32(out var maxMsgs))
|
||||
config.MaxMsgs = maxMsgs;
|
||||
|
||||
if (root.TryGetProperty("replicas", out var replicasEl) && replicasEl.TryGetInt32(out var replicas))
|
||||
config.Replicas = replicas;
|
||||
|
||||
return config;
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
return new StreamConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user