Forum Discussion

swalchemist's avatar
swalchemist
Occasional Contributor
4 years ago

Virtual service: reading the request headers in code injected into a response

Hi, SmartBear Customer Care sent me here when they couldn't find an answer for me.

 

We have set up a virtual service with ReadyAPI that's working well when we run it locally, and it's also working when we run it in a virtserver and have only one user accessing it. The service is keeping a small amount of state to simulate changes to a database. We used a simple load test to show that our service has a race condition that can cause it to return the wrong data up to 10% of the time, so we can't recommend rolling out the service to our broader organization yet.

 

We're trying to support the stateful service for multiple users by reading a "clientId" header in the request and dynamically generating the name of a property in order to look up its current value that can be unique for each client (the value is set in a different request). What's working for a single user now is that we have script code that sets the property, and then we inject this code into the response to return the per-client property value:

mode="${#MockService#${#MockService#clientId}-mode}"

 

This fails our load test probably because the time between running the script code to set the (global) property and running the code in the response gives an opportunity for another request to overwrite the property value.


To be clear: we have script code for this response (not shown here) that sets the property, and to inject a value into the response, we also have the code above directly in the response that reads both the clientId and the unique property value for the client. The scripting environment and the syntax for code in the response is somewhat different than in the script, and we have found very little documentation on what we can do with this code in the response.

One fix we tried didn't work, where we tried to access objects that are available in script code:

mode="${=def clientId = mockRequest.getRequestHeaders().get("myClientId").get(0); context.expand("#MockService#" + clientId + "-mode")}'"


Turns out we can't access mockRequest in the response:
  mode="No such property: mockRequest for class: Script36'"

I know we can store these per-client properties in headers instead of properties, but for that to work, we still have to figure out how to read the request headers in the response code. Anyone have ideas for a solution?

    • swalchemist's avatar
      swalchemist
      Occasional Contributor

      Hi, nmrao. That's a nice example of reading headers in the dispatch script. But your project doesn't have any code injected directly in the response, and that's where we're not able to use the kind of code you're using in the dispatch script to access the request headers.

       

      This does give me the idea that we could generate every combination of responses in a different hardcoded response file and choose one of them using the dispatch script. Right now it's just two boolean values, so there are four combinations, but that's likely to increase soon and create a maintenance problem.

       

      On the topic of load tests - the SmartBear documentation does suggest doing a load test. We didn't need a heavy load to demonstrate the problem, just 2 or 3 concurrent threads, so we used only the minimum load necessary.

      • nmrao's avatar
        nmrao
        Champion Level 3
        May be I didn't read the inject part by looking just read part.

        Of course one can inject as well, otherwise not possible for sending dynamic value in response. Will find a sample.