Sidebar

How to accept large incoming messages at a secure socket?

0 votes
686 views
asked Aug 19, 2020 by ardi-j-9343 (120 points)

Hello,

I've configured my channel to receive HL7 messages at a secure socket, and I've tested it with a small message (~10KB). The connection is established, message is received, processed and saved, and finally the socket connection is closed.

However, when attempting to send a large message (> approx. 100KB; in my usecase they're usually 1-4MB) to the socket, the connection is established and immediately terminated, and the message is never received. Here's a corresponding log merely indicating that the connection is terminated:

2020-08-19 12:33:54,180 GMT [server-socket p: 20003 (ssl)-recv5] WARN com.qvera.qie.engine.in.SecureSocketReceiver - Socket connection from /10.0.2.149:35620 terminated by peer (1 active connection)

I understand there's a Java option -Dqie.largeMessageLimit but I'm not sure this would fix it -- surely, by default, the channel should be able to accept messages larger than 100KB?!

Do you have any suggestions how to go about this, or how to even debug it further? Thank you very much!

1 Answer

0 votes

QIE is able to receive messages of any size.  The limit to the size of the messages processed is based on the amount of memory allocated to QIE and the volume of messages being processed by the engine.  Assuming that there is at least 1GB of memory allocated to QIE and that there is low volume, it should not have any problem receiving HL7 messages that are less than 50MB in size.

The error "Socket connection from /10.0.2.149:35620 terminated by peer" indicates that the other system closed the connection unexpectedly. To find out why, the logs of the other system should be evaluated.  If logs cannot be obtained, then installing wireshark on the QIE system might help, but usually only confirms that the other system is closing the connection.

The java option -Dqie.largeMessageLimit only controls the amount of data that is sent to the console when viewing the message detail.  By default it only sends a max of 3MB to the client dialog to prevent the browser from hanging.  However this option can be specified to increase this limit if needed.  But, you are correct that it would not effect the error you are seeing.

answered Aug 19, 2020 by brandon-w-8204 (33,170 points)
edited Aug 19, 2020 by ben-s-7515
commented Sep 2, 2020 by ardi-j-9343 (120 points)
edited Sep 2, 2020 by ardi-j-9343
Thank you very much for the prompt answer, I really appreciate it!

I tried submitting the same 'small' and 'large' messages over an insecure connection -- that is, I modified the Source Channel type from Secure Socket (HL7 MLLP) to Socket (HL7 MLLP). In this case, I had no issues receiving the message. The issue I originally described only happens when the socket is secure.

To debug, I added the -Djavax.net.debug=ssl,handshake flag for additional logging, and compared the logs when submitting a 'small' message (received and processed by QIE), and a 'large' message (connection established but message not received). The difference lies in that the 'large' message outputs these additional logs:

2020-09-02 12:43:26,148 GMT [Standard Error Consumer] INFO OutputConsumer.run() - stderr - javax.net.ssl|ERROR|4A|server-socket p: 20003 (ssl)-recv2|2020-09-02 12:43:26.148 GMT|TransportContext.java:316|Fatal (UNEXPECTED_MESSAGE): Read timed out (
"throwable" : {
    java.net.SocketTimeoutException: Read timed out
    at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:284)
    at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:310)
    at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:351)
    at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:802)
    at java.base/java.net.Socket$SocketInputStream.read(Socket.java:919)
    at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:450)
    at java.base/sun.security.ssl.SSLSocketInputRecord.decodeInputRecord(SSLSocketInputRecord.java:237)
    at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:190)
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:108)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1463)
        at java.base/sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1431)
        at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:1022)
        at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:245)
        at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:285)
        at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:344)
        at java.base/java.io.FilterInputStream.read(FilterInputStream.java:107)
        at com.qvera.qie.engine.in.SecureSocketReceiver$DataReader.read(SecureSocketReceiver.java:207)
        at com.qvera.qie.engine.in.SecureSocketReceiver.checkForMessage(SecureSocketReceiver.java:414)
        at com.qvera.qie.engine.in.Receiver.scheduledCheckForMessage(Receiver.java:430)
        at com.qvera.qie.engine.in.Receiver.run(Receiver.java:265)
        at java.base/java.lang.Thread.run(Thread.java:830)}
        )

Do you have any idea what's going on? Is there a time out parameter to be adjusted here?
commented Sep 2, 2020 by mike-r-7535 (13,830 points)
From the stack trace, the socket hits a read timeout.  Meaning there is nothing in the buffer to read, and it eventually throws the exception.  With the prior error message that the connection was terminated by peer, it sounds like something in the middle is filtering or manipulating packets.

Can we send the same file over a local secure connection to QIE? (If true, it leans toward a network issue.)
Can we capture a wireshark on the QIE system and the sending system? (Differences in the wireshark capture can confirm that a firewall in the middle is messing with the packets or closing the connection early.)
commented Oct 8, 2020 by ardi-j-9343 (120 points)
I apologize for my tardy response, but I've since understood where the problem was. I was originally using OpenJDK 13. After browsing the Knowledge Base, I understood I have to use OpenJDK 8 and this fixed the issue.

Thank you very much for your help!
...