You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by "etzel-mes (via GitHub)" <gi...@apache.org> on 2026/10/19 20:42:56 UTC
[PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #28128:
URL: https://github.com/apache/camel/pull/28128#issuecomment-6284327786
:star2: Thank you for your contribution to the Apache Camel project! :star2:
:robot: CI automation will test this PR automatically.
:camel: Apache Camel Committers, please review the following items:
* First-time contributors **require MANUAL approval** for the GitHub Actions to run
* You can use the command `/component-test (camel-)component-name1 (camel-)component-name2..` to request a test from the test bot although they are normally detected and executed by CI.
* You can label PRs using `skip-tests` and `test-dependents` to fine-tune the checks executed by this PR.
* Build and test logs are available in the summary page. **Only** [Apache Camel committers](https://camel.apache.org/community/team/#committers) have access to the summary.
:warning: Be careful when sharing logs. Review their contents before sharing them publicly.
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "etzel-mes (via GitHub)" <gi...@apache.org>.
etzel-mes commented on PR #28128:
URL: https://github.com/apache/camel/pull/28128#issuecomment-6284127609
Thanks @allthingssecurity, you are right: the counter is taken when the listener is created, before the connection is built, so a node registered during that attempt shared the generation of the connection's first value, and nothing ordered the report on the pool after it. Fixed in 66d3d312086 as you suggest: the report of a node registered without a connection carries generation 0, below every connection's, so any delivered value drops it. Module verify with `-Psourcecheck` is green (88 tests, no reruns).
_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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "davsclaus (via GitHub)" <gi...@apache.org>.
davsclaus commented on code in PR #28128:
URL: https://github.com/apache/camel/pull/28128#discussion_r4324149816
##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc:
##########
@@ -1806,6 +1806,28 @@ the server does not have, with the status code `Bad_NodeIdUnknown`, and the othe
affected. Previously an awaited write or read completed without an error and with a `null` body, and a browse failed
with a `NullPointerException`.
+=== camel-milo - the consumer reports a lost connection and refreshes its values after it
+
+The OPC UA client consumer delivers `Bad_NoCommunication` with a null value for every monitored node when
+communication with the server is lost, and the current value of every node once communication is restored. Before,
+the consumer delivered nothing during an outage, and values that did not change were not delivered again after it.
+
+A consumer that starts while the server cannot be reached, or whose client cannot connect at all, for example because
+of wrong credentials or an untrusted server certificate, delivers the status for its nodes too; the cause is in the
+log. A connection that Camel rebuilds after a failed request delivers it for every node of the connection. Each loss and
+each recovery delivers one exchange per node.
+
+A route that uses only the value of the `DataValue` body receives a null for these exchanges, which the type converters
+turn into `0` or `false`; a route that stores values checks the status code of the body first, for example with
+`${body.statusCode.bad}`. A value can now arrive again after an outage, so a route that counts values, computes
+differences or detects changes must tolerate repeats. The consumer's route also runs during an outage: an OPC UA write
+that it makes while the client reconnects waits for the next reconnect attempt and can take effect after communication
+is restored, and a request that fails rebuilds the connection.
+
+To keep the previous behaviour, filter the exchanges with a bad status out right after the consumer, for example with
+`filter(simple("${body.statusCode.good}"))`. This also drops the other bad statuses, such as the refusal of a node, and
Review Comment:
Nit (my suggestion, sorry): `${body.statusCode.good}` also drops Uncertain values, which were delivered before this change. `${body.statusCode.bad} == false` would be closer to the previous behaviour: it drops only the Bad statuses. Either is fine if you prefer to keep it as is.
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "davsclaus (via GitHub)" <gi...@apache.org>.
davsclaus merged PR #28128:
URL: https://github.com/apache/camel/pull/28128
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "etzel-mes (via GitHub)" <gi...@apache.org>.
etzel-mes commented on PR #28128:
URL: https://github.com/apache/camel/pull/28128#issuecomment-6286673398
Thanks for the review. On the status: OPC 10000-4 §7.38 lists `Bad_UserAccessDenied`, `Bad_SecurityChecksFailed` and `Bad_CertificateUntrusted` in Table 178, the common service result codes, i.e. the result of ActivateSession or OpenSecureChannel. `Bad_NoCommunication` is in Table 179, the operation level codes, defined as "communication with the data source is defined, but not established, and there is no last known value available", and OPC 10000-8 Table 61 and OPC 10000-14 Table 80 use it for exactly this situation, with a null value. A monitored item has no session failure of its own, so we would keep `Bad_NoCommunication` on the value and the cause in the log.
On the test: the 30 s and 60 s values are caps and are not spent when the value arrives; the class takes about 58 s. Each drop costs about 18 s that the test cannot remove: the embedded server answers ResendData on the Publish request of the dropped channel, so the value arrives with the next keep-alive (about 10 s, Milo derives the keep-alive count from a 10 s target), and the component's reconnect back-off is 10 s. The remaining fixed assert periods are small; I have left them as they are.
_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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "davsclaus (via GitHub)" <gi...@apache.org>.
davsclaus commented on code in PR #28128:
URL: https://github.com/apache/camel/pull/28128#discussion_r4321905633
##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc:
##########
@@ -1806,6 +1806,24 @@ the server does not have, with the status code `Bad_NodeIdUnknown`, and the othe
affected. Previously an awaited write or read completed without an error and with a `null` body, and a browse failed
with a `NullPointerException`.
+=== camel-milo - the consumer reports a lost connection and refreshes its values after it
+
+The OPC UA client consumer delivers `Bad_NoCommunication` with a null value for every monitored node when
+communication with the server is lost, and the current value of every node once communication is restored. Before,
+the consumer delivered nothing during an outage, and values that did not change were not delivered again after it.
+
+A consumer that starts while the server cannot be reached, or whose client cannot connect at all, for example because
+of wrong credentials or an untrusted server certificate, delivers the status for its nodes too; the cause is in the
+log. A connection that Camel rebuilds after a failed request delivers it for every node of the connection. Each loss and
+each recovery delivers one exchange per node.
+
+A route that uses only the value of the `DataValue` body receives a null for these exchanges, which the type converters
+turn into `0` or `false`; a route that stores values checks the status code of the body first, for example with
+`${body.statusCode.bad}`. A value can now arrive again after an outage, so a route that counts values, computes
Review Comment:
Since there is deliberately no option, could you add one sentence on how to keep the previous behaviour, for example `filter(simple("${body.statusCode.good}"))` right after the consumer? Users upgrading with routes that write `body.value` straight to a historian will look for exactly that sentence.
##########
components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java:
##########
@@ -115,25 +116,83 @@ public class SubscriptionManager {
StatusCodes.Bad_SecurityChecksFailed, StatusCodes.Bad_TcpSecureChannelUnknown,
StatusCodes.Bad_RequestTypeInvalid);
+ /**
+ * The status of a monitored node while communication with the server is lost: the source of the value is configured
+ * but cannot be reached, and no last value is kept (OPC 10000-8 Table 61, OPC 10000-14 Table 80).
+ */
+ private static final StatusCode NO_COMMUNICATION = new StatusCode(StatusCodes.Bad_NoCommunication);
+
private final AtomicLong clientHandleCounter = new AtomicLong();
+ /**
+ * The generation of the last connection built, zero before the first.
+ */
+ private final AtomicLong generationCounter = new AtomicLong();
+
/**
* Listens to the subscription of a connection and to the state of its session. It is registered on the client
* before the client connects, so that it sees every change of the session state.
*/
private final class SubscriptionListenerImpl
implements OpcUaSubscription.SubscriptionListener, SessionActivityListener {
- private volatile boolean sessionActive;
+ /**
+ * The generation of the connection, which orders its values and loss reports against those of the connection
+ * that replaces it.
+ */
+ private final long generation;
+
+ /**
+ * Whether the session is active. The client connects before the connection is used, and Milo dispatches the
+ * activity callbacks in the order of the transitions.
+ */
+ private volatile boolean sessionActive = true;
+
+ /**
+ * The subscription of the connection, once it is created.
+ */
+ private volatile OpcUaSubscription subscription;
+
+ SubscriptionListenerImpl(final long generation) {
Review Comment:
Nit: could the constructor move below the `closed` / `lostSessionId` fields, so all fields are declared together?
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "etzel-mes (via GitHub)" <gi...@apache.org>.
etzel-mes commented on code in PR #28128:
URL: https://github.com/apache/camel/pull/28128#discussion_r4322872059
##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc:
##########
@@ -1806,6 +1806,24 @@ the server does not have, with the status code `Bad_NodeIdUnknown`, and the othe
affected. Previously an awaited write or read completed without an error and with a `null` body, and a browse failed
with a `NullPointerException`.
+=== camel-milo - the consumer reports a lost connection and refreshes its values after it
+
+The OPC UA client consumer delivers `Bad_NoCommunication` with a null value for every monitored node when
+communication with the server is lost, and the current value of every node once communication is restored. Before,
+the consumer delivered nothing during an outage, and values that did not change were not delivered again after it.
+
+A consumer that starts while the server cannot be reached, or whose client cannot connect at all, for example because
+of wrong credentials or an untrusted server certificate, delivers the status for its nodes too; the cause is in the
+log. A connection that Camel rebuilds after a failed request delivers it for every node of the connection. Each loss and
+each recovery delivers one exchange per node.
+
+A route that uses only the value of the `DataValue` body receives a null for these exchanges, which the type converters
+turn into `0` or `false`; a route that stores values checks the status code of the body first, for example with
+`${body.statusCode.bad}`. A value can now arrive again after an outage, so a route that counts values, computes
Review Comment:
Done in aee1e03ad75: the section now ends with a paragraph on keeping the previous behaviour with `filter(simple("${body.statusCode.good}"))` right after the consumer, noting that this also drops the other bad statuses and that the current values delivered after an outage still arrive.
_Claude Code on behalf of etzel-mes_
##########
components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java:
##########
@@ -115,25 +116,83 @@ public class SubscriptionManager {
StatusCodes.Bad_SecurityChecksFailed, StatusCodes.Bad_TcpSecureChannelUnknown,
StatusCodes.Bad_RequestTypeInvalid);
+ /**
+ * The status of a monitored node while communication with the server is lost: the source of the value is configured
+ * but cannot be reached, and no last value is kept (OPC 10000-8 Table 61, OPC 10000-14 Table 80).
+ */
+ private static final StatusCode NO_COMMUNICATION = new StatusCode(StatusCodes.Bad_NoCommunication);
+
private final AtomicLong clientHandleCounter = new AtomicLong();
+ /**
+ * The generation of the last connection built, zero before the first.
+ */
+ private final AtomicLong generationCounter = new AtomicLong();
+
/**
* Listens to the subscription of a connection and to the state of its session. It is registered on the client
* before the client connects, so that it sees every change of the session state.
*/
private final class SubscriptionListenerImpl
implements OpcUaSubscription.SubscriptionListener, SessionActivityListener {
- private volatile boolean sessionActive;
+ /**
+ * The generation of the connection, which orders its values and loss reports against those of the connection
+ * that replaces it.
+ */
+ private final long generation;
+
+ /**
+ * Whether the session is active. The client connects before the connection is used, and Milo dispatches the
+ * activity callbacks in the order of the transitions.
+ */
+ private volatile boolean sessionActive = true;
+
+ /**
+ * The subscription of the connection, once it is created.
+ */
+ private volatile OpcUaSubscription subscription;
+
+ SubscriptionListenerImpl(final long generation) {
Review Comment:
Done in aee1e03ad75: the constructor now follows the `closed` and `lostSessionId` fields. Both changes are folded into the first commit; the branch keeps your rebase onto main.
_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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #28128:
URL: https://github.com/apache/camel/pull/28128#issuecomment-6284616469
<!-- ci-tested-modules -->
:test_tube: **CI tested the following changed modules:**
- `catalog/camel-catalog`
- `components/camel-milo`
- `docs`
:repeat: **1 test passed only after a retry on JDK 21** (1 retried attempt)
<details><summary>Recovered flaky tests on JDK 21 (1)</summary>
| Module | Test | Failed attempts | First failure |
| --- | --- | --- | --- |
| `dsl/camel-jbang/camel-jbang-plugin-tui` | `AiPanelAcpTest.usageUpdateFeedsTheTokenCounter` | 1 | 1234 + the 66 this turn added ==> expected: <1300> but was: <1234> |
> :information_source: These tests did **not** fail the build. Surefire retried them and they passed.
> Retries are enabled project-wide by `surefire.rerunFailingTestsCount` in `parent/pom.xml`.
</details>
---
<details><summary>:microscope: Scalpel shadow comparison — Scalpel: 8 of 707 tested, 25 compile-only — current: 8 all tested</summary>
[Maveniverse Scalpel](https://github.com/maveniverse/scalpel) detected **8 affected modules** (current approach: 8).
**Skip-tests mode would test 8 modules** (3 direct + 7 downstream), **skip tests for 25** (generated code, meta-modules)
<details><summary>Modules Scalpel would test (8)</summary>
- `camel-jbang-mcp` ← downstream of org.apache.camel:camel-catalog
- `camel-jbang-plugin-mcp` ← downstream of org.apache.camel:camel-jbang-core
- `camel-jbang-plugin-tui` ← downstream of org.apache.camel:camel-catalog
- `camel-jbang-plugin-validate` ← downstream of org.apache.camel:camel-yaml-dsl-validator
- `camel-launcher-container` ← downstream of org.apache.camel:camel-launcher
- `camel-milo` ← components/camel-milo/src/main/docs/milo-client-component.adoc, components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java, components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java, components/camel-milo/src/test/java/org/apache/camel/component/milo/CommunicationLossTest.java, components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemLifecycleTest.java, components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsTest.java, components/camel-milo/src/test/java/org/apache/camel/component/milo/ServerCertificateValidationTest.java
- `camel-yaml-dsl-validator` ← downstream of org.apache.camel:camel-catalog
- `camel-yaml-dsl-validator-maven-plugin` ← downstream of org.apache.camel:camel-yaml-dsl-validator
</details>
<details><summary>Modules with tests skipped (25)</summary>
- `apache-camel`
- `camel-allcomponents`
- `camel-catalog-console`
- `camel-catalog-maven`
- `camel-catalog-suggest`
- `camel-componentdsl`
- `camel-endpointdsl`
- `camel-endpointdsl-support`
- `camel-itest`
- `camel-jbang-core`
- `camel-jbang-it`
- `camel-jbang-main`
- `camel-jbang-plugin-edit`
- `camel-jbang-plugin-generate`
- `camel-jbang-plugin-kubernetes`
- `camel-jbang-plugin-test`
- `camel-kamelet-main`
- `camel-launcher`
- `camel-report-maven-plugin`
- `camel-route-parser`
- `camel-yaml-dsl`
- `camel-yaml-dsl-deserializers`
- `camel-yaml-dsl-maven-plugin`
- `coverage`
- `dummy-component`
</details>
> :information_source: Shadow mode — Scalpel observes but does not affect test execution. [Learn more](https://github.com/maveniverse/scalpel)
</details>
<details><summary>All tested modules (35 modules, 4m 22s total)</summary>
**Total reactor time:** 4m 22s
| Module | Duration | Status |
| --- | --- | --- |
| Camel :: JBang :: Plugin :: TUI | 59.3s | FAILURE |
| Camel :: JBang :: Plugin :: Validate | 25.1s | SUCCESS |
| Camel :: YAML DSL | 21.7s | SUCCESS |
| Camel :: JBang :: MCP | 19.6s | SUCCESS |
| Camel :: Catalog :: Camel Catalog | 18.5s | SUCCESS |
| Camel :: YAML DSL :: Validator | 17.4s | SUCCESS |
| Camel :: Component DSL | 16.3s | SUCCESS |
| Camel :: Docs | 12.5s | SUCCESS |
| Camel :: Kamelet Main | 12.2s | SUCCESS |
| Camel :: JBang :: Plugin :: Kubernetes | 9.7s | SUCCESS |
| Camel :: JBang :: Plugin :: Testing | 8.1s | SUCCESS |
| Camel :: Catalog :: Camel Report Maven Plugin | 7.3s | SUCCESS |
| Camel :: YAML DSL :: Deserializers | 6.3s | SUCCESS |
| Camel :: Catalog :: Camel Route Parser | 6.0s | SUCCESS |
| Camel :: All Components Sync point | 4.1s | SUCCESS |
| Camel :: YAML DSL :: Validator Maven Plugin | 4.1s | SUCCESS |
| Camel :: Catalog :: Maven | 2.4s | SUCCESS |
| Camel :: Catalog :: Suggest (deprecated) | 1.9s | SUCCESS |
| Camel :: YAML DSL :: Maven Plugins | 1.9s | SUCCESS |
| Camel :: Assembly | 1.4s | SUCCESS |
| Camel :: JBang :: Plugin :: Edit | 1.1s | SUCCESS |
| Camel :: Endpoint DSL :: Support | 1.0s | SUCCESS |
| Camel :: Catalog :: Dummy Component | 0.9s | SUCCESS |
| Camel :: JBang :: Plugin :: Generate | 0.9s | SUCCESS |
| Camel :: Coverage | 0.8s | SUCCESS |
| Camel :: Catalog :: Console | 0.7s | SUCCESS |
| Camel :: JBang :: Main | 0.6s | SUCCESS |
| Camel :: JBang :: Plugin :: MCP | 0.5s | SUCCESS |
| Camel :: Endpoint DSL | n/a | |
| Camel :: Integration Tests | n/a | |
| Camel :: JBang :: Core | n/a | |
| Camel :: JBang :: Integration tests | n/a | |
| Camel :: Launcher | n/a | |
| Camel :: Launcher :: Container | n/a | |
| Camel :: Milo | n/a | |
**Top 20 slowest modules:**
- `Camel :: JBang :: Plugin :: TUI` (59.3s)
- `Camel :: JBang :: Plugin :: Validate` (25.1s)
- `Camel :: YAML DSL` (21.7s)
- `Camel :: JBang :: MCP` (19.6s)
- `Camel :: Catalog :: Camel Catalog` (18.5s)
- `Camel :: YAML DSL :: Validator` (17.4s)
- `Camel :: Component DSL` (16.3s)
- `Camel :: Docs` (12.5s)
- `Camel :: Kamelet Main` (12.2s)
- `Camel :: JBang :: Plugin :: Kubernetes` (9.7s)
- `Camel :: JBang :: Plugin :: Testing` (8.1s)
- `Camel :: Catalog :: Camel Report Maven Plugin` (7.3s)
- `Camel :: YAML DSL :: Deserializers` (6.3s)
- `Camel :: Catalog :: Camel Route Parser` (6.0s)
- `Camel :: All Components Sync point` (4.1s)
- `Camel :: YAML DSL :: Validator Maven Plugin` (4.1s)
- `Camel :: Catalog :: Maven` (2.4s)
- `Camel :: Catalog :: Suggest (deprecated)` (1.9s)
- `Camel :: YAML DSL :: Maven Plugins` (1.9s)
- `Camel :: Assembly` (1.4s)
</details>
---
:gear: [View full build and test results](https://github.com/apache/camel/actions/runs/39375200951)
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] CAMEL-25835: camel-milo - the consumer reports a lost connection and refreshes its values after it [camel]
Posted by "etzel-mes (via GitHub)" <gi...@apache.org>.
etzel-mes commented on code in PR #28128:
URL: https://github.com/apache/camel/pull/28128#discussion_r4324207890
##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc:
##########
@@ -1806,6 +1806,28 @@ the server does not have, with the status code `Bad_NodeIdUnknown`, and the othe
affected. Previously an awaited write or read completed without an error and with a `null` body, and a browse failed
with a `NullPointerException`.
+=== camel-milo - the consumer reports a lost connection and refreshes its values after it
+
+The OPC UA client consumer delivers `Bad_NoCommunication` with a null value for every monitored node when
+communication with the server is lost, and the current value of every node once communication is restored. Before,
+the consumer delivered nothing during an outage, and values that did not change were not delivered again after it.
+
+A consumer that starts while the server cannot be reached, or whose client cannot connect at all, for example because
+of wrong credentials or an untrusted server certificate, delivers the status for its nodes too; the cause is in the
+log. A connection that Camel rebuilds after a failed request delivers it for every node of the connection. Each loss and
+each recovery delivers one exchange per node.
+
+A route that uses only the value of the `DataValue` body receives a null for these exchanges, which the type converters
+turn into `0` or `false`; a route that stores values checks the status code of the body first, for example with
+`${body.statusCode.bad}`. A value can now arrive again after an outage, so a route that counts values, computes
+differences or detects changes must tolerate repeats. The consumer's route also runs during an outage: an OPC UA write
+that it makes while the client reconnects waits for the next reconnect attempt and can take effect after communication
+is restored, and a request that fails rebuilds the connection.
+
+To keep the previous behaviour, filter the exchanges with a bad status out right after the consumer, for example with
+`filter(simple("${body.statusCode.good}"))`. This also drops the other bad statuses, such as the refusal of a node, and
Review Comment:
Thanks, applied: the guide now uses `${body.statusCode.bad} == false`, so Uncertain values still pass as before.
--
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: commits-unsubscribe@camel.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org