015c556ced
AddZbSecretsSqlServerStore / AddZbSecretsSqlServerReplication (and the Akka extension, same defect class) TryAdd-ed their ISecretStore, ISecretsStoreMigrator and ISecretReplicator ahead of their internal AddZbSecrets call. An application that had already called AddZbSecrets therefore silently kept the SQLite store (shared-store mode) or NoOpSecretReplicator (hub/Akka modes). They now call AddZbSecrets first and RemoveAll + AddSingleton their own registrations; a later AddZbSecrets only TryAdds, so either order yields the same graph with exactly one ISecretStore registration. - tests: RegistrationOrderTests (SqlServer + Akka) build and resolve the real container in both orders; core-first fails without the fix - Directory.Build.props 0.6.5 -> 0.6.6 (NOT packed or published) - code-reviews: Secrets-001 Resolved; README regenerated Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
50 lines
1.7 KiB
C#
50 lines
1.7 KiB
C#
using Akka.Actor;
|
|
using Akka.Cluster;
|
|
using Akka.Configuration;
|
|
|
|
namespace ZB.MOM.WW.Secrets.Replicator.AkkaDotNet.Tests.DependencyInjection;
|
|
|
|
/// <summary>
|
|
/// One self-joined single-node cluster shared by a test class — the miniature app node the
|
|
/// replication actor's DistributedPubSub mediator needs. Tests that spawn the actor must give each
|
|
/// container its own <c>Secrets:Replication:ActorName</c>, since actor names are unique per system.
|
|
/// </summary>
|
|
public sealed class SingleNodeClusterFixture : IAsyncLifetime
|
|
{
|
|
/// <summary>The joined, Up actor system.</summary>
|
|
public ActorSystem System { get; private set; } = null!;
|
|
|
|
/// <inheritdoc />
|
|
public async Task InitializeAsync()
|
|
{
|
|
System = ActorSystem.Create("zb-secrets-order", ConfigurationFactory.ParseString("""
|
|
akka {
|
|
loglevel = WARNING
|
|
actor.provider = cluster
|
|
remote.dot-netty.tcp {
|
|
hostname = "127.0.0.1"
|
|
public-hostname = "127.0.0.1"
|
|
port = 0
|
|
}
|
|
}
|
|
""").WithFallback(AkkaSecretsReplication.SerializationConfig));
|
|
|
|
Cluster cluster = Cluster.Get(System);
|
|
cluster.Join(cluster.SelfAddress);
|
|
|
|
DateTime deadline = DateTime.UtcNow + TimeSpan.FromSeconds(20);
|
|
while (cluster.State.Members.All(m => m.Status != MemberStatus.Up))
|
|
{
|
|
if (DateTime.UtcNow > deadline)
|
|
{
|
|
throw new TimeoutException("Single-node cluster never reached Up.");
|
|
}
|
|
|
|
await Task.Delay(100);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task DisposeAsync() => await System.Terminate();
|
|
}
|