diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs index 8f0f6299..718485b8 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs @@ -172,8 +172,8 @@ public static class DraftValidator var compat = ns.Kind switch { - NamespaceKind.SystemPlatform => di.DriverType == "Galaxy", - NamespaceKind.Equipment => di.DriverType != "Galaxy", + NamespaceKind.SystemPlatform => di.DriverType == "GalaxyMxGateway", + NamespaceKind.Equipment => di.DriverType != "GalaxyMxGateway", _ => true, }; diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser/GalaxyDriverBrowser.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser/GalaxyDriverBrowser.cs index 45ecd19c..35fcdccd 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser/GalaxyDriverBrowser.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser/GalaxyDriverBrowser.cs @@ -42,8 +42,10 @@ public sealed class GalaxyDriverBrowser : IDriverBrowser _logger = logger ?? NullLogger.Instance; } - /// Driver type key — matches the AdminUI's persisted "Galaxy" value. - public string DriverType => "Galaxy"; + /// Driver type key — matches the AdminUI's persisted "GalaxyMxGateway" value. + // Hardcoded literal: this project references Driver.Galaxy.Contracts, not Driver.Galaxy, + // so GalaxyDriverFactoryExtensions.DriverTypeName isn't available here. + public string DriverType => "GalaxyMxGateway"; /// /// Deserializes a blob, opens a transient diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriverProbe.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriverProbe.cs index c9cc7afd..49d0d31d 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriverProbe.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriverProbe.cs @@ -25,7 +25,7 @@ public sealed class GalaxyDriverProbe : IDriverProbe /// // Matches DriverInstance.DriverType strings set by the AdminUI's GalaxyDriverPage. - public string DriverType => "Galaxy"; + public string DriverType => GalaxyDriverFactoryExtensions.DriverTypeName; /// public async Task ProbeAsync(string configJson, TimeSpan timeout, CancellationToken ct) diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor index 55353cbf..dfbf30e0 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor @@ -59,7 +59,7 @@ else ["TwinCat"] = typeof(TwinCATDriverPage), ["Focas"] = typeof(FocasDriverPage), ["OpcUaClient"] = typeof(OpcUaClientDriverPage), - ["Galaxy"] = typeof(GalaxyDriverPage), + ["GalaxyMxGateway"] = typeof(GalaxyDriverPage), ["Historian.Wonderware"] = typeof(HistorianWonderwareDriverPage), }; diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/GalaxyDriverPage.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/GalaxyDriverPage.razor index c190e956..5c3b3e71 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/GalaxyDriverPage.razor +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/GalaxyDriverPage.razor @@ -208,7 +208,7 @@ else [Parameter] public string ClusterId { get; set; } = ""; [Parameter] public string? DriverInstanceId { get; set; } - private const string DriverTypeKey = "Galaxy"; + private const string DriverTypeKey = "GalaxyMxGateway"; private bool IsNew => string.IsNullOrEmpty(DriverInstanceId); diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/DriverIdentitySection.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/DriverIdentitySection.razor index 92291b82..a1354355 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/DriverIdentitySection.razor +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/DriverIdentitySection.razor @@ -35,7 +35,7 @@ - +
Cannot be changed after creation — drives the actor type that owns this instance.
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Pickers/GalaxyAddressPickerBody.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Pickers/GalaxyAddressPickerBody.razor index 8fd1e4e3..f1926888 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Pickers/GalaxyAddressPickerBody.razor +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Pickers/GalaxyAddressPickerBody.razor @@ -126,7 +126,7 @@ try { var json = GetConfigJson() ?? "{}"; - var result = await BrowserService.OpenAsync("Galaxy", json, default); + var result = await BrowserService.OpenAsync("GalaxyMxGateway", json, default); if (result.Ok) _token = result.Token; else _openError = result.Message; } diff --git a/tests/Core/ZB.MOM.WW.OtOpcUa.Configuration.Tests/DraftValidatorTests.cs b/tests/Core/ZB.MOM.WW.OtOpcUa.Configuration.Tests/DraftValidatorTests.cs index 0e86430d..1effa46b 100644 --- a/tests/Core/ZB.MOM.WW.OtOpcUa.Configuration.Tests/DraftValidatorTests.cs +++ b/tests/Core/ZB.MOM.WW.OtOpcUa.Configuration.Tests/DraftValidatorTests.cs @@ -122,15 +122,45 @@ public sealed class DraftValidatorTests DraftValidator.Validate(draft).ShouldContain(e => e.Code == "EquipmentIdNotDerived"); } - /// Verifies that Galaxy driver cannot be placed in Equipment namespace. + /// Verifies that the canonical Galaxy driver type (GalaxyMxGateway, per PR 7.2 — + /// it was "Galaxy" pre-PR-7.2) is allowed in a SystemPlatform namespace, i.e. produces no + /// kind-mismatch error. [Fact] - public void Galaxy_driver_in_Equipment_namespace_is_rejected() + public void GalaxyMxGateway_driver_in_SystemPlatform_namespace_is_allowed() + { + var draft = new DraftSnapshot + { + GenerationId = 1, ClusterId = "c", + Namespaces = [new Namespace { NamespaceId = "ns-1", ClusterId = "c", NamespaceUri = "urn:x", Kind = NamespaceKind.SystemPlatform }], + DriverInstances = [new DriverInstance { DriverInstanceId = "d-1", ClusterId = "c", NamespaceId = "ns-1", Name = "drv", DriverType = "GalaxyMxGateway", DriverConfig = "{}" }], + }; + + DraftValidator.Validate(draft).ShouldNotContain(e => e.Code == "DriverNamespaceKindMismatch"); + } + + /// Verifies that the canonical Galaxy driver type cannot be placed in an Equipment namespace. + [Fact] + public void GalaxyMxGateway_driver_in_Equipment_namespace_is_rejected() { var draft = new DraftSnapshot { GenerationId = 1, ClusterId = "c", Namespaces = [new Namespace { NamespaceId = "ns-1", ClusterId = "c", NamespaceUri = "urn:x", Kind = NamespaceKind.Equipment }], - DriverInstances = [new DriverInstance { DriverInstanceId = "d-1", ClusterId = "c", NamespaceId = "ns-1", Name = "drv", DriverType = "Galaxy", DriverConfig = "{}" }], + DriverInstances = [new DriverInstance { DriverInstanceId = "d-1", ClusterId = "c", NamespaceId = "ns-1", Name = "drv", DriverType = "GalaxyMxGateway", DriverConfig = "{}" }], + }; + + DraftValidator.Validate(draft).ShouldContain(e => e.Code == "DriverNamespaceKindMismatch"); + } + + /// Verifies that a non-Galaxy driver cannot be placed in a SystemPlatform namespace. + [Fact] + public void NonGalaxy_driver_in_SystemPlatform_namespace_is_rejected() + { + var draft = new DraftSnapshot + { + GenerationId = 1, ClusterId = "c", + Namespaces = [new Namespace { NamespaceId = "ns-1", ClusterId = "c", NamespaceUri = "urn:x", Kind = NamespaceKind.SystemPlatform }], + DriverInstances = [new DriverInstance { DriverInstanceId = "d-1", ClusterId = "c", NamespaceId = "ns-1", Name = "drv", DriverType = "ModbusTcp", DriverConfig = "{}" }], }; DraftValidator.Validate(draft).ShouldContain(e => e.Code == "DriverNamespaceKindMismatch"); @@ -145,7 +175,7 @@ public sealed class DraftValidatorTests { GenerationId = 1, ClusterId = "c-A", Namespaces = [new Namespace { NamespaceId = "ns-1", ClusterId = "c-B", NamespaceUri = "urn:x", Kind = NamespaceKind.Equipment }], - DriverInstances = [new DriverInstance { DriverInstanceId = "d-1", ClusterId = "c-A", NamespaceId = "ns-1", Name = "drv", DriverType = "Galaxy", DriverConfig = "{}" }], + DriverInstances = [new DriverInstance { DriverInstanceId = "d-1", ClusterId = "c-A", NamespaceId = "ns-1", Name = "drv", DriverType = "GalaxyMxGateway", DriverConfig = "{}" }], Equipment = [new Equipment { EquipmentUuid = uuid, EquipmentId = "EQ-wrong", Name = "BAD NAME", DriverInstanceId = "d-1", UnsLineId = "line-a", MachineCode = "m" }], }; diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.Tests/GalaxyDriverBrowserTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.Tests/GalaxyDriverBrowserTests.cs index ab917ef5..daf6bb61 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.Tests/GalaxyDriverBrowserTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.Tests/GalaxyDriverBrowserTests.cs @@ -16,10 +16,10 @@ public sealed class GalaxyDriverBrowserTests { private readonly GalaxyDriverBrowser _sut = new(); - /// The DriverType key must match the AdminUI's persisted "Galaxy" value + /// The DriverType key must match the AdminUI's persisted "GalaxyMxGateway" value /// so the factory wire-up picks the right browser implementation. [Fact] - public void DriverType_is_Galaxy() => _sut.DriverType.ShouldBe("Galaxy"); + public void DriverType_is_GalaxyMxGateway() => _sut.DriverType.ShouldBe("GalaxyMxGateway"); /// An empty Gateway.Endpoint must fail fast with a clear, endpoint-mentioning /// message rather than surfacing a downstream gRPC URI parse error.