Package org.activemq.usecases

Source Code of org.activemq.usecases.SystemTest

package org.activemq.usecases;

import junit.framework.TestCase;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

import javax.jms.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.derby.jdbc.EmbeddedDataSource;

import org.activemq.ActiveMQConnection;
import org.activemq.ActiveMQConnectionFactory;
import org.activemq.message.ActiveMQMessage;
import org.activemq.util.IdGenerator;
import org.activemq.broker.impl.BrokerConnectorImpl;
import org.activemq.broker.impl.BrokerContainerImpl;
import org.activemq.io.impl.DefaultWireFormat;
import org.activemq.store.PersistenceAdapter;
import org.activemq.store.jdbc.JDBCPersistenceAdapter;

public class SystemTest extends TestCase implements MessageListener {

    private static final Logger log = LoggingManager.getLoggerForClass();

    public static final String ACTIVEMQ_SERVER = "ActiveMQ Server";
    public static final boolean TRANSACTED_FALSE = false;
    public static final String TOOL_DEFAULT = "TOOL.DEFAULT";
    public static final String LAST_MESSAGE = "LAST";

    private static int msgCounter = 0;
    public static Map ProducerMap = Collections.synchronizedMap(new HashMap());

    private int producerCount = 0;
    private int consumerCount = 0;
    private int subjectCount = 0;
    private int messageCount = 0;
    private boolean isPersistent = true;
    private boolean isDurable = true;
    private boolean isTopic = true;
    private boolean isEmbeddedBroker = true;
    private boolean init = false;
    private boolean testStillRunning = true;
    private BrokerContainerImpl broker = null;
    private String brokerUrl = null;
    private MessageConsumer consumer = null;

    /**
     * Default constructor
     */
    protected SystemTest(){
        super();
        brokerUrl = "tcp://localhost:6099";
        isEmbeddedBroker = true;
        ProducerMap.clear();
        msgCounter = 0;
        init = false;
        consumer = null;
        testStillRunning = true;
    }

    /**
     * Constructor
     *
     * @param isTopic - true when topic, false when queue.
     * @parm isPersistent - true when the delivery mode is persistent.
     * @param isDurable - true when the suscriber is durable(For topic only).
     * @param producerCount - number of producers.
     * @param consumerCount - number of consumers.
     * @param subjectCount - number of destinations.
     * @param messageCount - number of messages to be delivered.
     * @param testTitle - test title/name.
     *
     */
    protected SystemTest(boolean isTopic,
                         boolean isPersistent,
                         boolean isDurable,
                         int producerCount,
                         int consumerCount,
                         int subjectCount,
                         int messageCount,
                         String testTitle){
        super();
        this.isTopic = isTopic;
        this.isPersistent = isPersistent;
        this.isDurable = isDurable;
        this.producerCount = producerCount;
        this.consumerCount = consumerCount;
        this.subjectCount = subjectCount;
        this.messageCount = messageCount;
        this.testParameterSettings(testTitle);

        brokerUrl = "tcp://localhost:6099";
        isEmbeddedBroker = true;
        ProducerMap.clear();
        msgCounter = 0;
        init = false;
        consumer = null;
        testStillRunning = true;
    }

    /*
     * Producer section
     */

    /**
     * Creates the message producer threads.
     */
    protected void publish() throws JMSException {
        String subjects[] = getSubjects();

        for (int i = 0; i < producerCount; i++) {
            final int x = i;
            final String subject = subjects[i % subjects.length];

            Thread thread = new Thread() {
                public void run() {
                    try {
                        publish(x, subject);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };

            thread.start();
        }
    }

    /**
     * Creates the producer and send the messages.
     *
     * @param x - producer number.
     * @param subject -  the destination where the messages will be sent.
     */
    protected void publish(int x, String subject) throws Exception {
        MessageProducer publisher = null;
        Connection connection = createConnectionFactory(brokerUrl, isEmbeddedBroker);

        if (isPersistent) {
            IdGenerator idGenerator = new IdGenerator();
            connection.setClientID(idGenerator.generateId());
        }

        Session session = createSession(connection, TRANSACTED_FALSE);
        Destination destination = createDestination(session, subject, isTopic);
        publisher = session.createProducer(destination);

        if (isPersistent) {
            publisher.setDeliveryMode(DeliveryMode.PERSISTENT);
        } else {
            publisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        }

        StringBuffer sb = new StringBuffer();
        sb.append("PROD");
        sb.append(x);
        sb.append("#BODY");

        //Sending messages
        for (int i = 0; i < messageCount - 1; ++i) {
            TextMessage message = session.createTextMessage(sb.toString());
            publisher.send(message);
        }
        sb.delete(0, sb.length());

        //Sending the last message
        sb.append("PROD");
        sb.append(x);
        sb.append("#");
        sb.append(LAST_MESSAGE);
        TextMessage message = session.createTextMessage(sb.toString());

        publisher.send(message);
    }

    /*
     * Consumer section
     */

    /**
     * Generates the topic/queue destinations.
     *
     * @return String[] - topic/queue destination name.
     */
    protected String[] getSubjects() {
        //Create the subjects.
        String[] subjects = new String[subjectCount];

        //Appended to the subject to determine if its a queue or topic.
        String prefix = null;
        if (this.isTopic) {
            prefix = ".TOPIC";
        } else {
            prefix = ".QUEUE";
        }

        for (int i = 0; i < subjects.length; i++) {
            subjects[i] = TOOL_DEFAULT + prefix + i;
        }

        return subjects;
    }

    /**
     * Suscribes the consumers to the topic/queue destinations.
     */
    protected void subscribe() throws JMSException {
        String subjects[] = getSubjects();

        for (int i = 0; i < consumerCount; i++) {
            String subject = subjects[i % subjectCount];
            subscribe(subject);
        }
    }

    /**
     * Suscribes the consumer to the topic/queue specified by the subject.
     *
     * @param subject - the Destination where the consumer waits upon for messages.
     */
    protected void subscribe(String subject) throws JMSException {
        Connection connection = createConnectionFactory(brokerUrl, isEmbeddedBroker);

        if (isDurable) {
            IdGenerator idGenerator = new IdGenerator();
            connection.setClientID(idGenerator.generateId());
        }

        //Start the connection before receiving messages.
        connection.start();
        Session session = createSession(connection, TRANSACTED_FALSE);
        Destination destination = createDestination(session, subject, isTopic);

        if (isDurable && isTopic) {
            consumer = session.createDurableSubscriber((Topic) destination, getClass().getName());
        } else {
            consumer = session.createConsumer(destination);
        }

        consumer.setMessageListener(this);
    }

    /**
     * Processes the received message.
     *
     * @param message - message received by the listener.
     */
    public void onMessage(Message message) {
        try {
            ActiveMQMessage amsg = (ActiveMQMessage) message;
            TextMessage textMessage = (TextMessage) message;

            StringBuffer sb = new StringBuffer();
            sb.append(textMessage.getText());
            sb.append("#");
            sb.append(amsg.getConsumerIdentifer());

            msgCounter++;
            String strMsgCounter = String.valueOf(msgCounter);
            ProducerMap.put(strMsgCounter, sb.toString());

        } catch (JMSException e) {
            //log.error("Unable to force deserialize the content", e);
        }
    }

    /**
     * Validates the result of the producing and consumption of messages by the server.
     * It checks for duplicate messages, message count and order.
     */
    protected synchronized void timerLoop() {
        System.out.println("MessagingSystemTest.timerLoop() * started * ");
        Map ProducerTextMap = new HashMap();
        Map currentProducerMap = null;
        String producerName = null;
        String msgBody = null;
        String consumerName = null;
        String mapKey = null;
        int expectedNoOfMessages = messageCount;
        boolean dowhile = true;

        while (dowhile) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //Retrieve the map containing the received messages data
            currentProducerMap = resetProducerMap();

            if (currentProducerMap.size() == 0) {
                dowhile = false;
            }

            //Put the map values to another map for parsing.
            for (int i = 1; i <= currentProducerMap.size(); i++) {
                String ProdMsg = (String) currentProducerMap.get(String.valueOf(i));
                producerName = ProdMsg.substring(0, ProdMsg.indexOf("#"));
                msgBody = ProdMsg.substring(ProdMsg.indexOf("#") + 1, ProdMsg.lastIndexOf("#"));
                consumerName = ProdMsg.substring(ProdMsg.lastIndexOf("#"), ProdMsg.length());

                if (isTopic) {
                    mapKey = consumerName + producerName;
                } else {
                    mapKey = producerName;
                }

                if (ProducerTextMap.containsKey(mapKey)) {
                    //Increment the counter value
                    Integer value = (Integer) ProducerTextMap.get(mapKey);
                    ProducerTextMap.put(mapKey, new Integer(value.intValue() + 1));
                } else {
                    //Put the Producer Name in the map
                    ProducerTextMap.put(mapKey, new Integer(1));
                }

                Integer messageCounter = (Integer) ProducerTextMap.get(mapKey);

                //Checks for duplicate messages.
                if (messageCounter.intValue() > expectedNoOfMessages) {
                    assertTrue("Should not have received duplicate messages!", messageCounter.intValue() <= expectedNoOfMessages);
                    if (messageCounter.intValue() > expectedNoOfMessages) {
                        System.out.println("Should not have received duplicate message!");
                    }
                    break;
                } else if (LAST_MESSAGE.equals(msgBody)) {

                    System.out.println("entered MsgBody.equals(LAST_MESSAGE)..." + mapKey +
                                       " " + messageCounter.intValue() +"=" + expectedNoOfMessages);

                    // Validates that the messages received is equal to the number
                    // of expected messages
                    if (messageCounter.intValue() != expectedNoOfMessages) {
                        System.out.println("entered messageCounter.intValue() != expectedNoOfMessages...");

                        // Checks for message order.
                        assertTrue("Should have received messages in order!", messageCounter.intValue() == expectedNoOfMessages);
                        if (messageCounter.intValue() != expectedNoOfMessages) {
                            System.out.println("Should have received messages in order!");
                        }
                        break;
                    } else if (currentProducerMap.size() == i) {
                        System.out.println("MessagingSystemTest.timerLoop() says system_test_pass!!!... ");
                        break;
                    }
                }
            }
        }

        testStillRunning = false;
        System.out.println("MessagingSystemTest.timerLoop() * ended * ");
    }

    /**
     * Returns the message entries and clears the map for another set
     * of messages to be processed.
     *
     * @return Map - messages to be processed.
     */
    protected synchronized Map resetProducerMap() {
        Map copy = Collections.synchronizedMap(new HashMap(ProducerMap));
        ProducerMap.clear();
        msgCounter = 0;

        return copy;
    }

    /*
     * Utility section
     */

    /**
     * Creates the connection to the broker.
     *
     * @param url            - broker url.
     * @param embeddedBroker - true if an embedded broker will be used.
     * @return Connection - broker connection.
     */
    private static Connection createConnectionFactory(String url,
                                                     boolean embeddedBroker) throws JMSException {
        //Used to create a session from the default MQ server ActiveMQConnectionFactory.
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);

        if (embeddedBroker) {
            factory.setUseEmbeddedBroker(true);
        }

        factory.setTurboBoost(true);
        ActiveMQConnection c = (ActiveMQConnection) factory.createConnection();

        c.getPrefetchPolicy().setQueuePrefetch(1000);
        c.getPrefetchPolicy().setQueueBrowserPrefetch(1000);
        c.getPrefetchPolicy().setTopicPrefetch(1000);
        c.getPrefetchPolicy().setDurableTopicPrefetch(1000);

        return c;
    }

    /**
     * Creates the connection session.
     *
     * @param connection   - broker connection.
     * @param isTransacted - true if the session will be session transacted.
     *                     otherwise the the session will be using auto acknowledge.
     * @return Session - connection session.
     */
    private static Session createSession(Connection connection,
                                        boolean isTransacted) throws JMSException {
        if (isTransacted) {
            return connection.createSession(true, Session.SESSION_TRANSACTED);
        } else {
            return connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        }
    }

    /**
     * Creates the session destination.
     *
     * @param session - connection session.
     * @param subject - destination name.
     * @param isTopic - true if the destination is a topic,
     *                otherwise the destination is a queue.
     * @return Destination - session destination.
     */
    private static Destination createDestination(Session session,
                                                String subject,
                                                boolean isTopic) throws JMSException {
        if (isTopic) {
            return session.createTopic(subject);
        } else {
            return session.createQueue(subject);
        }
    }

    /*
     * Unit test section
     */

    /**
     * Sets up the resources of the unit test.
     *
     * @throws Exception
     */
    protected void setUp() throws Exception {
        //Set up the broker
        createBroker();
    }

    /**
     * Clears up the resources used in the unit test.
     */
    protected void tearDown() throws Exception {
        //Shut down the broker
        destoryBroker();
    }

    /**
     * Executes the unit test by running the producers and consumers.
     * It checks for duplicate messages, message count and order.
     */
    protected void doTest() throws Exception {
        System.out.println("MessagingSystemTest.doTest() * start *");

        //Set up the consumers
        subscribe();

        System.out.println("MessagingSystemTest.doTest() after suscribe()...");

        //Set up the producers
        publish();

        System.out.println("MessagingSystemTest.doTest() after publish()...");

        //Run the test
        Thread timer = new Thread() {
            public void run() {
                timerLoop();
            }
        };
        timer.setPriority(Thread.MIN_PRIORITY);
        timer.start();

        while (testStillRunning) {
            try {
                if (Thread.currentThread() == timer) {
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("MessagingSystemTest.doTest() * end *");
    }

    /**
     * Sets up and starts the broker.
     */
    private void createBroker() throws Exception {
        broker = new BrokerContainerImpl("localhost");
        broker.addConnector(new BrokerConnectorImpl(broker, "vm://localhost", new DefaultWireFormat()));
        broker.setPersistenceAdapter(createPersistenceAdapter());
        broker.start();
    }

    /**
     * Closes the broker.
     */
    private void destoryBroker() throws Exception {
        if (broker != null) {
            broker.stop();
        }

        consumer = null;
        broker = null;
    }

    /**
     * Returns the persistence adapter.
     * Sets up the testing database to be used when the messages are persistent.
     * It attempts to recreate the tables everytime the test is executed.
     *
     * @return PersistenceAdapter - persistence adapter.
     */
    protected PersistenceAdapter createPersistenceAdapter() {
        EmbeddedDataSource ds = new EmbeddedDataSource();
        ds.setDatabaseName("testdb");
        if (!init) {
            ds.setCreateDatabase("create");
        }

        JDBCPersistenceAdapter persistenceAdapter = new JDBCPersistenceAdapter(ds, new DefaultWireFormat());

        if (!init) {
            persistenceAdapter.setDropTablesOnStartup(true);
        }

        init = true;

        return persistenceAdapter;
    }

    /**
     * Prints the test settings.
     *
     * @param strTestTitle - unit test name.
     */
    public void testParameterSettings(String strTestTitle) {
        System.out.println(strTestTitle);
        System.out.println("============================================================");
        System.out.println("Test settings:");
        System.out.println("isTopic=" + new Boolean(isTopic).toString());
        System.out.println("isPersistent=" + new Boolean(isPersistent).toString());
        System.out.println("isDurable=" + new Boolean(isDurable).toString());
        System.out.println("producerCount=" + producerCount);
        System.out.println("consumerCount=" + consumerCount);
        System.out.println("subjectCount=" + subjectCount);
        System.out.println("messageCount=" + messageCount);
        System.out.println("");
    }
}
TOP

Related Classes of org.activemq.usecases.SystemTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.