mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-6526 - fix <Unknown> Stomp operation in ProtocolException.
closes #217
This commit is contained in:
parent
e3d698b9d9
commit
9e35778943
|
@ -101,11 +101,15 @@ public class StompCodec {
|
||||||
} else {
|
} else {
|
||||||
currentCommand.write(b);
|
currentCommand.write(b);
|
||||||
if (currentCommand.size() > wireFormat.getMaxDataLength()) {
|
if (currentCommand.size() > wireFormat.getMaxDataLength()) {
|
||||||
transport.doConsume(new StompFrameError(new ProtocolException("The maximum data length was exceeded", true)));
|
StompFrameError errorFrame = new StompFrameError(new ProtocolException("The maximum data length was exceeded", true));
|
||||||
|
errorFrame.setAction(this.action);
|
||||||
|
transport.doConsume(errorFrame);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (frameSize.incrementAndGet() > wireFormat.getMaxFrameSize()) {
|
if (frameSize.incrementAndGet() > wireFormat.getMaxFrameSize()) {
|
||||||
transport.doConsume(new StompFrameError(new ProtocolException("The maximum frame size was exceeded", true)));
|
StompFrameError errorFrame = new StompFrameError(new ProtocolException("The maximum frame size was exceeded", true));
|
||||||
|
errorFrame.setAction(this.action);
|
||||||
|
transport.doConsume(errorFrame);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
package org.apache.activemq.transport.stomp;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import org.apache.activemq.command.ActiveMQQueue;
|
||||||
|
import org.apache.log4j.Appender;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.jms.Connection;
|
||||||
|
import javax.jms.Session;
|
||||||
|
import javax.net.SocketFactory;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
|
||||||
|
import org.apache.activemq.util.DefaultTestAppender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testcase for AMQ-6526.
|
||||||
|
* Checks if the \<Unknown\> in the Stomp ProtocolException is replaced
|
||||||
|
* with the proper Stomp operation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class StompNIOSSLLargeMessageTest extends StompTestSupport {
|
||||||
|
|
||||||
|
protected static final Logger LOG = LoggerFactory.getLogger(StompNIOSSLLargeMessageTest.class);
|
||||||
|
private Connection connection;
|
||||||
|
private Session session;
|
||||||
|
private ActiveMQQueue queue;
|
||||||
|
|
||||||
|
// flag to control if the bug in AMQ-XXXX got reproduced.
|
||||||
|
private boolean gotUnknownOperationInLog = false;
|
||||||
|
|
||||||
|
protected int stompFrameSize = 110000000; //slightly over 105 MB
|
||||||
|
|
||||||
|
// custom Log4J appender so we can filter the logging output in this test.
|
||||||
|
protected Appender appender = new DefaultTestAppender() {
|
||||||
|
//@Override
|
||||||
|
public void doAppend(org.apache.log4j.spi.LoggingEvent event) {
|
||||||
|
if (event.getMessage().toString().contains("<Unknown>") &&
|
||||||
|
event.getMessage().toString().contains("The maximum data length was exceeded")) {
|
||||||
|
gotUnknownOperationInLog = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isUseTcpConnector() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isUseNioPlusSslConnector() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Socket createSocket() throws IOException {
|
||||||
|
SocketFactory factory = SSLSocketFactory.getDefault();
|
||||||
|
return factory.createSocket("127.0.0.1", this.nioSslPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
// register custom Log4J Appender
|
||||||
|
org.apache.log4j.Logger.getRootLogger().addAppender(appender);
|
||||||
|
|
||||||
|
stompConnect();
|
||||||
|
connection = cf.createConnection("system", "manager");
|
||||||
|
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||||
|
queue = new ActiveMQQueue(getQueueName());
|
||||||
|
connection.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
// unregister Log4J appender
|
||||||
|
org.apache.log4j.Logger.getRootLogger().removeAppender(appender);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a Stomp message larger than maxDataLength bytes.
|
||||||
|
* Expects to receive an exception from the broker.
|
||||||
|
* The broker will throw an Stomp ProtocolException of type
|
||||||
|
* "Exception occurred processing: SEND ->
|
||||||
|
* org.apache.activemq.transport.stomp.ProtocolException:
|
||||||
|
* The maximum data length was exceeded"
|
||||||
|
*
|
||||||
|
* Before bug AMQ-6526 this exception would contain \<Unkown\> for the
|
||||||
|
* operation name. With the fix it should print the Stomp operation.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test(timeout = 6000000)
|
||||||
|
public void testSendMessageBytes() throws Exception {
|
||||||
|
|
||||||
|
String frame = "CONNECT\n" + "login:system\n" + "passcode:manager\n" +
|
||||||
|
"accept-version:1.1" + "\n\n" + Stomp.NULL;
|
||||||
|
stompConnection.sendFrame(frame);
|
||||||
|
|
||||||
|
frame = stompConnection.receiveFrame();
|
||||||
|
assertTrue(frame.startsWith("CONNECTED"));
|
||||||
|
|
||||||
|
frame = "SEND\n" +
|
||||||
|
"value:newest" + "\n" +
|
||||||
|
"value:older" + "\n" +
|
||||||
|
"value:oldest" + "\n" +
|
||||||
|
"destination:/queue/" + getQueueName() +
|
||||||
|
"\n\n";
|
||||||
|
|
||||||
|
byte[] buffer = createLargeByteBuffer(stompFrameSize);
|
||||||
|
try {
|
||||||
|
stompConnection.sendFrame(frame, buffer);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.error(ex.getMessage());
|
||||||
|
}
|
||||||
|
assertFalse("Stomp ProtocolException still contains <Unknown> operation.", gotUnknownOperationInLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a large byte buffer and fills it with char 'X' except for the
|
||||||
|
* last byte, it gets value 0x0 assigned.
|
||||||
|
*
|
||||||
|
* @param size - the size of the array to be created.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected byte[] createLargeByteBuffer(int size) {
|
||||||
|
byte[] buffer = new byte[size];
|
||||||
|
for (int i=0; i<size; i++) {
|
||||||
|
buffer[i] = (char) 'X';
|
||||||
|
}
|
||||||
|
//insert trailing 0x0
|
||||||
|
buffer[size-1] = 0;
|
||||||
|
LOG.info("Created byte buffer of size {} starting with content {}",
|
||||||
|
size,
|
||||||
|
new String(buffer,0,20));
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue