/** * Typically used before asserts to give producers and consumers some time to finish their tasks * before the final state is tested. * * @param broker BrokerService on which the destinations are looked up * @param destinationName * @param topic true if the destination is a Topic, false if it is a Queue * @param numEnqueueMsgs expected number of enqueued messages in the destination * @param numDequeueMsgs expected number of dequeued messages in the destination * @param waitTime number of milliseconds to wait for completion * @throws Exception */ private void waitForMessagesToBeConsumed( final BrokerService broker, final String destinationName, final boolean topic, final int numEnqueueMsgs, final int numDequeueMsgs, int waitTime) throws Exception { final ActiveMQDestination destination; if (topic) { destination = new ActiveMQTopic(destinationName); } else { destination = new ActiveMQQueue(destinationName); } Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return broker .getDestination(destination) .getDestinationStatistics() .getEnqueues() .getCount() == numEnqueueMsgs; } }, waitTime); Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return broker .getDestination(destination) .getDestinationStatistics() .getDequeues() .getCount() == numDequeueMsgs; } }, waitTime); }
private boolean verifyMessageCount(final int i, final AtomicInteger count) throws Exception { return Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return i == count.get(); } }); }
public void testSlowConnection() throws Exception { MockBroker broker = new MockBroker(); broker.start(); socketReadyLatch.await(); int timeout = 1000; URI tcpUri = new URI( "tcp://localhost:" + broker.ss.getLocalPort() + "?soTimeout=" + timeout + "&trace=true&connectionTimeout=" + timeout + "&wireFormat.maxInactivityDurationInitalDelay=" + timeout); ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("failover:(" + tcpUri + ")"); final Connection connection = cf.createConnection(); new Thread( new Runnable() { @Override public void run() { try { connection.start(); } catch (Throwable ignored) { } } }) .start(); int count = 0; assertTrue( "Transport count: " + count + ", expected <= 1", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { int count = 0; for (Thread thread : Thread.getAllStackTraces().keySet()) { if (thread.getName().contains("ActiveMQ Transport")) { count++; } } return count == 1; } })); broker.interrupt(); broker.join(); }
private void check(String connectionProperties) throws Exception { String s1URL = newURI(0), s2URL = newURI(1); String uri = "failover://(" + s1URL + "," + s2URL + ")?" + connectionProperties; ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(uri); final int initCount1 = getConnectionCount(s1); final int initCount2 = getConnectionCount(s2); for (int i = 0; i < 10; i++) { buildConnection(factory); } assertTrue( connectionProperties + " broker1 connection count not zero: was[" + getConnectionCount(s1) + "]", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return getConnectionCount(s1) == initCount1; } })); assertTrue( connectionProperties + " broker2 connection count not zero: was[" + getConnectionCount(s2) + "]", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return getConnectionCount(s2) == initCount2; } })); }
public void testJMX() throws Exception { clearSelectorCacheFiles(); // borkerA is local and brokerB is remote bridgeAndConfigureBrokers("BrokerA", "BrokerB"); startAllBrokers(); waitForBridgeFormation(); createConsumer( "BrokerB", createDestination("Consumer.B.VirtualTopic.tempTopic", false), "foo = 'bar'"); final BrokerService brokerA = brokers.get("BrokerA").broker; String testQueue = "queue://Consumer.B.VirtualTopic.tempTopic"; VirtualDestinationSelectorCacheViewMBean cache = getVirtualDestinationSelectorCacheMBean(brokerA); Set<String> selectors = cache.selectorsForDestination(testQueue); assertEquals(1, selectors.size()); assertTrue(selectors.contains("foo = 'bar'")); boolean removed = cache.deleteSelectorForDestination(testQueue, "foo = 'bar'"); assertTrue(removed); selectors = cache.selectorsForDestination(testQueue); assertEquals(0, selectors.size()); createConsumer( "BrokerB", createDestination("Consumer.B.VirtualTopic.tempTopic", false), "ceposta = 'redhat'"); Wait.waitFor( new Wait.Condition() { Destination dest = brokerA.getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")); @Override public boolean isSatisified() throws Exception { return dest.getConsumers().size() == 2; } }, 500); selectors = cache.selectorsForDestination(testQueue); assertEquals(1, selectors.size()); cache.deleteAllSelectorsForDestination(testQueue); selectors = cache.selectorsForDestination(testQueue); assertEquals(0, selectors.size()); }
@Test public void testSendToDlq() throws Exception { sendJMSMessageToKickOffRoute(); LOG.info("Wait for dlq message..."); assertTrue( Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return broker.getAdminView().getTotalEnqueueCount() == 2; } })); }
@Test(timeout = 60000) public void testSendAfterMissingHeartbeat() throws Exception { String connectFrame = "STOMP\n" + "login:system\n" + "passcode:manager\n" + "accept-version:1.1\n" + "heart-beat:1000,0\n" + "host:localhost\n" + "\n" + Stomp.NULL; stompConnection.sendFrame(connectFrame); String f = stompConnection.receiveFrame(); assertTrue(f.startsWith("CONNECTED")); assertTrue(f.indexOf("version:1.1") >= 0); assertTrue(f.indexOf("heart-beat:") >= 0); assertTrue(f.indexOf("session:") >= 0); LOG.debug("Broker sent: " + f); Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return getProxyToBroker().getCurrentConnectionsCount() == 0; } }, TimeUnit.SECONDS.toMillis(5), TimeUnit.MILLISECONDS.toMillis(25)); try { String message = "SEND\n" + "destination:/queue/" + getQueueName() + "\n" + "receipt:1\n\n" + "Hello World" + Stomp.NULL; stompConnection.sendFrame(message); stompConnection.receiveFrame(); fail("SEND frame has been accepted after missing heart beat"); } catch (Exception ex) { LOG.info(ex.getMessage()); } }
// JMX Helper Methods private boolean verifyConsumerCount( final long expectedCount, final ActiveMQDestination destination, final BrokerService broker) throws Exception { return Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { boolean result = false; try { ObjectName[] destinations; if (destination.isQueue()) { destinations = broker.getAdminView().getQueues(); } else { destinations = broker.getAdminView().getTopics(); } // We should have 1 consumer for the queue on the local broker for (ObjectName name : destinations) { DestinationViewMBean view = (DestinationViewMBean) broker .getManagementContext() .newProxyInstance(name, DestinationViewMBean.class, true); if (view.getName().equals(destination.getPhysicalName())) { LOG.info( "Consumers for " + destination.getPhysicalName() + " on " + broker + " : " + view.getConsumerCount()); LOG.info("Subs: " + Arrays.asList(view.getSubscriptions())); if (expectedCount == view.getConsumerCount()) { result = true; } } } } catch (Exception ignoreAndRetry) { } return result; } }); }
@Test public void testIndexRebuildsAfterSomeJobsExpire() throws Exception { IOHelper.deleteFile(schedulerStoreDir); JobSchedulerStoreImpl schedulerStore = createScheduler(); broker = createBroker(schedulerStore); broker.start(); ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost"); Connection connection = cf.createConnection(); connection.start(); for (int i = 0; i < NUM_JOBS; ++i) { scheduleRepeating(connection); scheduleOneShot(connection); } connection.close(); JobScheduler scheduler = schedulerStore.getJobScheduler("JMS"); assertNotNull(scheduler); assertEquals(NUM_JOBS * 2, scheduler.getAllJobs().size()); final JobScheduler awaitingOneShotTimeout = scheduler; assertTrue( "One shot jobs should time out", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return awaitingOneShotTimeout.getAllJobs().size() == NUM_JOBS; } }, TimeUnit.MINUTES.toMillis(2))); broker.stop(); IOHelper.delete(new File(schedulerStoreDir, "scheduleDB.data")); schedulerStore = createScheduler(); broker = createBroker(schedulerStore); broker.start(); scheduler = schedulerStore.getJobScheduler("JMS"); assertNotNull(scheduler); assertEquals(NUM_JOBS, scheduler.getAllJobs().size()); }
private boolean verifyDurableConsumerCount(final long expectedCount, final BrokerService broker) throws Exception { return Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { boolean result = false; BrokerView view = broker.getAdminView(); if (view != null) { ObjectName[] subs = broker.getAdminView().getInactiveDurableTopicSubscribers(); if (subs != null) { LOG.info("inactive durable subs on " + broker + " : " + Arrays.asList(subs)); if (expectedCount == subs.length) { result = true; } } } return result; } }); }
@Test(timeout = 30000) @Ignore("Test fails on windows") public void testReconnectUnlimited() throws Exception { Transport transport = TransportFactory.connect( new URI( "failover://(tcp://0.0.0.0:61616)?useExponentialBackOff=false&reconnectDelay=0&initialReconnectDelay=0")); transport.setTransportListener( new TransportListener() { @Override public void onCommand(Object command) {} @Override public void onException(IOException error) {} @Override public void transportInterupted() {} @Override public void transportResumed() {} }); transport.start(); this.failoverTransport = transport.narrow(FailoverTransport.class); assertTrue( "no implicit limit of 1000", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return failoverTransport.getConnectFailures() > 1002; } })); }
@Test public void testNew() throws Exception { final BrokerService brokerService = new BrokerService(); startBroker(brokerService); assertTrue("broker alive", brokerService.isStarted()); assertEquals("no network connectors", 0, brokerService.getNetworkConnectors().size()); DiscoveryNetworkConnector nc = createNetworkConnector(); javaConfigBroker.addNetworkConnector(nc); assertTrue( "new network connectors", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return 1 == brokerService.getNetworkConnectors().size(); } })); NetworkConnector networkConnector = brokerService.getNetworkConnectors().get(0); javaConfigBroker.addNetworkConnector(nc); TimeUnit.SECONDS.sleep(SLEEP); assertEquals("no new network connectors", 1, brokerService.getNetworkConnectors().size()); assertSame("same instance", networkConnector, brokerService.getNetworkConnectors().get(0)); // verify nested elements assertEquals("has exclusions", 2, networkConnector.getExcludedDestinations().size()); assertEquals( "one statically included", 1, networkConnector.getStaticallyIncludedDestinations().size()); assertEquals( "one dynamically included", 1, networkConnector.getDynamicallyIncludedDestinations().size()); assertEquals("one durable", 1, networkConnector.getDurableDestinations().size()); }
@Test public void testRemove() throws Exception { final BrokerService brokerService = new BrokerService(); startBroker(brokerService); assertTrue("broker alive", brokerService.isStarted()); assertEquals("no network connectors", 0, brokerService.getNetworkConnectors().size()); DiscoveryNetworkConnector nc1 = new DiscoveryNetworkConnector(); nc1.setUri(new URI("static:(tcp://localhost:5555)")); nc1.setNetworkTTL(1); nc1.setName("one"); DiscoveryNetworkConnector nc2 = new DiscoveryNetworkConnector(); nc2.setUri(new URI("static:(tcp://localhost:5555)")); nc2.setNetworkTTL(1); nc2.setName("one"); javaConfigBroker.addNetworkConnector(nc1); javaConfigBroker.addNetworkConnector(nc2); TimeUnit.SECONDS.sleep(SLEEP); assertEquals("correct network connectors", 2, brokerService.getNetworkConnectors().size()); javaConfigBroker.removeNetworkConnector(nc2); assertTrue( "expected mod on time", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return 1 == brokerService.getNetworkConnectors().size(); } })); NetworkConnector remainingNetworkConnector = brokerService.getNetworkConnectors().get(0); assertEquals("name match", "one", remainingNetworkConnector.getName()); }
public void testLoadBalancing() throws Exception { bridgeBrokers("BrokerA", "BrokerB"); bridgeBrokers("BrokerB", "BrokerA"); startAllBrokers(); waitForBridgeFormation(); // Setup destination Destination dest = createDestination("TEST.FOO", false); // Setup consumers MessageConsumer clientA = createConsumer("BrokerA", dest); // Setup consumers MessageConsumer clientB = createConsumer("BrokerB", dest); // Send messages sendMessages("BrokerA", dest, 5000); // Send messages sendMessages("BrokerB", dest, 1000); // Get message count final MessageIdList msgsA = getConsumerMessages("BrokerA", clientA); final MessageIdList msgsB = getConsumerMessages("BrokerB", clientB); Wait.waitFor( new Wait.Condition() { public boolean isSatisified() throws Exception { return msgsA.getMessageCount() + msgsB.getMessageCount() == 6000; } }); LOG.info("A got: " + msgsA.getMessageCount()); LOG.info("B got: " + msgsB.getMessageCount()); assertTrue("B got is fair share: " + msgsB.getMessageCount(), msgsB.getMessageCount() > 2000); }
public void testExpireMessagesForDurableSubscriber() throws Exception { createBroker(); ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(connectionUri); connection = factory.createConnection(); connection.setClientID("myConnection"); session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); connection.start(); Topic destination = session.createTopic("test"); producer = session.createProducer(destination); final int ttl = 1000; producer.setTimeToLive(ttl); final long sendCount = 10; TopicSubscriber sub = session.createDurableSubscriber(destination, "mySub"); sub.close(); for (int i = 0; i < sendCount; i++) { producer.send(session.createTextMessage("test")); } DestinationViewMBean view = createView((ActiveMQTopic) destination); LOG.info("messages sent"); LOG.info("expired=" + view.getExpiredCount() + " " + view.getEnqueueCount()); assertEquals(0, view.getExpiredCount()); assertEquals(10, view.getEnqueueCount()); Thread.sleep(5000); LOG.info("expired=" + view.getExpiredCount() + " " + view.getEnqueueCount()); assertEquals(10, view.getExpiredCount()); assertEquals(10, view.getEnqueueCount()); final AtomicLong received = new AtomicLong(); sub = session.createDurableSubscriber(destination, "mySub"); sub.setMessageListener( new MessageListener() { @Override public void onMessage(Message message) { received.incrementAndGet(); } }); LOG.info("Waiting for messages to arrive"); Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return received.get() >= sendCount; } }, 1000); LOG.info("received=" + received.get()); LOG.info("expired=" + view.getExpiredCount() + " " + view.getEnqueueCount()); assertEquals(0, received.get()); assertEquals(10, view.getExpiredCount()); assertEquals(10, view.getEnqueueCount()); }
public void testExpiredMessagesWithVerySlowConsumerCanContinue() throws Exception { createBroker(); final long queuePrefetch = 600; ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory( connectionUri + "?jms.prefetchPolicy.queuePrefetch=" + queuePrefetch); connection = factory.createConnection(); session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); producer = session.createProducer(destination); final int ttl = 4000; producer.setTimeToLive(ttl); final long sendCount = 1500; final CountDownLatch receivedOneCondition = new CountDownLatch(1); final CountDownLatch waitCondition = new CountDownLatch(1); final AtomicLong received = new AtomicLong(); MessageConsumer consumer = session.createConsumer(destination); consumer.setMessageListener( new MessageListener() { @Override public void onMessage(Message message) { try { if (LOG.isDebugEnabled()) { LOG.debug("Got my message: " + message); } receivedOneCondition.countDown(); received.incrementAndGet(); waitCondition.await(5, TimeUnit.MINUTES); if (LOG.isDebugEnabled()) { LOG.debug("acking message: " + message); } message.acknowledge(); } catch (Exception e) { e.printStackTrace(); fail(e.toString()); } } }); connection.start(); final Thread producingThread = new Thread("Producing Thread") { @Override public void run() { try { int i = 0; long tStamp = System.currentTimeMillis(); while (i++ < sendCount) { producer.send(session.createTextMessage("test")); if (i % 100 == 0) { LOG.info( "sent: " + i + " @ " + ((System.currentTimeMillis() - tStamp) / 100) + "m/ms"); tStamp = System.currentTimeMillis(); } } } catch (Throwable ex) { ex.printStackTrace(); } } }; producingThread.start(); assertTrue("got one message", receivedOneCondition.await(20, TimeUnit.SECONDS)); assertTrue( "producer failed to complete within allocated time", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { producingThread.join(1000); return !producingThread.isAlive(); } }, Wait.MAX_WAIT_MILLIS * 10)); final DestinationViewMBean view = createView(destination); assertTrue( "Not all dispatched up to default prefetch ", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return queuePrefetch == view.getDispatchCount(); } })); assertTrue( "all non inflight have expired ", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { LOG.info( "enqueue=" + view.getEnqueueCount() + ", dequeue=" + view.getDequeueCount() + ", inflight=" + view.getInFlightCount() + ", expired= " + view.getExpiredCount() + ", size= " + view.getQueueSize()); return view.getExpiredCount() > 0 && (view.getEnqueueCount() - view.getInFlightCount()) == view.getExpiredCount(); } })); LOG.info( "enqueue=" + view.getEnqueueCount() + ", dequeue=" + view.getDequeueCount() + ", inflight=" + view.getInFlightCount() + ", expired= " + view.getExpiredCount() + ", size= " + view.getQueueSize()); // let the ack happen waitCondition.countDown(); Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return 0 == view.getInFlightCount(); } }); LOG.info( "enqueue=" + view.getEnqueueCount() + ", dequeue=" + view.getDequeueCount() + ", inflight=" + view.getInFlightCount() + ", expired= " + view.getExpiredCount() + ", size= " + view.getQueueSize()); assertEquals("inflight didn't reduce to duck", 0, view.getInFlightCount()); assertEquals("size doesn't get back to 0 ", 0, view.getQueueSize()); assertEquals("dequeues don't match sent/expired ", sendCount, view.getDequeueCount()); // produce some more producer.setTimeToLive(0); long tStamp = System.currentTimeMillis(); for (int i = 0; i < sendCount; i++) { producer.send(session.createTextMessage("test-" + i)); if (i % 100 == 0) { LOG.info("sent: " + i + " @ " + ((System.currentTimeMillis() - tStamp) / 100) + "m/ms"); tStamp = System.currentTimeMillis(); } } Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return received.get() >= sendCount; } }); consumer.close(); Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return 0 == view.getInFlightCount(); } }); assertEquals("inflight did not go to zero on close", 0, view.getInFlightCount()); LOG.info("done: " + getName()); }
public void testExpiredMessagesWithNoConsumer() throws Exception { createBrokerWithMemoryLimit(); ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(connectionUri); connection = factory.createConnection(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); producer = session.createProducer(destination); producer.setTimeToLive(1000); connection.start(); final long sendCount = 2000; final Thread producingThread = new Thread("Producing Thread") { @Override public void run() { try { int i = 0; long tStamp = System.currentTimeMillis(); while (i++ < sendCount) { producer.send(session.createTextMessage("test")); if (i % 100 == 0) { LOG.info( "sent: " + i + " @ " + ((System.currentTimeMillis() - tStamp) / 100) + "m/ms"); tStamp = System.currentTimeMillis(); } } } catch (Throwable ex) { ex.printStackTrace(); } } }; producingThread.start(); assertTrue( "producer failed to complete within allocated time", Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { producingThread.join(TimeUnit.SECONDS.toMillis(3000)); return !producingThread.isAlive(); } })); final DestinationViewMBean view = createView(destination); Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { LOG.info( "enqueue=" + view.getEnqueueCount() + ", dequeue=" + view.getDequeueCount() + ", inflight=" + view.getInFlightCount() + ", expired= " + view.getExpiredCount() + ", size= " + view.getQueueSize()); return sendCount == view.getExpiredCount(); } }, Wait.MAX_WAIT_MILLIS * 10); LOG.info( "enqueue=" + view.getEnqueueCount() + ", dequeue=" + view.getDequeueCount() + ", inflight=" + view.getInFlightCount() + ", expired= " + view.getExpiredCount() + ", size= " + view.getQueueSize()); assertEquals("Not all sent messages have expired", sendCount, view.getExpiredCount()); assertEquals("memory usage doesn't go to duck egg", 0, view.getMemoryPercentUsage()); }
@Test(timeout = 60000) public void testDurableSubAndUnSubOnTwoTopics() throws Exception { stompConnection.setVersion(Stomp.V1_1); String domain = "org.apache.activemq"; ObjectName brokerName = new ObjectName(domain + ":type=Broker,brokerName=localhost"); BrokerViewMBean view = (BrokerViewMBean) brokerService .getManagementContext() .newProxyInstance(brokerName, BrokerViewMBean.class, true); String connectFrame = "STOMP\n" + "login:system\n" + "passcode:manager\n" + "accept-version:1.1\n" + "host:localhost\n" + "client-id:test\n" + "\n" + Stomp.NULL; stompConnection.sendFrame(connectFrame); String frame = stompConnection.receiveFrame(); LOG.debug("Broker sent: " + frame); assertTrue(frame.startsWith("CONNECTED")); assertEquals(view.getDurableTopicSubscribers().length, 0); // subscribe to first destination durably frame = "SUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "1" + "\n" + "ack:auto\n" + "receipt:1\n" + "id:durablesub-1\n" + "activemq.subscriptionName:test1\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); StompFrame receipt = stompConnection.receive(); LOG.debug("Broker sent: " + receipt); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("1", receipt.getHeaders().get("receipt-id")); assertEquals(view.getDurableTopicSubscribers().length, 1); // subscribe to second destination durably frame = "SUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "2" + "\n" + "ack:auto\n" + "receipt:2\n" + "id:durablesub-2\n" + "activemq.subscriptionName:test2\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); LOG.debug("Broker sent: " + receipt); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("2", receipt.getHeaders().get("receipt-id")); assertEquals(view.getDurableTopicSubscribers().length, 2); frame = "DISCONNECT\nclient-id:test\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return getProxyToBroker().getCurrentConnectionsCount() == 0; } }, TimeUnit.SECONDS.toMillis(5), TimeUnit.MILLISECONDS.toMillis(25)); // reconnect and send some messages to the offline subscribers and then try to get // them after subscribing again. stompConnect(); stompConnection.sendFrame(connectFrame); frame = stompConnection.receiveFrame(); LOG.debug("Broker sent: " + frame); assertTrue(frame.startsWith("CONNECTED")); assertEquals(view.getDurableTopicSubscribers().length, 0); assertEquals(view.getInactiveDurableTopicSubscribers().length, 2); // unsubscribe from topic 1 frame = "UNSUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "1\n" + "id:durablesub-1\n" + "receipt:3\n" + "activemq.subscriptionName:test1\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); LOG.debug("Broker sent: " + frame); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("3", receipt.getHeaders().get("receipt-id")); assertEquals(view.getInactiveDurableTopicSubscribers().length, 1); // unsubscribe from topic 2 frame = "UNSUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "2\n" + "id:durablesub-2\n" + "receipt:4\n" + "activemq.subscriptionName:test2\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); LOG.debug("Broker sent: " + frame); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("4", receipt.getHeaders().get("receipt-id")); assertEquals(view.getInactiveDurableTopicSubscribers().length, 0); }
@Test(timeout = 60000) public void testMultipleDurableSubsWithOfflineMessages() throws Exception { stompConnection.setVersion(Stomp.V1_1); final BrokerViewMBean view = getProxyToBroker(); String connectFrame = "STOMP\n" + "login:system\n" + "passcode:manager\n" + "accept-version:1.1\n" + "host:localhost\n" + "client-id:test\n" + "\n" + Stomp.NULL; stompConnection.sendFrame(connectFrame); String frame = stompConnection.receiveFrame(); LOG.debug("Broker sent: " + frame); assertTrue(frame.startsWith("CONNECTED")); assertEquals(view.getDurableTopicSubscribers().length, 0); // subscribe to first destination durably frame = "SUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "1" + "\n" + "ack:auto\n" + "receipt:1\n" + "id:durablesub-1\n" + "activemq.subscriptionName:test1\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); StompFrame receipt = stompConnection.receive(); LOG.debug("Broker sent: " + receipt); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("1", receipt.getHeaders().get("receipt-id")); assertEquals(view.getDurableTopicSubscribers().length, 1); // subscribe to second destination durably frame = "SUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "2" + "\n" + "ack:auto\n" + "receipt:2\n" + "id:durablesub-2\n" + "activemq.subscriptionName:test2\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); LOG.debug("Broker sent: " + receipt); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("2", receipt.getHeaders().get("receipt-id")); assertEquals(view.getDurableTopicSubscribers().length, 2); frame = "DISCONNECT\nclient-id:test\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); assertTrue( Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return view.getCurrentConnectionsCount() == 1; } }, TimeUnit.SECONDS.toMillis(5), TimeUnit.MILLISECONDS.toMillis(25))); // reconnect and send some messages to the offline subscribers and then try to get // them after subscribing again. stompConnect(); stompConnection.sendFrame(connectFrame); frame = stompConnection.receiveFrame(); LOG.debug("Broker sent: " + frame); assertTrue(frame.contains("CONNECTED")); assertEquals(view.getDurableTopicSubscribers().length, 0); assertEquals(view.getInactiveDurableTopicSubscribers().length, 2); frame = "SEND\n" + "destination:/topic/" + getQueueName() + "1\n" + "receipt:10\n" + "\n" + "Hello World 1" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); assertEquals("10", receipt.getHeaders().get(Stomp.Headers.Response.RECEIPT_ID)); frame = "SEND\n" + "destination:/topic/" + getQueueName() + "2\n" + "receipt:11\n" + "\n" + "Hello World 2" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); assertEquals("11", receipt.getHeaders().get(Stomp.Headers.Response.RECEIPT_ID)); // subscribe to first destination durably frame = "SUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "1" + "\n" + "ack:auto\n" + "receipt:3\n" + "id:durablesub-1\n" + "activemq.subscriptionName:test1\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); LOG.debug("Broker sent: " + receipt); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("3", receipt.getHeaders().get("receipt-id")); assertEquals(view.getDurableTopicSubscribers().length, 1); StompFrame message = stompConnection.receive(); assertEquals(Stomp.Responses.MESSAGE, message.getAction()); assertEquals("durablesub-1", message.getHeaders().get(Stomp.Headers.Message.SUBSCRIPTION)); assertEquals(view.getDurableTopicSubscribers().length, 1); assertEquals(view.getInactiveDurableTopicSubscribers().length, 1); // subscribe to second destination durably frame = "SUBSCRIBE\n" + "destination:/topic/" + getQueueName() + "2" + "\n" + "ack:auto\n" + "receipt:4\n" + "id:durablesub-2\n" + "activemq.subscriptionName:test2\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); receipt = stompConnection.receive(); LOG.debug("Broker sent: " + receipt); assertTrue(receipt.getAction().startsWith("RECEIPT")); assertEquals("4", receipt.getHeaders().get("receipt-id")); assertEquals(view.getDurableTopicSubscribers().length, 2); message = stompConnection.receive(); assertEquals(Stomp.Responses.MESSAGE, message.getAction()); assertEquals("durablesub-2", message.getHeaders().get(Stomp.Headers.Message.SUBSCRIPTION)); assertEquals(view.getDurableTopicSubscribers().length, 2); assertEquals(view.getInactiveDurableTopicSubscribers().length, 0); }
public void testSelectorAwareForwarding() throws Exception { clearSelectorCacheFiles(); // borkerA is local and brokerB is remote bridgeAndConfigureBrokers("BrokerA", "BrokerB"); startAllBrokers(); waitForBridgeFormation(); final BrokerService brokerB = brokers.get("BrokerB").broker; final BrokerService brokerA = brokers.get("BrokerA").broker; // Create the remote virtual topic consumer with selector MessageConsumer remoteConsumer = createConsumer( "BrokerB", createDestination("Consumer.B.VirtualTopic.tempTopic", false), "foo = 'bar'"); // let advisories propogate Wait.waitFor( new Wait.Condition() { Destination dest = brokerA.getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")); @Override public boolean isSatisified() throws Exception { return dest.getConsumers().size() == 1; } }, 500); ActiveMQQueue queueB = new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic"); Destination destination = getDestination(brokers.get("BrokerB").broker, queueB); assertEquals(1, destination.getConsumers().size()); ActiveMQTopic virtualTopic = new ActiveMQTopic("VirtualTopic.tempTopic"); assertNull(getDestination(brokers.get("BrokerA").broker, virtualTopic)); assertNull(getDestination(brokers.get("BrokerB").broker, virtualTopic)); // send two types of messages, one unwanted and the other wanted sendMessages("BrokerA", virtualTopic, 1, asMap("foo", "bar")); sendMessages("BrokerA", virtualTopic, 1, asMap("ceposta", "redhat")); MessageIdList msgsB = getConsumerMessages("BrokerB", remoteConsumer); // wait for the wanted one to arrive at the remote consumer msgsB.waitForMessagesToArrive(1); // ensure we don't get any more messages msgsB.waitForMessagesToArrive(1, 1000); // remote consumer should only get one of the messages assertEquals(1, msgsB.getMessageCount()); // and the enqueue count for the remote queue should only be 1 assertEquals( 1, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); // now let's remove the consumer on broker B and recreate it with new selector remoteConsumer.close(); // now let's shut down broker A and clear its persistent selector cache brokerA.stop(); brokerA.waitUntilStopped(); deleteSelectorCacheFile("BrokerA"); assertEquals(0, destination.getConsumers().size()); remoteConsumer = createConsumer( "BrokerB", createDestination("Consumer.B.VirtualTopic.tempTopic", false), "ceposta = 'redhat'"); assertEquals(1, destination.getConsumers().size()); // now let's start broker A back up brokerA.start(true); brokerA.waitUntilStarted(); System.out.println(brokerA.getNetworkConnectors()); // give a sec to let advisories propogate // let advisories propogate Wait.waitFor( new Wait.Condition() { Destination dest = brokerA.getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")); @Override public boolean isSatisified() throws Exception { return dest.getConsumers().size() == 1; } }, 500); // send two types of messages, one unwanted and the other wanted sendMessages("BrokerA", virtualTopic, 1, asMap("foo", "bar")); sendMessages("BrokerB", virtualTopic, 1, asMap("foo", "bar")); sendMessages("BrokerA", virtualTopic, 1, asMap("ceposta", "redhat")); sendMessages("BrokerB", virtualTopic, 1, asMap("ceposta", "redhat")); // lets get messages on consumer B msgsB = getConsumerMessages("BrokerB", remoteConsumer); msgsB.waitForMessagesToArrive(2); // ensure we don't get any more messages msgsB.waitForMessagesToArrive(1, 1000); // remote consumer should only get 10 of the messages assertEquals(2, msgsB.getMessageCount()); // queue should be drained assertEquals( 0, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); // and the enqueue count for the remote queue should only be 1 assertEquals( 3, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); }
public void testMessageLeaks() throws Exception { clearSelectorCacheFiles(); startAllBrokers(); final BrokerService brokerA = brokers.get("BrokerA").broker; // Create the remote virtual topic consumer with selector ActiveMQDestination consumerQueue = createDestination("Consumer.B.VirtualTopic.tempTopic", false); // create it so that the queue is there and messages don't get lost MessageConsumer consumer1 = createConsumer("BrokerA", consumerQueue, "SYMBOL = 'AAPL'"); MessageConsumer consumer2 = createConsumer("BrokerA", consumerQueue, "SYMBOL = 'AAPL'"); ActiveMQTopic virtualTopic = new ActiveMQTopic("VirtualTopic.tempTopic"); ProducerThreadTester producerTester = createProducerTester("BrokerA", virtualTopic); producerTester.setRunIndefinitely(true); producerTester.setSleep(5); producerTester.addMessageProperty("AAPL"); producerTester.addMessageProperty("VIX"); producerTester.start(); int currentCount = producerTester.getSentCount(); LOG.info( ">>>> currently sent: total=" + currentCount + ", AAPL=" + producerTester.getCountForProperty("AAPL") + ", VIX=" + producerTester.getCountForProperty("VIX")); // let some messages get sent Thread.sleep(2000); MessageIdList consumer1Messages = getConsumerMessages("BrokerA", consumer1); consumer1Messages.waitForMessagesToArrive(50, 1000); // switch one of the consumers to SYMBOL = 'VIX' consumer1.close(); consumer1 = createConsumer("BrokerA", consumerQueue, "SYMBOL = 'VIX'"); // wait till new consumer is on board Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getConsumers() .size() == 2; } }); currentCount = producerTester.getSentCount(); LOG.info( ">>>> currently sent: total=" + currentCount + ", AAPL=" + producerTester.getCountForProperty("AAPL") + ", VIX=" + producerTester.getCountForProperty("VIX")); // let some messages get sent Thread.sleep(2000); // switch the other consumer to SYMBOL = 'VIX' consumer2.close(); consumer2 = createConsumer("BrokerA", consumerQueue, "SYMBOL = 'VIX'"); // wait till new consumer is on board Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getConsumers() .size() == 2; } }); currentCount = producerTester.getSentCount(); LOG.info( ">>>> currently sent: total=" + currentCount + ", AAPL=" + producerTester.getCountForProperty("AAPL") + ", VIX=" + producerTester.getCountForProperty("VIX")); // let some messages get sent Thread.sleep(2000); currentCount = producerTester.getSentCount(); LOG.info( ">>>> currently sent: total=" + currentCount + ", AAPL=" + producerTester.getCountForProperty("AAPL") + ", VIX=" + producerTester.getCountForProperty("VIX")); // make sure if there are messages that are orphaned in the queue that this number doesn't // grow... final long currentDepth = brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount(); LOG.info(">>>>> Orphaned messages? " + currentDepth); // wait 5s to see if we can get a growth in the depth of the queue Wait.waitFor( new Wait.Condition() { @Override public boolean isSatisified() throws Exception { return brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount() > currentDepth; } }, 5000); // stop producers producerTester.setRunning(false); producerTester.join(); // pause to let consumers catch up Thread.sleep(1000); assertTrue( brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount() <= currentDepth); }
public void testSelectorsAndNonSelectors() throws Exception { clearSelectorCacheFiles(); // borkerA is local and brokerB is remote bridgeAndConfigureBrokers("BrokerA", "BrokerB"); startAllBrokers(); waitForBridgeFormation(); final BrokerService brokerA = brokers.get("BrokerA").broker; final BrokerService brokerB = brokers.get("BrokerB").broker; // Create the remote virtual topic consumer with selector ActiveMQDestination consumerBQueue = createDestination("Consumer.B.VirtualTopic.tempTopic", false); MessageConsumer selectingConsumer = createConsumer("BrokerB", consumerBQueue, "foo = 'bar'"); MessageConsumer nonSelectingConsumer = createConsumer("BrokerB", consumerBQueue); // let advisories propogate Wait.waitFor( new Wait.Condition() { Destination dest = brokerA.getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")); @Override public boolean isSatisified() throws Exception { return dest.getConsumers().size() == 2; } }, 500); Destination destination = getDestination(brokerB, consumerBQueue); assertEquals(2, destination.getConsumers().size()); // publisher publishes to this ActiveMQTopic virtualTopic = new ActiveMQTopic("VirtualTopic.tempTopic"); sendMessages("BrokerA", virtualTopic, 10, asMap("foo", "bar")); sendMessages("BrokerA", virtualTopic, 10); MessageIdList selectingConsumerMessages = getConsumerMessages("BrokerB", selectingConsumer); MessageIdList nonSelectingConsumerMessages = getConsumerMessages("BrokerB", nonSelectingConsumer); // we only expect half of the messages that get sent with the selector, because they get load // balanced selectingConsumerMessages.waitForMessagesToArrive(5, 1000L); assertEquals(5, selectingConsumerMessages.getMessageCount()); nonSelectingConsumerMessages.waitForMessagesToArrive(15, 1000L); assertEquals(15, nonSelectingConsumerMessages.getMessageCount()); // assert broker A stats waitForMessagesToBeConsumed(brokerA, "Consumer.B.VirtualTopic.tempTopic", false, 20, 20, 5000); assertEquals( 20, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 20, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 0, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); // assert broker B stats waitForMessagesToBeConsumed(brokerB, "Consumer.B.VirtualTopic.tempTopic", false, 20, 20, 5000); assertEquals( 20, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 20, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 0, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); // now let's close the consumer without the selector nonSelectingConsumer.close(); // let advisories propogate Wait.waitFor( new Wait.Condition() { Destination dest = brokerA.getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")); @Override public boolean isSatisified() throws Exception { return dest.getConsumers().size() == 1; } }, 500); // and let's send messages with a selector that doesnt' match selectingConsumerMessages.flushMessages(); sendMessages("BrokerA", virtualTopic, 10, asMap("ceposta", "redhat")); selectingConsumerMessages = getConsumerMessages("BrokerB", selectingConsumer); selectingConsumerMessages.waitForMessagesToArrive(1, 1000L); assertEquals(0, selectingConsumerMessages.getMessageCount()); // assert broker A stats waitForMessagesToBeConsumed(brokerA, "Consumer.B.VirtualTopic.tempTopic", false, 20, 20, 5000); assertEquals( 20, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 20, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 0, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); // assert broker B stats waitForMessagesToBeConsumed(brokerB, "Consumer.B.VirtualTopic.tempTopic", false, 20, 20, 5000); assertEquals( 20, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 20, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 0, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); // now lets disconect the selecting consumer for a sec and send messages with a selector that // DOES match selectingConsumer.close(); // let advisories propogate Wait.waitFor( new Wait.Condition() { Destination dest = brokerA.getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")); @Override public boolean isSatisified() throws Exception { return dest.getConsumers().size() == 0; } }, 500); selectingConsumerMessages.flushMessages(); sendMessages("BrokerA", virtualTopic, 10, asMap("foo", "bar")); // assert broker A stats waitForMessagesToBeConsumed(brokerA, "Consumer.B.VirtualTopic.tempTopic", false, 20, 20, 5000); assertEquals( 30, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 20, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 10, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); // assert broker B stats waitForMessagesToBeConsumed(brokerB, "Consumer.B.VirtualTopic.tempTopic", false, 20, 20, 5000); assertEquals( 20, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 20, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 0, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); selectingConsumer = createConsumer("BrokerB", consumerBQueue, "foo = 'bar'"); selectingConsumerMessages = getConsumerMessages("BrokerB", selectingConsumer); selectingConsumerMessages.waitForMessagesToArrive(10); assertEquals(10, selectingConsumerMessages.getMessageCount()); // let advisories propogate Wait.waitFor( new Wait.Condition() { Destination dest = brokerA.getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")); @Override public boolean isSatisified() throws Exception { return dest.getConsumers().size() == 1; } }, 500); // assert broker A stats waitForMessagesToBeConsumed(brokerA, "Consumer.B.VirtualTopic.tempTopic", false, 30, 30, 5000); assertEquals( 30, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 30, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 0, brokerA .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); // assert broker B stats waitForMessagesToBeConsumed(brokerB, "Consumer.B.VirtualTopic.tempTopic", false, 30, 30, 5000); assertEquals( 30, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getEnqueues() .getCount()); assertEquals( 30, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getDequeues() .getCount()); assertEquals( 0, brokerB .getDestination(new ActiveMQQueue("Consumer.B.VirtualTopic.tempTopic")) .getDestinationStatistics() .getMessages() .getCount()); }