@page "/clusters/{ClusterId}/redundancy" @attribute [Microsoft.AspNetCore.Authorization.Authorize] @rendermode RenderMode.InteractiveServer @using Microsoft.EntityFrameworkCore @using ZB.MOM.WW.OtOpcUa.Configuration @using ZB.MOM.WW.OtOpcUa.Configuration.Entities @inject IDbContextFactory DbFactory @if (!_loaded) {

Loading…

} else if (_cluster is null) {
Cluster @ClusterId was not found. Back to list.
} else {

@_cluster.Name · Redundancy

@_cluster.ClusterId
v2 redundancy is computed at runtime by RedundancyStateActor on each admin node. The values below are the static configuration; the resolved live ServiceLevel for each peer is broadcast on the redundancy-state DPS topic and consumed by the OPC UA host's ServerStatus publisher. See docs/v2/Architecture-v2.md.
Cluster redundancy
Mode@_cluster.RedundancyMode
Node count@_cluster.NodeCount
Node service-level configuration
@if (_nodes is null || _nodes.Count == 0) {
No nodes registered.
} else {
@foreach (var n in _nodes) { }
Node ID ApplicationUri ServiceLevel base Notes
@n.NodeId @n.ApplicationUri @n.ServiceLevelBase @if (n.ServiceLevelBase >= 200) { Primary preference } else if (n.ServiceLevelBase >= 100) { Secondary preference } else { Custom }
}
} @code { [Parameter] public string ClusterId { get; set; } = ""; private bool _loaded; private ServerCluster? _cluster; private List? _nodes; protected override async Task OnInitializedAsync() { await using var db = await DbFactory.CreateDbContextAsync(); _cluster = await db.ServerClusters.AsNoTracking() .FirstOrDefaultAsync(c => c.ClusterId == ClusterId); if (_cluster is not null) { _nodes = await db.ClusterNodes.AsNoTracking() .Where(n => n.ClusterId == ClusterId) .OrderBy(n => n.NodeId) .ToListAsync(); } _loaded = true; } }