diff --git a/ZB.MOM.WW.Overview/src/ZB.MOM.WW.Overview/appsettings.Wonder.json b/ZB.MOM.WW.Overview/src/ZB.MOM.WW.Overview/appsettings.Wonder.json index eaa4024..96744ae 100644 --- a/ZB.MOM.WW.Overview/src/ZB.MOM.WW.Overview/appsettings.Wonder.json +++ b/ZB.MOM.WW.Overview/src/ZB.MOM.WW.Overview/appsettings.Wonder.json @@ -16,6 +16,27 @@ // // Ports NOT to probe, confirmed 400 (h2c gRPC, which rejects an HTTP/1.1 health GET): // :8083 ScadaBridge central control plane, :8086. + // + // ── Why every BaseUrl is 127.0.0.1 and never "localhost" ──────────────────────────────────── + // LeaderResolver.ResolveToInstanceName maps a reported Akka leader address to an instance by + // matching on HOST ONLY — correct by design, since an app's Akka remoting port and its HTTP + // port differ, so comparing ports would never match. That resolution assumes what is true on + // the docker rig and false here: that instances have DISTINCT hosts. All five of these live on + // one box, and the scan is fleet-wide in registry order, so the first entry sharing the host + // wins the chip for EVERY group. + // + // Observed live with BaseUrl "localhost": the ScadaBridge *site* card claimed "Leader · central" + // — two separate Akka clusters, so that name was simply wrong. + // + // There is no host value that makes resolution CORRECT here, because the instances really are + // co-located. So the deliberate choice is to make it never match: ScadaBridge's Akka addresses + // use the host "localhost" and OtOpcUa's uses the FQDN, and "127.0.0.1" is string-unequal to + // both. Every leader chip then falls back to the raw Akka address, which is unambiguous and + // always true. A raw address beats a confident wrong name. + // + // Using the FQDN for OtOpcUa's BaseUrl WOULD resolve its chip correctly, and was rejected: the + // name resolves to a link-local IPv6 on this box, and routing the actual health probe through + // that to improve a label trades the primary function for a cosmetic one. "Serilog": { // Absolute, and deliberately OUTSIDE the Server directory the upgrade procedure replaces. @@ -59,10 +80,10 @@ // (it triggers on more than one DISTINCT reported address). "Name": "wonder", "Group": "MAIN", - // Probed by THIS service, on this box — localhost is the shortest path and is immune + // Probed by THIS service, on this box — loopback is the shortest path and is immune // to any host firewall rule. ManagementUrl is the opposite case: the operator's // browser follows it from their own machine, so it must carry the box address. - "BaseUrl": "http://localhost:9000", + "BaseUrl": "http://127.0.0.1:9000", "ManagementUrl": "http://10.220.157.247:9000/", "HasActiveRole": true } @@ -75,7 +96,7 @@ { "Name": "central", "Group": "central", - "BaseUrl": "http://localhost:8085", + "BaseUrl": "http://127.0.0.1:8085", "ManagementUrl": "http://10.220.157.247:8085/", "HasActiveRole": true }, @@ -85,7 +106,7 @@ // disagreement that does not exist. "Name": "site", "Group": "site", - "BaseUrl": "http://localhost:8084", + "BaseUrl": "http://127.0.0.1:8084", // No ManagementUrl: the site node serves no UI (/ returns 404), and a card linking to // a 404 is worse than a card with no link. "HasActiveRole": true @@ -101,7 +122,7 @@ // /health/active does answer 200, but only because the active tier runs an EMPTY // check set — an Active badge here would assert a role that does not exist. "Name": "wonder", - "BaseUrl": "http://localhost:5130", + "BaseUrl": "http://127.0.0.1:5130", "ManagementUrl": "http://10.220.157.247:5130/", "HasActiveRole": false } @@ -113,7 +134,7 @@ "Instances": [ { "Name": "wonder", - "BaseUrl": "http://localhost:5220", + "BaseUrl": "http://127.0.0.1:5220", "ManagementUrl": "http://10.220.157.247:5220/", "HasActiveRole": false, // Its readiness probe reaches the historian and the Galaxy SQL DB over the network,