Dhairya-007 opened a new pull request, #29678:
URL: https://github.com/apache/camel/pull/29678
## Problem
`Hl7Util` builds MSH-7 of every generated acknowledgement through a shared
`SimpleDateFormat`, and the line carries a TODO saying exactly what is wrong
with that:
```java
public static final SimpleDateFormat TIMESTAMP_FORMAT = new
SimpleDateFormat("yyyyMMddHHmmss.SSSZZZZ");
...
// TODO static field TIMESTAMP_FORMAT of type java.text.DateFormat isn't
thread safe! Think about using ThreadLocal
mllpSocketBuffer.write(TIMESTAMP_FORMAT.format(new Date()).getBytes());
```
`SimpleDateFormat` holds its formatting state in a `Calendar` field, so it
must not be shared. `MllpTcpServerConsumer` runs one handler thread per
accepted connection and each one acknowledges through this method, so two
concurrent `format()` calls can interleave and produce a timestamp assembled
from both instants, or throw `ArrayIndexOutOfBoundsException` from inside the
shared `Calendar`. Either way the ESME gets an acknowledgement whose MSH-7 is
wrong, or none at all.
## Fix
Make `TIMESTAMP_FORMAT` a `DateTimeFormatter`, which is immutable and thread
safe, and format a `ZonedDateTime.now()`.
The pattern is `yyyyMMddHHmmss.SSSZ`, not a letter-for-letter copy of the
old one, and the difference matters: for `SimpleDateFormat`, `Z` is the RFC 822
offset (`+0100`) whatever the letter count, but for `DateTimeFormatter` `ZZZZ`
means the localized `GMT+01:00` form. A naive port would have changed the wire
format.
I checked the two formatters against each other over several instants in
`America/New_York`, `Europe/Paris`, `UTC`, `Asia/Kolkata` and `Pacific/Chatham`
— crossing DST boundaries and covering 30- and 45-minute offsets — and the
output is identical in every case.
`TIMESTAMP_FORMAT` is public, but `org.apache.camel.component.mllp.internal`
is an internal package, so the type change is not an API break.
## Tests
The existing `testGenerateAcknowledgementPayloadTimestamp` already pins the
MSH-7 format (`\d{14}\.\d{3}[+-]\d{4}`) and still passes, which is what shows
the formatter swap did not change the output.
Added `testGenerateAcknowledgementPayloadTimestampIsThreadSafe`: 8 threads
generate 500 acknowledgements each and every MSH-7 field is matched against
that pattern. On `main` it reports corrupted timestamps (or an exception thrown
from the shared `Calendar`); with the fix it passes.
--
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]