package org.openamq.requestreply1; import org.apache.log4j.Logger; import org.openamq.AMQException; import org.openamq.client.AMQConnection; import org.openamq.client.AMQQueue; import org.openamq.client.AMQDestination; import org.openamq.jms.MessageConsumer; import org.openamq.jms.MessageProducer; import org.openamq.jms.Session; import javax.jms.*; import java.net.InetAddress; import java.net.UnknownHostException; /** * A client that behaves as follows: * <ul><li>Connects to a queue, whose name is specified as a cmd-line argument</li> * <li>Creates a temporary queue</li> * <li>Creates messages containing a property that is the name of the temporary queue</li> * <li>Fires off a message on the original queue and waits for a response on the temporary queue</li> * </ul> * */ public class ServiceRequestingClient { private static final Logger _log = Logger.getLogger(ServiceRequestingClient.class); private static final String MESSAGE_DATA_BYTES = "jfd ghljgl hjvhlj cvhvjf ldhfsj lhfdsjf hldsjfk hdslkfj hsdflk "; private String MESSAGE_DATA; private AMQConnection _connection; private Session _session; private long _averageLatency; private int _messageCount; private volatile boolean _completed; private AMQDestination _tempDestination; private MessageProducer _producer; private Object _waiter; private static String createMessagePayload(int size) { _log.info("Message size set to " + size + " bytes"); StringBuffer buf = new StringBuffer(size); int count = 0; while (count < size + MESSAGE_DATA_BYTES.length()) { buf.append(MESSAGE_DATA_BYTES); count += MESSAGE_DATA_BYTES.length(); } if (count < size) { buf.append(MESSAGE_DATA_BYTES, 0, size - count); } return buf.toString(); } private class CallbackHandler implements MessageListener { private int _expectedMessageCount; private int _actualMessageCount; private long _startTime; public CallbackHandler(int expectedMessageCount, long startTime) { _expectedMessageCount = expectedMessageCount; _startTime = startTime; } public void onMessage(Message m) { if (_log.isDebugEnabled()) { _log.debug("Message received: " + m); } try { if (m.propertyExists("timeSent")) { long timeSent = Long.parseLong(m.getStringProperty("timeSent")); long now = System.currentTimeMillis(); if (_averageLatency == 0) { _averageLatency = now - timeSent; _log.info("Latency " + _averageLatency); } else { _log.info("Individual latency: " + (now - timeSent)); _averageLatency = (_averageLatency + (now - timeSent)) / 2; _log.info("Average latency now: " + _averageLatency); } } } catch (JMSException e) { _log.error("Error getting latency data: " + e, e); } _actualMessageCount++; if (_actualMessageCount % 1000 == 0) { _log.info("Received message count: " + _actualMessageCount); } if (_actualMessageCount == _expectedMessageCount) { _completed = true; notifyWaiter(); long timeTaken = System.currentTimeMillis() - _startTime; _log.info("Total time taken to receive " + _expectedMessageCount + " messages was " + timeTaken + "ms, equivalent to " + (_expectedMessageCount / (timeTaken / 1000.0)) + " messages per second"); try { _connection.close(); _log.info("Connection closed"); } catch (JMSException e) { _log.error("Error closing connection"); } } } } private void notifyWaiter() { if (_waiter != null) { synchronized (_waiter) { _waiter.notify(); } } } public ServiceRequestingClient(String brokerHosts, String clientID, String username, String password, String vpath, String commandQueueName, final int messageCount, final int messageDataLength) throws AMQException { _messageCount = messageCount; MESSAGE_DATA = createMessagePayload(messageDataLength); try { createConnection(brokerHosts, clientID, username, password, vpath); _session = (Session) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); AMQQueue destination = new AMQQueue(commandQueueName); _producer = (MessageProducer) _session.createProducer(destination); _producer.setDisableMessageTimestamp(true); _producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); _tempDestination = new AMQQueue("TempResponse" + Long.toString(System.currentTimeMillis()), true); MessageConsumer messageConsumer = (MessageConsumer) _session.createConsumer(_tempDestination, 100, true, true, null); //Send first message, then wait a bit to allow the provider to get initialised TextMessage first = _session.createTextMessage(MESSAGE_DATA); first.setJMSReplyTo(_tempDestination); _producer.send(first); try { Thread.sleep(1000); } catch (InterruptedException ignore) { } //now start the clock and the test... final long startTime = System.currentTimeMillis(); messageConsumer.setMessageListener(new CallbackHandler(messageCount, startTime)); } catch (JMSException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } /** * Run the test and notify an object upon receipt of all responses. * @param waiter the object that will be notified * @throws JMSException */ public void run(Object waiter) throws JMSException { _waiter = waiter; _connection.start(); for (int i = 1; i < _messageCount; i++) { TextMessage msg = _session.createTextMessage(MESSAGE_DATA + i); msg.setJMSReplyTo(_tempDestination); if (i % 1000 == 0) { long timeNow = System.currentTimeMillis(); msg.setStringProperty("timeSent", String.valueOf(timeNow)); } _producer.send(msg); } _log.info("Finished sending " + _messageCount + " messages"); } public boolean isCompleted() { return _completed; } private void createConnection(String brokerHosts, String clientID, String username, String password, String vpath) throws AMQException { _connection = new AMQConnection(brokerHosts, username, password, clientID, vpath); } /** * @param args argument 1 if present specifies the name of the temporary queue to create. Leaving it blank * means the server will allocate a name. */ public static void main(String[] args) { if (args.length < 6) { System.err.println( "Usage: ServiceRequestingClient <brokerDetails - semicolon separated host:port list> <username> <password> <vpath> <command queue name> <number of messages> <message size>"); } try { int messageDataLength = args.length > 6 ? Integer.parseInt(args[6]) : 4096; InetAddress address = InetAddress.getLocalHost(); String clientID = address.getHostName() + System.currentTimeMillis(); ServiceRequestingClient client = new ServiceRequestingClient(args[0], clientID, args[1], args[2], args[3], args[4], Integer.parseInt(args[5]), messageDataLength); Object waiter = new Object(); client.run(waiter); synchronized (waiter) { while (!client.isCompleted()) { waiter.wait(); } } } catch (UnknownHostException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (Exception e) { System.err.println("Error in client: " + e); e.printStackTrace(); } } }