spinning10 / JMeterSoapSampler

JMeter Soap Sampler with support to attachments
10 stars 8 forks source link

Exception thrown when trying to empty list of registered attachments #3

Closed Sil68 closed 7 years ago

Sil68 commented 7 years ago

I'm trying to create a groovy-based pre-processor (JSR223PreProcessor) for *Custom SOAP Sampler plugin, which is intended to cover to following tasks:

After some quite extensive research on the net--I'm completely new to whole groovy, java, jmeter topic--, I managed to assemble the groovy script shown below.

    // read data from csv input file
    ArrayList recLst = new ArrayList();
    String fldsep = vars.get("fldsep");
    String fldhd = vars.get("fldhd");

    new File(vars.get("indat")).eachLine('UTF-8') {
        if ((it != null) && (fldhd != null) && (!it.trim().equals(fldhd.trim()))) {
            recLst.add(it.trim());
        } // if
    } // File.eachLine

    // extract relevant parts and feed into Custom SOAP Sampler (registered attachments)
    // csv format:  TMSTMP;PRODID;TENID;FNAM;MDAT
    if (recLst.size() > 0) {
        // empty current attachment list
        ArrayList oldAtts = ctx.getCurrentSampler().getAttachments();

        if (oldAtts.size() > 0) {
            for (attDef in oldAtts) {
                attDef.attachment = null; 
                attDef.contentID = null;
                attDef.contentType = null;
                attDef.type = null;
            } // for
        } // if

        // create new attachment list
        ArrayList newAtts = new ArrayList();

        for (rec in recLst) {
            String[] flds = rec.split(fldsep);

            def attDef = ctx.getCurrentSampler().getAttachmentDefinition();
            attDef.attachment = new File(flds[3]); 
            attDef.contentID = "flds[0]"; 
            attDef.contentType = "application/pdf"; // one of selections from the dropdown (no PDF listed there)
            attDef.type = 1;                        // 1 = resource, 2 = variable

            newAtts.add(attDef);
        } // for

        if (newAtts.size() > 0) {
            ctx.getCurrentSampler().setAttachments(newAtts);
        } // if
    } // if

In a previous post I was faced with an issue with BlazeMeter's step-by-step-debugger plugin, which I resolved by not using it. Now another challenge popped into existence.

Executing the test plan results in an error message, reading

    Unable to update attachment references, see log files for details.

Having a peek into the jmeter.log file reveals

    NUL NUL NUL NUL NUL NUL NUL NUL...
    ...NUL NUL NUL NUL...
    ...
    2017/04/07 09:14:47 INFO  - jmeter.engine.StandardJMeterEngine: Running the test! 
    2017/04/07 09:14:47 INFO  - jmeter.samplers.SampleEvent: List of sample_variables: [] 
    2017/04/07 09:14:48 INFO  - jmeter.gui.util.JMeterMenuBar: setRunning(true,*local*) 
    2017/04/07 09:14:48 INFO  - jmeter.engine.StandardJMeterEngine: Starting ThreadGroup: 1 : Number of Users (single key) 
    2017/04/07 09:14:48 INFO  - jmeter.engine.StandardJMeterEngine: Starting 1 threads for group Number of Users (single key). 
    2017/04/07 09:14:48 INFO  - jmeter.engine.StandardJMeterEngine: Thread will continue on error 
    2017/04/07 09:14:48 INFO  - jmeter.threads.ThreadGroup: Starting thread group number 1 threads 1 ramp-up 1 perThread 1000.0 delayedStart=false 
    2017/04/07 09:14:48 INFO  - jmeter.threads.ThreadGroup: Started thread group number 1 
    2017/04/07 09:14:48 INFO  - jmeter.engine.StandardJMeterEngine: All thread groups have been started 
    2017/04/07 09:14:48 INFO  - jmeter.threads.JMeterThread: Thread started: Number of Users (single key) 1-1 
    2017/04/07 09:14:48 INFO  - jmeter.services.FileServer: Stored: /media/sf_Projects/tstprj/archive/tstdoc.csv 
    2017/04/07 09:14:48 ERROR - jmeter.modifiers.JSR223PreProcessor: Problem in JSR223 script JSR223 PreProcessor javax.script.ScriptException: javax.script.ScriptException: java.lang.IllegalArgumentException: Can not set int field com.jmeter.protocol.soap.control.gui.AttachmentDefinition.type to null value
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155)
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
        at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:220)
        at org.apache.jmeter.modifiers.JSR223PreProcessor.process(JSR223PreProcessor.java:42)
        at org.apache.jmeter.threads.JMeterThread.runPreProcessors(JMeterThread.java:798)
        at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:453)
        at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:418)
        at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:249)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: javax.script.ScriptException: java.lang.IllegalArgumentException: Can not set int field com.jmeter.protocol.soap.control.gui.AttachmentDefinition.type to null value
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:346)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:152)
        ... 8 more
    Caused by: java.lang.IllegalArgumentException: Can not set int field com.jmeter.protocol.soap.control.gui.AttachmentDefinition.type to null value
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
        at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80)
        at java.lang.reflect.Field.set(Field.java:764)
        at org.codehaus.groovy.reflection.CachedField.setProperty(CachedField.java:74)
        at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2669)
        at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3747)
        at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:199)
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:484)
        at Script13.run(Script13.groovy:33)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:343)
        ... 9 more
    2017/04/07 09:14:49 ERROR - com.jmeter.protocol.soap.sampler.CustomSOAPSampler: Caught exception while updating attachments javax.xml.soap.SOAPException: InputStream does not represent a valid SOAP 1.2 Message
        at com.sun.xml.internal.messaging.saaj.soap.ver1_2.SOAPPart1_2Impl.createEnvelopeFromSource(SOAPPart1_2Impl.java:72)
        at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:128)
        at com.jmeter.protocol.soap.sampler.CustomSOAPSampler.updateAttachmentReferences(CustomSOAPSampler.java:448)
        at com.jmeter.protocol.soap.sampler.CustomSOAPSampler.sample(CustomSOAPSampler.java:256)
        at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:475)
        at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:418)
        at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:249)
        at java.lang.Thread.run(Thread.java:745)
    2017/04/07 09:14:51 INFO  - jmeter.threads.JMeterThread: Stopping Thread: org.apache.jorphan.util.JMeterStopThreadException: Unable to update attachment references 
    2017/04/07 09:14:51 INFO  - jmeter.threads.JMeterThread: Stop Thread detected by thread: Number of Users (single key) 1-1 
    2017/04/07 09:14:51 INFO  - jmeter.threads.JMeterThread: Thread finished: Number of Users (single key) 1-1 
    2017/04/07 09:14:51 INFO  - jmeter.engine.StandardJMeterEngine: Notifying test listeners of end of test 
    2017/04/07 09:14:51 INFO  - jmeter.services.FileServer: Close: /media/sf_Projects/tstprj/archive/tstdoc.csv 
    2017/04/07 09:14:51 INFO  - jmeter.gui.util.JMeterMenuBar: setRunning(false,*local*) 

Apparently the approach taken to empty the list of currently registered attachments is leading to this kind of error, which now is begging the question as how to implement this is a correct fashion (where are these NUL entries coming from, which are making up apprximately 95% of the whole log file?).

One tackled, another one to go..

My setup comprises:

Sample input csv file

    TMSTMP;PRODID;TENID;FNAM;MDAT
    '20170406112044044970077';'PROD01';'TENANT03';'/media/sf_Projects/tstprj/archive/tstdoc/tstdoc-00000.pdf';'<?xml version=1.0 encoding=UTF-8?><tstpfx:metainformation xmlns:tstpfx=http://my.host.local/tstprj/metainformation_v2.xsd id=000000069496>meta data #01</tstpfx:metainformation>
    '
    '20170406112047030620037';'PROD02';'TENANT01';'/media/sf_Projects/tstprj/archive/tstdoc/tstdoc-00001.pdf';'<?xml version=1.0 encoding=UTF-8?><tstpfx:metainformation xmlns:tstpfx=http://my.host.local/tstprj/metainformation_v2.xsd id=000000069496>meta data #02</tstpfx:metainformation>
    '

This file is getting read twice: (1) by the JSR223 pre-processor to build the attachment list; (2) by the Custom SOAP Sampler, which subsequently iterates over each entry of this file, and passes the relevant bits & bobs to the SOAP Envelop

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tstprj="http://my.host.local/">
       <soapenv:Header/>
       <soapenv:Body>
          <tstprj:archive>
             <product>${PRODID}</product>
             <tenant>${TENID}</tenant>
             <filename>${FNAM}</filename>
             <metadata>${MDAT}</metadata>
             <content>cid:${TMSTMP}</content>
          </tstprj:archive>
       </soapenv:Body>
    </soapenv:Envelope>
spinning10 commented 7 years ago

Like I commented in previous your issue the way of cleaning attachments by setting attachment properties to NULL - is incorrect. Try first what happens if you comment out cleaning logic and go straight to attachment setting.

Another thing is that although on the list of attachment content-type the choice is limited, you can still put any content-type you like. Both in UI by typing the desired value, or programmatically.