package org.skyscreamer.nevado.jms.facilities;
import junit.framework.Assert;
import org.junit.Test;
import org.skyscreamer.nevado.jms.AbstractJMSTest;
import org.skyscreamer.nevado.jms.NevadoConnection;
import org.skyscreamer.nevado.jms.NevadoSession;
import org.skyscreamer.nevado.jms.message.JMSXProperty;
import org.skyscreamer.nevado.jms.message.NevadoMessage;
import org.skyscreamer.nevado.jms.message.NevadoTextMessage;
import org.skyscreamer.nevado.jms.util.RandomData;
import org.skyscreamer.nevado.jms.util.TestMessageListener;
import javax.jms.*;
/**
* Test message acknowledgement in different modes (JMS 1.1, Sec 4.4.11)
*
* @author Carter Page <carter@skyscreamer.org>
*/
public class MessageAcknowledgementTest extends AbstractJMSTest {
@Test
public void testAutoAcknowledge() throws JMSException {
NevadoConnection connection = getConnection();
NevadoSession session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Message msg = session.createMessage();
Queue tempQueue = createTempQueue(session);
session.createProducer(tempQueue).send(msg);
NevadoMessage msgOut = (NevadoMessage)session.createConsumer(tempQueue).receive();
Assert.assertTrue(msgOut.isAcknowledged());
}
@Test
public void testAsyncAutoAcknowledge() throws JMSException, InterruptedException {
NevadoConnection connection = getConnection();
NevadoSession session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Message msg = session.createMessage();
Queue tempQueue = createTempQueue(session);
session.createProducer(tempQueue).send(msg);
TestMessageListener messageListener = new TestMessageListener(false);
session.createConsumer(tempQueue).setMessageListener(messageListener);
Thread.sleep(1000);
NevadoMessage message = messageListener.getMessage(1000);
Assert.assertTrue("Message should be acknowledged after it returns from the listener",
message.isAcknowledged());
Assert.assertTrue(messageListener.isEmpty());
session.close();
}
@Test
public void testDupsOkayAcknowledge() throws JMSException {
NevadoConnection connection = getConnection();
NevadoSession session = connection.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
Message msg = session.createMessage();
Queue tempQueue = createTempQueue(session);
session.createProducer(tempQueue).send(msg);
NevadoMessage msgOut = (NevadoMessage)session.createConsumer(tempQueue).receive();
Assert.assertFalse(msgOut.isAcknowledged());
msgOut.acknowledge();
}
@Test
public void testClientAcknowledge() throws JMSException {
// Send messages
NevadoConnection connection = getConnection();
NevadoSession session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
TextMessage msg1 = session.createTextMessage(RandomData.readString());
TextMessage msg2 = session.createTextMessage(RandomData.readString());
TextMessage msg3 = session.createTextMessage(RandomData.readString());
Queue tempQueue = createTempQueue(session);
MessageProducer producer = session.createProducer(tempQueue);
producer.send(msg1);
producer.send(msg2);
producer.send(msg3);
// Get messages
MessageConsumer consumer = session.createConsumer(tempQueue);
NevadoTextMessage msgOut1 = (NevadoTextMessage)consumer.receive();
Assert.assertEquals(1, msgOut1.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
NevadoTextMessage msgOut2 = (NevadoTextMessage)consumer.receive();
Assert.assertEquals(1, msgOut2.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
NevadoTextMessage msgOut3 = (NevadoTextMessage)consumer.receive();
Assert.assertEquals(1, msgOut3.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertFalse(msgOut1.isAcknowledged());
Assert.assertFalse(msgOut2.isAcknowledged());
Assert.assertFalse(msgOut3.isAcknowledged());
compareTextMessages(new TextMessage[] {msg1, msg2, msg3}, new TextMessage[] {msgOut1, msgOut2, msgOut3});
// Recover and replay
session.recover();
msgOut1 = (NevadoTextMessage)consumer.receive();
msgOut2 = (NevadoTextMessage)consumer.receive();
msgOut3 = (NevadoTextMessage)consumer.receive();
Assert.assertTrue(msgOut1.getJMSRedelivered());
Assert.assertTrue(msgOut2.getJMSRedelivered());
Assert.assertTrue(msgOut3.getJMSRedelivered());
Assert.assertEquals(2, msgOut1.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertEquals(2, msgOut2.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertEquals(2, msgOut3.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertFalse(msgOut1.isAcknowledged());
Assert.assertFalse(msgOut2.isAcknowledged());
Assert.assertFalse(msgOut3.isAcknowledged());
compareTextMessages(new TextMessage[] {msg1, msg2, msg3}, new TextMessage[] {msgOut1, msgOut2, msgOut3});
// Acknowledging one should acknowledge the others
msgOut2.acknowledge();
Assert.assertTrue(msgOut1.isAcknowledged());
Assert.assertTrue(msgOut2.isAcknowledged());
Assert.assertTrue(msgOut3.isAcknowledged());
}
@Test
public void testPartialClientAcknowledge() throws JMSException {
// Send messages
NevadoConnection connection = getConnection();
NevadoSession session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
TextMessage msg1 = session.createTextMessage(RandomData.readString());
TextMessage msg2 = session.createTextMessage(RandomData.readString());
TextMessage msg3 = session.createTextMessage(RandomData.readString());
Queue tempQueue = createTempQueue(session);
MessageProducer producer = session.createProducer(tempQueue);
producer.send(msg1);
producer.send(msg2);
producer.send(msg3);
// Get messages
MessageConsumer consumer = session.createConsumer(tempQueue);
NevadoTextMessage msgOut1 = (NevadoTextMessage)consumer.receive();
Assert.assertEquals(1, msgOut1.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
NevadoTextMessage msgOut2 = (NevadoTextMessage)consumer.receive();
Assert.assertEquals(1, msgOut2.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
NevadoTextMessage msgOut3 = (NevadoTextMessage)consumer.receive();
Assert.assertEquals(1, msgOut3.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertFalse(msgOut1.isAcknowledged());
Assert.assertFalse(msgOut2.isAcknowledged());
Assert.assertFalse(msgOut3.isAcknowledged());
compareTextMessages(new TextMessage[] {msg1, msg2, msg3}, new TextMessage[] {msgOut1, msgOut2, msgOut3});
// Recover and replay (partially)
session.recover();
NevadoTextMessage msgAfterRecover1 = (NevadoTextMessage)consumer.receive();
NevadoTextMessage msgAfterRecover2 = (NevadoTextMessage)consumer.receive();
Assert.assertTrue(msgAfterRecover1.getJMSRedelivered());
Assert.assertTrue(msgAfterRecover2.getJMSRedelivered());
Assert.assertEquals(2, msgAfterRecover1.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertEquals(2, msgAfterRecover2.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertFalse(msgAfterRecover1.isAcknowledged());
Assert.assertFalse(msgAfterRecover2.isAcknowledged());
compareTextMessages(new TextMessage[] {msgOut1, msgOut2}, new TextMessage[] {msgAfterRecover1, msgAfterRecover2});
// Acknowledging one should acknowledge the others
msgAfterRecover2.acknowledge();
Assert.assertTrue(msgAfterRecover1.isAcknowledged());
Assert.assertTrue(msgAfterRecover2.isAcknowledged());
// The third message should be back on the queue
NevadoTextMessage msgAfterAck = (NevadoTextMessage)consumer.receive(500);
// TODO - This isn't supported yet. In this edge case, the message is reset on the queue, but there is no way
// to indicate a redelivery because you can't edit the message in the queue
// CORRECTION: You should be able to use the delivery count from SQS!
// Assert.assertTrue(msgAfterAck.getJMSRedelivered());
// Assert.assertEquals(2, msgAfterAck.getIntProperty(JMSXProperty.JMSXDeliveryCount + ""));
Assert.assertFalse(msgAfterAck.isAcknowledged());
Assert.assertEquals(msgOut3.getText(), msgAfterAck.getText());
msgAfterAck.acknowledge();
Assert.assertTrue(msgAfterAck.isAcknowledged());
}
}