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]

Reply via email to