etzel-mes opened a new pull request, #28128: URL: https://github.com/apache/camel/pull/28128
# Description [CAMEL-25835](https://issues.apache.org/jira/browse/CAMEL-25835). The `milo-client` consumer hands every data change notification to its route and reports nothing when the values stop. When the session drops and Milo activates it again, the consumer only flips its `sessionActive` flag, and the values that did not change during the outage are not delivered again. When the subscription is transferred or the connection is rebuilt, the route sees a pause and then first values. When the server cannot be reached at startup, or the client cannot connect at all, the route sees nothing. A route cannot tell "unchanged" from "unknown": a historian keeps the last value, a publisher republishes it as live, an alarm stays quiet. The change, following the OPC UA specifications (OPC 10000-4 §7.38 Table 179 and 10000-8 §7.3 Table 61 for `Bad_NoCommunication`, 10000-4 §7.11.3 for the timestamps, 10000-14 §6.2.11.1 Table 80 for a consumer without a last value, 10000-4 §6.7 step 6 and 10000-5 §9.2 for `ResendData`): - **Signal.** When communication with the server is lost, every monitored node delivers one exchange whose `DataValue` has a null value and the status `Bad_NoCommunication`, both timestamps set to the time the loss was recognised. The triggers are the session becoming inactive (`SessionActivityListener`), a rebuild of the connection (`handleConnectionFailure`, before it disposes the connection), and a registration while there is no connection or the session is inactive. The report of a connection is queued on its subscription's delivery queue, so it lands after the values the queue still holds and before the values of the activated session; a registration without a connection is reported on the connection's executor, not on the thread that starts the route. - **Once per loss.** Each registration keeps whether its last delivery was the report, and the generation of the connection that delivered its last value; both guarded by the registration, so a report and a value of the same node never interleave. A report is skipped when the node is reported already, when a later connection has delivered a value, and when the server refused the node's monitored item (it keeps that status, which does not depend on the communication; the mark is cleared when an item is created for it). - **Refresh.** When the same session is activated again (same session ID as the lost one), the consumer calls `ResendData` for its subscription, so the server sends the current value of every node, the unchanged ones included. Any answer other than Good or a lost session recreates the subscription with the recovery of CAMEL-25691 (delete, then create again in the session; the new items deliver their first values), logged at WARN. After a transfer or a rebuild the server sends the first values anyway. - **Not done.** No value cache, no option, no debounce, no marker header, no read fallback (every open-source server stack I read implements `ResendData`: Milo, open62541, node-opcua, the OPC Foundation .NET stack), no handling of lost notifications, no per-node ordering rules. Event items are unchanged. - **Tests.** New `CommunicationLossTest` with a TCP relay between the client and the embedded server: two losses in a row on the same client and session (asserted), the unchanged value resent, a change in between delivered, a refused node on the same connection keeps `Bad_NodeIdUnknown`; and a consumer started with the relay down reports first and receives its value once the relay is up. `MonitorItemLifecycleTest`, `MonitorItemMultiConnectionsTest` and `ServerCertificateValidationTest` now expect the report for a rebuilt connection and for clients that cannot connect at all. The embedded Milo server answers `ResendData` on the oldest queued Publish request, which belongs to the dropped channel, so the resent value reaches the client 10-20 s later through its republish of the missed notification; the relay test waits for it and says why (a real server answered in 2 ms). - **Docs.** A "Communication loss and recovery" section in the component doc (with its catalog copy) and a 4.24 upgrade-guide note: the null body becomes `0` or `false` through the type converters, a route checks `${body.statusCode.bad}`; repeats after an outage; clients that cannot connect now report; the consumer's route runs during an outage. Against a server that is not built on Milo (Microsoft opc-plc 2.15.4): a 20 s silent drop with and without writes, a 150 s drop, a server restart, a value held in a slow route with another queued behind it and then a drop, a consumer started while the server was stopped, and a refused node next to a good one. One `Bad_NoCommunication` per node per outage in every run; `ResendData` answered Good after the same session was activated again (the unchanged value arrived 0.1 s later), a silent drop was recognised after 10-14 s with Milo's keep-alive defaults, and the long drop and the restart ended in a transfer failure and a rebuild with first values. The report that was queued behind a value held in the route landed after that value. CAMEL-25692 (retry of refused monitored items) changes the registration code too; I will rebase whichever lands second. A producer request that fails because the session was lost still rebuilds the shared connection, so its consumers see the report and first values instead of a reactivation; a rebuild only for other failures belongs with CAMEL-25694 (#27956), which rewrites those blocks. Checked with `-Psourcecheck verify` on the module (88 tests, no reruns). @davsclaus @oscerd could you take a look? # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [ ] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes. # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. _Claude Code on behalf of etzel-mes_ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
