fix(m9/T24a): scope move-guard native-alarm scan to source-site templates (Ordinal); purpose-built include; add guard-4 + repo tests
This commit is contained in:
@@ -1426,17 +1426,40 @@ public class ManagementActor : ReceiveActor
|
||||
// instances may override that name
|
||||
// (InstanceNativeAlarmSourceOverride.ConnectionNameOverride). Moving a
|
||||
// connection changes which physical connection that name resolves to on
|
||||
// the source site, so any such reference to the moving name is a blocker.
|
||||
// Detect and report only — never auto-rewrite.
|
||||
// the SOURCE site, so any such reference *on the source site* to the
|
||||
// moving name is a blocker. Detect and report only — never auto-rewrite.
|
||||
//
|
||||
// Scoping: templates are site-agnostic and ConnectionName resolves
|
||||
// against the DEPLOYING site's connection pool at flatten time, so the
|
||||
// template scan is restricted to templates actually instantiated on the
|
||||
// SOURCE site. A template referencing the same connection NAME but only
|
||||
// instantiated on another site is NOT affected by this move (that site
|
||||
// keeps its own connection of the same name), so a global template scan
|
||||
// would be a false positive that over-blocks legitimate moves whenever
|
||||
// connection names are reused across sites (the common case).
|
||||
//
|
||||
// Comparison is StringComparison.Ordinal to match the
|
||||
// flattening/deployment pipeline (FlatteningService / FlatteningPipeline
|
||||
// resolve connection names case-sensitively) — block exactly the
|
||||
// references the runtime would actually fail to resolve.
|
||||
var referenceBlockers = new List<string>();
|
||||
|
||||
// Source-site instances with their native-alarm-source overrides eagerly
|
||||
// loaded (purpose-built load so the hot-path GetInstancesBySiteIdAsync
|
||||
// stays lean). Reused below for both the override scan and to derive the
|
||||
// set of templates to scan.
|
||||
var sourceInstances = await repo.GetInstancesWithNativeAlarmOverridesBySiteIdAsync(sourceSiteId);
|
||||
|
||||
// Only templates instantiated on the SOURCE site can be broken by the move.
|
||||
var templateRepo = sp.GetRequiredService<ITemplateEngineRepository>();
|
||||
var templates = await templateRepo.GetAllTemplatesAsync();
|
||||
foreach (var template in templates)
|
||||
var sourceTemplateIds = sourceInstances.Select(i => i.TemplateId).Distinct();
|
||||
foreach (var templateId in sourceTemplateIds)
|
||||
{
|
||||
var template = await templateRepo.GetTemplateByIdAsync(templateId);
|
||||
if (template is null) continue;
|
||||
foreach (var source in template.NativeAlarmSources)
|
||||
{
|
||||
if (string.Equals(source.ConnectionName, conn.Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(source.ConnectionName, conn.Name, StringComparison.Ordinal))
|
||||
{
|
||||
referenceBlockers.Add(
|
||||
$"template '{template.Name}' native-alarm-source '{source.Name}'");
|
||||
@@ -1446,12 +1469,11 @@ public class ManagementActor : ReceiveActor
|
||||
|
||||
// Instance-level overrides on the SOURCE site that name this connection
|
||||
// would orphan once the connection leaves the site.
|
||||
var sourceInstances = await repo.GetInstancesBySiteIdAsync(sourceSiteId);
|
||||
foreach (var instance in sourceInstances)
|
||||
{
|
||||
foreach (var ovr in instance.NativeAlarmSourceOverrides)
|
||||
{
|
||||
if (string.Equals(ovr.ConnectionNameOverride, conn.Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(ovr.ConnectionNameOverride, conn.Name, StringComparison.Ordinal))
|
||||
{
|
||||
referenceBlockers.Add(
|
||||
$"instance '{instance.UniqueName}' (ID {instance.Id}) native-alarm-source override '{ovr.SourceCanonicalName}'");
|
||||
|
||||
Reference in New Issue
Block a user