docs(comments): strip internal task/milestone/bundle bookkeeping from code comments
Remove project bookkeeping citations from shipped code comments across the solution: hyphenated task IDs (WP-14, StoreAndForward-025), milestone/task/ issue refs (M3, Task 4, Audit Log #23, #21), Bundle X task-bundle labels, and C/D/K/S/T phase labels. Comment text only — no code logic, string/log literals, or XML-doc structure changed. Genuine descriptions are preserved (only the citation is stripped), and technical lookalikes are retained (UTF-8, SHA-256, T00:00:00, M365, UTC-5, pre-C4/pre-C5 schema versions). Flagged by the new CommentChecker TaskReferenceInComment / TrackingReferenceInComment checks plus targeted grep passes; full solution builds clean, append-only guard tests pass.
This commit is contained in:
@@ -19,20 +19,20 @@ using ZB.MOM.WW.ScadaBridge.TemplateEngine.Validation;
|
||||
namespace ZB.MOM.WW.ScadaBridge.DeploymentManager;
|
||||
|
||||
/// <summary>
|
||||
/// WP-1: Central-side deployment orchestration service.
|
||||
/// Central-side deployment orchestration service.
|
||||
/// Coordinates the full deployment pipeline:
|
||||
/// 1. Validate instance state transition (WP-4)
|
||||
/// 2. Acquire per-instance operation lock (WP-3)
|
||||
/// 3. Flatten configuration via TemplateEngine (captures template state at time of flatten -- WP-16)
|
||||
/// 1. Validate instance state transition
|
||||
/// 2. Acquire per-instance operation lock
|
||||
/// 3. Flatten configuration via TemplateEngine (captures template state at time of flatten)
|
||||
/// 4. Validate flattened configuration
|
||||
/// 5. Compute revision hash and diff
|
||||
/// 6. Stage a PendingDeployment row + send RefreshDeploymentCommand (notify-and-fetch; site fetches the config over HTTP)
|
||||
/// 7. Track deployment status with optimistic concurrency (WP-4)
|
||||
/// 8. Store deployed config snapshot (WP-8)
|
||||
/// 7. Track deployment status with optimistic concurrency
|
||||
/// 8. Store deployed config snapshot
|
||||
/// 9. Audit log all actions
|
||||
///
|
||||
/// WP-2: Each deployment has a unique deployment ID (GUID) + revision hash.
|
||||
/// WP-16: Template state captured at flatten time -- last-write-wins on templates is safe.
|
||||
/// Each deployment has a unique deployment ID (GUID) + revision hash.
|
||||
/// Template state captured at flatten time -- last-write-wins on templates is safe.
|
||||
/// </summary>
|
||||
public class DeploymentService
|
||||
{
|
||||
@@ -52,7 +52,7 @@ public class DeploymentService
|
||||
/// <summary>
|
||||
/// Prefix written to <see cref="DeploymentRecord.ErrorMessage"/> when a
|
||||
/// deployment fails because the site command timed out or was cancelled.
|
||||
/// Used by the query-before-redeploy trigger (DeploymentManager-006) to tell
|
||||
/// Used by the query-before-redeploy trigger to tell
|
||||
/// a timeout-induced failure apart from other deployment errors.
|
||||
/// </summary>
|
||||
private const string TimeoutFailurePrefix = "Communication failure:";
|
||||
@@ -111,7 +111,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CentralUI-006: raises a push notification that a deployment record's
|
||||
/// Raises a push notification that a deployment record's
|
||||
/// status was just persisted, so the Central UI deployment-status page can
|
||||
/// re-render over its SignalR circuit instead of polling. Called at every
|
||||
/// point a <see cref="DeploymentRecord"/> status is written.
|
||||
@@ -124,7 +124,7 @@ public class DeploymentService
|
||||
/// Resolves the site's string identifier from the numeric DB ID.
|
||||
/// The communication layer routes by string identifier (e.g. "site-a"), not DB ID.
|
||||
///
|
||||
/// DeploymentManager-021: when the <see cref="Site"/> row is missing (FK was
|
||||
/// When the <see cref="Site"/> row is missing (FK was
|
||||
/// deleted, race with admin delete, DB inconsistency) the previous behaviour
|
||||
/// silently substituted the numeric id rendered as a string — every
|
||||
/// downstream `CommunicationService` call then failed with a confusing
|
||||
@@ -146,12 +146,12 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-1: Deploy an instance to its site.
|
||||
/// WP-2: Generates unique deployment ID, computes revision hash.
|
||||
/// WP-4: Validates state transitions, uses optimistic concurrency.
|
||||
/// WP-5: Site-side apply is all-or-nothing (handled by DeploymentManagerActor).
|
||||
/// WP-8: Stores deployed config snapshot on success.
|
||||
/// WP-16: Captures template state at time of flatten.
|
||||
/// Deploy an instance to its site.
|
||||
/// Generates unique deployment ID, computes revision hash.
|
||||
/// Validates state transitions, uses optimistic concurrency.
|
||||
/// Site-side apply is all-or-nothing (handled by DeploymentManagerActor).
|
||||
/// Stores deployed config snapshot on success.
|
||||
/// Captures template state at time of flatten.
|
||||
/// </summary>
|
||||
/// <param name="instanceId">The database ID of the instance to deploy.</param>
|
||||
/// <param name="user">The username initiating the deployment, recorded in the audit log.</param>
|
||||
@@ -167,19 +167,19 @@ public class DeploymentService
|
||||
if (instance == null)
|
||||
return Result<DeploymentRecord>.Failure($"Instance with ID {instanceId} not found.");
|
||||
|
||||
// WP-4: Validate state transition
|
||||
// Validate state transition
|
||||
var transitionError = StateTransitionValidator.ValidateTransition(instance.State, "deploy");
|
||||
if (transitionError != null)
|
||||
return Result<DeploymentRecord>.Failure(transitionError);
|
||||
|
||||
// WP-3: Acquire per-instance operation lock
|
||||
// Acquire per-instance operation lock
|
||||
using var lockHandle = await _lockManager.AcquireAsync(
|
||||
instance.UniqueName, _options.OperationLockTimeout, cancellationToken);
|
||||
|
||||
// WP-2: Generate unique deployment ID
|
||||
// Generate unique deployment ID
|
||||
var deploymentId = Guid.NewGuid().ToString("N");
|
||||
|
||||
// WP-1/16: Flatten configuration (captures template state at this point in time)
|
||||
// Flatten configuration (captures template state at this point in time)
|
||||
var flattenResult = await _flatteningPipeline.FlattenAndValidateAsync(instanceId, cancellationToken);
|
||||
if (flattenResult.IsFailure)
|
||||
return Result<DeploymentRecord>.Failure($"Validation failed: {flattenResult.Error}");
|
||||
@@ -190,7 +190,7 @@ public class DeploymentService
|
||||
|
||||
if (!validationResult.IsValid)
|
||||
{
|
||||
// Followup #8: return a grouped/summarized error (leading count + per-module
|
||||
// Return a grouped/summarized error (leading count + per-module
|
||||
// rollup, capped) instead of a flat semicolon-joined dump that becomes a wall
|
||||
// of text for instances with dozens of unbound attributes. The full per-entry
|
||||
// list still goes to the deploy log for operators who need every clause.
|
||||
@@ -208,7 +208,7 @@ public class DeploymentService
|
||||
// snapshot on success / reconciliation).
|
||||
var configJson = JsonSerializer.Serialize(flattenedConfig);
|
||||
|
||||
// DeploymentManager-006: query-the-site-before-redeploy idempotency.
|
||||
// Query-the-site-before-redeploy idempotency.
|
||||
// If a prior deployment for this instance is stuck InProgress or Failed
|
||||
// due to a timeout, the site may have actually applied the config. Query
|
||||
// the site for its currently-applied revision before re-sending so a
|
||||
@@ -230,13 +230,13 @@ public class DeploymentService
|
||||
return Result<DeploymentRecord>.Failure(
|
||||
"CentralFetchBaseUrl is not configured — required for deployment (notify-and-fetch).");
|
||||
|
||||
// WP-4: Create the deployment record directly in InProgress.
|
||||
// Create the deployment record directly in InProgress.
|
||||
//
|
||||
// DeploymentManager-022: the previous code wrote the record as Pending,
|
||||
// The previous code wrote the record as Pending,
|
||||
// then immediately updated it to InProgress with no work in between
|
||||
// (flattening, validation, and reconciliation all completed above). The
|
||||
// back-to-back write cost an extra SaveChangesAsync round-trip, an
|
||||
// extra IDeploymentStatusNotifier push (CentralUI-006 rendered a
|
||||
// extra IDeploymentStatusNotifier push (which rendered a
|
||||
// Pending→InProgress flicker for ~ms), and an extra row-version bump
|
||||
// for nothing. The transient Pending slot carried no operational
|
||||
// meaning — it was set and immediately overwritten — so dropping it
|
||||
@@ -290,12 +290,12 @@ public class DeploymentService
|
||||
// CommunicationOptions.PendingDeploymentPurgeInterval cadence.
|
||||
var response = await _communicationService.RefreshDeploymentAsync(siteId, command, cancellationToken);
|
||||
|
||||
// WP-1: Update status based on site response.
|
||||
// Update status based on site response.
|
||||
record.Status = response.Status;
|
||||
record.ErrorMessage = response.ErrorMessage;
|
||||
record.CompletedAt = DateTimeOffset.UtcNow;
|
||||
|
||||
// DeploymentManager-003: once the site has confirmed the apply,
|
||||
// Once the site has confirmed the apply,
|
||||
// commit the deployment record's terminal status BEFORE touching
|
||||
// instance state and the deployed-config snapshot. If a later write
|
||||
// (instance update / snapshot store) fails, the recorded fact that
|
||||
@@ -342,12 +342,12 @@ public class DeploymentService
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DeploymentManager-001: any exception out of the try (timeout,
|
||||
// Any exception out of the try (timeout,
|
||||
// cancellation, transport, serialization, DB) must leave the
|
||||
// deployment record as Failed -- the design requires an interrupted
|
||||
// deployment to be treated as failed, never stuck in InProgress.
|
||||
//
|
||||
// DeploymentManager-002: the failure-status write must NOT use the
|
||||
// The failure-status write must NOT use the
|
||||
// operation's cancellation token. If the operation was cancelled or
|
||||
// timed out, that token is already cancelled and the cleanup writes
|
||||
// would themselves throw before the Failed status is persisted.
|
||||
@@ -398,7 +398,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-6: Disable an instance. Stops Instance Actor, retains config, S&F drains.
|
||||
/// Disable an instance. Stops Instance Actor, retains config, S&F drains.
|
||||
/// </summary>
|
||||
/// <param name="instanceId">The database ID of the instance to disable.</param>
|
||||
/// <param name="user">The username initiating the operation, recorded in the audit log.</param>
|
||||
@@ -424,7 +424,7 @@ public class DeploymentService
|
||||
var siteId = await ResolveSiteIdentifierAsync(instance.SiteId, cancellationToken);
|
||||
var command = new DisableInstanceCommand(commandId, instance.UniqueName, DateTimeOffset.UtcNow);
|
||||
|
||||
// WP-6: bound the round-trip with the configured lifecycle timeout so a
|
||||
// Bound the round-trip with the configured lifecycle timeout so a
|
||||
// hung/unreachable site does not block the operation lock indefinitely.
|
||||
InstanceLifecycleResponse response;
|
||||
try
|
||||
@@ -435,7 +435,7 @@ public class DeploymentService
|
||||
}
|
||||
catch (Exception ex) when (ex is TimeoutException or OperationCanceledException)
|
||||
{
|
||||
// DeploymentManager-019: a lifecycle command timeout produced no
|
||||
// A lifecycle command timeout produced no
|
||||
// audit row pre-fix — the operator saw a timeout in the UI but
|
||||
// the audit trail showed nothing happened, contrary to the
|
||||
// design's "audit logging for all instance lifecycle changes"
|
||||
@@ -468,7 +468,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-6: Enable an instance. Re-creates Instance Actor from stored config.
|
||||
/// Enable an instance. Re-creates Instance Actor from stored config.
|
||||
/// </summary>
|
||||
/// <param name="instanceId">The database ID of the instance to enable.</param>
|
||||
/// <param name="user">The username initiating the operation, recorded in the audit log.</param>
|
||||
@@ -494,7 +494,7 @@ public class DeploymentService
|
||||
var siteId = await ResolveSiteIdentifierAsync(instance.SiteId, cancellationToken);
|
||||
var command = new EnableInstanceCommand(commandId, instance.UniqueName, DateTimeOffset.UtcNow);
|
||||
|
||||
// WP-6: bound the round-trip with the configured lifecycle timeout.
|
||||
// Bound the round-trip with the configured lifecycle timeout.
|
||||
InstanceLifecycleResponse response;
|
||||
try
|
||||
{
|
||||
@@ -504,7 +504,7 @@ public class DeploymentService
|
||||
}
|
||||
catch (Exception ex) when (ex is TimeoutException or OperationCanceledException)
|
||||
{
|
||||
// DeploymentManager-019: emit an audit entry on lifecycle timeout
|
||||
// Emit an audit entry on lifecycle timeout
|
||||
// so the operator's attempted Enable is recorded; see the matching
|
||||
// comment in DisableInstanceAsync for the full rationale.
|
||||
await TryLogLifecycleTimeoutAsync(
|
||||
@@ -532,7 +532,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-6: Delete an instance. Stops the site actor, removes site config, and
|
||||
/// Delete an instance. Stops the site actor, removes site config, and
|
||||
/// removes the central instance record (deployment history, snapshot,
|
||||
/// overrides, and connection bindings go with it). S&F NOT cleared.
|
||||
/// Delete fails if the site is unreachable within
|
||||
@@ -563,7 +563,7 @@ public class DeploymentService
|
||||
var siteId = await ResolveSiteIdentifierAsync(instance.SiteId, cancellationToken);
|
||||
var command = new DeleteInstanceCommand(commandId, instance.UniqueName, DateTimeOffset.UtcNow);
|
||||
|
||||
// WP-6: bound the round-trip with the configured lifecycle timeout.
|
||||
// Bound the round-trip with the configured lifecycle timeout.
|
||||
InstanceLifecycleResponse response;
|
||||
try
|
||||
{
|
||||
@@ -573,7 +573,7 @@ public class DeploymentService
|
||||
}
|
||||
catch (Exception ex) when (ex is TimeoutException or OperationCanceledException)
|
||||
{
|
||||
// DeploymentManager-019: emit an audit entry on lifecycle timeout
|
||||
// Emit an audit entry on lifecycle timeout
|
||||
// so the operator's attempted Delete is recorded; see the matching
|
||||
// comment in DisableInstanceAsync for the full rationale.
|
||||
await TryLogLifecycleTimeoutAsync(
|
||||
@@ -590,7 +590,7 @@ public class DeploymentService
|
||||
// Deployment records, snapshot, overrides, and connection bindings
|
||||
// are removed with it (see repository implementation).
|
||||
//
|
||||
// DeploymentManager-004: the site has already destroyed the Instance
|
||||
// The site has already destroyed the Instance
|
||||
// Actor and removed its config. If the central record removal now
|
||||
// fails (DB error / concurrency), the exception must NOT escape
|
||||
// uncaught -- that would leave the central record orphaned and
|
||||
@@ -630,7 +630,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-8: Get the deployed config snapshot and compare with current
|
||||
/// Get the deployed config snapshot and compare with current
|
||||
/// template-derived state. Produces both a staleness flag and — per the
|
||||
/// design's "Diff View" — a structured <see cref="ConfigurationDiff"/> of
|
||||
/// added/removed/changed attributes, alarms, and scripts (including data
|
||||
@@ -658,7 +658,7 @@ public class DeploymentService
|
||||
|
||||
// I-1 (latent): the snapshot's ConfigurationJson + RevisionHash froze the
|
||||
// FLATTENED config at deploy time. The current config is a FRESH flatten,
|
||||
// now always in native List form (#93 consolidated element-type/coercion
|
||||
// now always in native List form (consolidated element-type/coercion
|
||||
// into AttributeValueCodec, which emits native-form JSON arrays). A List
|
||||
// attribute deployed in the OLD quoted form (e.g. ["10","20"]) therefore
|
||||
// both (a) hashes differently from the native re-flatten — a spurious
|
||||
@@ -669,7 +669,7 @@ public class DeploymentService
|
||||
// equal to the native re-flatten, then drive BOTH the staleness hash and
|
||||
// the diff off that normalized snapshot. Scalars are left untouched.
|
||||
//
|
||||
// DeploymentManager-007: a snapshot that cannot be deserialized (corrupt /
|
||||
// A snapshot that cannot be deserialized (corrupt /
|
||||
// older schema) still yields the frozen-hash staleness result, with a
|
||||
// null diff.
|
||||
var deployedRevisionHash = snapshot.RevisionHash;
|
||||
@@ -781,7 +781,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-2: Returns the current persisted <see cref="DeploymentRecord"/> for
|
||||
/// Returns the current persisted <see cref="DeploymentRecord"/> for
|
||||
/// the given deployment ID from the configuration database. This is a pure
|
||||
/// local DB read — it does not contact the site. The query-the-site-before-
|
||||
/// redeploy reconciliation (design: "Deployment Identity & Idempotency")
|
||||
@@ -799,7 +799,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DeploymentManager-006: query-the-site-before-redeploy reconciliation.
|
||||
/// Query-the-site-before-redeploy reconciliation.
|
||||
///
|
||||
/// The site query is issued ONLY when a prior <see cref="DeploymentRecord"/>
|
||||
/// for this instance is stuck <see cref="DeploymentStatus.InProgress"/>, or
|
||||
@@ -810,11 +810,11 @@ public class DeploymentService
|
||||
///
|
||||
/// Reconciliation: if the site already has the TARGET revision hash, the
|
||||
/// prior record is marked <see cref="DeploymentStatus.Success"/> (with its
|
||||
/// <see cref="DeploymentRecord.RevisionHash"/> corrected to the target —
|
||||
/// DeploymentManager-016) and returned (the caller must NOT re-send the
|
||||
/// <see cref="DeploymentRecord.RevisionHash"/> corrected to the target)
|
||||
/// and returned (the caller must NOT re-send the
|
||||
/// deploy). The same post-success side effects as the normal deploy path
|
||||
/// are applied — instance <see cref="InstanceState.Enabled"/> and a stored
|
||||
/// <see cref="DeployedConfigSnapshot"/> (DeploymentManager-015) — so central
|
||||
/// <see cref="DeployedConfigSnapshot"/> — so central
|
||||
/// and site state do not diverge. Otherwise <c>null</c> is returned and the
|
||||
/// normal deploy proceeds.
|
||||
///
|
||||
@@ -875,7 +875,7 @@ public class DeploymentService
|
||||
prior.Status = DeploymentStatus.Success;
|
||||
prior.ErrorMessage = null;
|
||||
prior.CompletedAt = DateTimeOffset.UtcNow;
|
||||
// DeploymentManager-016: the prior record can legitimately carry a
|
||||
// The prior record can legitimately carry a
|
||||
// different (stale) revision hash than the current target. The site
|
||||
// confirmed it is running the target revision, so the persisted
|
||||
// record, the audit entry below, and the site must all agree.
|
||||
@@ -884,13 +884,13 @@ public class DeploymentService
|
||||
await _repository.SaveChangesAsync(cancellationToken);
|
||||
NotifyStatusChange(prior);
|
||||
|
||||
// DeploymentManager-015: a reconciled deployment must perform the
|
||||
// A reconciled deployment must perform the
|
||||
// SAME post-success side effects as the normal deploy path — set
|
||||
// the instance State to Enabled and store/refresh the deployed
|
||||
// config snapshot — otherwise the central state machine and the
|
||||
// deployed-snapshot invariant diverge from what the site is running.
|
||||
//
|
||||
// DeploymentManager-018: the reconciliation path runs only when the
|
||||
// The reconciliation path runs only when the
|
||||
// prior record is InProgress or timeout-Failed — exactly the cases
|
||||
// that survive a central failover. The in-memory operation lock is
|
||||
// lost on failover, so an operator may have legitimately invoked
|
||||
@@ -906,7 +906,7 @@ public class DeploymentService
|
||||
instance, prior.DeploymentId, targetRevisionHash, configJson,
|
||||
forceEnabledState: false, cancellationToken);
|
||||
|
||||
// DeploymentManager-020: attribute the audit row to the user driving
|
||||
// Attribute the audit row to the user driving
|
||||
// THIS redeploy (the caller of DeployInstanceAsync), not the user
|
||||
// who issued the original timed-out / stuck deployment. The original
|
||||
// deployer is preserved in the detail object so forensics can still
|
||||
@@ -930,7 +930,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DeploymentManager-006: the site is queried before a re-deploy only when a
|
||||
/// The site is queried before a re-deploy only when a
|
||||
/// prior record is stuck <see cref="DeploymentStatus.InProgress"/>, or is
|
||||
/// <see cref="DeploymentStatus.Failed"/> because the site command timed out
|
||||
/// (detected via the <see cref="TimeoutFailurePrefix"/> error-message
|
||||
@@ -944,12 +944,12 @@ public class DeploymentService
|
||||
|
||||
/// <summary>
|
||||
/// Post-success side effects shared by the normal deploy path and the
|
||||
/// DeploymentManager-006 reconciliation path: set the instance
|
||||
/// <see cref="InstanceState.Enabled"/> (WP-4) and store/refresh the
|
||||
/// deployed config snapshot (WP-8). Factored into one helper so the two
|
||||
/// paths cannot drift (DeploymentManager-015).
|
||||
/// reconciliation path: set the instance
|
||||
/// <see cref="InstanceState.Enabled"/> and store/refresh the
|
||||
/// deployed config snapshot. Factored into one helper so the two
|
||||
/// paths cannot drift.
|
||||
///
|
||||
/// DeploymentManager-018: <paramref name="forceEnabledState"/> distinguishes
|
||||
/// <paramref name="forceEnabledState"/> distinguishes
|
||||
/// the two callers. The normal deploy path passes <c>true</c> — a fresh
|
||||
/// successful apply legitimately puts the instance into <see cref="InstanceState.Enabled"/>
|
||||
/// (the documented "Deploy on a Disabled instance also enables it" semantics
|
||||
@@ -977,8 +977,8 @@ public class DeploymentService
|
||||
{
|
||||
try
|
||||
{
|
||||
// WP-4: Update instance state to Enabled on successful deployment.
|
||||
// DeploymentManager-018: on the reconciliation path
|
||||
// Update instance state to Enabled on successful deployment.
|
||||
// On the reconciliation path
|
||||
// (forceEnabledState=false) only promote NotDeployed → Enabled,
|
||||
// preserving an intentional Disabled state set between the original
|
||||
// timed-out deploy and the redeploy.
|
||||
@@ -988,7 +988,7 @@ public class DeploymentService
|
||||
}
|
||||
await _repository.UpdateInstanceAsync(instance, cancellationToken);
|
||||
|
||||
// WP-8: Store deployed config snapshot
|
||||
// Store deployed config snapshot
|
||||
await StoreDeployedSnapshotAsync(
|
||||
instance.Id, deploymentId, revisionHash, configJson, cancellationToken);
|
||||
|
||||
@@ -1005,7 +1005,7 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DeploymentManager-019: write a "<Action>TimedOut" audit entry on
|
||||
/// Write a "<Action>TimedOut" audit entry on
|
||||
/// behalf of a lifecycle command (Disable / Enable / Delete) whose site
|
||||
/// round-trip exceeded <see cref="DeploymentManagerOptions.LifecycleCommandTimeout"/>.
|
||||
///
|
||||
@@ -1094,10 +1094,10 @@ public class DeploymentService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-8: Result of comparing deployed vs template-derived configuration.
|
||||
/// Result of comparing deployed vs template-derived configuration.
|
||||
/// </summary>
|
||||
/// <param name="Diff">
|
||||
/// DeploymentManager-007: structured added/removed/changed detail for
|
||||
/// Structured added/removed/changed detail for
|
||||
/// attributes, alarms, and scripts. Null only when the deployed snapshot could
|
||||
/// not be deserialized (corrupt / older schema), in which case
|
||||
/// <see cref="IsStale"/> still reflects the hash comparison.
|
||||
|
||||
Reference in New Issue
Block a user