How to create a dynamic request in Jmeter - json

I have a response from an API
[{
"userSourceMeta": {
"userId": "sss#gmail.com",
"source": "BOX",
"organisationId": 1,
"emailId": "sss#gmail.com",
"sourceUserId": "15548727375",
"accessToken": null,
"refreshToken": null,
"lastCursorPosition": null,
"lastAccessTime": 1626025027228,
"name": "John",
"createdAt": 1622444279509
},
"connectionStatus": null}, {
"userSourceMeta": {
"userId": "test#gmail.com",
"source": "ONEDRIVE",
"organisationId": 1,
"emailId": "sss#outlook.com",
"sourceUserId": "3969b928a1a28f34",
"accessToken": null,
"refreshToken": null,
"lastCursorPosition": null,
"lastAccessTime": 1626025027228,
"name": "sss ddd",
"createdAt": 1624262423446
},
"connectionStatus": null}]
I have to use two parameters in the successive request(source,sourceUserId) . This is a dynamic request it can be varied 3, 4,5 ..etc.
Next API request.
{
"Answer": "My name is xyz",
"queryChannel": "WEB_APP",
"timeZone": "Asia/Calcutta",
"sourceFilterInfo": [{
"sourceUserId": "15548727375",
"source": "BOX"
}, {
"sourceUserId": "3969b928a1a28f34",
"source": "ONEDRIVE"
}],
"contextIds": []
}
Please provide a solution to send a dynamic request with the previous API response.
I used regular expression extractor to store values. But how to send it in a request.

Add JSR223 PostProcessor as a child of the request which returns the above JSON and put the following code into "Script" area:
def response = new groovy.json.JsonSlurper().parse(prev.getResponseData())
def sourceFilterInfo = []
response.each { entry ->
def user = [sourceUserId: entry['userSourceMeta'].sourceUserId, source: entry['userSourceMeta'].source]
sourceFilterInfo.add(user)
}
def payload = [:]
payload.put('Answer', 'My name is xyz')
payload.put('queryChannel', 'WEB_APP')
payload.put('timeZone', 'Asia/Calcutta')
payload.put('sourceFilterInfo', sourceFilterInfo)
payload.put('contextIds', [])
vars.put('payload', new groovy.json.JsonBuilder(payload).toPrettyString())
That's it, now you should be able to refer the generated request as ${payload} where required
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

Related

How to parse a jsonArray

I want to parse a JSON Array, Here is the example JSON
[
{"Vulnerabilities": [
{
"Id": "Cx35ef42d7-054c",
"CveName": "",
"Score": 9.8,
"Severity": "High",
"PublishDate": "2021-01-22T13:34:00",
"References": [
"https://github.com/mde/ejs/issues/571",
"https://github.com/mde/ejs/commit/abaee2be937236b1b8da9a1f55096c17dda905fd"
],
"Description": "ejs package before 3.1.6 is vulnerable to arbitrary code injection. The vulnerability exists due to improper input validation passed via the options parameter - the filename, compileDebug, and client option.",
"Cvss": {
"Score": 9.8,
"Severity": "High",
"AttackVector": "NETWORK",
"AttackComplexity": "LOW",
"Confidentiality": "HIGH",
"Availability": "HIGH",
"ExploitCodeMaturity": null,
"RemediationLevel": null,
"ReportConfidence": null,
"ConfidentialityRequirement": null,
"IntegrityRequirement": null,
"AvailabilityRequirement": null,
"Version": 3.0
},
"Recommendations": null,
"PackageId": "Npm-ejs-2.7.4",
"FixResolutionText": "3.1.7",
"IsIgnored": true,
"ExploitableMethods": [],
"Cwe": "CWE-94",
"IsViolatingPolicy": true,
"IsNewInRiskReport": false,
"Type": "Regular"
},
{
"Id": "CVE-2022-29078",
"CveName": "CVE-2022-29078",
"Score": 9.8,
"Severity": "High",
"PublishDate": "2022-04-25T15:15:00",
"References": [
"https://github.com/advisories/GHSA-phwq-j96m-2c2q",
"https://eslam.io/posts/ejs-server-side-template-injection-rce/",
"https://github.com/mde/ejs/commit/61b6616fd34ff4d21c38fe1dbaf2b3aa936bb749",
"https://github.com/mde/ejs/issues/451",
"https://github.com/mde/ejs/pull/601"
],
"Description": "The ejs (aka Embedded JavaScript templates) package up to 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).",
"Cvss": {
"Score": 9.8,
"Severity": "High",
"AttackVector": "NETWORK",
"AttackComplexity": "LOW",
"Confidentiality": "HIGH",
"Availability": "HIGH",
"ExploitCodeMaturity": null,
"RemediationLevel": null,
"ReportConfidence": null,
"ConfidentialityRequirement": null,
"IntegrityRequirement": null,
"AvailabilityRequirement": null,
"Version": 3.0
},
"Recommendations": null,
"PackageId": "Npm-ejs-2.7.4",
"FixResolutionText": "3.1.7",
"IsIgnored": true,
"ExploitableMethods": [],
"Cwe": "CWE-74",
"IsViolatingPolicy": true,
"IsNewInRiskReport": false,
"Type": "Regular"
}
}
]
I want to parse the JSON array and get the value of Ids in a list. If it was a JSON response my code would be
id = response.getBody.jsonPath.getList("vulnerabilities.Id");
but it is a JSON file. I have to read the file and then parse the JSON to fetch value of id into a List. Can someone please help?
(Assuming you're doing it in Java)
You do the following (using Google gson):
Gson gson = new Gson();
JsonReader reader = new JsonReader(new FileReader(file_path));
After this - there are two approaches,
Either,
Create a POJO that matches your Objects (Preferred)
ResponseHolder response = gson.fromJson(reader, ResponseHolder.class);
In your case, as it's an array
List<ResponseHolder> responses = gson.fromJson(yourJson, new TypeToken<List<ResponseHolder>>() {}.getType());
Then extract the required field from your object.
//Or loop on each-element based on your use case
responses.get(0).getVulnerabilities().get(0).getId()
OR
Use JsonArray/JsonObject class
JsonArray responses = gson.fromJson(reader, JsonArray.class);
for (JsonElement response : responses) {
JsonObject item = response.getAsJsonObject();
JsonArray vulnerabilities = item.get("vulnerabilities").getAsJsonArray();
//Or Loop
Strring idOfFirst = vulnerabilities.get(0).getAsJsonObject("id").getAsString();
}

Concatenating lists in Groovy

I have captured two sets of values by using JSON extractor in JMeter which I want to concatenate. Let me give you an example below for the format which I want to use.
The following are the two sets of captured values:
Set 1: [V2520 V2522 V2521 V2500 V2500]
Set 2: [PL PL PL NP NP]
So from the above sets, I am looking for the something like the following value, because the body which I have to send in a subsequent call contains the combination of these 2 values:
Answer: ["V2520PL", "V2522PL", "V2521PL", "V2500NP", "V2500NP"]
Can you please help me how to solve this in JMeter using Groovy?
This is the JSON I have:
{ "body": {
"responseObject": [
{
"benefitInfo": [
{
"procedureCode": "V2520",
"modifier": "PL",
"usage": "Dress",
"authorizationID": null,
"description": "ContactLensDisposable",
"id": "96",
"coPayAmount": "25"
},
{
"procedureCode": "V2522",
"modifier": "PL",
"usage": "Dress",
"authorizationID": null,
"description": "ContactLensDisposableBifocal",
"id": "98",
"coPayAmount": "25"
},
{
"procedureCode": "V2521",
"modifier": "PL",
"usage": "Dress",
"authorizationID": null,
"description": "ContactLensDisposableToric",
"id": "97",
"coPayAmount": "25"
},
{
"procedureCode": "V2500",
"modifier": "NP",
"usage": "Dress",
"authorizationID": null,
"description": "ContactLens (Non Plan)",
"id": "89",
"coPayAmount": "0"
},
{
"procedureCode": "V2500",
"modifier": "NP",
"usage": "Dress",
"authorizationID": null,
"description": "ContactLensConventional (Non Plan)",
"id": "157",
"coPayAmount": "0"
}
]
}
]}}
An easy way to do this is to combine them as you collect the values from the JSON when you parse it.
def json = new groovy.json.JsonSlurper().parseText(text)
def answer = json.body.responseObject[0].benefitInfo.collect { it.procedureCode + it.modifier }
assert answer == ["V2520PL", "V2522PL", "V2521PL", "V2500NP", "V2500NP"]
Another method would be to use transpose() and join():
def r = new groovy.json.JsonSlurper().parseText(text).body.responseObject.benefitInfo[0]
def answer = [r.procedureCode, r.modifier].transpose()*.join()
assert answer == ["V2520PL", "V2522PL", "V2521PL", "V2500NP", "V2500NP"]
Add JSR223 PostProcessor as a child of the request which returns the above JSON
Put the following code into "Script" area:
def answer = []
def benefitInfos = com.jayway.jsonpath.JsonPath.read(prev.getResponseDataAsString(), '$..benefitInfo')
benefitInfos.each { benefitInfo ->
benefitInfo.each { entry ->
answer.add(entry.get('procedureCode') + entry.get('modifier'))
}
}
vars.put('answer', new groovy.json.JsonBuilder(answer).toPrettyString())
That's it, you will be able to access generated value as ${answer} where required:
References:
Jayway JsonPath
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

Gravity Forms Web API - Field Names with fullstops issue

I'm using the Web API to download form entries into an offline system and having an issue with my JSON parser with some of the form field IDs. For example I receive an entry with fields like this:
{
"response": {
"entries": [
{
"3.3": "Henry",
"3.6": "Ford",
"3.2": "",
"3.4": "",
"status": "active",
"transaction_id": null,
"transaction_type": null,
The period/fullstop in the field ID is throwing out my JSON parser which uses the period/fullstop as the separator ($.response.entries[0].3). Is there a way to change the period/fullstops to underscores of have the API return the name of the field instead like it does for "transaction_type" etc?
A hacky solution if you can't change how the data is coming from the API would be to pre-parse it yourself. You can do something like this using a simple string replace:
var data = {
"response": {
"entries": [
{
"3.3": "Henry",
"3.6": "Ford",
"3.2": "",
"3.4": "",
"status": "active",
"transaction_id": null,
"transaction_type": null,
}
]
}
}
data = JSON.stringify(data)
data = data.replace(/\./g, '_');
data = JSON.parse(data)
console.log(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

Parse JSON data from string

I'm getting JSON data using HTTP methods in Arduino and storing in a String object. The data is:
{
"item": {
"Identity": {
"Id": "327681",
"ItemId": "64006A962B71A1E7B3A0428637DA997C.327681",
"Level": 1,
"EntityType": "64006A962B71A1E7B3A0428637DA997C",
"ItemStatus": 1
},
"Properties": {
"AssetName": "PHE-1001",
"Category": "Electrical Appliance",
"RegistrationTime": "2017-12-14Z",
"Activated": true,
"Status": "Offline",
"Manufacturer": "Philips",
"ModelNumber": "1E-S00ER11",
"SerialNumber": "YGTJGJK458545",
"sample_property": null,
"AssetLocation": null,
"AssetType": null,
"ActivationTime": "2017-12-24T05:44:38Z",
"Country": "India",
"PostalAddress": "500081",
"dummy": null,
"TotalHours": 16,
"TotalWorkingHoursFromInstallation": 38,
"TotalLifeTime": 62,
"AssetSensorDistance": null
}
}
}
Arduino code:
HTTPClient http;
http.begin("URL");
int httpCode = http.GET(); // //Send the request
if (httpCode == 200) {
String payload = http.getString();
Serial.println(payload);
}
Now I want to get only AssetName, Status and AssetSensorDistance. I have tried payload["Status"] but it prints nothing.
Can anyone help me with this? Thanks in advance.
You are missing some important bits here.
You need to include the ArduinoJson library
You need to actually parse the string into a JsonObject using JsonBuffer
The path to status would be yourRootObject["Properties"]["Status"], since it is contained inside your Properties.
See here: https://arduinojson.org/doc/decoding/
Good Luck!

Json Slupper assert and extract

I'm using the next Json
{
"ID": 8,
"MenuItems": [
{
"ID": 38,
"Name": "Home",
"URL": "{\"PageLayout\":\"Home\",\"Icon\":\"home\"}",
"Culture": "en",
"Children": null
},
{
"ID": 534,
"Name": "GUIDE ",
"URL": "{''PageLayout'':''Page A'', ''Icon'':''A''}",
"MenuType": 1,
"PageID": 0,
"Culture": "en",
"Children": [
{
"ID": 6,
"Name": "Form A",
"URL": "[''Type'':''Form A'',''Icon'':''Form'',''ItemID'':\"358\"]",
"Culture": "he",
"RuleID": 0
},
{
"ID": 60,
"Name": "Drama",
"URL": "[''Type'':''Form B'',''Icon'':''Form'',''ItemID'':\"3759\"]",
"Culture": "en",
"RuleID": 0
}
]
}
]
}
i'm using Groovy script in soapUI and i need to:
Assert the exitance of node that has the name GUIDE
Extract a list of all Itemsid
You can parse the JSON content using JsonSlurper and then work with the results like so:
import groovy.json.JsonSlurper
// Assuming your JSON is stored in "jsonString"
def jsonContent = new JsonSlurper().parseText(jsonString)
// Assert node exists with name GUIDE
assert(jsonContent.MenuItems.Name.contains("GUIDE"))
// Get list of ItemIDs
def itemList = jsonContent.MenuItems.Children.URL.ItemID[0].toList()
// List the items
itemList.each {log.info it}
Note that the above will fail given your current example, because of a few issues. Firstly, Name contains "GUIDE " (trailing space) rather than "GUIDE" (so you will need to adapt accordingly). Secondly, it is invalid JSON; the URL nodes have various erroneous characters.
On a side note, if you first need to retrieve your JSON from the response associated with a previous TestStep (say one called "SendMessage") within the existing testCase, this can be done as follows:
def jsonString = context.testCase.getTestStepByName("SendMessage").testRequest.response.getContentAsString()