Red Hat Bugzilla – Bug 959216
Cannot send larger messages using Stomp protocol
Last modified: 2013-09-16 16:21:30 EDT
There is problem to send larger messages ~64KB (not large messages) using Stomp protocol. I've modified StompTest.testSendManyMessages to send ~64KB messages (try attached StompTest.java) Fail: testSendManyMessages(org.hornetq.tests.integration.stomp.StompTest) Time elapsed: 0.172 sec <<< ERROR! java.net.SocketException: Connection reset at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113) at java.net.SocketOutputStream.write(SocketOutputStream.java:132) at org.hornetq.tests.integration.stomp.StompTestBase.sendFrame(StompTestBase.java:232) at org.hornetq.tests.integration.stomp.StompTest.testSendManyMessages(StompTest.java:63)
Created attachment 743167 [details] StompTest.java
this is a known issue and not a blocker. Stomp doesn't support the large messages protocol.
Attention: Clebert OK - I also need help with this ticket. I understand from comment 5 that Stomp does not support large messages. In documenting this in the EAP 6.1.0 Release Notes I need to specify an upper limit on message size, as supported by Stomp. If I understand correctly, the threshold above which messages are considered large is user-configurable. Please specify the message size threshold above which Stomp will not support.
@Russel you have to increase the journal Size and buffer size to the maximum size sent through stomp. We will fix this on the next release so a message beyond those limits would then be converted into a large message.
Howard: Can you work on this issue please?
Current stomp implementation doesn't have size limit configurable. The message size is up to the HornetQ's large message settings. I'll create a Jira for the implementation of the limit configuration at stomp level. Ref: [from STOMP spec] "Size Limits To prevent malicious clients from exploiting memory allocation in a server, servers MAY place maximum limits on: the number of frame headers allowed in a single frame the maximum length of header lines the maximum size of a frame body " Howard
Clebert Suconic <clebert.suconic@jboss.com> made a comment on jira HORNETQ-1208 Howard: BTW this task gets precedance on Junit4 task.
Clebert Suconic <clebert.suconic@jboss.com> made a comment on jira HORNETQ-1208 You could set these limits on the acceptor, having a default to 100K (just like the other defaults). you could open a dev forum to discuss this further
Yong Hao Gao <hgao@redhat.com> made a comment on jira HORNETQ-1208 https://community.jboss.org/message/818738#818738
Hi Mirek, Actually your test is not a valid one. You have to initialize your char array before constructing a string with it, like: char[] chars = new char[1024]; for (int i = 0; i < 1024; i++) { chars[i] = 'a'; } String text = new String(chars); Otherwise the char array may have contain invalid values that cause the Stomp connection to be reset. Can you adjust your test? Howard
Hi Howard, I've modified test StompTest.testSendMessage according to your suggestion: public void testSendMessage() throws Exception { MessageConsumer consumer = session.createConsumer(queue); String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL; sendFrame(frame); frame = receiveFrame(10000); Assert.assertTrue(frame.startsWith("CONNECTED")); char[] chars = new char[1024]; for (int i = 0; i < 1024; i++) { chars[i] = 'a'; } String text = new String(chars); frame = "SEND\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n\n" + "Hello World" + text + Stomp.NULL; sendFrame(frame); TextMessage message = (TextMessage)consumer.receive(1000); Assert.assertNotNull(message); Assert.assertEquals("Hello World", message.getText()); // Assert default priority 4 is used when priority header is not set Assert.assertEquals("getJMSPriority", 4, message.getJMSPriority()); // Make sure that the timestamp is valid - should // be very close to the current time. long tnow = System.currentTimeMillis(); long tmsg = message.getJMSTimestamp(); Assert.assertTrue(Math.abs(tnow - tmsg) < 1000); } but i'm still getting exception: java.net.SocketException: Connection reset at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113) at java.net.SocketOutputStream.write(SocketOutputStream.java:132) at org.hornetq.tests.integration.stomp.StompTestBase.sendFrame(StompTestBase.java:232) at org.hornetq.tests.integration.stomp.StompTest.testSendManyMessages(StompTest.java:63) I also tried this 2 different Stomp client libraries but without success. Mirek
Hmm, strange. Can you attach the new test code? The line-number seems to point to the old test at org.hornetq.tests.integration.stomp.StompTest.testSendManyMessages(StompTest.java:63)
Yong Hao Gao <hgao@redhat.com> made a comment on jira HORNETQ-1208 I'll create another Jira for the Stomp Size Limit support feature. I'll keep this Jira for the purpose of tracking the bugzilla issue. Howard
Miroslav Novak <mnovak@redhat.com> made a comment on jira HORNETQ-1208 StompTest.java attached. Let's solve this here on jira.
Yong Hao Gao <hgao@redhat.com> made a comment on jira HORNETQ-1208 Hi Mirek, What you need to do is replace this line: String text = new String(new char[32 * 1024]); with the following char[] chars = new char[32*1024]; for (int i = 0; i < 32*1024; i++) { chars[i] = 'a'; } String text = new String(chars); And the test will pass. If you intend to send binary data in the frame body, you have to add the content-length header so that the server can correctly extract the body of the message. Howard
Miroslav Novak <mnovak@redhat.com> made a comment on jira HORNETQ-1208 Sorry I've accidentally took a look at the bad test and also attached the old one. With your modification the test is passing. It seems that content of the message was the issue.
Hi guys, With the test passing I wonder what else can be done to accommodate the requirement here. I've already created another Jira targeted specifically for the 'size limit' feature of stomp support. But this is a separate issue from what is concerned in this one. I'd suggest this be closed if everybody is fine with it. Howard
Yong Hao Gao <hgao@redhat.com> made a comment on jira HORNETQ-1208 OK after discussing with Clebert we decide to do the following for this issue: 1) add a minLargeMessageSize (min-large-message-size) configuration parameter to stomp acceptor. 2) this parameter controls the message processing sent from stomp clients. If the incoming message size >= minLargeMessageSize it will be treated as a large message. That means the server will break the message down into trunks just as if a core/jms client sent a large message. If the incoming message size is less than minLargeMessageSize, it will be treated as a normal message. Howard
Yong Hao Gao <hgao@redhat.com> made a comment on jira HORNETQ-1208 A problem to be addressed: when a stomp client sends a message whose size is bigger than minLargeMessageSize, the message will be converted into trunks. However if the message doesn't have 'content-length' header, it will be mapped to Text message and be broken down into trunks. If a jms client receives the message it's going to be a problem. The received message is a TextMessage and if you set an output stream on it, you'll see exception: javax.jms.IllegalStateException: LargeMessage streaming is only possible on ByteMessage or StreamMessage I've to think of a way of handling it. Maybe in that case the message will be converted into ByteMessage before delivering to the consumer. Howard
Clebert Suconic <clebert.suconic@jboss.com> made a comment on jira HORNETQ-1208 Howard, is this solved already or you're still working on it?
I'm backporting hornetq-1208 into 2.3.x, I should have a release (tag tomorrow) https://github.com/hornetq/hornetq/pull/1132
Yong Hao Gao <hgao@redhat.com> updated the status of jira HORNETQ-1208 to Closed
Yong Hao Gao <hgao@redhat.com> made a comment on jira HORNETQ-1208 Sorry I forgot to close it.
This fix is in hornetq 2.3.2.Final
HornetQ 2.3.2.Final was included in 6.1.1 ER3
Verified using provided tests in EAP 6.1.1.ER7. I've tried manually that new param min-large-message-size can be set in acceptor.