How to extract json and randomize it in jmeter? - json

Below is the server response in a JSON format which I need to work on, In this JSON some of the objects I need to pass in the next request, which I am successfully able to do for the first occurrence, but the problem is coming on randomization in the below JSON
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sword of Honour",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "test_title",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Sword of Honour",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "India",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
if I apply $..book[0][?(#.title == 'Sword of Honour')].author condition I am seeing successful output but when I use $..book[1][?(#.title == 'Sword of Honour')].author I get a blank O/P which I understand all because at book[1] level there is not title like that.
How do I randomize the data in every Iteration so that it picks different authors for the same title? we have to take multiple values from JSON and pass it in the next request.

Extract all the titles using JSON Extractor:
It will give you the following variables:
title_1=Sword of Honour
title_2=test_title
title_3=Sword of Honour
title_4=India
title_matchNr=4
Then you can use __Random() and __V() functions combination to refer the random book title where required:
${__V(title_${__Random(1,${title_matchNr},)},)}

Related

How to join two json path query in json path extractor of jmeter?

Let's say I have this popular data sample.
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"color": "red",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"color": "blue",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
What I want from here is a all the book where category == fiction and all the bicycle where color == red.
That is, I want,
{
"category": "fiction",
"author": "Evelyn Waugh",
"color": "red",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"color": "blue",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
},
"bicycle": {
"color": "red",
"price": 19.95
}
I know, I can use $.store.book[?(#.category == "fiction")] to achieve the targeted books and $.store.bicycle[?(#.color == 'red')] to achieve the targeted bicycle.
But how can I achieve both at one go?
You can use && and || operators.
$.store.*[?(#.color== 'red' || #.category == 'fiction')]
will fetch the results as you wanted
I would recommend implementing your scenario using JSR223 PostProcessor and Groovy language. Example code to extract the elements and build a new JSON out of the filtered data will look something like:
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def json = new JsonSlurper().parseText(prev.getResponseDataAsString())
def fictionBooks = json.store.book.findAll {it.category == "fiction"}
def redBikes = json.store.bicycle.findAll{it.color="red"}
JsonBuilder builder = new JsonBuilder(fictionBooks + redBikes)
prev.setResponseData(builder.toPrettyString())
The above code will replace the parent sampler response data with the filtered JSON
References:
Groovy: Parsing and Producing JSON
JsonBuilder class reference
Groovy Is the New Black
To return books and bicycle, both you need to :
$..*[?(#.color== 'red' || #.category == 'fiction')]
For books which have color==red or category==fiction, you will need :
$.store.*[?(#.color== 'red' || #.category == 'fiction')]

jsonPath query for single array object not working

I have a JSON look like this and if I make a query
jsonPath($.book[?(#.price)]).is("8.95") it works.
{"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
]
}
But, if I have a JSON with only one object inside it, the same query logic won't work. i.e jsonPath($.book[?(#.price)]).is("8.95")
Any thoughts why ?
{"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
}
]}
I need to stick with query as I'm not sure whether the API will return multiple object or single one.
Oh, I found that's Gatling's bug, it is not able to parse the jsonPath with query having some braces e.g. { or [ or )
https://github.com/gatling/jsonpath/issues/23

Retrieving json data from a single object using JSONPath

Given the JSON below:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century"
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3"
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": null,
"isbn": "0-395-19395-8",
"price": null
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
What JSON path could I use to retrieve the first element of book that contains a category, author, price, and title parameter? To be clear, I don't want any category, author, price, and title parameter -- only those that come from a single book object. Also, the structure of the book array varies (i.e. the number and configuration of its elements changes over time) so I can't really hardcode anything.
I think you mean you want:
$..book[?(#.category && #.author && #.price && #.title)]

How to access a JSON Array response using JsonPath?

How to handle when REST service response is returned as Json Array: for e.g:
[{"boolField":true,"intField":991, "StringField":"SampleString"},
{"boolField":false, "intField":998, "StringField": "SampleString2"}]";
All the blogs & examples I have seen didn't deal with the scenario mentioned above. For example, I went through http://goessner.net/articles/JsonPath/ expression syntax, but couldn't locate the solution.
For example the following json, if I want to get all the authors, I can use $.store.book[*].author or $..author
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}]}
}
However, if the REST service response is returned like below, then how to get all authors from the list
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
]
$..author will retrieve all of the authors.
In general when your root object is an array, you can think of the $ as an array and do things like $[0] to inspect the first item (You'll still get an array back however).
In my case [0].author worked (I left out the $).

Parse JSON in Mule 3.2 Flow

If I have the following JSON
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
]
I can get the price of "Moby Dick" using the following JSONPath:
$..[?(#.title=='Moby Dick')].price
RESULT:
'0' => "8.99"
BUT how do I do this in Mule..... what would the json expression look like to get the same result within a mule 3.2 flow?
I don't mind if your answer shows how to do it another way as long as I get the same result within mule.
Can anyone please help me with this??
The way to do that with MEL is to deserialize the JSON payload and use an MVEL filtered projection:
<json:json-to-object-transformer returnClass="java.util.List" />
<expression-transformer
expression="#[($.price in message.payload if $.title == 'Moby Dick')[0]]" />
This expression doesn't take into account cases when Moby Dick isn't present. You didn't mention what to do in that case: I can beef up the expression if you specify the desired behavior when the book's not found.