-- docker-dev cluster seed. Idempotent — safe to re-run on every `docker compose up`. -- -- Populates: -- ServerCluster MAIN, SITE-A, SITE-B -- ClusterNode driver-a, driver-b → MAIN -- site-a-1, site-a-2 → SITE-A -- site-b-1, site-b-2 → SITE-B -- -- ServerCluster.NodeCount + RedundancyMode are coupled by CHECK constraint: -- NodeCount=1 ⇒ RedundancyMode='None' -- NodeCount=2 ⇒ RedundancyMode∈('Warm','Hot') -- -- Each ClusterNode.ApplicationUri MUST be globally unique (UX_ClusterNode_ApplicationUri). -- Convention: urn:OtOpcUa:. -- -- Host = Compose service name (resolves inside the otopcua-dev network). -- OpcUaPort stays at the container-internal 4840; the host-side port mapping is in -- docker-compose.yml ports: blocks and is irrelevant to ClusterNode rows. SET NOCOUNT ON; SET XACT_ABORT ON; BEGIN TRANSACTION; ------------------------------------------------------------------------------ -- ServerCluster ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT 1 FROM dbo.ServerCluster WHERE ClusterId = 'MAIN') INSERT INTO dbo.ServerCluster (ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, Notes, CreatedBy) VALUES ('MAIN', 'Main cluster', 'zb', 'docker-dev', 2, 'Warm', 1, 'docker-dev seed — admin-a/admin-b control-plane, driver-a/driver-b OPC UA publishers.', 'docker-dev-seed'); IF NOT EXISTS (SELECT 1 FROM dbo.ServerCluster WHERE ClusterId = 'SITE-A') INSERT INTO dbo.ServerCluster (ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, Notes, CreatedBy) VALUES ('SITE-A', 'Site A', 'zb', 'site-a', 2, 'Warm', 1, 'docker-dev seed — 2-node fused admin+driver cluster.', 'docker-dev-seed'); IF NOT EXISTS (SELECT 1 FROM dbo.ServerCluster WHERE ClusterId = 'SITE-B') INSERT INTO dbo.ServerCluster (ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, Notes, CreatedBy) VALUES ('SITE-B', 'Site B', 'zb', 'site-b', 2, 'Warm', 1, 'docker-dev seed — 2-node fused admin+driver cluster.', 'docker-dev-seed'); ------------------------------------------------------------------------------ -- ClusterNode — main cluster OPC UA publishers -- -- NodeId is ":4053" so it matches what ClusterRoleInfo + -- ConfigPublishCoordinator derive from Akka.Cluster.Get(system).State.Members -- (member.Address.Host:Port). NodeDeploymentState.NodeId is FK-bound to -- ClusterNode.NodeId; mismatched values cause FK 547 on deploy. ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT 1 FROM dbo.ClusterNode WHERE NodeId = 'driver-a:4053') INSERT INTO dbo.ClusterNode (NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) VALUES ('driver-a:4053', 'MAIN', 'driver-a', 4840, 8081, 'urn:OtOpcUa:driver-a', 200, 1, 'docker-dev-seed'); IF NOT EXISTS (SELECT 1 FROM dbo.ClusterNode WHERE NodeId = 'driver-b:4053') INSERT INTO dbo.ClusterNode (NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) VALUES ('driver-b:4053', 'MAIN', 'driver-b', 4840, 8081, 'urn:OtOpcUa:driver-b', 150, 1, 'docker-dev-seed'); ------------------------------------------------------------------------------ -- ClusterNode — site A ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT 1 FROM dbo.ClusterNode WHERE NodeId = 'site-a-1:4053') INSERT INTO dbo.ClusterNode (NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) VALUES ('site-a-1:4053', 'SITE-A', 'site-a-1', 4840, 8081, 'urn:OtOpcUa:site-a-1', 200, 1, 'docker-dev-seed'); IF NOT EXISTS (SELECT 1 FROM dbo.ClusterNode WHERE NodeId = 'site-a-2:4053') INSERT INTO dbo.ClusterNode (NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) VALUES ('site-a-2:4053', 'SITE-A', 'site-a-2', 4840, 8081, 'urn:OtOpcUa:site-a-2', 150, 1, 'docker-dev-seed'); ------------------------------------------------------------------------------ -- ClusterNode — site B ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT 1 FROM dbo.ClusterNode WHERE NodeId = 'site-b-1:4053') INSERT INTO dbo.ClusterNode (NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) VALUES ('site-b-1:4053', 'SITE-B', 'site-b-1', 4840, 8081, 'urn:OtOpcUa:site-b-1', 200, 1, 'docker-dev-seed'); IF NOT EXISTS (SELECT 1 FROM dbo.ClusterNode WHERE NodeId = 'site-b-2:4053') INSERT INTO dbo.ClusterNode (NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) VALUES ('site-b-2:4053', 'SITE-B', 'site-b-2', 4840, 8081, 'urn:OtOpcUa:site-b-2', 150, 1, 'docker-dev-seed'); ------------------------------------------------------------------------------ -- Galaxy MxAccess gateway — MAIN cluster -- -- Namespace.Kind=SystemPlatform is required for Galaxy/MXAccess data per -- decision #107; raw equipment drivers use Equipment. DriverInstance points -- at the external mxaccessgw process. The driver code lives in this repo -- (.NET 10, cross-platform); only the gateway worker needs Windows. -- -- ApiKeySecretRef = env:GALAXY_MXGW_API_KEY → resolved at runtime by -- GalaxyDriver.ResolveApiKey. The env var is set on every driver-role -- container in docker-compose.yml. ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT 1 FROM dbo.Namespace WHERE NamespaceId = 'MAIN-galaxy') INSERT INTO dbo.Namespace (NamespaceRowId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled, Notes) VALUES (NEWID(), 'MAIN-galaxy', 'MAIN', 'SystemPlatform', 'urn:zb:docker-dev:galaxy', 1, 'docker-dev seed — Galaxy / MXAccess namespace served by the MAIN cluster.'); IF NOT EXISTS (SELECT 1 FROM dbo.DriverInstance WHERE DriverInstanceId = 'MAIN-galaxy-mxgw') INSERT INTO dbo.DriverInstance (DriverInstanceRowId, DriverInstanceId, ClusterId, NamespaceId, Name, DriverType, Enabled, DriverConfig) VALUES (NEWID(), 'MAIN-galaxy-mxgw', 'MAIN', 'MAIN-galaxy', 'MxAccess gateway (10.100.0.48:5120)', 'GalaxyMxGateway', 1, N'{ "Gateway": { "Endpoint": "http://10.100.0.48:5120", "ApiKeySecretRef": "env:GALAXY_MXGW_API_KEY", "UseTls": false, "ConnectTimeoutSeconds": 10, "DefaultCallTimeoutSeconds": 30 }, "MxAccess": { "ClientName": "OtOpcUa-MAIN-docker-dev", "PublishingIntervalMs": 1000 }, "Repository": { "DiscoverPageSize": 5000, "WatchDeployEvents": true }, "Reconnect": { "InitialBackoffMs": 500, "MaxBackoffMs": 30000, "ReplayOnSessionLost": true } }'); ------------------------------------------------------------------------------ -- Galaxy test tags — TestMachine_001.TestAlarm001..003 -- -- SystemPlatform-namespace tags have EquipmentId=NULL and use FolderPath + -- Name to address the MXAccess item. The Galaxy driver subscribes via the -- "FolderPath.Name" MXAccess reference form; OPC UA browse path is the -- equivalent "FolderPath/Name" under the SystemPlatform namespace. ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT 1 FROM dbo.Tag WHERE TagId = 'MAIN-galaxy-TestMachine_001-TestAlarm001') INSERT INTO dbo.Tag (TagRowId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig) VALUES (NEWID(), 'MAIN-galaxy-TestMachine_001-TestAlarm001', 'MAIN-galaxy-mxgw', NULL, NULL, 'TestAlarm001', 'TestMachine_001', 'Boolean', 0, 0, NULL, N'{}'); IF NOT EXISTS (SELECT 1 FROM dbo.Tag WHERE TagId = 'MAIN-galaxy-TestMachine_001-TestAlarm002') INSERT INTO dbo.Tag (TagRowId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig) VALUES (NEWID(), 'MAIN-galaxy-TestMachine_001-TestAlarm002', 'MAIN-galaxy-mxgw', NULL, NULL, 'TestAlarm002', 'TestMachine_001', 'Boolean', 0, 0, NULL, N'{}'); IF NOT EXISTS (SELECT 1 FROM dbo.Tag WHERE TagId = 'MAIN-galaxy-TestMachine_001-TestAlarm003') INSERT INTO dbo.Tag (TagRowId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig) VALUES (NEWID(), 'MAIN-galaxy-TestMachine_001-TestAlarm003', 'MAIN-galaxy-mxgw', NULL, NULL, 'TestAlarm003', 'TestMachine_001', 'Boolean', 0, 0, NULL, N'{}'); COMMIT TRANSACTION; ------------------------------------------------------------------------------ -- Summary (logged by sqlcmd output) ------------------------------------------------------------------------------ SELECT ClusterId, Name, NodeCount, RedundancyMode FROM dbo.ServerCluster ORDER BY ClusterId; SELECT NodeId, ClusterId, Host, OpcUaPort, ApplicationUri, ServiceLevelBase FROM dbo.ClusterNode ORDER BY ClusterId, NodeId; SELECT NamespaceId, ClusterId, Kind, NamespaceUri FROM dbo.Namespace ORDER BY ClusterId, NamespaceId; SELECT DriverInstanceId, ClusterId, DriverType, NamespaceId, Name FROM dbo.DriverInstance ORDER BY ClusterId, DriverInstanceId; SELECT TagId, DriverInstanceId, FolderPath, Name, DataType FROM dbo.Tag ORDER BY DriverInstanceId, FolderPath, Name;