Extract field id in Vaadin json response by JMeter - json

Currently I'm trying to extract field id from Vaadin json response to detect all comboboxes (RTFComboBox) and process them further. Example response (cut down):
for(;;);[{
"syncId": 113,
"clientId": 113,
"changes": [],
"state": {
"1273": {
"caption": "",
"styles": ["tokenfield", "tokentextfield"]
},
"1274": {
"styles": ["RTFTokenField"]
},
"1275": {
"width": "185.0px",
"immediate": true,
"styles": ["RTFTokenField", "RTFComboBox", "tiny"],
"registeredEventListeners": ["focus"]
}
}
}]
What I need is to get id number (here 1275), I can deal with "for(;;)" junk but I can't extract proper id values. I was trying to use Regex Extractor but this solution isn't very flexible (or I just can't write proper expression).
Any ideas how to get parent id when styles child array contains 'RTFComboBox'? Maybe here is required some more complex solution, like some script in groovy, than JMeter's JSON Extractor?

I would advice, to write a groovy script in the beanshell processor, parse the JSON and then get all the keys for the state object. Here's the code snippet, please make sure you add the java-json.jar in the JMETER_HOME/lib folder
try {
String jsonString = prev.getResponseDataAsString();
JSONArray jsonArray = new JSONArray(jsonString);
JSONObject object = jsonArray.getJSONObject(0);
JSONObject states = object.getJSONObject("state");
String keys[] = states.getNames(states);
for(int i=0; i< keys.length; i++) {
log.info(keys[i]);
}
} catch (JSONException e) {
e.printStackTrace();
}

I've finally made it using JsonSlurper, this is my JSR223 PostProcessor script:
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def response = jsonSlurper.parseText(prev.getResponseDataAsString().drop(8))
//drop to remove for(;;); junk preventing proper parse
def map = [:]
response.state[0].each {k, v -> if(v.styles != null && v.styles.contains("RTFComboBox")) {map.put(k, v)}}
//map contains key (field id-most important to me) and key (rest of values in node)
If you need some specific value, just in map.put line set v.field, i.e.:
map.put(k, v.immediate)

Related

How to replace a JSON value stored in a JSON file and use that in a Rest Assured test

I have a set of input data files in JSON and I am trying to replace a value present in a JSON file and use that value to do a post request in restAssured
The JSON file has
{
"items": [
{
"item_ref": 241,
"price": 100
}
]
}
jsonbody below is a String of the above JSON file
This is the code that fails:
JSONObject jObject = new JSONObject(jsonbody);
jObject.remove("item_ref");
jObject.put("item_ref","251");
System.out.println(jObject);
This is what I am getting:
{"item_ref":"251","items":[{"item_ref":241,"price":100}]}
What I want is {"items":[{"item_ref":251,"price":100}]}
I also tried
JSONObject jObject = new JSONObject(jsonbody);
jObject.getJSONObject("items").remove("item_ref");
jObject.getJSONObject("items").put("item_ref","251");
System
But it says JSONObject["items"] is not a JSONObject.
All I need is to replace the 241 with 251. Is there an easier way to do this?
In general if we have a predefined JSON body file and if we want to replace some of the values in the body and use that in our POST calls within RestAssured, is there any easier way to do it?
The problem is - field item_ref and price are not in JSON Object as you think they are.
They are in JSON Array which contains JSON Objects. In order to modify that value, you have to get elements of the array and THEN execute very similar code you wrote.
Check this out:
JSONObject jObject = new JSONObject(jsonbody);
JSONArray array = jObject.getJSONArray("items");
JSONObject itemObject = (JSONObject) array.get(0); //here we get first JSON Object in the JSON Array
itemObject.remove("item_ref");
itemObject.put("item_ref", 251);
The output is:
{"items":[{"item_ref":251,"price":100}]}
Also, you can create a Hashmap:
HashMap<String,String> map = new HashMap<>();
map.put("key", "value");
RestAssured.baseURI = BASE_URL;
RequestSpecification request = RestAssured.given();
request.auth().preemptive().basic("Username", "Password").body(map).put("url");
System.out.println("The value of the field after change is: " + map.get("key"));

Apache Nifi manipulate nested json with Execute Script

I am looking for a way to update the given Json's values and keys in a dynamic way. The way the Json is delivered is Always the same(in Terms of structure). The only Thing that differs is the amount of Data that is provided. So for example there could sometimes be 30, sometimes only 10 nestings etc.
…
"ampdata": [
{
"nr": "303",
"code": "JGJGh4958GH",
"status": "AVAILABLE",
"ability": [ "" ],
"type": "wheeled",
"conns": [
{
"nr": "447",
"status": "",
"version": "3",
"format": "sckt",
"amp": "32",
"vol": "400",
"vpower": 22
}
]
}
As Json uses other keys/values than I in my DB, I Need to convert them. Additionally I Need to Change some values if they match explicit strings.
So for example: "Code" has to be renamed to"adrID" and "sckt" should map to the values "bike".
I tried a simple Groovy-Script to remove the key and or Change the value. There is no Problem in changing values, but in changing the key itself. So I tried removing the key and adding a new key. Unfortunately I could not figure out how to add a new key:value to the given json. So how can I add a new pair of key:value or rename the key, if that´s possible. Have a look at my code-example
def flowFile = session.get()
if (!flowFile) return
try {
flowFile = session.write(flowFile,
{ inputStream, outputStream ->
def text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
def obj = new JsonSlurper().parseText(text)
def objBuilder = new JsonBuilder(obj)
// Update ingestionDate field with today's date
for(i in 0..obj.data.size()-1){
obj.data[0].remove("postal_code")
objBuilder.data[0].postal_code=5
}
// Output updated JSON
def json = JsonOutput.toJson(obj)
outputStream.write(JsonOutput.prettyPrint(json).getBytes(StandardCharsets.UTF_8))
} as StreamCallback)
flowFile = session.putAttribute(flowFile, "filename", flowFile.getAttribute('filename').tokenize('.')[0]+'_translated.json')
session.transfer(flowFile, REL_SUCCESS)
} catch(Exception e) {
log.error('Error during JSON operations', e)
session.transfer(flowFile, REL_FAILURE)
}
...
def obj = new JsonSlurper().parse(inputStream, "UTF-8")
obj.data.each{e->
def value = e.remove("postal_code")
//set old value with a new key into object
e["postalCode"] = value
}
//write to output
def builder = new JsonBuilder(obj)
outputStream.withWriter("UTF-8"){ it << builder.toPrettyString() }

Accessing JSON response

I am storing the response of a REST Get request and trying to access as below,
final JSONObject receivedItem = new JSONObject(response.readEntity(String.class));
This is the sample response,
[
{
"timeStamp": 1511136000000,
"contextKeys": [
{
"tKey": "Test1",
"contextKey": "Location",
"contextValue": "San Jose",
"eCount": 3
},
{
"tKey": "Test1",
"contextKey": "Name",
"contextValue": "User1",
"eCount": 3
}
}
]
And i am getting the below error,
org.json.JSONException: A JSONObject text must begin with '{' at character 1
at org.json.JSONTokener.syntaxError(JSONTokener.java:496)
at org.json.JSONObject.<init>(JSONObject.java:180)
at org.json.JSONObject.<init>(JSONObject.java:403)
Any clues ?
Thanks
As Rajkumar pointed out, in your example there is a missing close bracket - but this may just be a simple typing error.
The actual error message is saying A JSONObject text must begin with '{' which is because JSON objects are exactly that, objects. You need to use a JSONArray to parse your example JSON as follows:
final JSONArray receivedItem = new JSONArray(response.readEntity(String.class));
This may change some of your other code to handle this as an array vs an object.
If your problem is with storing and accessing json response try this response instead;
I am presuming that you are using javascript; Anyways, core idea is the same;
var jsonStorage;
$.getJSON('your url',(json) => {
jsonStorage = json;
});
console.log(jsonStorage) //your jsonresponse is now available here;

Getting the name of each field in JSON

I'm trying to parse a random JSON file in Grails.
First I need to get the name of each field
For example, given below JSON file,
{
"abbreviation": "EX",
"guid": "1209812-1l2kj1j-fwefoj9283jf-ae",
"metadata": {
"dataOrigin": "Example"
},
"rooms":
[
],
"site": {
"guid": "1209812-1l2kj1j-fwefoj9283jf-ae"
},
"title": "Example!!"
}
I want to find out the structure of the JSON file(lists of keys maybe), for example I want to save the list of keys such as 'abbreviation', 'guid', 'metadata', 'rooms', 'site', 'title' from this JSON file.
How would I do this?
(We need the name of the keys in order to get the value of that key, so with a arbitrarily structured JSON file I need to find out the keys first)
You can try below code
def filePath = "JSONFILE.json"
def text = new File(filePath).getText()
def json = JSON.parse(text)
def jsonKeys = json.collect{it.key}
println(jsonKeys)
This will print all json keys
From what dmahaptro commented, I figured out how to get all the keys within a JSON object.
Here is a simple sample code I wrote to test it
String jsonFile = new JsonSlurper().parseText(new URL(path to the json file).text)
JSONArray jsonParse = new JSONArray(jsonFile)
int len = jsonParse.length()
def names = []
def keys = []
(0..len-1).each {
JSONObject val = jsonParse.getJSONObject(it)
int numKeys = val.length()
names = val.names()
keys = val.keySet()
(0..numKeys-1).each {
def field = names[it]
println field +" : " + val."${field}"
}
}
This will print the key:value pair given a JSON file.

JSON to Groovy with JsonSlurper and unknown "string"

I am writing a Grails/Groovy app and I have a JSON object with a "string" name (grommet and widget) inside the params member that can change. That is, next time it might be acme and zoom. Here is the JSON:
def jx = """{
"job": "42",
"params": {
"grommet": {"name": "x", "data": "y"},
"widget": { "name": "a", "data": "b"}
}
}"""
I am trying to figure out how to get the string grommet . Code so far:
def dalist = new JsonSlurper().parseText(jx)
println dalist.job // Gives: 42
println dalist.params // Gives: [grommet:[name:x, data:y], widget:[name:a, data:b]]
println dalist.params[0] // Gives: null
Any idea how to get the string grommet? Iama going to keep hitting my head against a wall.
The params key on the JSON object is associated with a JSON object, not an array, so you cannot access it by index. JsonSlurper maps JSON objects to Groovy Maps, so you can access params by its keys, which are strings, e.g. dalist.params.grommet, which will give you the map [name: 'x', data: 'y'].
To access the keys on the params you can do dalist.params.keySet(), which will give you the list ['grommet', 'widget']. If you are interested in just knowing params keys, that should do the trick. If you need to get the 'grommet' string for some reason, you can do it by accessing the first element on that list, i.e. dalist.params.keySet()[0], but i don't know why you would want to know that. And i'm not sure if it is guaranteed that the first key of that map will always be 'grommet', as JSON objects are unordered by the spec (from json.org: An object is an unordered set of name/value pairs), but, in turn, Groovy maps are ordered (the default implementation is LinkedHashMap)... so i would assume that the order is preserved when parsing JSON to the Groovy world, but i'd try not to rely on that particular behavior hehe.
It's Map instance, try:
def params = dalist.params.entrySet() as List // entrySet() returns Set, but it's easier to use it as a List
println params
println params.size()
println params[0]
println params[0].key
println params[0].value
This might help you.
import groovy.json.JsonSlurper;
def jx='{"job":"42","params":{"grommet":{"name":"x","data":"y"},"widget":{"name":"a","data":"b"}}}'
def dalist = new JsonSlurper().parseText( jx )
assert dalist.params.getClass().name == "java.util.HashMap";
assert dalist.params.size() == 2;
def keys = dalist.params.collect{ a, b -> a}; // returns "[grommet, widget]"
assert !!dalist.params.get( "grommet" ) == true