Submit and vote on feature ideas.

Welcome to the new Parasoft forums! We hope you will enjoy the site and try out some of the new features, like sharing an idea you may have for one of our products or following a category.

extensionTool - Groovy example to modify the response payload

Can you point me to a couple examples of how to use Groovy code in extensionTools to modify things like response headers, payloads, etc.

Comments

  • williammccusker
    williammccusker Posts: 642 ✭✭✭

    Hi,

    Would it make sense to add the header using the Transport HTTP Headers table and then script the value? That would be easier since the script could just handle returning the value in that case.

    For modifying the payload the extension tool can be chained to the outgoing response and then whatever the tool returns as output from the script would override the original body. Is the goal to modify xml or json? Groovy has different libraries for processing xml and json that help make them easier to modify/wrok with.

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    Hi William. Just looking for a basic example of a script updating the response. I've done a good bit of that in the past when building VAs in the Parasoft client. I'm generating an extensionTool via the API and I am not seeing any changes to the response as I would expect based on the things I have done in the past. I have chained it to the Outgoing Response and I am returning text.

  • williammccusker
    williammccusker Posts: 642 ✭✭✭

    Hi,

    A trick I use to is to build the asset using the desktop and then call the relevant REST API GET calls to see how the tool was configured for a working case. That response should then be very close to the payload that would need to be sent in a POST to configure a new tool in the exact same way.

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    excellent idea!

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    Still struggling a bit here. My process generates an extensionTool in the VA and I can see it in CTP. However the code doesn't seem to have any effect on the response. Can you post a simple Groovy script that I can apply to the Incoming Request to change the request using a replace("this", "that");

  • OmarR
    OmarR Posts: 233 admin
    edited April 2023

    To clarify, do you want to replace items in an incoming request payload or the outgoing response payload? The groovy scripts below should work for either one, but just make sure you're attaching the Extension Tool to the desired output.

    Here's a groovy script to replace a string in the outgoing response payload:

    import com.parasoft.api.Application
    
    def replaceString(input,context) {
        modified = input.replace("test","REPLACED STRING")
        Application.showMessage("Original payload: \n" + input + "\n");
        Application.showMessage("Modified payload: \n" + modified + "\n");
        return modified
    }
    

    Here's a groovy script to replace the entire payload in the outgoing response:

    import com.parasoft.api.Application
    
    def replacePayload(input,context) {
        modified = input.toString().replaceAll("[\n\r]","").replaceAll("[^\n]+","REPLACED ENTIRE PAYLOAD")
        Application.showMessage("Original payload: \n" + input + "\n");
        Application.showMessage("Modified payload: \n" + modified + "\n");
        return modified
    }
    
  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    Awesome. Thank you. I may also want to modify the request, but I would imagine I could use this approach on the Incoming Request. Thanks again. This is very helpful to something I am working on for my employer. JT

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    Is scripting via extensionTool something that can be disabled in the Virtualize configuration? I am able to generate the tool locally and it correctly updates the response payload. However when it is hosted on our enterprise instance of Virtualize the update does not happen. Similar to how there was a setting to disable autodeploy, I am wondering if tools are disabled. Is this possible in the config?

    Thanks,

    JT

  • williammccusker
    williammccusker Posts: 642 ✭✭✭

    Hi,

    I am not aware of any options to disable scripting. Are the tool settings the same? I believe for it to work the option "exitCodeIndicatesSuccess" is supposed to be false and it must be attached to the outgoing response.

    Perhaps comparing a tool created by the REST API with one created using the Desktop in the UI might help to spot if there are any differences in settings.

    Can you use event monitoring on the enterprise instance to make sure the expected responder is the one providing the response?

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    message just says error during script execution. view details for more information not sure how to view details in CTP

  • williammccusker
    williammccusker Posts: 642 ✭✭✭

    Hi,

    I think the details would be in an event. Not exactly sure how to find it in CTP, if you have the server added to your desktop you could start monitoring the asset. In CTP I think there is the "Events" tab under Service Virtualization that you could probably use to filter down to events for that asset.

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    I was able to locate the problem The "method" value in my request payload didn't match the method name I had set up in my script.

  • williammccusker
    williammccusker Posts: 642 ✭✭✭

    Glad you were able to find the issue!

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    What is the best way to update the response headers using a Extension Tool on the Traffic Object?

    THanks,

    JT

  • williammccusker
    williammccusker Posts: 642 ✭✭✭

    Hi,

    First thought would be to use scripting in the transport headers table. Would that be an option in your case?

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    yeah but is the input a Map or some other object?

  • williammccusker
    williammccusker Posts: 642 ✭✭✭

    Hi,

    In the Transport Header section, you can script the value for a specific header. The script for the value of the header accepts only a single argument, which I believe is the 'context' object. The script is expected to return the value for the header.

    The traffic object and the outgoing response transport header output occur after the response has been sent to the client so those wouldn't be able to update the header value.

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    oh that works perfectly great info thanks. JT

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    Somewhat related, I have updated my responder creation calls to include this: "allowRequestModificationBeforeCorrelation": true,

    I would really like to see some actual Groovy examples on how to modify the request before correlation. This looks like a potential solution to one of my biggest users. Specifically I'd love to see several code examples of how to get the request header/body and manipulate both prior to correlation. I'm not quite sure how that would work because the tools to modify are tied to a responder.

    Thanks,

    JT

  • benken_parasoft
    benken_parasoft Posts: 1,228 ✭✭✭

    I would really like to see some actual Groovy examples on how to modify the request before correlation

    I would refer to the Groovy example that Omar provided earlier. You chain your Extension Tool to "Incoming Request" instead of "Outgoing Response". However, regardless of whether you chain it to Request or Response, the "input" argument is the original message. Whatever your script returns is treated as the modified message.

    I'm not quite sure how that would work because the tools to modify are tied to a responder.

    This option affects data source correlation or multiple response correlation which is responder-specific. In the UI, this option is specifically labeled "Allow incoming request tools to modify the message before applying data source or multiple response correlations".

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    Thanks I have been successful modifying the payload body, but I am not able to get the request headers loaded into an extension tool chained to the incoming transport header. I would like to read in the headers and potentially add/edit/delete a header. The example seems to be dealing with the body. Do you have an example of updating the request header using scripting? THanks JT

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    I guess what I am saying is that when I create a Groovy method and chain it to the Incoming Transport Header and then do an Application.showMessage(input.toString()) the only output I get is the word text

    I've tried getHeaders(input, context) and getHeaders(input)

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    and input.getClass().toString() returns class webtool.packet.TextUsable

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    if I create getBody(input, context) I am able to see the request body with Application.showMessage(input.toString())

    when I look at the Details of the request received I do see the headers I am trying to get... I just don't get them chaining an extension tool to the incoming transport header

  • benken_parasoft
    benken_parasoft Posts: 1,228 ✭✭✭
    edited July 2023

    when I create a Groovy method and chain it to the Incoming Transport Header and then do an Application.showMessage(input.toString()) the only output I get is the word text

    This behavior is not ideal but you can call getText() instead of toString() or call soaptest.api.SOAPUtil.getStringFromObject(input).

    However, I don't believe Request/Response headers can be modified by the Extension Tool like you can do with the message body. If you need to dynamically generate an outgoing header then you can script specific header values on the Transport Header tab but that's it.

  • jefftuckerbofa
    jefftuckerbofa Posts: 229

    Thanks for all of the input. I think I made this way harder than it needed to be. But I learned quite a few things along the way.

    I was eventually able to solve the issue by simply adding the header to a header data bank and then
    evaluating it in an extension tool chained to the outgoing response. Tried that first but wasn't getting anywhere because of how I was examining the result. Turns out my conditional statements based on header value were not working because I had not cast the object to a String. Once I did that I was able to test for "null" and "" to achieve the desired result.

    JT