/** * 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.perf; import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.Destination; 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 junit.framework.TestCase; import junit.textui.TestRunner; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; import org.apache.activemq.network.NetworkConnector; import org.apache.activemq.xbean.BrokerFactoryBean; import org.apache.xbean.spring.context.ClassPathXmlApplicationContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; public class NetworkedSyncTest extends TestCase { // constants public static final int MESSAGE_COUNT = 10000; //100000; public final static String config = "org/apache/activemq/perf/networkSync.xml"; public final static String broker1URL = "tcp://localhost:61616"; public final static String broker2URL = "tcp://localhost:62616"; private final String networkConnectorURL = "static://(" + broker2URL + ")"; private static final Logger LOG = LoggerFactory.getLogger(NetworkedSyncTest.class); BrokerService broker1 = null; BrokerService broker2 = null; NetworkConnector connector = null; /** * @param name */ public NetworkedSyncTest(String name) { super(name); LOG.info("Testcase started."); } public static void main(String args[]) { TestRunner.run(NetworkedSyncTest.class); } /** * @throws java.lang.Exception */ @Override protected void setUp() throws Exception { LOG.info("setUp() called."); ClassPathXmlApplicationContext context1 = null; BrokerFactoryBean brokerFactory = new BrokerFactoryBean(new ClassPathResource(config)); assertNotNull(brokerFactory); /* start up first broker instance */ try { // resolve broker1 Thread.currentThread().setContextClassLoader(NetworkedSyncTest.class.getClassLoader()); context1 = new ClassPathXmlApplicationContext(config); broker1 = (BrokerService) context1.getBean("broker1"); // start the broker if (!broker1.isStarted()) { LOG.info("Broker broker1 not yet started. Kicking it off now."); broker1.start(); } else { LOG.info("Broker broker1 already started. Not kicking it off a second time."); broker1.waitUntilStopped(); } } catch (Exception e) { LOG.error("Error: " + e.getMessage()); throw e; // brokerService.stop(); } /* start up second broker instance */ try { Thread.currentThread().setContextClassLoader(NetworkedSyncTest.class.getClassLoader()); context1 = new ClassPathXmlApplicationContext(config); broker2 = (BrokerService) context1.getBean("broker2"); // start the broker if (!broker2.isStarted()) { LOG.info("Broker broker2 not yet started. Kicking it off now."); broker2.start(); } else { LOG.info("Broker broker2 already started. Not kicking it off a second time."); broker2.waitUntilStopped(); } } catch (Exception e) { LOG.error("Error: " + e.getMessage()); throw e; } // setup network connector from broker1 to broker2 connector = broker1.addNetworkConnector(networkConnectorURL); connector.setBrokerName(broker1.getBrokerName()); connector.setDuplex(true); connector.start(); LOG.info("Network connector created."); } /** * @throws java.lang.Exception */ @Override protected void tearDown() throws Exception { LOG.info("tearDown() called."); if (broker1 != null && broker1.isStarted()) { LOG.info("Broker1 still running, stopping it now."); broker1.stop(); } else { LOG.info("Broker1 not running, nothing to shutdown."); } if (broker2 != null && broker2.isStarted()) { LOG.info("Broker2 still running, stopping it now."); broker2.stop(); } else { LOG.info("Broker2 not running, nothing to shutdown."); } } public void testMessageExchange() throws Exception { LOG.info("testMessageExchange() called."); long start = System.currentTimeMillis(); // create producer and consumer threads Thread producer = new Thread(new Producer()); Thread consumer = new Thread(new Consumer()); // start threads consumer.start(); Thread.sleep(2000); producer.start(); // wait for threads to finish producer.join(); consumer.join(); long end = System.currentTimeMillis(); System.out.println("Duration: " + (end - start)); } } /** * Message producer running as a separate thread, connecting to broker1 * * @author tmielke */ class Producer implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(Producer.class); /** * connect to broker and constantly send messages */ @Override public void run() { Connection connection = null; Session session = null; MessageProducer producer = null; try { ActiveMQConnectionFactory amq = new ActiveMQConnectionFactory(NetworkedSyncTest.broker1URL); connection = amq.createConnection(); connection.setExceptionListener(new javax.jms.ExceptionListener() { @Override public void onException(javax.jms.JMSException e) { e.printStackTrace(); } }); connection.start(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Topic destination = session.createTopic("TEST.FOO"); producer = session.createProducer(destination); producer.setDeliveryMode(DeliveryMode.PERSISTENT); long counter = 0; // Create and send message for (int i = 0; i < NetworkedSyncTest.MESSAGE_COUNT; i++) { String text = "Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode() + ":" + counter; TextMessage message = session.createTextMessage(text); producer.send(message); counter++; if ((counter % 1000) == 0) LOG.info("sent " + counter + " messages"); } } catch (Exception ex) { LOG.error(ex.toString()); return; } finally { try { if (producer != null) producer.close(); if (session != null) session.close(); if (connection != null) connection.close(); } catch (Exception e) { LOG.error("Problem closing down JMS objects: " + e); } } } } /* * * Message consumer running as a separate thread, connecting to broker2 * @author tmielke * */ class Consumer implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(Consumer.class); /** * connect to broker and receive messages */ @Override public void run() { Connection connection = null; Session session = null; MessageConsumer consumer = null; try { ActiveMQConnectionFactory amq = new ActiveMQConnectionFactory(NetworkedSyncTest.broker2URL); connection = amq.createConnection(); // need to set clientID when using durable subscription. connection.setClientID("tmielke"); connection.setExceptionListener(new javax.jms.ExceptionListener() { @Override public void onException(javax.jms.JMSException e) { e.printStackTrace(); } }); connection.start(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Destination destination = session.createTopic("TEST.FOO"); consumer = session.createDurableSubscriber((Topic) destination, "tmielke"); long counter = 0; // Wait for a message for (int i = 0; i < NetworkedSyncTest.MESSAGE_COUNT; i++) { Message message2 = consumer.receive(); if (message2 instanceof TextMessage) { TextMessage textMessage = (TextMessage) message2; textMessage.getText(); // logger.info("Received: " + text); } else { LOG.error("Received message of unsupported type. Expecting TextMessage. " + message2); } counter++; if ((counter % 1000) == 0) LOG.info("received " + counter + " messages"); } } catch (Exception e) { LOG.error("Error in Consumer: " + e); return; } finally { try { if (consumer != null) consumer.close(); if (session != null) session.close(); if (connection != null) connection.close(); } catch (Exception ex) { LOG.error("Error closing down JMS objects: " + ex); } } } }