refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)
Solution + 23 src projects + 26 test projects renamed; folders, csproj, namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated. ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated. SQL roles/logins, LDAP domains, CLI command name, and CLI config dir (~/.scadalink → ~/.scadabridge) also renamed. Build green; 5 Host.Tests fail awaiting SQL login rename in next commit. Pre-existing StaleTagMonitor timing flakes unchanged. Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23 — M4 Bundle A: thin decorator over the
|
||||
/// <see cref="DbConnection"/> returned by
|
||||
/// <see cref="ScriptRuntimeContext.DatabaseHelper.Connection"/>. The decorator
|
||||
/// itself does no audit work — it simply intercepts
|
||||
/// <see cref="CreateDbCommand"/> so the <see cref="DbCommand"/> handed back to
|
||||
/// the script is wrapped in an <see cref="AuditingDbCommand"/> that emits one
|
||||
/// <c>DbOutbound</c>/<c>DbWrite</c> audit row per execution.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// All other <see cref="DbConnection"/> members forward to the inner connection
|
||||
/// unchanged so the script keeps full ADO.NET semantics (transactions, state
|
||||
/// transitions, server-version queries, etc.). Disposing the wrapper disposes
|
||||
/// the inner connection — the caller is still responsible for disposal per
|
||||
/// the <see cref="IDatabaseGateway"/> contract.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The audit-write failure contract (alog.md §7) is honoured at the
|
||||
/// <see cref="AuditingDbCommand"/> layer — see that class for the 3-layer
|
||||
/// fail-safe pattern (build, write, observe).
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal sealed class AuditingDbConnection : DbConnection
|
||||
{
|
||||
private readonly DbConnection _inner;
|
||||
private readonly IAuditWriter _auditWriter;
|
||||
private readonly string _connectionName;
|
||||
private readonly string _siteId;
|
||||
private readonly string _instanceName;
|
||||
private readonly string? _sourceScript;
|
||||
private readonly Guid _executionId;
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23 (ParentExecutionId): the spawning execution's id when this
|
||||
/// run was inbound-API-routed; <c>null</c> for non-routed runs. Threaded
|
||||
/// alongside <see cref="_executionId"/> into the
|
||||
/// <see cref="AuditingDbCommand"/> so its <c>DbWrite</c> row stamps it.
|
||||
/// </summary>
|
||||
private readonly Guid? _parentExecutionId;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new auditing database connection decorator.
|
||||
/// </summary>
|
||||
/// <param name="inner">The inner database connection to wrap and audit commands through.</param>
|
||||
/// <param name="auditWriter">Writer for audit log entries.</param>
|
||||
/// <param name="connectionName">Name of the database connection being used.</param>
|
||||
/// <param name="siteId">Identifier of the site executing commands.</param>
|
||||
/// <param name="instanceName">Unique name of the instance executing commands.</param>
|
||||
/// <param name="sourceScript">Optional name of the source script for audit trail.</param>
|
||||
/// <param name="logger">Logger for diagnostics and warnings.</param>
|
||||
/// <param name="executionId">Unique identifier for this script execution.</param>
|
||||
/// <param name="parentExecutionId">Optional identifier of the parent execution (for routed calls).</param>
|
||||
// Parameter ordering: executionId sits immediately after the ILogger,
|
||||
// consistent with the other three audit-threaded ctors (ExternalSystemHelper,
|
||||
// DatabaseHelper, AuditingDbCommand). parentExecutionId is a trailing
|
||||
// optional param so existing positional callers stay source-compatible.
|
||||
public AuditingDbConnection(
|
||||
DbConnection inner,
|
||||
IAuditWriter auditWriter,
|
||||
string connectionName,
|
||||
string siteId,
|
||||
string instanceName,
|
||||
string? sourceScript,
|
||||
ILogger logger,
|
||||
Guid executionId,
|
||||
Guid? parentExecutionId = null)
|
||||
{
|
||||
_inner = inner ?? throw new ArgumentNullException(nameof(inner));
|
||||
_auditWriter = auditWriter ?? throw new ArgumentNullException(nameof(auditWriter));
|
||||
_connectionName = connectionName ?? throw new ArgumentNullException(nameof(connectionName));
|
||||
_siteId = siteId ?? string.Empty;
|
||||
_instanceName = instanceName ?? string.Empty;
|
||||
_sourceScript = sourceScript;
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_executionId = executionId;
|
||||
_parentExecutionId = parentExecutionId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SiteRuntime-022: exposes the wrapped <see cref="DbConnection"/> to the
|
||||
/// sibling <see cref="AuditingDbCommand"/> in the same assembly, so the
|
||||
/// command's <c>DbConnection</c> setter can unwrap an
|
||||
/// <see cref="AuditingDbConnection"/> without reflecting into the
|
||||
/// private <c>_inner</c> field. Both classes are <c>internal sealed</c>
|
||||
/// in this assembly, so the accessor stays out of the public API and
|
||||
/// matches the SiteRuntime-006 precedent of preferring proper API surface
|
||||
/// over <see cref="System.Reflection"/>.
|
||||
/// </summary>
|
||||
internal DbConnection Inner => _inner;
|
||||
|
||||
/// <inheritdoc />
|
||||
// ConnectionString is settable on DbConnection — forward both halves.
|
||||
public override string ConnectionString
|
||||
{
|
||||
// Some providers throw on get when the connection hasn't been opened
|
||||
// with a string set explicitly. The wrapper has no opinion — forward.
|
||||
#pragma warning disable CS8765 // nullability of overridden member parameter — base setter accepts null in practice
|
||||
get => _inner.ConnectionString;
|
||||
set => _inner.ConnectionString = value;
|
||||
#pragma warning restore CS8765
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Database => _inner.Database;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string DataSource => _inner.DataSource;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ServerVersion => _inner.ServerVersion;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ConnectionState State => _inner.State;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ChangeDatabase(string databaseName) => _inner.ChangeDatabase(databaseName);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Close() => _inner.Close();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Open() => _inner.Open();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task OpenAsync(CancellationToken cancellationToken) => _inner.OpenAsync(cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
|
||||
=> _inner.BeginTransaction(isolationLevel);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override DbCommand CreateDbCommand()
|
||||
{
|
||||
var innerCmd = _inner.CreateCommand();
|
||||
// Hand the script an auditing wrapper. The wrapper preserves the
|
||||
// inner command's identity for parameters / type maps via delegation.
|
||||
return new AuditingDbCommand(
|
||||
innerCmd,
|
||||
_auditWriter,
|
||||
_connectionName,
|
||||
_siteId,
|
||||
_instanceName,
|
||||
_sourceScript,
|
||||
_logger,
|
||||
_executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning execution's id,
|
||||
// threaded alongside _executionId. Null for non-routed runs.
|
||||
_parentExecutionId);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_inner.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ValueTask DisposeAsync()
|
||||
{
|
||||
// DbConnection.DisposeAsync is virtual; calling base would run the
|
||||
// synchronous Dispose path. Forward to the inner connection
|
||||
// asynchronously and short-circuit the base.
|
||||
var task = _inner.DisposeAsync();
|
||||
GC.SuppressFinalize(this);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user