/*
* LoadRunner Java script. (Build: 763)
*
* Script Description: This script is used for all synchronous SOAP over JMS requests.
* It must be run on Windows load generators. It has only been tested with Java 1.5.
* Note that this client will be a little unrealistic. A real client probably creates
* 1 Connection and multipe Sessions. We will be creating multiple Connections (1 per
* virtual user), each with a single Session.
*
*/
import lrapi.lr;
import javax.jms.*;
import javax.naming.*;
import java.util.Hashtable;
import com.tibco.tibjms.naming.*;
import com.tibco.tibjms.*;
public class Actions
{
// JMS Connection properties
private final String providerContextFactory = "com.tibco.tibjms.naming.TibjmsInitialContextFactory";
private final String providerURL = "tcp://myloadtest.com.au:7333";
private final String connectionFactoryName = "MLT_QueueConnectionFactory";
//private final userName = ""; // To be used if authentication is implemented.
//private final password = "";
// Queues
private final String requestQueueName = "MyLoadTest.ServiceName.Request";
private final String responseQueueName = "MyLoadTest.ServiceName.Response";
// JMS Header properties
private final int jmsDeliveryMode = DeliveryMode.NON_PERSISTENT; // Note that this is the same value as the Driver.
private final long jmsExpiration = 1800000; // 30 minutes
private final int jmsPriority = 4;
private final String jmsMessageType = "BytesMessage"; // Note that the message type may only be BytesMessage or TextMessage (other message types not implemented in script).
//private final String jmsMessageType = "TextMessage";
// JMS SOAP properties
private final String SOAPJMS_targetService = "";
private final String SOAPJMS_bindingVersion = "";
private final String SOAPJMS_contentType = "";
private final String SOAPJMS_soapAction = "";
private final String SOAPJMS_isFault = "false";
private final String SOAPJMS_requestIRI = "";
private final String SOAPJMS_soapMEP = "http://www.w3.org/2003/05/soap/mep/request-response/";
// Connection-related variables.
private Context jndiContext = null;
private ConnectionFactory queueConnectionFactory = null;
private Queue requestQueue = null;
private Queue responseQueue = null;
private Connection queueConnection = null;
private Session queueSession = null;
private MessageProducer sender = null;
private MessageConsumer receiver = null;
// JMS Messages
private Message messageSend = null;
private Message messageRecv = null;
private String messageText = null; // the text of the received message.
// Milliseconds to wait for response.
private final int timeout = 60000;
// JMS Message ID
private String messageID = null;
// Selector used by MessageConsumer
private String messageSelector = null;
public int init() {
/*
Before performing any operation on a naming or directory service, you need to acquire an
initial context--the starting point into the namespace. This is because all methods on
naming and directory services are performed relative to some context. To get an initial
context, you must follow these steps.
1. Select the service provider of the corresponding service you want to access.
2. Specify any configuration that the initial context needs.
3. Call the InitialContext(in the API reference documentation) constructor.
*/
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, providerContextFactory);
env.put(Context.PROVIDER_URL, providerURL);
//env.put(Context.SECURITY_PRINCIPAL, userName);
//env.put(Context.SECURITY_CREDENTIALS, password);
jndiContext = new InitialContext(env);
} catch (NamingException e) {
System.out.println("Could not create JNDI context: " + e.toString());
lr.abort();
}
/*
Look up the needed data via JNDI.
1. Use JNDI to find a ConnectionFactory object.
2. Use JNDI to find a Destination object.
*/
try {
queueConnectionFactory = (QueueConnectionFactory) jndiContext.lookup(connectionFactoryName);
requestQueue = (Queue) jndiContext.lookup(requestQueueName);
responseQueue = (Queue) jndiContext.lookup(responseQueueName);
} catch (NamingException e) {
System.out.println("JNDI lookup failed: " + e.toString());
lr.abort();
}
/*
1. Use the ConnectionFactory to create a JMS Connection with message delivery inhibited.
2. Use the Connection to create a JMS Session.
3. Use the Session and the Destination to create the MessageProducers needed (the MessageConsumers are created at a later stage).
4. Tell the Connection to start delivery of messages.
*/
try {
queueConnection = queueConnectionFactory.createConnection();
queueSession = queueConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); // Note that session is not transacted.
sender = queueSession.createProducer(requestQueue);
queueConnection.start();
} catch (JMSException e) {
System.out.println("Could not create JMS Connection or Session: " + e.toString());
lr.abort();
}
return 0;
}//end of init
public int action() {
/*
Create a message to send.
1. Create a Message object (TextMessage or BytesMessage).
2. Set the JMS Header properties
2. Set the Message properties
3. Set the Message body
4. In case of Driver which expects synchronous response, populate the JMSReplyTo in the JMS Header
*/
try {
if (jmsMessageType.equals("BytesMessage")) {
messageSend = queueSession.createBytesMessage();
} else if (jmsMessageType.equals("TextMessage")) {
messageSend = queueSession.createTextMessage();
} else {
lr.error_message("Message types other than BytesMessage and TextMessage have not been implemented.");
lr.abort();
}
// Set JMS Header properties.
messageSend.setJMSDeliveryMode(jmsDeliveryMode);
messageSend.setJMSExpiration(jmsExpiration);
messageSend.setJMSPriority(jmsPriority);
messageSend.setJMSType(jmsMessageType);
messageSend.setJMSReplyTo(responseQueue);
// Set Message properties
messageSend.setStringProperty("SOAPJMS_targetService", SOAPJMS_targetService);
messageSend.setStringProperty("SOAPJMS_bindingVersion", SOAPJMS_bindingVersion);
messageSend.setStringProperty("SOAPJMS_contentType", SOAPJMS_contentType);
messageSend.setStringProperty("SOAPJMS_soapAction", SOAPJMS_soapAction);
messageSend.setStringProperty("SOAPJMS_isFault", SOAPJMS_isFault);
messageSend.setStringProperty("SOAPJMS_requestIRI", SOAPJMS_requestIRI);
messageSend.setStringProperty("SOAPJMS_soapMEP", SOAPJMS_soapMEP);
// Message body
if (jmsMessageType.equals("BytesMessage")) {
byte b[] = INV_BY_ID_SEND.getBytes();
((BytesMessage) messageSend).writeBytes(b,0,b.length);
} else if (jmsMessageType.equals("TextMessage")) {
((TextMessage) messageSend).setText(INV_BY_ID_SEND);
} else {
lr.error_message("Message types other than BytesMessage and TextMessage have not been implemented.");
lr.abort();
}
} catch (JMSException e) {
System.out.println("Exception thrown when creating message: " + e.toString());
lr.abort();
}
lr.rendezvous("send");
lr.start_transaction(transactionName);
// Send message.
try {
sender.send(messageSend);
} catch (JMSException e) {
System.out.println("Exception thrown when sending message: " + e.toString());
lr.abort();
}
/*
Create a MessageConsumer to receive the response for the message that was sent.
1. Get the JMSMessageID from the sent message (to be used in a message Selector).
2. Use the Session and the Destination to create a MessageConsumers with a message selector (filter).
*/
try {
messageID = messageSend.getJMSMessageID();
messageSelector = "JMSCorrelationID = '" + messageID + "'";
receiver = queueSession.createConsumer(responseQueue, messageSelector);
} catch (JMSException e) {
System.out.println("Exception thrown when creating MessageConsumer: " + e.toString());
lr.abort();
}
/*
Receive the message (wait for timeout period).
Note that if timeout period is reached, then it does not throw an exception, just returns null.
*/
try {
messageRecv = receiver.receive(timeout);
receiver.close(); // close the receiver (with the selector), or else the number of receivers in Tibco will increase with each iteration.
if (messageRecv instanceof BytesMessage) {
int messageLength = (int) ((BytesMessage)messageRecv).getBodyLength() ;
byte b[] = new byte[messageLength];
((BytesMessage)messageRecv).readBytes(b);
messageText = new String(b);
} else if (messageRecv instanceof TextMessage) {
messageText = ((TextMessage)messageRecv).getText();
} else if (messageRecv == null) {
lr.error_message("Message received is null. This indicates a timeout. Script timeout is: " + timeout);
lr.abort();
} else {
lr.error_message("Unexpected response message type. MessageReceived: " + messageRecv.toString());
lr.abort();
}
} catch (JMSException e) {
System.out.println("Exception thrown when receiving message: " + e.toString());
lr.abort();
}
// If received message does not match expected message, then fail the transaction.
if (!messageText.equals(INV_BY_ID_RECV)) {
lr.error_message("Received message does not match expected message: " + messageText);
}
lr.end_transaction(transactionName, lr.AUTO);
return 0;
}//end of action
public int end() {
// Close the session, and then close the connection
try {
queueSession.close();
queueConnection.close();
} catch (JMSException e) {
System.out.println("Exception thrown when closing session and connection: " + e.toString());
lr.abort();
}
return 0;
}//end of end
/*
* Here is an example of how a client might format a SOAP message requesting product information from a fictional warehouse
* web service. The client needs to know which product corresponds with the ID 827635:
*/
public static final String transactionName = "inventry_lookup_by_id";
public static final String INV_BY_ID_SEND =
"\n" +
" \n" +
" \n" +
" 827635\n" +
" \n" +
" \n" +
"";
public static final String INV_BY_ID_RECV =
"\n" +
" \n" +
" \n" +
" \n" +
" Toptimate 3-Piece Set\n" +
" 827635\n" +
" 3-Piece luggage set. Black Polyester.\n" +
" 96.50\n" +
" true\n" +
" \n" +
" \n" +
" \n" +
"";
}