public void testConsumerAckImmediateAutoCommitFalse() throws Exception { ClientSessionFactory sf = createSessionFactory(locator); ClientSession session = sf.createSession(false, true, false, true); session.createQueue(QUEUE, QUEUE, null, false); ClientProducer producer = session.createProducer(QUEUE); final int numMessages = 100; for (int i = 0; i < numMessages; i++) { ClientMessage message = createTextMessage(session, "m" + i); producer.send(message); } ClientConsumer consumer = session.createConsumer(QUEUE); session.start(); for (int i = 0; i < numMessages; i++) { ClientMessage message2 = consumer.receive(1000); Assert.assertEquals("m" + i, message2.getBodyBuffer().readString()); } // assert that all the messages are there and none have been acked Assert.assertEquals( 0, ((Queue) server.getPostOffice().getBinding(QUEUE).getBindable()).getDeliveringCount()); Assert.assertEquals( 0, ((Queue) server.getPostOffice().getBinding(QUEUE).getBindable()).getMessageCount()); session.close(); }
/** * This would recreate the scenario where a queue was duplicated * * @throws Exception */ @Test public void testHangDuplicateQueues() throws Exception { final Semaphore blocked = new Semaphore(1); final CountDownLatch latchDelete = new CountDownLatch(1); class MyQueueWithBlocking extends QueueImpl { /** * @param id * @param address * @param name * @param filter * @param pageSubscription * @param durable * @param temporary * @param scheduledExecutor * @param postOffice * @param storageManager * @param addressSettingsRepository * @param executor */ public MyQueueWithBlocking( final long id, final SimpleString address, final SimpleString name, final Filter filter, final PageSubscription pageSubscription, final boolean durable, final boolean temporary, final ScheduledExecutorService scheduledExecutor, final PostOffice postOffice, final StorageManager storageManager, final HierarchicalRepository<AddressSettings> addressSettingsRepository, final Executor executor) { super( id, address, name, filter, pageSubscription, durable, temporary, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executor); } @Override public synchronized int deleteMatchingReferences(final int flushLimit, final Filter filter) throws Exception { latchDelete.countDown(); blocked.acquire(); blocked.release(); return super.deleteMatchingReferences(flushLimit, filter); } } class LocalFactory extends QueueFactoryImpl { public LocalFactory( final ExecutorFactory executorFactory, final ScheduledExecutorService scheduledExecutor, final HierarchicalRepository<AddressSettings> addressSettingsRepository, final StorageManager storageManager) { super(executorFactory, scheduledExecutor, addressSettingsRepository, storageManager); } @Override public Queue createQueue( final long persistenceID, final SimpleString address, final SimpleString name, final Filter filter, final PageSubscription pageSubscription, final boolean durable, final boolean temporary) { queue = new MyQueueWithBlocking( persistenceID, address, name, filter, pageSubscription, durable, temporary, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor()); return queue; } } LocalFactory queueFactory = new LocalFactory( server.getExecutorFactory(), server.getScheduledPool(), server.getAddressSettingsRepository(), server.getStorageManager()); queueFactory.setPostOffice(server.getPostOffice()); ((HornetQServerImpl) server).replaceQueueFactory(queueFactory); queue = server.createQueue(QUEUE, QUEUE, null, true, false); blocked.acquire(); ClientSessionFactory factory = locator.createSessionFactory(); ClientSession session = factory.createSession(false, false, false); ClientProducer producer = session.createProducer(QUEUE); producer.send(session.createMessage(true)); session.commit(); Thread tDelete = new Thread() { @Override public void run() { try { server.destroyQueue(QUEUE); } catch (Exception e) { e.printStackTrace(); } } }; tDelete.start(); Assert.assertTrue(latchDelete.await(10, TimeUnit.SECONDS)); try { server.createQueue(QUEUE, QUEUE, null, true, false); } catch (Exception expected) { } blocked.release(); server.stop(); tDelete.join(); session.close(); // a duplicate binding would impede the server from starting server.start(); waitForServer(server); server.stop(); }
protected int getMessageCount(final HornetQServer service, final String address) throws Exception { return getMessageCount(service.getPostOffice(), address); }
@Test public void testPageCounter() throws Throwable { boolean persistentMessages = true; Configuration config = createDefaultConfig(); config.setJournalSyncNonTransactional(false); HornetQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>()); server.start(); final int messageSize = 1024; final int numberOfMessages = 500; ServerLocator locator = createInVMNonHALocator(); locator.setClientFailureCheckPeriod(1000); locator.setConnectionTTL(2000); locator.setReconnectAttempts(0); locator.setBlockOnNonDurableSend(true); locator.setBlockOnDurableSend(true); locator.setBlockOnAcknowledge(true); locator.setConsumerWindowSize(1024 * 1024); ClientSessionFactory sf = createSessionFactory(locator); ClientSession session = sf.createSession(false, false, false); Queue q1 = server.createQueue(ADDRESS, ADDRESS, null, true, false); Queue q2 = server.createQueue(ADDRESS, new SimpleString("inactive"), null, true, false); ClientProducer producer = session.createProducer(PagingTest.ADDRESS); byte[] body = new byte[messageSize]; ByteBuffer bb = ByteBuffer.wrap(body); for (int j = 1; j <= messageSize; j++) { bb.put(getSamplebyte(j)); } final AtomicInteger errors = new AtomicInteger(0); Thread t1 = new Thread() { @Override public void run() { try { ServerLocator sl = createInVMNonHALocator(); ClientSessionFactory sf = sl.createSessionFactory(); ClientSession sess = sf.createSession(true, true, 0); sess.start(); ClientConsumer cons = sess.createConsumer(ADDRESS); for (int i = 0; i < numberOfMessages; i++) { ClientMessage msg = cons.receive(5000); assertNotNull(msg); assertEquals(i, msg.getIntProperty("id").intValue()); msg.acknowledge(); } assertNull(cons.receiveImmediate()); sess.close(); sl.close(); } catch (Throwable e) { e.printStackTrace(); errors.incrementAndGet(); } } }; t1.start(); for (int i = 0; i < numberOfMessages; i++) { ClientMessage message = session.createMessage(persistentMessages); HornetQBuffer bodyLocal = message.getBodyBuffer(); bodyLocal.writeBytes(body); message.putIntProperty(new SimpleString("id"), i); producer.send(message); if (i % 20 == 0) { session.commit(); } } session.commit(); t1.join(); assertEquals(0, errors.get()); assertEquals(numberOfMessages, q2.getMessageCount()); assertEquals(numberOfMessages, q2.getMessagesAdded()); assertEquals(0, q1.getMessageCount()); assertEquals(numberOfMessages, q1.getMessagesAdded()); session.close(); sf.close(); locator.close(); server.stop(); server.start(); Bindings bindings = server.getPostOffice().getBindingsForAddress(ADDRESS); q1 = null; q2 = null; for (Binding bind : bindings.getBindings()) { if (bind instanceof LocalQueueBinding) { LocalQueueBinding qb = (LocalQueueBinding) bind; if (qb.getQueue().getName().equals(ADDRESS)) { q1 = qb.getQueue(); } if (qb.getQueue().getName().equals(new SimpleString("inactive"))) { q2 = qb.getQueue(); } } } assertNotNull(q1); assertNotNull(q2); assertEquals("q2 msg count", numberOfMessages, q2.getMessageCount()); assertEquals("q2 msgs added", numberOfMessages, q2.getMessagesAdded()); assertEquals("q1 msg count", 0, q1.getMessageCount()); // 0, since nothing was sent to the queue after the server was restarted assertEquals("q1 msgs added", 0, q1.getMessagesAdded()); }