etzel-mes opened a new pull request, #27780: URL: https://github.com/apache/camel/pull/27780
# Description One `milo-client` consumer can now monitor many OPC UA nodes ([CAMEL-25566](https://issues.apache.org/jira/browse/CAMEL-25566)): - **`nodes` option.** A comma-separated list of node IDs, used instead of `node`: `nodes=RAW(ns=2;s=line1/temperature,ns=2;s=line1/pressure)`. Entries are trimmed, empty entries are skipped, and a node that is listed twice is monitored once. Long lists can come from a property placeholder. A string node ID that contains a comma cannot be used in `nodes`. - **`CamelMiloNodeId` header.** Every consumer exchange carries the node ID as configured, also for a single `node`. The body is still the `DataValue`. - **Batch create and delete.** The monitored items of all nodes are created with one call when the consumer starts, and deleted with one call when it stops. Milo splits the requests by the server's `MaxMonitoredItemsPerCall`. - A consumer that sets both `node` and `nodes`, or no node at all, fails with an `IllegalArgumentException`. Measured locally against the embedded Milo server, with 10,000 nodes: | | one consumer, `nodes=RAW({{nodes}})` | 10,000 single-node routes | |---|---|---| | start until every node has its first value | 1.4 to 2.4 s | 30 to 70 s | | client heap after GC | +15 to +17 MiB | +70 MiB | | context stop | 62 to 64 ms | 8.6 to 34.6 s | The test suite does not contain this measurement. ## Also fixes CAMEL-25599 This PR also fixes [CAMEL-25599](https://issues.apache.org/jira/browse/CAMEL-25599), because the feature builds on the same code. Since camel-milo came back with Eclipse Milo 1.x (CAMEL-22086, Camel 4.16), `SubscriptionManager` ignored the results of `createMonitoredItems()`: - `goodSubscriptions` was never filled. Stopping a consumer left its item on the server while another endpoint kept the shared connection open, so a restarted consumer received each value twice. - A failed item, for example `Bad_NodeIdUnknown`, was not reported to the consumer. - The data value listener was set after the item was created, so a value that arrived in between was dropped. ea9aca27fe2 evaluated the results, but looked them up by the client handle that Milo assigns in `addMonitoredItem`, not by the handle Camel uses as the key of its subscriptions. f61f19e3b20 replaced that lookup with `itemToClientHandle` for the listeners and dropped the evaluation. This change maps the results through `itemToClientHandle` again, and `createMonitoredItems(Predicate)` creates only the items of the current call. A failed item is reported once (delivered when `omitNullValues=false`), removed from the Milo subscription, and created again when the route restarts or Camel rebuilds the connection. Unlike Camel 3.x, it is not retried on a timer. In an outage test, a blocking retry on Milo's shared scheduled executor kept the client from recovering on a JVM that sees one CPU. Known limitation: as in Camel 3.x (`deleteMonitoredItems(…).get()`), stopping a consumer waits for the deletion of its items. While the server is unreachable, Milo's synchronous call returns only when the client's next attempt to reconnect has failed. In our outage test, three consumers of one connection, stopped one after the other, took 4, 8 and 32 s (the last one also closes the connection); on `main`, where the stop sends no delete, they took at most 4 s. With `nodes`, one consumer deletes all its items with one call. ## Tests - `MonitorNodesTest` (6 tests): several nodes with the header, an unknown node among good ones, duplicates and whitespace, the header on a single-node consumer, and both rejected configurations. - `MonitorItemLifecycleTest` (2 tests): a restarted consumer receives each value once, and an unknown node receives `Bad_NodeIdUnknown` while the other consumers keep working. Tested in `components/camel-milo` with `-Psourcecheck`: 51 tests, 0 failures, 1 skipped (also skipped on `main`). The 4.24 upgrade guide has a note. The regenerated files are included: the component JSON, configurer and URI factory, the catalog copies, and the Endpoint DSL. I regenerated them per module and did not run `mvn clean install -DskipTests` from the root folder. I cannot assign JIRA issues; my JIRA user is `mardonius`, and both issues are unassigned. @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_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- 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]
