/* * 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.artemis.tests.integration.scheduling; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; import org.apache.activemq.artemis.api.core.Message; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.core.config.Configuration; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.core.transaction.impl.XidImpl; import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.activemq.artemis.utils.UUIDGenerator; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ScheduledMessageTest extends ActiveMQTestBase { private static final IntegrationTestLogger log = IntegrationTestLogger.LOGGER; private final SimpleString atestq = new SimpleString("ascheduledtestq"); private final SimpleString atestq2 = new SimpleString("ascheduledtestq2"); private Configuration configuration; private ActiveMQServer server; private ServerLocator locator; @Override @Before public void setUp() throws Exception { super.setUp(); startServer(); } /** * @throws Exception */ protected void startServer() throws Exception { configuration = createDefaultInVMConfig(); server = createServer(true, configuration); server.start(); locator = createInVMNonHALocator(); } @Test public void testRecoveredMessageDeliveredCorrectly() throws Exception { testMessageDeliveredCorrectly(true); } @Test public void testMessageDeliveredCorrectly() throws Exception { testMessageDeliveredCorrectly(false); } @Test public void testScheduledMessagesDeliveredCorrectly() throws Exception { testScheduledMessagesDeliveredCorrectly(false); } @Test public void testRecoveredScheduledMessagesDeliveredCorrectly() throws Exception { testScheduledMessagesDeliveredCorrectly(true); } @Test public void testScheduledMessagesDeliveredCorrectlyDifferentOrder() throws Exception { testScheduledMessagesDeliveredCorrectlyDifferentOrder(false); } @Test public void testRecoveredScheduledMessagesDeliveredCorrectlyDifferentOrder() throws Exception { testScheduledMessagesDeliveredCorrectlyDifferentOrder(true); } @Test public void testScheduledAndNormalMessagesDeliveredCorrectly() throws Exception { testScheduledAndNormalMessagesDeliveredCorrectly(false); } @Test public void testRecoveredScheduledAndNormalMessagesDeliveredCorrectly() throws Exception { testScheduledAndNormalMessagesDeliveredCorrectly(true); } @Test public void testTxMessageDeliveredCorrectly() throws Exception { testTxMessageDeliveredCorrectly(false); } @Test public void testRecoveredTxMessageDeliveredCorrectly() throws Exception { testTxMessageDeliveredCorrectly(true); } @Test public void testPagedMessageDeliveredCorrectly() throws Exception { // then we create a client as normal ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, true, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); ClientMessage message = createDurableMessage(session, "m1"); long time = System.currentTimeMillis(); time += 10000; message.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(message); producer.close(); ClientConsumer consumer = session.createConsumer(atestq); session.start(); ClientMessage message2 = consumer.receive(10250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m1", message2.getBodyBuffer().readString()); message2.acknowledge(); // Make sure no more messages consumer.close(); consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } @Test public void testPagedMessageDeliveredMultipleConsumersCorrectly() throws Exception { AddressSettings qs = new AddressSettings().setRedeliveryDelay(5000L); server.getAddressSettingsRepository().addMatch(atestq.toString(), qs); // then we create a client as normal ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, true, false); session.createQueue(atestq, atestq, null, true); session.createQueue(atestq, atestq2, null, true); ClientProducer producer = session.createProducer(atestq); ClientMessage message = createDurableMessage(session, "m1"); producer.send(message); producer.close(); ClientConsumer consumer = session.createConsumer(atestq); ClientConsumer consumer2 = session.createConsumer(atestq2); session.start(); ClientMessage message3 = consumer.receive(1000); message3.acknowledge(); ClientMessage message2 = consumer2.receive(1000); message2.acknowledge(); Assert.assertEquals("m1", message3.getBodyBuffer().readString()); Assert.assertEquals("m1", message2.getBodyBuffer().readString()); long time = System.currentTimeMillis(); // force redelivery consumer.close(); consumer2.close(); // this will make it redelivery-delay session.rollback(); consumer = session.createConsumer(atestq); consumer2 = session.createConsumer(atestq2); message3 = consumer.receive(5250); message2 = consumer2.receive(1000); time += 5000; Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m1", message3.getBodyBuffer().readString()); Assert.assertEquals("m1", message2.getBodyBuffer().readString()); message2.acknowledge(); message3.acknowledge(); // Make sure no more messages consumer.close(); consumer2.close(); consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } @Test public void testPagedMessageDeliveredMultipleConsumersAfterRecoverCorrectly() throws Exception { AddressSettings qs = new AddressSettings().setRedeliveryDelay(5000L); server.getAddressSettingsRepository().addMatch(atestq.toString(), qs); // then we create a client as normal ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, true, false); session.createQueue(atestq, atestq, null, true); session.createQueue(atestq, atestq2, null, true); ClientProducer producer = session.createProducer(atestq); ClientMessage message = createDurableMessage(session, "m1"); producer.send(message); producer.close(); ClientConsumer consumer = session.createConsumer(atestq); ClientConsumer consumer2 = session.createConsumer(atestq2); session.start(); ClientMessage message3 = consumer.receive(1000); Assert.assertNotNull(message3); message3.acknowledge(); ClientMessage message2 = consumer2.receive(1000); Assert.assertNotNull(message2); message2.acknowledge(); Assert.assertEquals("m1", message3.getBodyBuffer().readString()); Assert.assertEquals("m1", message2.getBodyBuffer().readString()); long time = System.currentTimeMillis(); // force redelivery consumer.close(); consumer2.close(); session.rollback(); producer.close(); session.close(); server.stop(); server = null; server = createServer(true, configuration); server.start(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(false, true, true); consumer = session.createConsumer(atestq); consumer2 = session.createConsumer(atestq2); session.start(); message3 = consumer.receive(5250); Assert.assertNotNull(message3); message2 = consumer2.receive(1000); Assert.assertNotNull(message2); time += 5000; Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m1", message3.getBodyBuffer().readString()); Assert.assertEquals("m1", message2.getBodyBuffer().readString()); message2.acknowledge(); message3.acknowledge(); // Make sure no more messages consumer.close(); consumer2.close(); consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } public void testMessageDeliveredCorrectly(final boolean recover) throws Exception { // then we create a client as normal ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, true, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, false, 0, System.currentTimeMillis(), (byte) 1); message.getBodyBuffer().writeString("testINVMCoreClient"); message.setDurable(true); long time = System.currentTimeMillis(); time += 10000; message.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(message); ScheduledMessageTest.log.info("Recover is " + recover); if (recover) { producer.close(); session.close(); server.stop(); server = null; server = createServer(true, configuration); server.start(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(false, true, true); } ClientConsumer consumer = session.createConsumer(atestq); session.start(); ClientMessage message2 = consumer.receive(11000); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("testINVMCoreClient", message2.getBodyBuffer().readString()); message2.acknowledge(); // Make sure no more messages consumer.close(); consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } public void testScheduledMessagesDeliveredCorrectly(final boolean recover) throws Exception { ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, true, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); ClientMessage m1 = createDurableMessage(session, "m1"); ClientMessage m2 = createDurableMessage(session, "m2"); ClientMessage m3 = createDurableMessage(session, "m3"); ClientMessage m4 = createDurableMessage(session, "m4"); ClientMessage m5 = createDurableMessage(session, "m5"); long time = System.currentTimeMillis(); time += 10000; m1.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m1); time += 1000; m2.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m2); time += 1000; m3.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m3); time += 1000; m4.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m4); time += 1000; m5.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m5); time -= 4000; if (recover) { producer.close(); session.close(); server.stop(); server = null; server = createServer(true, configuration); server.start(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(false, true, true); } ClientConsumer consumer = session.createConsumer(atestq); session.start(); ClientMessage message = consumer.receive(11000); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m1", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m2", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m3", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m4", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m5", message.getBodyBuffer().readString()); message.acknowledge(); // Make sure no more messages consumer.close(); consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } public void testScheduledMessagesDeliveredCorrectlyDifferentOrder(final boolean recover) throws Exception { ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, true, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); ClientMessage m1 = createDurableMessage(session, "m1"); ClientMessage m2 = createDurableMessage(session, "m2"); ClientMessage m3 = createDurableMessage(session, "m3"); ClientMessage m4 = createDurableMessage(session, "m4"); ClientMessage m5 = createDurableMessage(session, "m5"); long time = System.currentTimeMillis(); time += 10000; m1.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m1); time += 3000; m2.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m2); time -= 2000; m3.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m3); time += 3000; m4.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m4); time -= 2000; m5.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m5); time -= 2000; ClientConsumer consumer = null; if (recover) { producer.close(); session.close(); server.stop(); server = null; server = createServer(true, configuration); server.start(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(false, true, true); } consumer = session.createConsumer(atestq); session.start(); ClientMessage message = consumer.receive(10250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m1", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m3", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m5", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m2", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m4", message.getBodyBuffer().readString()); message.acknowledge(); // Make sure no more messages consumer.close(); consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } @Test public void testManyMessagesSameTime() throws Exception { ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, false, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); long time = System.currentTimeMillis(); time += 1000; for (int i = 0; i < 10; i++) { ClientMessage message = session.createMessage(true); message.putIntProperty("value", i); message.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(message); } session.commit(); session.start(); ClientConsumer consumer = session.createConsumer(atestq); for (int i = 0; i < 10; i++) { ClientMessage message = consumer.receive(15000); assertNotNull(message); message.acknowledge(); assertEquals(i, message.getIntProperty("value").intValue()); } session.commit(); Assert.assertNull(consumer.receiveImmediate()); session.close(); } public void testScheduledAndNormalMessagesDeliveredCorrectly(final boolean recover) throws Exception { ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, true, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); ClientMessage m1 = createDurableMessage(session, "m1"); ClientMessage m2 = createDurableMessage(session, "m2"); ClientMessage m3 = createDurableMessage(session, "m3"); ClientMessage m4 = createDurableMessage(session, "m4"); ClientMessage m5 = createDurableMessage(session, "m5"); long time = System.currentTimeMillis(); time += 10000; m1.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m1); producer.send(m2); time += 1000; m3.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m3); producer.send(m4); time += 1000; m5.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(m5); time -= 2000; ClientConsumer consumer = null; if (recover) { producer.close(); session.close(); server.stop(); server = null; server = createServer(true, configuration); server.start(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(false, true, true); } consumer = session.createConsumer(atestq); session.start(); ClientMessage message = consumer.receive(1000); Assert.assertEquals("m2", message.getBodyBuffer().readString()); message.acknowledge(); message = consumer.receive(1000); Assert.assertEquals("m4", message.getBodyBuffer().readString()); message.acknowledge(); message = consumer.receive(10250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m1", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m3", message.getBodyBuffer().readString()); message.acknowledge(); time += 1000; message = consumer.receive(1250); Assert.assertTrue(System.currentTimeMillis() >= time); Assert.assertEquals("m5", message.getBodyBuffer().readString()); message.acknowledge(); // Make sure no more messages consumer.close(); consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } public void testTxMessageDeliveredCorrectly(final boolean recover) throws Exception { Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); Xid xid2 = new XidImpl("xa2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(true, false, false); session.createQueue(atestq, atestq, null, true); session.start(xid, XAResource.TMNOFLAGS); ClientProducer producer = session.createProducer(atestq); ClientMessage message = createDurableMessage(session, "testINVMCoreClient"); long time = System.currentTimeMillis() + 1000; message.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, time); producer.send(message); session.end(xid, XAResource.TMSUCCESS); session.prepare(xid); if (recover) { producer.close(); session.close(); server.stop(); server = null; server = createServer(true, configuration); server.start(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(true, false, false); } session.commit(xid, false); ClientConsumer consumer = session.createConsumer(atestq); session.start(); session.start(xid2, XAResource.TMNOFLAGS); ClientMessage message2 = consumer.receive(11000); long end = System.currentTimeMillis(); System.out.println("elapsed time = " + (end - time)); Assert.assertTrue(end >= time); Assert.assertNotNull(message2); Assert.assertEquals("testINVMCoreClient", message2.getBodyBuffer().readString()); message2.acknowledge(); session.end(xid2, XAResource.TMSUCCESS); session.prepare(xid2); session.commit(xid2, false); consumer.close(); // Make sure no more messages consumer = session.createConsumer(atestq); Assert.assertNull(consumer.receiveImmediate()); session.close(); } @Test public void testPendingACKOnPrepared() throws Exception { int NUMBER_OF_MESSAGES = 100; ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(true, false, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); long scheduled = System.currentTimeMillis() + 1000; for (int i = 0; i < NUMBER_OF_MESSAGES; i++) { ClientMessage msg = session.createMessage(true); msg.putIntProperty("value", i); msg.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, scheduled); producer.send(msg); } session.close(); for (int i = 0; i < NUMBER_OF_MESSAGES; i++) { Xid xid = newXID(); session = sessionFactory.createSession(true, false, false); ClientConsumer consumer = session.createConsumer(atestq); session.start(); session.start(xid, XAResource.TMNOFLAGS); ClientMessage msg = consumer.receive(5000); assertNotNull(msg); msg.acknowledge(); session.end(xid, XAResource.TMSUCCESS); session.prepare(xid); session.close(); } sessionFactory.close(); locator.close(); server.stop(); startServer(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(false, false); ClientConsumer consumer = session.createConsumer(atestq); session.start(); assertNull(consumer.receive(1000)); session.close(); sessionFactory.close(); } @Test public void testScheduledDeliveryTX() throws Exception { scheduledDelivery(true); } @Test public void testScheduledDeliveryNoTX() throws Exception { scheduledDelivery(false); } @Test public void testRedeliveryAfterPrepare() throws Exception { AddressSettings qs = new AddressSettings().setRedeliveryDelay(5000L); server.getAddressSettingsRepository().addMatch(atestq.toString(), qs); ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(false, false, false); session.createQueue(atestq, atestq, true); ClientProducer producer = session.createProducer(atestq); for (int i = 0; i < 100; i++) { ClientMessage msg = session.createMessage(true); msg.putIntProperty("key", i); producer.send(msg); session.commit(); } session.close(); session = sessionFactory.createSession(true, false, false); ClientConsumer consumer = session.createConsumer(atestq); ArrayList<Xid> xids = new ArrayList<>(); session.start(); for (int i = 0; i < 100; i++) { Xid xid = newXID(); session.start(xid, XAResource.TMNOFLAGS); ClientMessage msg = consumer.receive(5000); assertNotNull(msg); msg.acknowledge(); session.end(xid, XAResource.TMSUCCESS); session.prepare(xid); xids.add(xid); } session.rollback(xids.get(0)); xids.set(0, null); session.close(); server.stop(); configuration = createDefaultInVMConfig().addAddressesSetting(atestq.toString(), qs); server = createServer(true, configuration); server.start(); locator = createInVMNonHALocator(); final AtomicInteger count = new AtomicInteger(0); Thread t = new Thread() { @Override public void run() { try { ClientSessionFactory sf = createSessionFactory(locator); ClientSession session = sf.createSession(false, false); session.start(); ClientConsumer cons = session.createConsumer(atestq); for (int i = 0; i < 100; i++) { ClientMessage msg = cons.receive(100000); assertNotNull(msg); count.incrementAndGet(); msg.acknowledge(); session.commit(); } session.close(); sf.close(); } catch (Throwable e) { e.printStackTrace(); count.set(-1); } } }; t.start(); sessionFactory = createSessionFactory(locator); session = sessionFactory.createSession(true, false, false); for (Xid xid : xids) { if (xid != null) { session.rollback(xid); } } session.close(); t.join(); assertEquals(100, count.get()); } // Private ------------------------------------------------------- private void scheduledDelivery(final boolean tx) throws Exception { ActiveMQTestBase.forceGC(); Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); ClientSessionFactory sessionFactory = createSessionFactory(locator); ClientSession session = sessionFactory.createSession(tx, false, false); session.createQueue(atestq, atestq, null, true); ClientProducer producer = session.createProducer(atestq); ClientConsumer consumer = session.createConsumer(atestq); session.start(); if (tx) { session.start(xid, XAResource.TMNOFLAGS); } // Send one scheduled long now = System.currentTimeMillis(); ClientMessage tm1 = createDurableMessage(session, "testScheduled1"); tm1.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, now + 7000); producer.send(tm1); // First send some non scheduled messages ClientMessage tm2 = createDurableMessage(session, "testScheduled2"); producer.send(tm2); ClientMessage tm3 = createDurableMessage(session, "testScheduled3"); producer.send(tm3); ClientMessage tm4 = createDurableMessage(session, "testScheduled4"); producer.send(tm4); // Now send some more scheduled messages ClientMessage tm5 = createDurableMessage(session, "testScheduled5"); tm5.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, now + 5000); producer.send(tm5); ClientMessage tm6 = createDurableMessage(session, "testScheduled6"); tm6.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, now + 4000); producer.send(tm6); ClientMessage tm7 = createDurableMessage(session, "testScheduled7"); tm7.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, now + 3000); producer.send(tm7); ClientMessage tm8 = createDurableMessage(session, "testScheduled8"); tm8.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, now + 6000); producer.send(tm8); // And one scheduled with a -ve number ClientMessage tm9 = createDurableMessage(session, "testScheduled9"); tm9.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, -3); producer.send(tm9); if (tx) { session.end(xid, XAResource.TMSUCCESS); session.prepare(xid); session.commit(xid, false); } else { session.commit(); } // First the non scheduled messages should be received if (tx) { session.start(xid, XAResource.TMNOFLAGS); } ClientMessage rm1 = consumer.receive(250); Assert.assertNotNull(rm1); Assert.assertEquals("testScheduled2", rm1.getBodyBuffer().readString()); ClientMessage rm2 = consumer.receive(250); Assert.assertNotNull(rm2); Assert.assertEquals("testScheduled3", rm2.getBodyBuffer().readString()); ClientMessage rm3 = consumer.receive(250); Assert.assertNotNull(rm3); Assert.assertEquals("testScheduled4", rm3.getBodyBuffer().readString()); // Now the one with a scheduled with a -ve number ClientMessage rm5 = consumer.receive(250); Assert.assertNotNull(rm5); Assert.assertEquals("testScheduled9", rm5.getBodyBuffer().readString()); // Now the scheduled ClientMessage rm6 = consumer.receive(3250); Assert.assertNotNull(rm6); Assert.assertEquals("testScheduled7", rm6.getBodyBuffer().readString()); long now2 = System.currentTimeMillis(); Assert.assertTrue(now2 - now >= 3000); ClientMessage rm7 = consumer.receive(1250); Assert.assertNotNull(rm7); Assert.assertEquals("testScheduled6", rm7.getBodyBuffer().readString()); now2 = System.currentTimeMillis(); Assert.assertTrue(now2 - now >= 4000); ClientMessage rm8 = consumer.receive(1250); Assert.assertNotNull(rm8); Assert.assertEquals("testScheduled5", rm8.getBodyBuffer().readString()); now2 = System.currentTimeMillis(); Assert.assertTrue(now2 - now >= 5000); ClientMessage rm9 = consumer.receive(1250); Assert.assertNotNull(rm9); Assert.assertEquals("testScheduled8", rm9.getBodyBuffer().readString()); now2 = System.currentTimeMillis(); Assert.assertTrue(now2 - now >= 6000); ClientMessage rm10 = consumer.receive(1250); Assert.assertNotNull(rm10); Assert.assertEquals("testScheduled1", rm10.getBodyBuffer().readString()); now2 = System.currentTimeMillis(); Assert.assertTrue(now2 - now >= 7000); if (tx) { session.end(xid, XAResource.TMSUCCESS); session.prepare(xid); session.commit(xid, false); } session.close(); sessionFactory.close(); } private ClientMessage createDurableMessage(final ClientSession session, final String body) { ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, true, 0, System.currentTimeMillis(), (byte) 1); message.getBodyBuffer().writeString(body); return message; } }