shashank created CAMEL-25291:
--------------------------------
Summary: camel-plc4x - a write that cannot be done completes the
exchange successfully, and the polling consumer answers a failed read with an
empty result
Key: CAMEL-25291
URL: https://issues.apache.org/jira/browse/CAMEL-25291
Project: Camel
Issue Type: Bug
Reporter: shashank
h3. 1. Producer: failed reconnect reported as success, message removed on
failure
With {{autoReconnect=true}}, {{Plc4XProducer.process}} catches the
{{PlcConnectionException}} of a failed reconnect and returns:
{code:java}
} catch (PlcConnectionException e) {
log.warn("Unable to reconnect, skipping request");
return;
}
{code}
The exchange completes successfully although nothing was written to the PLC:
the error handler, redeliveries and a dead letter channel never see the
failure, and the values are silently lost (the PLC is down, the network is
interrupted).
When a write does fail (exception from the write future), the asynchronous
{{process}} does {{exchange.setMessage(null)}} before setting the exception, so
the message is replaced by an empty one: a redelivery then fails with "The body
must contain a Map", and a dead letter channel gets no body.
h3. 2. Polling consumer: failures answered with an empty Map
{{Plc4XPollingConsumer.doReceive}} (used by {{pollEnrich}}) catches
{{ExecutionException}}, {{TimeoutException}} and {{PlcConnectionException}} and
returns an exchange whose body is an empty {{HashMap}} and that has no
exception. The route cannot tell a failed read from a read, and goes on with no
values. A read that does not answer within the timeout is answered the same
way; with {{receiveNoWait()}} ({{pollEnrich}} with timeout 0) this is nearly
always the case, since {{future.get(0, ms)}} times out unless the response is
already there. The {{PollingConsumer}} contract is to return {{null}} when
nothing is received within the timeout.
h3. Reproduction
{{Plc4XFailureTest}} (new, mocked {{Plc4XEndpoint}}):
* {{testProducerFailsWhenReconnectFails}}: on main the exchange has no
exception.
* {{testProducerKeepsTheMessageWhenTheWriteFails}}: on main the body is
{{null}} after the failed write.
* {{testPollingConsumerFailsWhenReconnectFails}},
{{testPollingConsumerFailsWhenReadFails}}: on main no exception (body {{{}}}).
* {{testPollingConsumerReturnsNullWithoutResponse}}: on main an exchange with
an empty Map instead of {{null}}.
* {{testPollingConsumerReadsTags}}: control, passes on main.
h3. Proposed fix
* Producer: let the reconnect failure fail the exchange; do not remove the
message on failure.
* Polling consumer: set the exception of a failed connection or read on the
returned exchange ({{pollEnrich}} copies it to the exchange), return {{null}}
when the read does not answer within the timeout, keep the interrupt status
when interrupted.
History: the "skipping request" of the producer came with the {{autoReconnect}}
option (2023, PR #8971) without a stated reason; the review only asked to log
it at WARN, in the event-driven consumer, where skipping a read is harmless.
The empty Map of the polling consumer was a choice of CAMEL-18861 (PR #9254,
commit note: "An exchange with an empty map is created when no connection could
be made" (instead of no exchange)). The fix keeps returning an exchange for a
failed connection or read, but with the exception, so that the route sees the
failure; only a read without an answer within the timeout returns {{null}}, as
the {{PollingConsumer}} contract says ({{camel-jpa}} does the same;
{{camel-http}} throws). The event-driven consumer is not changed. CAMEL-22553
(open) plans a larger rework of the connection code; this change is independent
of it.
The upgrade guide for 4.23 gets a note, which also says how a periodically
polling route can go on while the PLC is unreachable ({{onException}},
{{doTry}}). With the fix the 6 tests pass, and the module suite passes (23
tests).
Affected: 4.14.x, 4.18.x and main (same code).
Duplicate check (2026-10-03): JIRA text "plc4x" (10 issues: CAMEL-24171, 22491,
20871, 19199, 18861, ...): none about failures reported as success. GitHub pull
requests "plc4x": none open about the component.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)