Sidebar
0 votes
12 views
ago by david-f-5427 (1.7k points)
This KB article is about the Binary message's getNode('/') and toString() methods, providing real-world use case examples and explanations, as well as alternatives for when performance considerations need to be addressed.

1 Answer

0 votes

Summary
A Binary channel's payload can be read as a string with the BinaryMessageModel's toString() or getNode('/') methods. Under ISO-8859-1, which is the default encoding for a Binary message, that conversion is exact for any content and the resulting string can be converted back to its original binary byte array without any loss of data or corruption. Under other encodings, this is not necessarily the case and the original bytes may not be recoverable. There are payload size/performance considerations that should be understood with using this pattern, especially when a database is involved.

Why the ISO-8859-1 string is exact
ISO-8859-1 maps each of the 256 possible byte values to exactly one distinct character. No byte value is unmappable and no two share a character, so a string produced this way has one character per byte and converts back to precisely the bytes it came from. The content is irrelevant: a PDF, a JPEG, an encrypted blob, or random noise all round-trip identically.
 

var originalBytesAsString = message.toString(); // one character per byte
messageCache.setValue('originalBytesAsString', originalBytesAsString);
// ...in a later node...
var cachedBytesAsString = messageCache.getValue('originalBytesAsString');
message.setBytes(new java.lang.String(cachedBytesAsString).getBytes('ISO-8859-1'));


Two things to expect:

  1. The string looks unreadable for non-text content. A PDF read this way is a jumble of characters on screen. That is normal and nothing has been lost. If the payload really is plain text, the string is the readable text.
  2. ISO-8859-1 gives the guarantee. If the source node's message type is configured with a different encoding, the read is lossy before the value ever reaches a cache. UTF-8 replaces byte sequences it cannot interpret with a placeholder character, and that substitution is not reversible. Check the encoding on the source node before relying on a round trip.


When to reach for base64, hex, or a file
The ISO-8859-1 string is correct at any size. The reason to do something different is cost, not correctness.

A cached value is a database row. Writing it means sending the whole value to the database and, on the way back, reading and materializing it again in JVM memory. If a channel does that once per message on a busy interface, the payload size is multiplied across every message in flight.

As rough guidance:

  • Up to a few hundred kilobytes — an ISO-8859-1 string in the cache is fine. A 20 KB HL7 message or a 200 KB scanned page will not cause trouble.
  • Around 1 MB and above — start thinking about it. A 5 MB PDF held in the message cache is a 5 MB database write and a 5 MB read, per message.
  • Tens of megabytes — use a file. A 40 MB radiology report or a large batch file should not travel through a cache at all.


Base64 or hex
Both produce plain ASCII, which is convenient if the value is ever going to be logged, inspected in the database, or sent through something that expects text:
 

// base64: about a third larger than the raw bytes
messageCache.setValue('payloadBase64', qie.base64EncodeBytes(message.getBytes()));
message.setBytes(qie.base64DecodeToBytes(messageCache.getValue('payloadBase64')));
// hex: twice the size, but trivial to read when troubleshooting
messageCache.setValue('payloadHex', qie.hexEncodeBytes(message.getBytes()));
message.setBytes(qie.hexDecodeToBytes(messageCache.getValue('payloadHex')));


Note that both make the stored value bigger, not smaller. Choose them for readability and for safety when a value crosses a system boundary, not to save space.

A temporary file
For a large payload this is the better option, because the bytes never enter the database and the cache holds only a short path:
 

var tempPath = 'C:/qie/temp/' + qie.getUUID() + '.bin';
qie.writeFile(tempPath, message.getBytes());
messageCache.setValue('payloadPath', tempPath);
// ...in a later node...
message.setBytes(qie.readFile(messageCache.getValue('payloadPath')));


The channel then owns the file's lifetime. Delete it once the payload has been read, including on the error path, or the directory grows without limit. A scheduled script that removes files older than a day is a reasonable safety net.

Which cache to use
channelCache and messageCache accept strings only, so a payload has to be converted either way. They differ in scope:

  • messageCache is scoped to the one message. Use it to carry a payload between nodes of the same message, which is what most of these examples are doing.
  • channelCache outlives the message, so a value written by one message can be read by a later one. Use it when that is what you want, and remove the entry when finished, since nothing else will.
  • sharedCache accepts an arbitrary object rather than a string, so it can hold the byte array with no conversion at all. It is shared across channels, so it is not a substitute for a per-message stash, and the value only stays in memory unless the entry is persisted.


Reconsider whether the payload needs to move
Often a payload is cached so a later node can send it. If the destination node can read the message directly, or the work fits in a single node, the round trip and its cost disappear together. That is worth checking before optimizing the encoding.

Debugging Tips
When you notice a corrupted Binary payload after a cache round trip:

  • Check the message encoding on the source node. If it is anything other than ISO-8859-1, the payload was already altered when it was read, and the cache is not the problem. This is the most common cause.
  • Check that the restore uses ISO-8859-1, not the channel default and not UTF-8: new java.lang.String(value).getBytes('ISO-8859-1').
  • Compare byte counts. message.length() before the stash and after the restore should be identical. A mismatch points at the encoding, not at the cache.


When the problem is about performance or memory rather than corruption, check the typical and maximum payload sizes. Anything into the megabytes suggests that the fix may be to move the payload to a temporary file rather than using message cache or channel cache.

ago by david-f-5427 (1.7k points)
...