Generate json body using groovy in jmeter having array inside an array - groovy

I'm trying to generate JSON body dynamically using values in csv file. For this i'm making use of JSR223 PreProcessor with groovy script.
I'm expecting the below format to be generate when i run the groovy script
{
"transactionId": "100",
"lineItems": [{
"lineItemNo": "1",
"cardInfo": {
"cardNumber": "3456"
}
},
{
"lineItemNo": "2",
"cardInfo": {
"cardNumber": "45698"
}
}
]
}
but when i execute script i'm getting below format
POST data:
{
"transactionId": "100",
"lineItems": [
{
"lineItemNo": "1",
"Cardinfo": [
9255000012794606,
9255000012794645
]
},
{
"lineItemNo": "1",
"Cardinfo": [
9255000012794606,
9255000012794645
]
}
]
}
Script to generate json body
File csvFile = new File("D:\\Project Related Docs\\Jmeter\\apache-jmeter-5.0\\bin\\Map_Performance\\Map_New_Auto_jmx\\2Cards.csv")
def cards = csvFile.readLines()
List<String> cardnumbmer = new ArrayList<>()
def counter = 1
cards.eachWithIndex{line,idx->cardnumbmer.add(line)}
log.info("size of csv = "+cardnumbmer.size())
log.info("File conents = "+cardnumbmer[0])
//build the json body
def ids = new groovy.json.JsonSlurper().parseText(cardnumbmer.toString())
log.info("cardnumbmer to string = "+cardnumbmer.toString())
def builder = new groovy.json.JsonBuilder()
builder([
transactionId:"100",
lineItems:ids.collect{[lineItemNo:"1",Cardinfo: ids.collect{carnumber: it}]}
])
//sampler.getArguments().removeAllArguments()
sampler.addNonEncodedArgument('',builder.toPrettyString(),'')
sampler.setPostBodyRaw(true);
--CSV FILE have cardnumbers listed in row-wise look like below
9255000012794606
9255000012794645
Request to help me to know how to fix this issue.

ids.collect{carnumber: it} is basically ids. Be explicit about returning the map: ids.collect{ [carnumber: it] }

Below code resolved the problem
//build the json body
def ids = new groovy.json.JsonSlurper().parseText(cardnumbmer.toString())
log.info("cardnumbmer to string = "+cardnumbmer.toString())
def builder = new groovy.json.JsonBuilder()
def count = 1
builder([
transactionId:"100",
//lineItems:ids.collect{[lineItemNo:"1",Cardinfo: count.collect{[carnumber: it]}]}
lineItems:ids.collect{[lineItemNo:count++,Cardinfo: [Cardnumber:it]]}
])
//sampler.getArguments().removeAllArguments()
sampler.addNonEncodedArgument('',builder.toPrettyString(),'')
sampler.setPostBodyRaw(true);

Related

Remove empty Keys from JSON arrays using Groovy

I would like to remove the array SEO from the json when the keys "Description" and "Title" in the has no value.
json:
[
{
"SEO": [
{
"Description": "",
"Title": ""
}
],
"accesoires": [
"1167296"
],
"shortCode": "S-576",
"spareParts": [
"800236"
]
}]
I tried the below code but i'm not able to remove the array.
def Message processData(Message message) {
def body = message.getBody(String);
def json = new JsonSlurper().parseText(body)
json.each{
it.SEO.each{
if(!(it.findResults{k, v -> v?.size() > 0 && v[0]?.length() > 0 ? v[0] : null })){
json.remove("SEO")
} } }
def out= JsonOutput.toJson(json)
message.setBody(out)
return message}
To remove the array "SEO" from the JSON when the keys "Description" and "Title" have no value, you can use the following Groovy code:
def jsonString = '[{"SEO": [{"Description": "", "Title": ""}], "accesoires": ["1167296"], "shortCode": "S-576", "spareParts": ["800236"]}]'
def json = new JsonSlurper().parseText(jsonString)
for (item in json) {
if (!item.SEO[0].Description && !item.SEO[0].Title) {
item.remove('SEO')
}
}
println(JsonOutput.toJson(json))
This will first parse the JSON string into a list of maps using JsonSlurper. Then it iterates through each map in the list and checks if the "Description" and "Title" keys in the "SEO" array are empty. If they are, it removes the "SEO" array from the map using the remove() method. Finally, it prints the modified JSON using the JsonOutput.toJson() method.

How to create json array and values using Groovy jsonBiulder

trying to create the below json structure with groovy jsonBuilder in jmeter using JSR223 sampler
{
"Catalogues":[
{
"Catalogue":{
"itemName":"XYZ",
"Level":"Class1",
"Color":"Orange",
"Id":"232f2d6820822840"
},
"sales":[
[
"7:19 PM 3-31-2022",
"gadfma53742w3585657er43"
],
[
"5:02 PM 3-30-2022",
"iytyvh53742w3585657er41"
]
]
}
]
}
I have tried the below groovy script
def json = new groovy.json.JsonBuilder()
json {
Catalogues(
[{
Catalogue {
itemName('XYZ')
Level('Class1')
Color('Orange')
Id('232f2d6820822840')
},
{
sales(
('7:19 PM 3-31-2022'), ('gadfma53742w3585657er43')
)
}
}]
)
}
log.info '\n\n\n' + json.toPrettyString() + '\n\n\n'
Output:
{
"Catalogues":[
{
"Catalogue":[
{
"itemName":"XYZ",
"Level":"Class1",
"Color":"Orange",
"Id":"232f2d6820822840"
},
{
"sales":[
"7:19 PM 3-31-2022",
"gadfma53742w3585657er43"
]
}
]
}
]
}
Problems:
If I remove the '{' before sales and after (at corresponding location), it adds sales values into catalogue
unable to include second set of sales values
I'm suggesting another way to use builder because it's easier to understand.
To declare array in groovy use [1, 2, 3]
To declare map [a:1, b:2, c:3]
So, if you replace in original json { to [ - you will get valid groovy object that corresponds to parsed json
def data = [
"Catalogues":[
[
"Catalogue":[
"itemName":"XYZ",
"Level":"Class1",
"Color":"Orange",
"Id":"232f2d6820822840"
},
"sales":[
[
"7:19 PM 3-31-2022",
"gadfma53742w3585657er43"
],
[
"5:02 PM 3-30-2022",
"iytyvh53742w3585657er41"
]
]
]
]
]
//then you could convert it to json:
def json = new groovy.json.JsonBuilder(data).toPrettyString()
log.info(json)
JsonBuilder translates Map to JSON Object and List to JSON Array
So I would recommend for better readability and clarity amending your code to look like:
def body = [:]
def Catalogues = []
def Catalogue = [:]
def entry = [:]
Catalogue.put('itemName', 'XYZ')
Catalogue.put('Level', 'Class1')
Catalogue.put('Color', 'Orange')
Catalogue.put('Id', '232f2d6820822840')
def sales = []
sales.add(['7:19 PM 3-31-2022', 'gadfma53742w3585657er43'])
sales.add(['5:02 PM 3-30-2022', 'iytyvh53742w3585657er41'])
entry.put('Catalogue', Catalogue)
entry.put('sales', sales)
Catalogues.add(entry)
body.put('Catalogues', Catalogues)
def json = new groovy.json.JsonBuilder(body)
More information:
JsonBuilder
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

Updating Jmeter Json request

I have created a json block file which looks like this, I like to add a new element i.e
{
"Id": 0,
"cc": "123"
}
I need to add a new element
"xyz": ${abc}
the resulting to look like
{
"Id": 0,
"cc": "123",
"xyz": ${abc}
}
I have retrieved the file
String json1 = vars.get("basePath")+"Jmeter/Results/json1";
json1= new groovy.json.JsonSlurper().parse(json1);
How do I add
"xyz": ${abc},
to json1 ?
Use the following code:
String json1 = vars.get("basePath")+"Jmeter/Results/json1";
def parsedJson = new groovy.json.JsonSlurper().parse(json1);
parsedJson.put('xyz',vars.get('abc'))
def newJson = new groovy.json.JsonBuilder(parsedJson).toPrettyString()
More information:
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

How to reference parent names in JSON response (with Groovy)

I have the following JSON response in SoapUI
{
"formatted": {
"line1": "14/8 QUAY STREET",
"line2": "14/8 QUAY STREET"
},
"structure": {
"level": null
},
"location": {
"nzX": 1758749.75300025
},
"references": {
"aid": "A1003467096"
}
}
I want the following as the output
formatted, structure, location and references.
I am using Json slurper but i am not able to get all the parent element names.
How do i do it using JSON slurper in groovy.
Assuming the JSON is in a string s, consider the following which illustrates getting the top level keys:
import groovy.json.*
def json = new JsonSlurper().parseText(s)
def parentNames = json.keySet()
parentNames.each { println it }

get this JSON representation of your neo4j objects

I want to get data from thisarray of json object :
[
{
"outgoing_relationships": "http://myserver:7474/db/data/node/4/relationships/out",
"data": {
"family": "3",
"batch": "/var/www/utils/batches/d32740d8-b4ad-49c7-8ec8-0d54fcb7d239.resync",
"name": "rahul",
"command": "add",
"type": "document"
},
"traverse": "http://myserver:7474/db/data/node/4/traverse/{returnType}",
"all_typed_relationships": "http://myserver:7474/db/data/node/4/relationships/all/{-list|&|types}",
"property": "http://myserver:7474/db/data/node/4/properties/{key}",
"self": "http://myserver:7474/db/data/node/4",
"properties": "http://myserver:7474/db/data/node/4/properties",
"outgoing_typed_relationships": "http://myserver:7474/db/data/node/4/relationships/out/{-list|&|types}",
"incoming_relationships": "http://myserver:7474/db/data/node/4/relationships/in",
"extensions": {},
"create_relationship": "http://myserver:7474/db/data/node/4/relationships",
"paged_traverse": "http://myserver:7474/db/data/node/4/paged/traverse/{returnType}{?pageSize,leaseTime}",
"all_relationships": "http://myserver:7474/db/data/node/4/relationships/all",
"incoming_typed_relationships": "http://myserver:7474/db/data/node/4/relationships/in/{-list|&|types}"
}
]
what i tried is :
def messages=[];
for ( i in families) {
messages?.add(i);
}
how i can get familes.data.name in message array .
Here is what i tried :
def messages=[];
for ( i in families) {
def map = new groovy.json.JsonSlurper().parseText(i);
def msg=map*.data.name;
messages?.add(i);
}
return messages;
and get this error :
javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: groovy.json.JsonSlurper.parseText() is applicable for argument types: (com.tinkerpop.blueprints.pgm.impls.neo4j.Neo4jVertex) values: [v[4]]\nPossible solutions: parseText(java.lang.String), parse(java.io.Reader)
Or use Groovy's native JSON parsing:
def families = new groovy.json.JsonSlurper().parseText( jsonAsString )
def messages = families*.data.name
Since you edited the question to give us the information we needed, you can try:
def messages=[];
families.each { i ->
def map = new groovy.json.JsonSlurper().parseText( i.toString() )
messages.addAll( map*.data.name )
}
messages
Though it should be said that the toString() method in com.tinkerpop.blueprints.pgm.impls.neo4j.Neo4jVertex makes no guarantees to be valid JSON... You should probably be using the getProperty( name ) function of Neo4jVertex rather than relying on a side-effect of toString()
What are you doing to generate the first bit of text (which you state is JSON and make no mention of how it's created)
Use JSON-lib.
GJson.enhanceClasses()
def families = json_string as JSONArray
def messages = families.collect {it.data.name}
If you are using Groovy 1.8, you don't need JSON-lib anymore as a JsonSlurper is included in the GDK.
import groovy.json.JsonSlurper
def families = new JsonSlurper().parseText(json_string)
def messages = families.collect { it.data.name }

Resources