Showing posts with label SOA protocol. Show all posts
Showing posts with label SOA protocol. Show all posts

Friday, December 30, 2011

Loadrunner SOAP over JMS script for Websphere MQ

Question:
How to submit a SOAP over JMS request to Websphere MQ using LoadRunner SOA protocol?

Solution:
Prerequisite
  1. JMS Queue details
  2. Websphere MQ Client installed (if not installed, instructions are below)
  3. Websphere MQ jar files installed (if not installed, instructions are below)
  4. JDK installed (if not installed, instructions are below)

JMS Queue Details
Depending on which queue(s) you want to send and receive a message from as well as the MQ architecture design, you will require following MQ information from your Websphere MQ Admin.
  • HostName
  • Channel
  • Port
  • Queue Manager
  • Input Queue
  • Output Queue
  • Queue Connection Factory
  • Username and password

For example, in my case, to send a message to an Input Queue, following information was required:
  • HostName – xxx.xxx.xxx
  • Channel - ICF.DEF.SVRCONN
  • Port - 1414(might be different)
  • Queue Manager - Not Required
  • Input Queue - Input_queue_name
  • Output Queue - Not Required
  • Queue Connection Factory - qcf
  • Username and password - Not required
Webshere MQ Jar files
  1. Install JAVA JDK on your local machine
  2. Copy MQ jar files into the JDK...->Java ->jre-> ext folder. You will need to get these jar files from your Webpshere MQ admin
  3. Also, since we are using fscontext as initial context factory, you will need to download and save fscontext and providerutil.jar files in the above mentioned folder
How to create JNDI binding
  1. Install Websphere MQ Client application on your local machine.
  2. Navigate to the location where JMSAdmin.config file is located and open it. We are going to select a context factory to use and path where to create the binding file. In my case this file is located at C:\Program Files (x86)\IBM\WebSphere MQ\Java\bin Update and save the file with following details:
  3. INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory PROVIDER_URL=file:/C:/JNDI
  4. Create a new qm.scp file (make sure this file is in the same folder as JMSAdmin.bat file) and put there the MQ details. The .scp file will look like this:
  5. DEFINE QCF(qcf) tran(client) chan(ICF.DEF.SVRCONN) host(xxx.xxx.xxx) port(1414) DISPLAY QCF(qcf) DEFINE Q(Input_queue) QUEUE(Input_queue) DISPLAY Q(Input_queue) end
  6. Create the JNDI folder on your C drive. This is where your binding file will automatically be saved.
  7. Navigate to “...\WebSphere MQ\Java\bin” and edit JMSAdmin.bat by replacing “java” text with the full java path incase it is not already defined in your System environment settings.
  8. Navigate to Websphere MQ Java bin folder via the command prompt and execute the JMSAdmin Tool (JMSAdmin. Bat file) with qm.scp as the parameter. This will generate a .bindings file in the JNDI folder automatically.



  9. You will see something like this when JMSAdmin bat application is executed.
    Cool, JNDI binding is done.
Creating a Webservices Loadrunner Script
  1. Open up a new web services script.
  2. Press F4 to Navigate to Run-time setting and update the following fields in JMS->Advanced option:
  3. -JVM Home: JAVA path
    -JNDI initial context factory: com.sun.jndi.fscontext.RefFSContextFactory
    -JNDI provider URL: file:/C:/JNDI/
    -JMS connection factory: QCF name
  4. Now you are ready to create your MQ script.
  5. You can then use Web Services jms_set_general_property, jms_send_message_queue, jms_set_message_property and jms_receive_message_property functions.
NOTE: JMS Bindings Extensions are not supported in Loadrunner 11.

Sunday, December 12, 2010

LoadRunner script for SOAP over JMS to test TIBCO Middleware

Following is a script that I created to test SOAP message over JMS using SOA protocol. I would suggest using JAVA protocol to script SOAP over JMS rather than SOA protocol. It provides greater flexibility than SOA protocol. There is a good blog written by Stuart Moncrieff and I suggest reading it if you are planning on using JAVA protocol to test SOAP message over JMS. I don't want to reinvent the wheel by writing a new code. You will require some modification to the Java script. For example, if you are using username and password, you will need to pass these values into the createConnection function.

It will look like this(It is modification of Stuart's code):
queueConnection = queueConnectionFactory.createConnection(username,password);

Before you starting writing your script using either SOA or Java protocol, you will need few files and information and they are:

1: Tibjms.jar -compulsory
2: Java 1.6 -compulsory (older version may work, but I tested against 1.6)
3: JNDI initial context factory -compulsory
4: JNDI provider URL - compulsory
5: JMS connection factory - compulsory
6: JMS security credentials - compulsory, if implemented
7: JMS security principal - compulsory, if implemented
8: Request queue name - required, if you are sending message to the request queue
9: Receive queue name - required, if you are receiving message from the receive queue

You will need to get information for points 3-9 from your JMS administrator or whoever may have implemented JMS.

SOA Protocol script
The script was meant to test TIBCO with JMS Fire and forget pattern. No response was expected from TIBCO because the test was to find out whether the request queue is able to handle the expected requests per hour. Therefore, I did not require Receive queue name details.

Following details were set in the Run-time setting-> JMS advance option. For points 2-5, I have used dummy names.

1:JNDI initial context factory :com.tibco.tibjms.naming.TibjmsInitalContextFactory //testing TIBCO JMS. This is a dropdown option and might change depending on what you are testing.
2:JNDI provider URL :tibjmsnaming://tim.tom.au:12345
3:JMS connection factory :QueueConnectionFactory
4:JMS security credentials :jmsPerTester
5:JMS security principal :jmsPerTester

SOAP request
char *EmployeeDetails=
""
""
"Tom"
""
"110 Latrobe st"
"Melbourne"
"3000"
"Vic"
"1234567890";

Action()
{
long currentTime=1; 
char *ExpiryTime; 

//get current time in seconds
currentTime=time(¤tTime); 

currentTime = currentTime + 500000; 

ExpiryTime = (char*)malloc(20, sizeof(char)); 

//save current time value into ExpiryTime variable. This is how long the message should be valid for
sprintf(ExpiryTime,"%d",currentTime); 

//Save EmployeeDetails SOAP request into LR parameter
lr_save_string(EmployeeDetails,"EmployeeDetailSOAP_param");

//lr_output_message ("%s",lr_eval_string ("{EmployeeDetailSOAP_param}"));


//setup JMS properties
jms_set_general_property("msgJMSMessageType","JMS_MESSAGE_TYPE","BytesMessage"); //Change 'ByteMessage' to 'TextMessage', if you are sending as a text
jms_set_message_property("msgJMSExpiration","JMSExpiration", ExpiryTime); 
jms_set_message_property("msgJMSMessageID","JMSMessageID", "-JMSMessageID-");
jms_set_message_property("msgJMSPriority","JMSPriority", "4"); 
jms_set_message_property("msgJMSRedelivered","JMSRedelivered", "false");
jms_set_message_property ("msgJMSDeliveryMode","JMSDeliveryMode","2");
jms_set_message_property("msgJMSCorrelationID", "JMSCorrelationID", "VuserID-{VUserID}_{TimeDate}"); //VUserID & TimeDate are loadrunner parameters


//sending message
lr_start_transaction ("SoapRequest"); 
jms_send_message_queue("step 1: Sending SOAP message","{EmployeeDetailSOAP_param}", "EmployeeDetail.request.queue.com.au");  


//Receive message
/*jms_receive_message_queue("step 2: Received SOAP message", "EmployeeDetail.response.queue.com.au"); 
lr_message(lr_eval_string("{JMS_message}")); */

lr_end_transaction ("SoapRequest",LR_AUTO);

free(ExpiryTime);
return  0;
}

Note:In the above code I am using lr_start_transaction function to capture total number of requests posted to the queue. It does not measure the response time. This is because we are not expecting any response due to Fire and Forget pattern.

You could use file(/char array) for the SOAP request as well as parametrize the SOAP content. I will leave this as an exercise for anyone who wants to try it out.

Thursday, November 25, 2010

Common error messages for SOAP over JMS using SOA protocol in LoadRunner 11.0

While testing SOAP over JMS using SOA protocol in LoadRunner, you may come across different error messages if you have not configured JMS parameters correctly in LoadRunner. Below are some common error that you may encounter and what could the cause of these error messages.

1: Wrong queue name

Error: Failed to send message ...SOAP details go here...to test.test.test.address.update due to the following exception : javax.naming.NameNotFoundException: Name not found: 'test.test.test.address.update'
javax.naming.NameNotFoundException: Name not found: 'test.test.test.address.update'
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:713)
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:489)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at com.mercury.ws.jms.SessionManagerImpl.getQueue(SessionManagerImpl.java:94)
at com.mercury.ws.jms.JMSSupportImpl.sendMessageQueue(JMSSupportImpl.java:96)
at com.mercury.ws.jms.JMSBridge.send_message_queue(JMSBridge.java:43)



2: Incorrect port number for your JNDI provider URL

Error: Failed to set property name JMS_MESSAGE_TYPE value BytesMessage due to the following exception : javax.naming.InvalidNameException: Supplied URL (xxxxx:342434) contains an invalid port number: Invalid port number
javax.naming.InvalidNameException: Supplied URL (xxxxx:342434) contains an invalid port number: Invalid port number
at com.tibco.tibjms.naming.TibjmsNamingEnvUtil._parseURL(TibjmsNamingEnvUtil.java:184)
at com.tibco.tibjms.naming.TibjmsNamingEnvUtil.parseURL(TibjmsNamingEnvUtil.java:263



3: You may get following error message incase you have entered incorrect credentials (username/&password)


Error: Failed to set property name JMS_MESSAGE_TYPE value BytesMessage due to the following exception : javax.naming.AuthenticationException: Not permitted: invalid name or password [Root exception is javax.jms.JMSSecurityException: invalid name or password]
javax.naming.AuthenticationException: Not permitted: invalid name or password [Root exception is javax.jms.JMSSecurityException: invalid name or password]
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:668)
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:489)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at com.mercury.ws.jms.ConnectionManagerImpl.initialize(ConnectionManagerImpl.java:99)
...5 more



4: You may get following error message incase you have setup an Incorrect JNDI URL

Error: Failed to set property name JMS_MESSAGE_TYPE value BytesMessage due to the following exception : javax.naming.ServiceUnavailableException: Failed to query JNDI: Failed to connect to the server at tcp://xxxx.xxx.xx:12345 [Root exception is javax.jms.JMSException: Failed to connect to the server at tcp://xxxx.xxx.xx:12345]
javax.naming.ServiceUnavailableException: Failed to query JNDI: Failed to connect to the server at tcp://xxxx.xxx.xx:12345 [Root exception is javax.jms.JMSException: Failed to connect to the server at tcp://xxxx.xxx.xx:12345]
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:669)
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:489)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
... 5 more



5: You may get following errors incase you haven’t set up ConnectionFactory or it is incorrect.


No ConnectionFactory
Error:Failed to set property name JMS_MESSAGE_TYPE value BytesMessage due to the following exception : java.lang.ClassCastException: com.tibco.tibjms.naming.TibjmsContext
java.lang.ClassCastException: com.tibco.tibjms.naming.TibjmsContext
at com.mercury.ws.jms.ConnectionManagerImpl.initialize(ConnectionManagerImpl.java:109)
at com.mercury.ws.jms.JMSSupportImpl.initialize(JMSSupportImpl.java:28)
at com.mercury.ws.jms.JMSBridge.init_jms(JMSBridge.java:154)


Incorrect ConnectionFactory Name
Error:Failed to set property name JMS_MESSAGE_TYPE value BytesMessage due to the following exception : javax.naming.NameNotFoundException: Name not found: 'xxxxQueueConnectionFactory'
javax.naming.NameNotFoundException: Name not found: 'xxxxQueueConnectionFactory'
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:713)
at com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:489)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at com.mercury.ws.jms.ConnectionManagerImpl.initialize(ConnectionManagerImpl.java:99)
at com.mercury.ws.jms.JMSSupportImpl.initialize(JMSSupportImpl.java:28)
at com.mercury.ws.jms.JMSBridge.init_jms(JMSBridge.java:154)



6: You may get following error message if you have Incorrect Initial Context Factory name (For example, it is expected that you use com.tibco.tibjms.naming.tibjmsinitialcontextfactory but by mistake you selected weblogic.jndi.WLinitialContextFactory from InitialContectFactory dropdown list in LR)

Error: Failed to set property name JMS_MESSAGE_TYPE value BytesMessage due to the following exception : javax.naming.NamingException: Cannot parse url: tibjmsnaming://xxxx.xxx.xx:12345 [Root exception is java.net.MalformedURLException: Not an LDAP URL: tibjmsnaming://xxxx.xxx.xx:12345]
javax.naming.NamingException: Cannot parse url: tibjmsnaming://xxxx.xxx.xx:12345 [Root exception is java.net.MalformedURLException: Not an LDAP URL: tibjmsnaming://xxxx.xxx.xx:12345]
at com.sun.jndi.ldap.LdapURL.(LdapURL.java:77)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:146)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:247)
at javax.naming.InitialContext.init(InitialContext.java:223)
... 11 more



Let me know if you encounter other error messages using LoadRunner or any other tool for SOAP over JMS.