feat: add stream import cycle detection (Gap 9.3)

Add StreamImportFormsCycle DFS method to Account plus GetStreamImportSources
and HasStreamImportFrom helpers. Add GetStreamImportSourceAccounts to ImportMap.
10 tests cover direct, indirect, self, diamond, and empty import scenarios.
This commit is contained in:
Joseph Doherty
2026-02-25 12:53:04 -05:00
parent 3107615885
commit 2bdf0e75ed
5 changed files with 436 additions and 0 deletions

View File

@@ -1,3 +1,5 @@
using NATS.Server.Auth;
namespace NATS.Server.Imports;
public sealed class ImportMap
@@ -15,4 +17,23 @@ public sealed class ImportMap
list.Add(si);
}
/// <summary>
/// Returns the distinct set of source accounts referenced by stream imports.
/// Go reference: accounts.go imports.streams — each streamImport has an acc field.
/// </summary>
public IReadOnlyList<Account> GetStreamImportSourceAccounts()
{
if (Streams.Count == 0)
return [];
var seen = new HashSet<string>(StringComparer.Ordinal);
var result = new List<Account>(Streams.Count);
foreach (var si in Streams)
{
if (seen.Add(si.SourceAccount.Name))
result.Add(si.SourceAccount);
}
return result;
}
}

View File

@@ -0,0 +1,12 @@
namespace NATS.Server.Imports;
/// <summary>
/// Immutable view of a service export, returned by Account query methods.
/// IsWildcard is true when the subject contains '*' or '>'.
/// Go reference: accounts.go serviceExport struct.
/// </summary>
public sealed record ServiceExportInfo(
string Subject,
ServiceResponseType ResponseType,
IReadOnlyList<string> ApprovedAccounts,
bool IsWildcard);