Search This Blog

Thursday, February 4, 2016

JMeter Custom Soap Sampler

This post is dedicated to a custom JMeter SOAP sampler having support to enclose attachments to the request

This functionality was not present in standard JMeter binary (v2.13) so had to be created.

The Maven project with source code and already built JAR is in Github under : Custom Soap Sampler Java Project

The plugin UI looks like that:


The sampler appears in sampler list as 'Custom SOAP Sampler'. It can work with one or more attachments (multiple attachments) and also without attachments, this way behaving as normal Soap sampler. As seen in the screenshot it has the following features:
- drop-down for SOAP protocol version with values 1_1 and 1_2
- URL - endpoint for the request
- checkbox 'Treat selected attachment as response'. If this is enabled then for services that in response return attachments the assertions can be made. So if the option is enabled there is a choice to locate the proper attachment in response by content type or content ID
- fields for adding attachment: browser to locate the file, checkbox 'Use relative paths', Content ID, type (values: resource, value). If resource is added then the content of the file is loaded as stream to the attachment object. If value is selected then the value from text is taken 'as is'.
- content-type. Values: auto, text/plain, text/xml, text/html, application/xml, application/gzip. If other types are required then the project needs to be updated and rebuilt.
- buttons to Add and Remove attachments

Other than that the sampler behaves just as other ordinary sampler.
Programmatic use of the plugin in JSR223 PreProcessor, for example to add, delete attachments from the code because there is exposed a getter: 'getAttachmentDefinition()':
//add attachments 
ArrayList attList = new ArrayList(); 
def att1 = ctx.getCurrentSampler().getAttachmentDefinition();
att1.attachment = new File(pathToFile); 
att1.contentID ="someContentID"; 
att1.contentType="application/xml"; //one of selections from the dropdown 
att1.type=1; //1 means resource, 2 means variable
attList.add(att1);
//confirm (set) adding all attachments 
ctx.getCurrentSampler().setAttachments(attList);
//set request body
ctx.getCurrentSampler().setXmlData(xmlRequest);

8 comments:

  1. Great idea. However, I tried copying the jar to ${JMETER}/lib/ext and restarting JMeter. I do not see it in the list of samplers. This is the first time I've tried adding a custom sampler. Am I missing a step?

    ReplyDelete
    Replies
    1. I am using JMeter 2.13 r1665067, java 1.8. I put in the mentioned location the CustomSoapSampler-1.1-SNAPSHOT.jar (size 88,3kB). Then I added just thread group to have list of samplers visible. Then on the list there is Custom SOAP Sampler.

      Delete
    2. you need to use the plugin manager but first you have to download jmeter plugin manager jar file from the google and paste the jar file in lib/ext folder then restart your jmeter in option menu button you will get the option in last plugin manager click and add and remove plugins there

      Delete
  2. Be sure to use a java 8 runtime, I've tested with JMeter 2.9 and works fine. Thx to Lucas for this plugin, nice work.

    ReplyDelete
  3. Thanks for valid remark. I attached the information on Github about it, in wiki. Indeed I am using Java 1.8 only, so didn't do compatibility tests.
    In all cases someone who wants to use the plugin in 1.7 version can load sources and compile with previous JDK.
    I added 1.7 built JAR in target directory on GitHub.

    ReplyDelete
  4. Hello Lucas,
    I'm using Jmeter to send a SOAP request to a WCF Service with MTOM encoding , I need to attach a file to the request. Thanks to your plugin, it attaches a file to the SOAP Request, but it always sets the Request's content-type to "text/xml" instead of using the parameters specified in the Http Header Manager template. I've looked at your code, I'm new to Java & I'd like to know if there's a way to force the soapconnection to use the Header Manager.

    The request type expected by the server is application/xop+xml.
    So I'm unable to use the plugin to do what I need, any help will be much appreciated.

    ReplyDelete
    Replies
    1. I have looked a bit and it makes matter a bit more complicated. Probably this is not just only change of content-type. I think content type changes when MTOM support is turned on in the java code. It will take me some time to find out how to enhance the sampler. I need to look in SoapUI sources to find how they do that, because on the Internet there are no examples that could help.

      Reading the Http Header Manager is separate thing, but here I also am not sure if just changing the content-type is the solution.

      Delete
  5. I spent some time on it and here are the results (not optimistic):
    - even though I found a way to utilize values stored in HTTP Header Manager it doesn't bring any value in Soap messaging. In pure http requests it does in fact. The "type" in Content-Type is set automatically if MTOM is enabled, the same way there is a difference in Soap 1_1 and Soap 1_2 protocol. If we set the MIME header it is further overriden anyway, and "type: seems not possible to set.
    - the task is a bit overwhelming for my timeslot. Look at the page: http://www.codejava.net/java-ee/web-services/using-mtom-to-optimize-binary-data-transfer-with-jax-ws-web-services there is explained how to create Soap MTOM client. Wsimport is required to generate classes based on wsdl. If you have any outcome then I would like to have a look as well.

    Code snippet for using manager below:

    MimeHeaders headers = message.getMimeHeaders();

    if (getHeaderManager() != null) {
    // headerManager was set, so let's set the connection
    // to use it.
    HeaderManager mngr = getHeaderManager();
    int headerSize = mngr.size();
    for (int idx = 0; idx < headerSize; idx++) {
    Header hd = mngr.getHeader(idx);
    headers.addHeader(hd.getName(), hd.getValue());
    //log.info("Header Name: " + hd.getName() + " header value: " + hd.getValue());
    }
    }

    Java Imports:
    import org.apache.jmeter.protocol.http.control.Header;
    import org.apache.jmeter.protocol.http.control.HeaderManager;
    import org.apache.jmeter.protocol.http.sampler.HTTPSampler;

    So you need to add dependency for ApacheJMeter_http with exclusion for commons-math3 and commons-pool2.

    ReplyDelete