shashank created CAMEL-25125:
--------------------------------
Summary: camel-mllp - automatic acknowledgement fails with
ArrayIndexOutOfBoundsException when MSH-2 defines a component separator other
than '^', so no ACK is sent (regression of CAMEL-22421)
Key: CAMEL-25125
URL: https://issues.apache.org/jira/browse/CAMEL-25125
Project: Camel
Issue Type: Bug
Components: camel-mllp
Reporter: shashank
Since CAMEL-22421 (4.15.0), {{Hl7Util.generateAcknowledgementPayload}} decides
whether MSH-9 has a third component by counting the component separators of
MSH-9. It finds the start of MSH-9.2 with the component separator of the
message ({{hl7MessageBytes\[4\]}}, the first character of MSH-2), but it counts
the components with {{caretPositionsIn}}, which looks for a hard-coded '^':
{code:java}
final byte componentSeparator = hl7MessageBytes[4];
... // msh92start = first componentSeparator in MSH-9
final String msh9Content = convertToPrintFriendlyString(hl7MessageBytes,
fieldSeparatorIndexes.get(7) + 1, fieldSeparatorIndexes.get(8));
final int[] componentIndexesInMsh9 = caretPositionsIn(msh9Content); //
positions of '^' only
final int componentDiff = componentIndexesInMsh9[componentIndexesInMsh9.length
- 1] - componentIndexesInMsh9[0];
{code}
HL7 v2 recommends the encoding characters "^~\&" but lets MSH-2 define others.
When the component separator is not '^' and MSH-9 contains no '^', the array is
empty and the automatic acknowledgement fails:
{noformat}
MSH|$~\&|SENDAPP|SENDFAC|RECVAPP|RECVFAC|20260929083646||ADT$A01|MSG00003|P|2.3
-> java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for
length 0
{noformat}
The exception is not an {{MllpAcknowledgementGenerationException}}, so
{{MllpTcpServerConsumer.sendAcknowledgement}} does not handle it.
{{processMessage}} catches it after the route has already processed the
message, resets the connection and passes the exception to the consumer's
exception handler. The sender gets no acknowledgement. HL7 senders normally
resend a message that was not acknowledged, so every resend is processed by the
route again (a duplicate) and fails in the same way, and the interface is stuck
on that message.
With three components the result is wrong instead of an exception: for
{{ADT$A01$ADT^X}} the ACK has MSH-9 {{ACK$A01$ADT^X}} instead of
{{ACK$A01$ACK}}, because the '^' in the data is counted and the two '$' are not.
The count also runs on the log-friendly String, which is cut to
{{logPhiMaxBytes}}: with a {{logPhiMaxBytes}} of 3 or less, even a message with
'^' fails the same way.
h3. Reproduction
{{new Hl7Util(5120, true).generateAcknowledgementPayload(buffer, message,
"AA")}} with the MSH above, and end to end with an {{mllp://}} consumer with
the default {{autoAck=true}}: the client's connection is reset and no ACK
arrives. Reproduced on main three times. The same message with the 4.14.0
{{Hl7Util}} gives the ACK {{ACK$A01}}. A small formal model (Lean 4) of the
MSH-9 code shows that every separator other than '^' with an MSH-9 without '^'
fails, and that counting the MSH-2 separator gives the same result as today for
'^' and never fails.
h3. Affected versions
4.15.0 and later (4.18.x and 4.22.x LTS, main). 4.14.x does not have the change
of CAMEL-22421 and is not affected.
h3. Proposed fix
Count the component separator of MSH-2, on the message bytes, instead of '^' on
the log String. For messages with '^', the default, the acknowledgement stays
exactly the same.
Duplicate check (2026-09-29): JIRA component camel-mllp since 2025, and "mllp"
with "separator", "ArrayIndexOutOfBoundsException", "MSH-9" or
"acknowledgement": only CAMEL-22421 itself. No open pull request touches
camel-mllp.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)