Serdar Gökay created CAMEL-25626:
------------------------------------
Summary: camel-milo - milo-client consumer drops Bad status
notifications by default (omitNullValues)
Key: CAMEL-25626
URL: https://issues.apache.org/jira/browse/CAMEL-25626
Project: Camel
Issue Type: Bug
Components: camel-milo
Affects Versions: 4.16.0, 4.22.1, 4.18.5
Reporter: Serdar Gökay
The {{milo-client}} consumer does not deliver a data change whose status is Bad
when the server follows the specification and sends no value. With the default
{{omitNullValues=true}}, {{MiloClientConsumer.handleValueUpdate}} discards
every DataValue with a null value, regardless of its status code.
OPC UA requires a null value for Bad statuses (OPC 10000-4 v1.05.07, 7.11.1,
Table 131): "If the StatusCode indicates an error then the value is to be
ignored and the Server shall set it to null." So for a spec-conform server, the
status code is the only thing that tells the client a value is no longer valid,
and the default configuration filters exactly these notifications.
*Why it matters in automation systems*
In SCADA, MES and Unified Namespace setups, a consumer route typically forwards
each tag to a historian or an MQTT broker (often as a retained message). When a
sensor fails or a node becomes unavailable, the route receives nothing, so
downstream systems keep showing the last Good value as current. Operators,
alarms and reports then act on a value the server has already declared
unusable. OPC UA clients are expected to check the status of every value
(7.11.5: "It is required that Clients minimally check the StatusCode Severity
of all results"); the Eclipse Milo client itself and other clients such as
node-opcua deliver these notifications unchanged.
*Reproduction*
Two milo-client consumers on two milo-server items, {{samplingInterval=100}},
{{requestedPublishingInterval=100}}. Item B is set to {{1}}, then to {{new
DataValue(Variant.NULL_VALUE, new StatusCode(StatusCodes.Bad_SensorFailure),
DateTime.now())}}, then to a Bad_SensorFailure value with a value of {{99}},
then to {{4}}. Messages received by the consumer of item B:
{noformat}
default (omitNullValues=true): [1 Good] [99 Bad_SensorFailure] [4 Good]
omitNullValues=false: [null Bad] [1 Good] [null Bad_SensorFailure] [99
Bad_SensorFailure] [4 Good]
{noformat}
The consumer of item A (always Good) receives every value in both modes. Tested
with the embedded milo-server on main plus the open PR #27780, which does not
change this code path.
*Background*
{{omitNullValues}} was introduced with the Milo 0.6.6 update (CAMEL-18144,
3.18.0) to skip an early notification with a null value after route startup and
to keep the unit tests stable. That early notification is the server item's
initial Bad status ({{[null Bad]}} above), so the option also covers
status-only notifications that carry real information. This also hides the Bad
status that CAMEL-25599 reports for monitored items that cannot be created.
*Proposed change*
Apply {{omitNullValues}} only to notifications with a Good status; always
deliver notifications whose status is Uncertain or Bad, with or without a
value. The option keeps its default and its original purpose. Tests that relied
on the early notification being skipped would set the initial server value or
expect the initial status.
We use camel-milo for OPC UA to MQTT and would be happy to provide a PR for
this, including a test, if the approach is acceptable.
_Claude Code on behalf of etzel-mes_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)