/********************************************************* {COPYRIGHT-TOP} *** * Copyright 2016 IBM Corporation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the MIT License * which accompanies this distribution, and is available at * http://opensource.org/licenses/MIT ********************************************************** {COPYRIGHT-END} **/ package com.ibm.uk.hursley.perfharness.jms.r11; import java.util.logging.Level; import javax.jms.Message; import javax.jms.Queue; import javax.jms.TemporaryQueue; import com.ibm.uk.hursley.perfharness.Config; import com.ibm.uk.hursley.perfharness.Log; import com.ibm.uk.hursley.perfharness.WorkerThread; import com.ibm.uk.hursley.perfharness.jms.DestinationWrapper; /** * Puts a message to a queue then waits for a reply on another queue. Currently * the only use of correlation idenfiers is to keep using the same id for every * request (ie NOT to use the sent messageId of each request). This is much faster * for JMS applications. */ public final class Requestor extends JMS11WorkerThread implements WorkerThread.Paceable { @SuppressWarnings("unused") private static final String c = com.ibm.uk.hursley.perfharness.Copyright.COPYRIGHT; // IGNORE compiler warning protected Message inMessage = null; protected Message outMessage = null; protected String correlID = null; private static boolean tempQueues; private static boolean tempQueuePerMessage; public static void registerConfig() { Config.registerSelf( Requestor.class ); //We use temporary queues if no specific output queue specified tempQueues = Config.parms.getString("oq").length() == 0; //The current default is to use a temp queue per message //Its more performant to cache a temporary queue per thread/session tempQueuePerMessage = Config.parms.getBoolean("tqpm"); } /** * Constructor for JMSClientThread. * @param name */ public Requestor(String name) { super(name); } protected void buildJMSResources() throws Exception { super.buildJMSResources(); // Create message outMessage = msgFactory.createMessage(session, getName(), 0); // Set correlationID for this thread onto the cached message if (Config.parms.getBoolean("co") ) { correlID = msgFactory.setJMSCorrelationID(this, outMessage); } // Get destination pair if multiple are configured. int destID = destFactory.generateDestinationID(getThreadNum()); String iq = Config.parms.getString("iq"); String oq = Config.parms.getString("oq"); if (destID >= 0) { iq += String.valueOf(destID); oq += String.valueOf(destID); } // Open queues destProducer = jmsProvider.lookupQueue(iq, session).destination; Log.logger.log( Level.FINE, "Creating sender on {0}", getDestinationName(destProducer)); messageProducer = session.createProducer(destProducer); String selector = null; if (correlID != null) { StringBuffer sb = new StringBuffer("JMSCorrelationID='"); sb.append(correlID); sb.append("'"); selector = sb.toString(); } if (!tempQueues) { //Use permanent queues DestinationWrapper<Queue> consumerDestinationWrapper = jmsProvider.lookupQueue(oq, session); destConsumer = consumerDestinationWrapper.destination; String consumerDestinationName = consumerDestinationWrapper.name; Log.logger.log(Level.FINE, "Creating receiver on {0} selector:{1}", new Object[] {consumerDestinationName, selector}); messageConsumer = session.createConsumer(destConsumer, selector); } else if (!tempQueuePerMessage) { Log.logger.info("Using temporary reply queue per session"); //Use 1 temporary queue per session destConsumer = session.createTemporaryQueue(); Log.logger.log(Level.FINE, "Creating receiver on {0} temporary queue per thread", getDestinationName(destConsumer)); messageConsumer = session.createConsumer(destConsumer); } else { Log.logger.log(Level.FINE, "Using temporary reply queue per message"); } //Set the reply to field to be the output queue name outMessage.setJMSReplyTo(destConsumer); } public void run() { run(this, null); // call superclass generic method. } /* (non-Javadoc) * @see com.ibm.uk.hursley.perfharness.WorkerThread.Paceable#oneIteration() */ public final boolean oneIteration() throws Exception { if ((tempQueues) && (tempQueuePerMessage)) { // Close temporary queue if (messageConsumer != null) messageConsumer.close(); if (destConsumer != null) { ((TemporaryQueue) destConsumer).delete(); } // Open new temporary queue destConsumer = session.createTemporaryQueue(); messageConsumer = session.createConsumer(destConsumer); outMessage.setJMSReplyTo(destConsumer); } startResponseTimePeriod(); messageProducer.send(outMessage, deliveryMode, priority, expiry); if (transacted) session.commit(); if ((inMessage = messageConsumer.receive(timeout))!= null) { if (transacted) session.commit(); incIterations(); } else { throw new Exception("No response to message (\nID: "+outMessage.getJMSMessageID()+ "\nCorrId: " + outMessage.getJMSCorrelationID() +")"); } return true; } }