Using Azure API Management Services ,remove extra space from JSON request - azure-api-management

I am using azure API Management Services to log request and response of api's.
Now I have a requirement to remove extra space from incoming JSON request.I tried so many things like 'find and replace' and replace filter but not able to achieve it.
eg: Incoming request
body.FullName ="XYZ ABC"
<set-body template="liquid">
{
"Id": "{{body.Id}}",
"FullName":"{{body.FullName]}}"
}
</set-body>
As you see above in FullName between XYZ and ABC has three spaces.
My requirement is to remove extra spaces between them as you see in below example.
Final output would be :
{
"Id" : 12
"FullName" : "XYZ ABC"
}

If you want to do do that only for certain properties, then try:
<set-body template="liquid">
{
"Id": "{{body.Id}}",
"FullName":"{{body.FullName | split: " " | join: " "}}"
}
</set-body>
Seems there is no better way to do that in liquid.
If you want to do that in whole body without analyzing it's structure, then:
<set-body>#(Regex.Replace(context.Request.Body.As<string>(), #"\s+", " "))</set-body>
Alternatively you could parse entire body as JObject and iterate over is recursively fixing up every property value.

Related

how do I combine strings with jmespath queries to build up a webhook body?

I am trying to use Cloud Custodian webhooks to create tagged events in Datadog using the Datadog API.
The following code nearly works, except account_id is not created as a tag in Datadog. If I capture the body sent, it contains "01234" (i.e. a string.)
- type: webhook
url: https://api.datadoghq.eu/api/v1/events
method: POST
headers:
DD-API-KEY: '`{{ dd_api_key }}`'
body: |-
{
"title": `nutkin news`,
"text": `squirrel found in account`,
"tags": [resource.Name, policy.name, account_id]
}
If I remove the jmespath queries in tags and just send string literals e.g.
`01234`
, it will not be appear in Datadog as a tag, but if I send
`aws_account_id:01234`
it will appear as a tag.
Ideally, for all the tags, I would like a mix of a string and the result of the jmespath query, as it would be more useable for users of Datadog (e.g. something like what is included below.)
"tags": [`resource_name:`resource.Name, `policy_name:`policy.name, `account_id:`account_id]
I've spent days on this. I've read all the docs on custodian, json and jmespath and just can't find the right syntax of brackets, quotes and backticks. Maybe it is not even possible to mix string literals and jmespath queries.
Just to reiterate the question, how do I combine string literals with jmespath queries to build up a web hook body in custodian web hooks?
Solved! Needed a join statement for each tag, like:
- type: webhook
url: https://api.datadoghq.eu/api/v1/events
method: POST
headers:
DD-API-KEY: '`{{ dd_api_key }}`'
body: |-
{
"title": `nutkin news`,
"text": `squirrel found in account`,
"tags": [join(``, [`aws_resource:`, resource.Name]), join(``, [`custodian_policy:`, policy.name]), join(``, [`aws_account:`, account_id])]
}

How to store entire response and update it for next rest call using Jmeter

Question: How to extract entire restAPI response and modify it with some values and use the updated response for sub-sequent rest call. I am using Jmeter
Question Scenario:
I have one POST call ex: "/check1/id1/post"
POST body :
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz"
}
}
POST call RESPONSE :
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz"
"status":"updated"
}
}
=====================================================================
QUESTION: Now, I have to use entire above RESPONSE in next POST Call body as below, BUT, I wanted to update "id" value as 2 and then need to POST rest call.
REST CALL: ------ > "/check1/id2/post"
POST BODY as below : ------->
{
"test":"rest",
"check" :{
"id":2,
"name": "xyz"
"status":"updated"
}
}
=============================================================
Can anyone please guide on this? , I am clueless about how to solve this issue?, I need to solve this using Jmeter.
To store entire response:
add Regular Expression Extractor as a child of the request which response you want to capture
configure it as follows:
Reference name: anything meaningful, i.e. response
Regular Expression: (?s)(^.*)
Template: $1$
To replace 1 with 2 you can go for __strReplace() function like ${__strReplace(${response},1,2,)}. Note that you need to install Custom JMeter Functions bundle using JMeter Plugins Manager in order get it.
You can do this using beanshell or JSR223 PreProcessor
Assuming a valid JSON
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz",
"status":"updated"
}
}
Here are the steps
Add a JSR223 preprocessor to the 2nd post request.
Add the following code to the preprocessor
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def slurped = new JsonSlurper().parse(prev.getResponseData())
def builder = new JsonBuilder(slurped)
builder.content.check.id = '2'
vars.put("POSTDATA",builder.toPrettyString())
Above code will update ID value with 2 and stores the JSON in POSTDATA , you can use ${POSTDATA} to post the JSON FILE
In my pre processor i'm saving the response using prev.getResponseData() , that means this pre processor must included with the sampler right next to the first sampler.
For more information on beanshell Please follow this link

Modify Request Payload with Charles Proxy

I'm sending a post request with a json object in the body of the request. I'd like to change the value of one field in the json object.
For example:
{ "json_params" :
{
"first_name": "John",
"last_name": "Doe",
"fav_foods":{
"dessert": "icecream",
"pizza": "cheese"
}
}
}
How can I use Charles to change "fav_foods" to "least_fav_foods", for example, or "dessert" to "appetizer"?
I've tried using the Rewrite tool, putting "fav_foods" as the match and "least_fav_foods" as the replace.
Also tried using {"json_params": {"fav_foods": {"dessert": "icecream", "pizza": "cheese"}}} --> {"json_params": {"least_fav_foods": {"dessert": "icecream", "pizza": "cheese"}}} but haven't had luck with either format.
I've tested and verified that I am detecting the right request. I can add a header to the request, but can't change anything in the json payload.
Well, turns out it's far simpler than I was assuming. Charles just does a simple string matching search.
Creating a rewrite rule for type Body with Match Value: "fav_foods" -> Replace Value: "least_fav_foods" did what I wanted.

How to escape \r\n in the body of a POST in JMeter

I have a JSON response as follows,
{
"name":"John Smith",
"address": "#123\r\nRenault Road\r\n123456\r\n"
}
and I need to extract the address and put it into my next POST request. I use the JSON Extractor as a post processing element and with $..address I set the extracted address to the variable address.
In my next request, I use the following as the POST data,
{
"id": "123456",
"address": "${address}"
}
So when I make the request I see the POST data as,
{
"id": "123456",
"address": "#123
Renault Road
123456
"
}
This breaks at my backend and nevertheless this payload is not identified as a valid JSON as well.
I want to make the request so that the POST data is as follow,
{
"id": "123456",
"address": "#123\r\nRenault Road\r\n123456\r\n"
}
Any help to get this done is highly appreciated.
If you really need to send these line breaks as \r\n you can use some scripting to convert them back.
Add Beanshell PreProcessor as a child of the "next request" HTTP Request Sampler
Put the following code into the PreProcessor's "Script" area:
address = vars.get("address");
address = address.replaceAll("\\r\\n","\\\\r\\\\n");
vars.put("address", address);
The above script will convert line breaks to the textual representation.
References:
vars is a shorthand for JMeterVariables class instance, it provides read/write access to all JMeter Variables
String.replaceAll() - is the method of String class which comes out of box with Java SDK
How to Use BeanShell: JMeter's Favorite Built-in Component - guide demonstrating how to use Java and JMeter APIs using Beanshell test elements to enhance your JMeter tests with scripting if required

JMeter Variables in JSON request

When I pass an variable in JMeter HTTP request, I'm getting an exception
"Unexpected escape character after back slash"
The request body:
"Draft":{
"id": 123654656,
"draftdata":{\\\"accCat\\\":\\\"207\\\",\\\"accNumber\\\":\\\"656565
\\\",\\\"id\\\":${Var_ID},...}
}
When I send the request, one of the two back-slashes are omitted. I guess the variable ${Var_ID} should be passed in a way that does not conflict with the json body
I don't think you need these \\\ signs
I believe you need to surround ${Var_ID} with quotation marks
Something like:
{
"id": 123654656,
"draftdata": {
"accCat": "207",
"accNumber": "656565 ",
"id": "${Var_ID}"
}
}
You can use online JSON validation tools like Online JSON Viewer to test your JSON payload. Also check out Testing SOAP/REST Web Services Using JMeter article for some initial information on testing REST APIs using JMeter
Maybe making changes like:
{
"Draft": {
"id": 123654656,
"draftdata": {
\"accCat\":\"207\",
\"accNumber\":\"656565\",
\"id\":\"${Var_ID}\",...}
}
I don't see any need to have \ signs, just one will escape original " signs.
The variables, or the request to some function of JMeter, into json body must be passed without quotation marks, something like this:
"Draft":{
"id": 123654656,
"draftdata":{
"accCat":"207",
"accNumber":"656565",
"id":${Var_ID},...}
}
Also yout don't need the backslashes signs. Hope this help.