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]

Reply via email to