chore: organize solution into module folders (Core/Server/Drivers/Client/Tooling)
Group all 69 projects into category subfolders under src/ and tests/ so the Rider Solution Explorer mirrors the module structure. Folders: Core, Server, Drivers (with a nested Driver CLIs subfolder), Client, Tooling. - Move every project folder on disk with git mv (history preserved as renames). - Recompute relative paths in 57 .csproj files: cross-category ProjectReferences, the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external mxaccessgw refs in Driver.Galaxy and its test project. - Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders. - Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL, integration, install). Build green (0 errors); unit tests pass. Docs left for a separate pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+73
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Ipc;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Backend
|
||||
{
|
||||
/// <summary>
|
||||
/// Production <see cref="IAlarmHistorianWriteBackend"/> backed by AVEVA Historian's
|
||||
/// <c>aahClientManaged</c> alarm-event write API. The exact SDK entry point is
|
||||
/// pinned during the live-rig smoke in PR D.1 — until that gate, this backend
|
||||
/// reports <see cref="AlarmHistorianWriteOutcome.RetryPlease"/> for every
|
||||
/// event with a structured diagnostic so the lmxopcua-side
|
||||
/// <c>SqliteStoreAndForwardSink</c> retains the queued events rather than dropping
|
||||
/// or hard-failing them.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Cluster failover reuses <see cref="HistorianClusterEndpointPicker"/> via
|
||||
/// the shared <see cref="HistorianDataSource"/> connection pool — there is
|
||||
/// no second connection pool for writes. Wonderware Historian's alarm-event
|
||||
/// write surface accepts the same <c>HistorianAccess</c> session a read
|
||||
/// opens, so reusing the picker is parity-preserving with v1's
|
||||
/// <c>GalaxyHistorianWriter</c>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Once D.1 confirms the SDK entry point, this class swaps the placeholder
|
||||
/// body for the real call sequence. The mapping from raw HRESULT /
|
||||
/// <c>HistorianError</c> codes onto <see cref="AlarmHistorianWriteOutcome"/>
|
||||
/// is already shared via <see cref="AahClientManagedAlarmEventWriter.MapOutcome"/>
|
||||
/// so the smoke-pinned change stays minimal.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class SdkAlarmHistorianWriteBackend : IAlarmHistorianWriteBackend
|
||||
{
|
||||
private static readonly ILogger Log = Serilog.Log.ForContext<SdkAlarmHistorianWriteBackend>();
|
||||
|
||||
private readonly HistorianConfiguration _config;
|
||||
|
||||
public SdkAlarmHistorianWriteBackend(HistorianConfiguration config)
|
||||
{
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
public Task<AlarmHistorianWriteOutcome[]> WriteBatchAsync(
|
||||
AlarmHistorianEventDto[] events,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (events is null || events.Length == 0)
|
||||
{
|
||||
return Task.FromResult(new AlarmHistorianWriteOutcome[0]);
|
||||
}
|
||||
|
||||
// Placeholder: pin the SDK entry point in PR D.1 against a live AVEVA
|
||||
// Historian. Until then the call returns RetryPlease for every slot so
|
||||
// the lmxopcua-side sink keeps the events queued rather than dropping
|
||||
// them — same effect as the current NullAlarmHistorianSink fallback,
|
||||
// but visible through the structured diagnostic + per-event outcome.
|
||||
Log.Warning(
|
||||
"Alarm historian SDK write path not yet pinned — returning RetryPlease for {Count} event(s) from server {Server}. PR D.1 swaps this for the live aahClientManaged call.",
|
||||
events.Length,
|
||||
_config.ServerName);
|
||||
|
||||
var outcomes = new AlarmHistorianWriteOutcome[events.Length];
|
||||
for (var i = 0; i < outcomes.Length; i++)
|
||||
{
|
||||
outcomes[i] = AlarmHistorianWriteOutcome.RetryPlease;
|
||||
}
|
||||
return Task.FromResult(outcomes);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user