/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.activemq.usecases; import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.Destination; import javax.jms.ExceptionListener; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.activemq.test.TestSupport; import org.apache.activemq.util.IdGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * */ public class TopicRedeliverTest extends TestSupport { private static final Logger LOG = LoggerFactory.getLogger(TopicRedeliverTest.class); private static final int RECEIVE_TIMEOUT = 10000; protected int deliveryMode = DeliveryMode.PERSISTENT; private IdGenerator idGen = new IdGenerator(); public TopicRedeliverTest() { } public TopicRedeliverTest(String n) { super(n); } @Override protected void setUp() throws Exception { super.setUp(); topic = true; } /** * test messages are acknowledged and recovered properly * * @throws Exception */ public void testClientAcknowledge() throws Exception { Destination destination = createDestination(getClass().getName()); Connection connection = createConnection(); connection.setClientID(idGen.generateId()); connection.start(); Session consumerSession = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageConsumer consumer = consumerSession.createConsumer(destination); Session producerSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(destination); producer.setDeliveryMode(deliveryMode); // send some messages TextMessage sent1 = producerSession.createTextMessage(); sent1.setText("msg1"); sent1.setStringProperty("str", "1"); producer.send(sent1); TextMessage sent2 = producerSession.createTextMessage(); sent2.setText("msg2"); sent2.setStringProperty("str", "2"); producer.send(sent2); TextMessage sent3 = producerSession.createTextMessage(); sent2.setText("msg3"); sent2.setStringProperty("str", "3"); producer.send(sent3); TextMessage msgTest = (TextMessage) consumer.receive(RECEIVE_TIMEOUT); System.out.println("msgTest::" + msgTest + " // " + msgTest.getText()); TextMessage rec2 = (TextMessage) consumer.receive(RECEIVE_TIMEOUT); System.out.println("msgTest::" + rec2 + " // " + rec2.getText()); assertNull(consumer.receiveNoWait()); // ack rec2 rec2.acknowledge(); TextMessage sent4 = producerSession.createTextMessage(); sent4.setText("msg4"); producer.send(sent4); TextMessage rec4 = (TextMessage) consumer.receive(RECEIVE_TIMEOUT); assertTrue(rec4.equals(sent4)); consumerSession.recover(); rec4 = (TextMessage) consumer.receive(RECEIVE_TIMEOUT); assertTrue(rec4.equals(sent4)); assertTrue(rec4.getJMSRedelivered()); rec4.acknowledge(); connection.close(); } /** * Test redelivered flag is set on rollbacked transactions * * @throws Exception */ public void testRedilveredFlagSetOnRollback() throws Exception { Destination destination = createDestination(getClass().getName()); Connection connection = createConnection(); connection.setClientID(idGen.generateId()); connection.start(); Session consumerSession = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE); MessageConsumer consumer = null; if (topic) { consumer = consumerSession.createDurableSubscriber((Topic) destination, "TESTRED"); } else { consumer = consumerSession.createConsumer(destination); } Session producerSession = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(destination); producer.setDeliveryMode(deliveryMode); TextMessage sentMsg = producerSession.createTextMessage(); sentMsg.setText("msg1"); producer.send(sentMsg); producerSession.commit(); Message recMsg = consumer.receive(RECEIVE_TIMEOUT); assertFalse(recMsg.getJMSRedelivered()); recMsg = consumer.receive(RECEIVE_TIMEOUT); consumerSession.rollback(); recMsg = consumer.receive(RECEIVE_TIMEOUT); assertTrue(recMsg.getJMSRedelivered()); consumerSession.commit(); assertTrue(recMsg.equals(sentMsg)); assertTrue(recMsg.getJMSRedelivered()); connection.close(); } public void testNoExceptionOnRedeliveryAckWithSimpleTopicConsumer() throws Exception { Destination destination = createDestination(getClass().getName()); Connection connection = createConnection(); final AtomicBoolean gotException = new AtomicBoolean(); connection.setExceptionListener(new ExceptionListener() { @Override public void onException(JMSException exception) { LOG.error("unexpected ex:" + exception); gotException.set(true); } }); connection.setClientID(idGen.generateId()); connection.start(); Session consumerSession = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE); MessageConsumer consumer = null; if (topic) { consumer = consumerSession.createConsumer(destination); } else { consumer = consumerSession.createConsumer(destination); } Session producerSession = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(destination); producer.setDeliveryMode(deliveryMode); TextMessage sentMsg = producerSession.createTextMessage(); sentMsg.setText("msg1"); producer.send(sentMsg); producerSession.commit(); Message recMsg = consumer.receive(RECEIVE_TIMEOUT); assertFalse(recMsg.getJMSRedelivered()); recMsg = consumer.receive(RECEIVE_TIMEOUT); consumerSession.rollback(); recMsg = consumer.receive(RECEIVE_TIMEOUT); assertTrue(recMsg.getJMSRedelivered()); consumerSession.rollback(); recMsg = consumer.receive(RECEIVE_TIMEOUT); assertTrue(recMsg.getJMSRedelivered()); consumerSession.commit(); assertTrue(recMsg.equals(sentMsg)); assertTrue(recMsg.getJMSRedelivered()); connection.close(); assertFalse("no exception", gotException.get()); } /** * Check a session is rollbacked on a Session close(); * * @throws Exception */ public void xtestTransactionRollbackOnSessionClose() throws Exception { Destination destination = createDestination(getClass().getName()); Connection connection = createConnection(); connection.setClientID(idGen.generateId()); connection.start(); Session consumerSession = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE); MessageConsumer consumer = null; if (topic) { consumer = consumerSession.createDurableSubscriber((Topic) destination, "TESTRED"); } else { consumer = consumerSession.createConsumer(destination); } Session producerSession = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(destination); producer.setDeliveryMode(deliveryMode); TextMessage sentMsg = producerSession.createTextMessage(); sentMsg.setText("msg1"); producer.send(sentMsg); producerSession.commit(); Message recMsg = consumer.receive(RECEIVE_TIMEOUT); assertFalse(recMsg.getJMSRedelivered()); consumerSession.close(); consumerSession = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE); consumer = consumerSession.createConsumer(destination); recMsg = consumer.receive(RECEIVE_TIMEOUT); consumerSession.commit(); assertTrue(recMsg.equals(sentMsg)); connection.close(); } /** * check messages are actuallly sent on a tx rollback * * @throws Exception */ public void testTransactionRollbackOnSend() throws Exception { Destination destination = createDestination(getClass().getName()); Connection connection = createConnection(); connection.setClientID(idGen.generateId()); connection.start(); Session consumerSession = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE); MessageConsumer consumer = consumerSession.createConsumer(destination); Session producerSession = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(destination); producer.setDeliveryMode(deliveryMode); TextMessage sentMsg = producerSession.createTextMessage(); sentMsg.setText("msg1"); producer.send(sentMsg); producerSession.commit(); Message recMsg = consumer.receive(RECEIVE_TIMEOUT); consumerSession.commit(); assertTrue(recMsg.equals(sentMsg)); sentMsg = producerSession.createTextMessage(); sentMsg.setText("msg2"); producer.send(sentMsg); producerSession.rollback(); sentMsg = producerSession.createTextMessage(); sentMsg.setText("msg3"); producer.send(sentMsg); producerSession.commit(); recMsg = consumer.receive(RECEIVE_TIMEOUT); assertTrue(recMsg.equals(sentMsg)); consumerSession.commit(); connection.close(); } }