refactor(configdb): drop ClusterNode.RedundancyRole (replaced by Akka leader)

Phase 1d of the v2 entity-model rewrite. The static RedundancyRole column
is replaced by Akka cluster's role-leader-of-"driver" election at runtime
(see RedundancyStateActor + ServiceLevelCalculator in Task 35).

Changes:

  - Removed `public required RedundancyRole RedundancyRole` from
    ClusterNode entity.
  - Removed `e.Property(x => x.RedundancyRole).HasConversion<string>()...`
    mapping from OtOpcUaConfigDbContext.ConfigureClusterNode.
  - Removed the `UX_ClusterNode_Primary_Per_Cluster` filtered unique index
    (filter referenced [RedundancyRole]='Primary').
  - Dropped `using ZB.MOM.WW.OtOpcUa.Configuration.Enums` from ClusterNode.cs
    (no longer needed).
  - Deleted `Enums/RedundancyRole.cs` — the enum is unused in v2-kept code.
  - DraftValidator: dropped the "exactly one Primary per cluster"
    validation block. Comment in place explaining v2 picks primary at
    runtime via Akka.
  - DraftValidatorTests: dropped ValidateClusterTopology_flags_multiple_Primary
    test; reworked BuildNode helper to no longer take a `role` argument.

Untouched (Server + Admin still reference RedundancyRole; accepted broken
per Task 56 policy):

  src/Server/ZB.MOM.WW.OtOpcUa.Server/Redundancy/{ClusterTopologyLoader,
    RedundancyStatePublisher, RedundancyTopology, ServiceLevelCalculator}.cs
  src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/RedundancyMetrics.cs

DB-runtime tests will fail against the new schema (Task 14f's migration
drops the column) — to be updated in Task 14f's SchemaComplianceTests
update:

  - SchemaComplianceTests.cs:55 (expected filtered index list)
  - StoredProceduresTests.cs:263 (raw INSERT names the column)

Verification:
  src/Core/ZB.MOM.WW.OtOpcUa.Configuration            -> 0 errors
  tests/Core/ZB.MOM.WW.OtOpcUa.Configuration.Tests    -> 0 errors
  whole solution                                       -> 71 errors
    (70 from Task 14b in Server/Admin, +1 new Server/Redundancy reference)
This commit is contained in:
Joseph Doherty
2026-05-26 04:11:57 -04:00
parent 1ddf8bb50e
commit 3c915e652e
5 changed files with 16 additions and 45 deletions

View File

@@ -161,7 +161,7 @@ public sealed class DraftValidatorTests
{
var cluster = BuildCluster(nodeCount: nodeCount, mode: mode);
var nodes = Enumerable.Range(0, enabledNodes)
.Select(i => BuildNode($"n-{i}", enabled: true, role: i == 0 ? RedundancyRole.Primary : RedundancyRole.Secondary))
.Select(i => BuildNode($"n-{i}", enabled: true))
.ToList();
var errors = DraftValidator.ValidateClusterTopology(cluster, nodes);
@@ -175,33 +175,24 @@ public sealed class DraftValidatorTests
var cluster = BuildCluster(nodeCount: 2, mode: RedundancyMode.Hot);
var nodes = new[]
{
BuildNode("primary", enabled: true, role: RedundancyRole.Primary),
BuildNode("backup", enabled: false, role: RedundancyRole.Secondary),
BuildNode("primary", enabled: true),
BuildNode("backup", enabled: false),
};
var errors = DraftValidator.ValidateClusterTopology(cluster, nodes);
errors.ShouldContain(e => e.Code == "ClusterEnabledNodeCountMismatch");
}
[Fact]
public void ValidateClusterTopology_flags_multiple_Primary()
{
var cluster = BuildCluster(nodeCount: 2, mode: RedundancyMode.Hot);
var nodes = new[]
{
BuildNode("a", enabled: true, role: RedundancyRole.Primary),
BuildNode("b", enabled: true, role: RedundancyRole.Primary),
};
var errors = DraftValidator.ValidateClusterTopology(cluster, nodes);
errors.ShouldContain(e => e.Code == "ClusterMultiplePrimary");
}
// v2: the "exactly one Primary per cluster" check is gone — Akka cluster's
// role-leader-of-"driver" elects the primary at runtime. The corresponding
// ValidateClusterTopology_flags_multiple_Primary test (and the
// ClusterMultiplePrimary error code it asserted) were removed alongside Task 14d.
[Fact]
public void ValidateClusterTopology_returns_no_errors_on_valid_standalone()
{
var cluster = BuildCluster(nodeCount: 1, mode: RedundancyMode.None);
var nodes = new[] { BuildNode("only", enabled: true, role: RedundancyRole.Primary) };
var nodes = new[] { BuildNode("only", enabled: true) };
var errors = DraftValidator.ValidateClusterTopology(cluster, nodes);
errors.ShouldBeEmpty();
@@ -219,11 +210,10 @@ public sealed class DraftValidatorTests
CreatedBy = "t",
};
private static ClusterNode BuildNode(string id, bool enabled, RedundancyRole role) => new()
private static ClusterNode BuildNode(string id, bool enabled) => new()
{
NodeId = id,
ClusterId = "c-test",
RedundancyRole = role,
Host = "localhost",
OpcUaPort = 4840,
DashboardPort = 5001,