Renames all 11 projects (5 src + 6 tests), the .slnx solution file, all source-file namespaces, all axaml namespace references, and all v1 documentation references in CLAUDE.md and docs/*.md (excluding docs/v2/ which is already in OtOpcUa form). Also updates the TopShelf service registration name from "LmxOpcUa" to "OtOpcUa" per Phase 0 Task 0.6.
Preserves runtime identifiers per Phase 0 Out-of-Scope rules to avoid breaking v1/v2 client trust during coexistence: OPC UA `ApplicationUri` defaults (`urn:{GalaxyName}:LmxOpcUa`), server `EndpointPath` (`/LmxOpcUa`), `ServerName` default (feeds cert subject CN), `MxAccessConfiguration.ClientName` default (defensive — stays "LmxOpcUa" for MxAccess audit-trail consistency), client OPC UA identifiers (`ApplicationName = "LmxOpcUaClient"`, `ApplicationUri = "urn:localhost:LmxOpcUaClient"`, cert directory `%LocalAppData%\LmxOpcUaClient\pki\`), and the `LmxOpcUaServer` class name (class rename out of Phase 0 scope per Task 0.5 sed pattern; happens in Phase 1 alongside `LmxNodeManager → GenericDriverNodeManager` Core extraction). 23 LmxOpcUa references retained, all enumerated and justified in `docs/v2/implementation/exit-gate-phase-0.md`.
Build clean: 0 errors, 30 warnings (lower than baseline 167). Tests at strict improvement over baseline: 821 passing / 1 failing vs baseline 820 / 2 (one flaky pre-existing failure passed this run; the other still fails — both pre-existing and unrelated to the rename). `Client.UI.Tests`, `Historian.Aveva.Tests`, `Client.Shared.Tests`, `IntegrationTests` all match baseline exactly. Exit gate compliance results recorded in `docs/v2/implementation/exit-gate-phase-0.md` with all 7 checks PASS or DEFERRED-to-PR-review (#7 service install verification needs Windows service permissions on the reviewer's box).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
570 lines
20 KiB
C#
570 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using ZB.MOM.WW.OtOpcUa.Host.Domain;
|
|
using ZB.MOM.WW.OtOpcUa.Host.Metrics;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Host.Status
|
|
{
|
|
/// <summary>
|
|
/// DTO containing all dashboard data. (DASH-001 through DASH-009)
|
|
/// </summary>
|
|
public class StatusData
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the current MXAccess and service connectivity summary shown on the dashboard.
|
|
/// </summary>
|
|
public ConnectionInfo Connection { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the overall health state communicated to operators.
|
|
/// </summary>
|
|
public HealthInfo Health { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets subscription counts that show how many live tag streams the bridge is maintaining.
|
|
/// </summary>
|
|
public SubscriptionInfo Subscriptions { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets Galaxy-specific metadata such as deploy timing and address-space counts.
|
|
/// </summary>
|
|
public GalaxyInfo Galaxy { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets MXAccess data change dispatch queue metrics.
|
|
/// </summary>
|
|
public DataChangeInfo DataChange { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets per-operation performance statistics used to diagnose bridge throughput and latency.
|
|
/// </summary>
|
|
public Dictionary<string, MetricsStatistics> Operations { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the historian integration status (plugin load outcome, server target).
|
|
/// </summary>
|
|
public HistorianStatusInfo Historian { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the alarm integration status and event counters.
|
|
/// </summary>
|
|
public AlarmStatusInfo Alarms { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the redundancy state when redundancy is enabled.
|
|
/// </summary>
|
|
public RedundancyInfo? Redundancy { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the listening OPC UA endpoints and active security profiles.
|
|
/// </summary>
|
|
public EndpointsInfo Endpoints { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Galaxy runtime host state (Platforms + AppEngines).
|
|
/// </summary>
|
|
public RuntimeStatusInfo RuntimeStatus { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets footer details such as the snapshot timestamp and service version.
|
|
/// </summary>
|
|
public FooterInfo Footer { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model summarizing per-host Galaxy runtime state.
|
|
/// </summary>
|
|
public class RuntimeStatusInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the total number of tracked runtime hosts ($WinPlatform + $AppEngine).
|
|
/// </summary>
|
|
public int Total { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the count of hosts currently reported Running.
|
|
/// </summary>
|
|
public int RunningCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the count of hosts currently reported Stopped.
|
|
/// </summary>
|
|
public int StoppedCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the count of hosts whose state is still Unknown (either awaiting initial
|
|
/// probe resolution or transported-through-disconnected).
|
|
/// </summary>
|
|
public int UnknownCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the per-host state in stable alphabetical order.
|
|
/// </summary>
|
|
public List<GalaxyRuntimeStatus> Hosts { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model describing the OPC UA server's listening endpoints and active security profiles.
|
|
/// </summary>
|
|
public class EndpointsInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the list of opc.tcp base addresses the server is listening on.
|
|
/// </summary>
|
|
public List<string> BaseAddresses { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the list of configured user token policies (Anonymous, UserName, Certificate).
|
|
/// </summary>
|
|
public List<string> UserTokenPolicies { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the active security profiles reported to clients.
|
|
/// </summary>
|
|
public List<SecurityProfileInfo> SecurityProfiles { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for a single configured OPC UA server security profile.
|
|
/// </summary>
|
|
public class SecurityProfileInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the OPC UA security policy URI (e.g., http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256).
|
|
/// </summary>
|
|
public string PolicyUri { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the short policy name extracted from the policy URI.
|
|
/// </summary>
|
|
public string PolicyName { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the message security mode (None, Sign, SignAndEncrypt).
|
|
/// </summary>
|
|
public string SecurityMode { get; set; } = "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for current runtime connection details.
|
|
/// </summary>
|
|
public class ConnectionInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the current MXAccess connection state shown to operators.
|
|
/// </summary>
|
|
public string State { get; set; } = "Disconnected";
|
|
|
|
/// <summary>
|
|
/// Gets or sets how many reconnect attempts have occurred since the service started.
|
|
/// </summary>
|
|
public int ReconnectCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of active OPC UA sessions connected to the bridge.
|
|
/// </summary>
|
|
public int ActiveSessions { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for the overall health banner.
|
|
/// </summary>
|
|
public class HealthInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the high-level health state, such as Healthy, Degraded, or Unhealthy.
|
|
/// </summary>
|
|
public string Status { get; set; } = "Unknown";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the operator-facing explanation for the current health state.
|
|
/// </summary>
|
|
public string Message { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the color token used by the dashboard UI to render the health banner.
|
|
/// </summary>
|
|
public string Color { get; set; } = "gray";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for subscription load.
|
|
/// </summary>
|
|
public class SubscriptionInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the number of active tag subscriptions mirrored from MXAccess into OPC UA.
|
|
/// This total includes bridge-owned runtime status probes; see <see cref="ProbeCount"/> for the
|
|
/// subset attributable to probes.
|
|
/// </summary>
|
|
public int ActiveCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the count of bridge-owned runtime status probes included in
|
|
/// <see cref="ActiveCount"/>. Surfaced on the dashboard so operators can distinguish probe
|
|
/// overhead from client-driven subscription load.
|
|
/// </summary>
|
|
public int ProbeCount { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for Galaxy metadata and rebuild status.
|
|
/// </summary>
|
|
public class GalaxyInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the Galaxy name currently being bridged into OPC UA.
|
|
/// </summary>
|
|
public string GalaxyName { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the repository database is currently reachable.
|
|
/// </summary>
|
|
public bool DbConnected { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the most recent deploy timestamp observed in the Galaxy repository.
|
|
/// </summary>
|
|
public DateTime? LastDeployTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of Galaxy objects currently represented in the address space.
|
|
/// </summary>
|
|
public int ObjectCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of Galaxy attributes currently represented as OPC UA variables.
|
|
/// </summary>
|
|
public int AttributeCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the UTC timestamp of the last completed address-space rebuild.
|
|
/// </summary>
|
|
public DateTime? LastRebuildTime { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for MXAccess data change dispatch metrics.
|
|
/// </summary>
|
|
public class DataChangeInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the rate of MXAccess data change events received per second.
|
|
/// </summary>
|
|
public double EventsPerSecond { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the average number of items processed per dispatch cycle.
|
|
/// </summary>
|
|
public double AvgBatchSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of items currently waiting in the dispatch queue.
|
|
/// </summary>
|
|
public int PendingItems { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the total MXAccess data change events received since startup.
|
|
/// </summary>
|
|
public long TotalEvents { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for the Wonderware historian integration (runtime-loaded plugin).
|
|
/// </summary>
|
|
public class HistorianStatusInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether historian support is enabled in configuration.
|
|
/// </summary>
|
|
public bool Enabled { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the most recent plugin load outcome as a string.
|
|
/// Values: <c>Disabled</c>, <c>NotFound</c>, <c>LoadFailed</c>, <c>Loaded</c>.
|
|
/// </summary>
|
|
public string PluginStatus { get; set; } = "Disabled";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the error message from the last load attempt when <see cref="PluginStatus"/> is <c>LoadFailed</c>.
|
|
/// </summary>
|
|
public string? PluginError { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the absolute path the loader probed for the plugin assembly.
|
|
/// </summary>
|
|
public string PluginPath { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the configured historian server hostname.
|
|
/// </summary>
|
|
public string ServerName { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the configured historian TCP port.
|
|
/// </summary>
|
|
public int Port { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the total number of historian read queries attempted since startup.
|
|
/// </summary>
|
|
public long QueryTotal { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of historian queries that completed without an exception.
|
|
/// </summary>
|
|
public long QuerySuccesses { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of historian queries that raised an exception.
|
|
/// </summary>
|
|
public long QueryFailures { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of consecutive failures since the last successful query.
|
|
/// </summary>
|
|
public int ConsecutiveFailures { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the UTC timestamp of the last successful query.
|
|
/// </summary>
|
|
public DateTime? LastSuccessTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the UTC timestamp of the last query failure.
|
|
/// </summary>
|
|
public DateTime? LastFailureTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the exception message from the most recent failure.
|
|
/// </summary>
|
|
public string? LastQueryError { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the plugin currently holds an open process-path
|
|
/// SDK connection.
|
|
/// </summary>
|
|
public bool ProcessConnectionOpen { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the plugin currently holds an open event-path
|
|
/// SDK connection.
|
|
/// </summary>
|
|
public bool EventConnectionOpen { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the total number of configured historian cluster nodes.
|
|
/// </summary>
|
|
public int NodeCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of cluster nodes currently eligible for new connections
|
|
/// (i.e., not in failure cooldown).
|
|
/// </summary>
|
|
public int HealthyNodeCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the node currently serving process (historical value) queries, or null
|
|
/// when no process connection is open.
|
|
/// </summary>
|
|
public string? ActiveProcessNode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the node currently serving event (alarm history) queries, or null when
|
|
/// no event connection is open.
|
|
/// </summary>
|
|
public string? ActiveEventNode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the per-node cluster state in configuration order.
|
|
/// </summary>
|
|
public List<Historian.HistorianClusterNodeState> Nodes { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for alarm integration health and event counters.
|
|
/// </summary>
|
|
public class AlarmStatusInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether alarm condition tracking is enabled in configuration.
|
|
/// </summary>
|
|
public bool TrackingEnabled { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of distinct alarm conditions currently tracked.
|
|
/// </summary>
|
|
public int ConditionCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of alarms currently in the InAlarm=true state.
|
|
/// </summary>
|
|
public int ActiveAlarmCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the total number of InAlarm transitions observed since startup.
|
|
/// </summary>
|
|
public long TransitionCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the total number of alarm acknowledgement transitions observed since startup.
|
|
/// </summary>
|
|
public long AckEventCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the total number of alarm acknowledgement MXAccess writes that have failed since startup.
|
|
/// </summary>
|
|
public long AckWriteFailures { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the template-based alarm object filter is active.
|
|
/// </summary>
|
|
public bool FilterEnabled { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of compiled alarm filter patterns.
|
|
/// </summary>
|
|
public int FilterPatternCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of Galaxy objects included by the alarm filter during the most recent build.
|
|
/// </summary>
|
|
public int FilterIncludedObjectCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the raw alarm filter patterns exactly as configured, for dashboard display.
|
|
/// </summary>
|
|
public List<string> FilterPatterns { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for redundancy state. Only populated when redundancy is enabled.
|
|
/// </summary>
|
|
public class RedundancyInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets whether redundancy is enabled.
|
|
/// </summary>
|
|
public bool Enabled { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the redundancy mode (e.g., "Warm", "Hot").
|
|
/// </summary>
|
|
public string Mode { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets this instance's role ("Primary" or "Secondary").
|
|
/// </summary>
|
|
public string Role { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the current ServiceLevel byte.
|
|
/// </summary>
|
|
public byte ServiceLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets this instance's ApplicationUri.
|
|
/// </summary>
|
|
public string ApplicationUri { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the list of all server URIs in the redundant set.
|
|
/// </summary>
|
|
public List<string> ServerUris { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// DTO for the /api/health endpoint. Includes component-level health, ServiceLevel, and redundancy state.
|
|
/// </summary>
|
|
public class HealthEndpointData
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the overall health status: Healthy, Degraded, or Unhealthy.
|
|
/// </summary>
|
|
public string Status { get; set; } = "Unknown";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the computed OPC UA ServiceLevel byte (0-255). Only meaningful when redundancy is enabled.
|
|
/// </summary>
|
|
public byte ServiceLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether redundancy is enabled.
|
|
/// </summary>
|
|
public bool RedundancyEnabled { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets this instance's redundancy role when enabled (Primary/Secondary), or null when disabled.
|
|
/// </summary>
|
|
public string? RedundancyRole { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the redundancy mode when enabled (Warm/Hot), or null when disabled.
|
|
/// </summary>
|
|
public string? RedundancyMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the per-component health breakdown.
|
|
/// </summary>
|
|
public ComponentHealth Components { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Gets or sets the server uptime since the health endpoint was initialized.
|
|
/// </summary>
|
|
public string Uptime { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the UTC timestamp of this health snapshot.
|
|
/// </summary>
|
|
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Per-component health breakdown for the health endpoint.
|
|
/// </summary>
|
|
public class ComponentHealth
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets MXAccess runtime connectivity status.
|
|
/// </summary>
|
|
public string MxAccess { get; set; } = "Disconnected";
|
|
|
|
/// <summary>
|
|
/// Gets or sets Galaxy repository database connectivity status.
|
|
/// </summary>
|
|
public string Database { get; set; } = "Disconnected";
|
|
|
|
/// <summary>
|
|
/// Gets or sets OPC UA server status.
|
|
/// </summary>
|
|
public string OpcUaServer { get; set; } = "Stopped";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the historian plugin status.
|
|
/// Values: <c>Disabled</c>, <c>NotFound</c>, <c>LoadFailed</c>, <c>Loaded</c>.
|
|
/// </summary>
|
|
public string Historian { get; set; } = "Disabled";
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether alarm condition tracking is enabled.
|
|
/// Values: <c>Disabled</c>, <c>Enabled</c>.
|
|
/// </summary>
|
|
public string Alarms { get; set; } = "Disabled";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dashboard model for the status page footer.
|
|
/// </summary>
|
|
public class FooterInfo
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the UTC time when the status snapshot was generated.
|
|
/// </summary>
|
|
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the service version displayed to operators for support and traceability.
|
|
/// </summary>
|
|
public string Version { get; set; } = "";
|
|
}
|
|
} |