How to set value of Json inside array - json

I have the following JSON with in an array and when I try to set a value for this JSON, script passes but value isn't set:
{
"langauageCode": "en-US",
"Test": [{
"_modificationTypeCode": "added",
"allocationTypeCode": "3",
"code": "Test1"
}]
}
My code:
def jsonRequest = slurper.parseText(rawRequest)
def builder = new JsonBuilder(jsonRequest)
builder.content.Test.code[0] ='Test2' //Code value is not getting set to 'Test2'
log.info builder.toPrettyString()
Am I not setting the value correctly?

I assume that slurper is an instance of JsonSlurper. If so, there's no need to use JsonBuilder at all, since sluper returns an instance of a Map. So:
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def req = '''{
"langauageCode": "en-US",
"Test": [{
"_modificationTypeCode": "added",
"allocationTypeCode": "3",
"code": "Test1"
}]
}'''
def slurped = new JsonSlurper().parseText(req)
slurped.Test[0].code = 'Test2'
println JsonOutput.prettyPrint(JsonOutput.toJson(slurped))

Related

Groovy Modifying Json

I'm trying to modify a json which I'm reading from a file:
String response = new File("response.json").text
here is what response looks like:
{
"TerminatingInstances": [
{
"InstanceId": "id",
"CurrentState": {
"Code": 32,
"Name": "shutting-down"
},
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
To modify it I did as follows:
def slurped = new JsonSlurper().parseText(response)
def builder = new JsonBuilder(slurped)
builder.content.TerminatingInstances.InstanceId = "id-updated"
but I get argument type mismatch error, not sure why.
That's because it's an array of instances inside TerminatingInstances
You can either set all of them to the new id with *.:
builder.content.TerminatingInstances*.InstanceId = "id-updated"
Or set just the first one with
builder.content.TerminatingInstances[0].InstanceId = "id-updated"

Extracting JSON response by Groovy Script (SoapUI)

I have response like one below (it's just a fragment of whole response). How can I extract currencies codeName (RUB), name, symbol values? I'm using jsonSlurper and I was able to extract code only. I was trying to pass RUB (to make it dynamical) it didn't work. However if I typed manually RUB it gets proper value.
[{
"name": {
"common": "Russia",
"official": "Russian Federation",
"nativeName": {"rus": {
"official": "Российская Федерация",
"common": "Россия"
}}
},
"tld": [
".ru",
".su",
".рф"
],
"cca2": "RU",
"ccn3": "643",
"cca3": "RUS",
"cioc": "RUS",
"independent": true,
"status": "officially-assigned",
"unMember": true,
"currencies": {"RUB": {
"name": "Russian ruble",
"symbol": "₽"
}}
}]
What I have so far
import groovy.*
import groovy.json.JsonSlurper
import static org.junit.Assert.*;
def responseContent = testRunner.testCase.getTestStepByName("CountryCode").getPropertyValue("Response")
def slurperResponse = new JsonSlurper().parseText(responseContent)
def String countryCurrency =slurperResponse.currencies[0]
def String countryCurrencyCode = countryCurrency.replace("{", "").substring(0,3)
def String countryCurrencyName = slurperResponse.currencies.**RUB**.name.[0]
// in line above I'd like to pass the currency code dynamically)

groovy json builder json.call - to combine single Json output

I have two ArrayList and I need to print in JSON format. I used the below code to print the ArrayList as JSON string
def a = ['R1','R2']
def b = ['R3','R4']
def json = new groovy.json.JsonBuilder()
json set1: a
println groovy.json.JsonOutput.prettyPrint(json.toString())
json set2: b
println groovy.json.JsonOutput.prettyPrint(json.toString())
Actual output
{
"set1": [
"R1",
"R2"
]
}
{
"set2": [
"R3",
"R4"
]
}
It will be printed as two JSON files, but do I need to print/combine all two sets into a single JSON output?
My expected Output
{
"set1": [
"R1",
"R2"
],
"set2": [
"R3",
"R4"
]
}
def a=[111,222,333]
def b=[444,555,666]
def jb = new groovy.json.JsonBuilder()
jb {
set1(a)
set2(b)
}
println jb.toPrettyString()
Or
println new groovy.json.JsonBuilder([ set1:a, set2:b ]).toPrettyString()

how to parse CSV to JSON from 2 CSV Files in Groovy

Please help with parse CSV to JSON from 2 CSV Files in groovy
For example :
CSV1:
testKey,status
Name001,PASS
Name002,PASS
Name003,FAIL
CSV2:
Kt,Pd
PT-01,Name001
PT-02,Name002
PT-03,Name003
PT-04,Name004
I want to input in "testlist" data from CSV2.val[1..-1],CSV1.val[1..-1]
Result should be like :
{
"testExecutionKey": "DEMO-303",
"info": {
"user": "admin"
},
"tests": [
{
"TestKey": "PT-01",
"status": "PASS"
},
{
"TestKey": "PT-02",
"status": "PASS"
},
{
"TestKey": "PT-03",
"status": "FAIL"
}
]
code without this modification (from only 1 csv):
import groovy.json.*
def kindaFile = '''
TestKey;Finished;user;status
Name001;PASS;
Name002;PASS;
'''.trim()
def keys
def testList = []
//parse CSV
kindaFile.splitEachLine( /;/ ){ parts ->
if( !keys )
keys = parts
else{
def test = [:]
parts.eachWithIndex{ val, ix -> test[ keys[ ix ] ] = val }
testList << test
}
}
def builder = new JsonBuilder()
def root = builder {
testExecutionKey 'DEMO-303'
info user: 'admin'
tests testList
}
println JsonOutput.prettyPrint(JsonOutput.toJson(root))
Your sample JSON doesn't match the CSV definition. It looks lile you're using fields [1..-1] from CSV 1, as you stated, but fields [0..-2] from CSV 2. As you only have 2 fields in each CSV that's the equivalent of csv1[1] and csv2[0]. The example below uses [0..-2]. Note that if you always have exactly two fields in your input files then the following code could be simplified a little. I've given a more generic solution that can cope with more fields.
Load both CSV files into lists
File csv1 = new File( 'one.csv')
File csv2 = new File( 'two.csv')
def lines1 = csv1.readLines()
def lines2 = csv2.readLines()
assert lines1.size() <= lines2.size()
Note the assert. That's there as I noticed you have 4 tests in CSV2 but only 3 in CSV1. To allow the code to work with your sample data, it iterates through through CSV1 and adds the matching data from CSV2.
Get the field names
fieldSep = /,[ ]*/
def fieldNames1 = lines1[0].split( fieldSep )
def fieldNames2 = lines1[0].split( fieldSep )
Build the testList collection
def testList = []
lines1[1..-1].eachWithIndex { csv1Line, lineNo ->
def mappedLine = [:]
def fieldsCsv1 = csv1Line.split( fieldSep )
fieldsCsv1[1..-1].eachWithIndex { value, fldNo ->
String name = fieldNames1[ fldNo + 1 ]
mappedLine[ name ] = value
}
def fieldsCsv2 = lines2[lineNo + 1].split( fieldSep )
fieldsCsv2[0..-2].eachWithIndex { value, fldNo ->
String name = fieldNames2[ fldNo ]
mappedLine[ name ] = value
}
testList << mappedLine
}
Parsing
You can now parse the list of maps with your existing code. I've made a change to the way the JSON string is displayed though.
def builder = new JsonBuilder()
def root = builder {
testExecutionKey 'DEMO-303'
info user: 'admin'
tests testList
}
println builder.toPrettyString()
JSON Output
Running the above code, using your CSV1 and CSV 2 data, gives the JSON that you desire.
for CSV1:
testKey,status
Name001,PASS
Name002,PASS
Name003,FAIL
and CSV2:
Kt,Pd
PT-01,Name007
PT-02,Name001
PT-03,Name003
PT-05,Name002
PT-06,Name004
PT-07,Name006
result is:
{
"testExecutionKey": "DEMO-303",
"info": {
"user": "admin"
},
"tests": [
{
"status": "PASS",
"testKey": "PT-01"
},
{
"status": "PASS",
"testKey": "PT-02"
},
{
"status": "FAIL",
"testKey": "PT-03"
}
]
}
but I need exactly the same values for testKey (testKey from CSV1=Kt from CSV2)
{
"testExecutionKey": "DEMO-303",
"info": {
"user": "admin"
},
"tests": [
{
"testKey": "PT-02",
"status": "PASS"
},
{
"testKey": "PT-05",
"status": "PASS"
},
{
"testKey": "PT-03",
"status": "FAIL"
}
]
}

Unexpected character (g) at position 0 when trying to parse json - HttpResponseDecorator

Whenever I try to execute below script I keep getting error, saying unexpected character (g).
Basically I want to be able to parse the json response and be able to get the upstream job name from it.
Script:
#Grapes([
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1'),
#Grab(group='commons-collections', module='commons-collections', version='3.2.1'),
#Grab(group='org.jsoup', module='jsoup', version='1.10.2'),
#Grab(group='org.json', module='json', version='20190722'),
#Grab(group='com.googlecode.json-simple', module='json-simple', version='1.1.1')
])
import static groovyx.net.http.ContentType.*
import groovyx.net.http.HttpResponseException
import groovyx.net.http.RESTClient
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import java.net.*
import java.util.*
import org.json.simple.*
import org.json.simple.parser.JSONParser;
def getRestClient(){
String jenkinsUrl="http://somedomainname:8080"
def restClient = new RESTClient(jenkinsUrl)
return restClient
}
def getJobsInfo(String jobname,RESTClient restClient){
def requrl= '/job/'+jobname+'/lastBuild/api/json/?pretty=true'
def response = restClient.get( path : requrl)
return response
}
def writeToPropertyFile(){
def jsonResponseObject = getJobsInfo("sampleJobName",getRestClient())
println "\n\n\n\n\n Json String :---- "+ jsonResponseObject.toString()
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonResponseObject.toString());
JSONArray upstreamJobInfoArray = jsonObject.getJSONArray("causes");
for (int i = 0; i < upstreamJobInfoArray.length(); i++) {
JSONObject jobCauses = upstreamJobInfoArray.getJSONObject(i);
String upstreamProjectName = jobCauses.getString("upstreamProject");
println upstreamProjectName
}
}
writeToPropertyFile()
Error :
Json String :---- groovyx.net.http.HttpResponseDecorator#6b063470
Caught: Unexpected character (g) at position 0.
Unexpected character (g) at position 0.
at org.json.simple.parser.Yylex.yylex(Yylex.java:610)
at org.json.simple.parser.JSONParser.nextToken(JSONParser.java:269)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:118)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:81)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:75)
at org.json.simple.parser.JSONParser$parse.call(Unknown Source)
at getUpstreamJob.writeToPropertyFile(getUpstreamJob.groovy:39)
at getUpstreamJob.run(getUpstreamJob.groovy:50)
EDIT 1 : START
JSON response that I am trying to parse :
{
"_class": "hudson.model.FreeStyleBuild",
"actions": [
{
"_class": "hudson.model.CauseAction",
"causes": [
{
"_class": "hudson.model.Cause$UpstreamCause",
"shortDescription": "Started by upstream project \"sampleJobName\" build number 712",
"upstreamBuild": 712,
"upstreamProject": "sampleJobName",
"upstreamUrl": "job/sampleJobName/"
},
{
"_class": "hudson.model.Cause$UserIdCause",
"shortDescription": "Started by user Malick, Asif",
"userId": "asifma00",
"userName": "Malick, Asif"
},
{
"_class": "com.sonyericsson.rebuild.RebuildCause",
"shortDescription": "Rebuilds build #300",
"upstreamBuild": 300,
"upstreamProject": "sampleJobName",
"upstreamUrl": "view/ABCProjectView/job/sampleJobName/"
}
]
},
{
"_class": "hudson.model.ParametersAction",
"parameters": [
{
"_class": "hudson.model.StringParameterValue",
"name": "SNAPSHOTNAME",
"value": "ABCDE_12121.2000-2121212121212"
},
{
"_class": "hudson.model.StringParameterValue",
"name": "BUILD_LABEL",
"value": "ABCDE_12121.2000"
}
]
},
{},
{},
{},
{},
{
"_class": "hudson.plugins.parameterizedtrigger.BuildInfoExporterAction"
},
{},
{},
{},
{}
],
"artifacts": [],
"building": false,
"description": null,
"displayName": "#301",
"duration": 1199238,
"estimatedDuration": 1194905,
"executor": null,
"fullDisplayName": "sampleJobName #301",
"id": "301",
"keepLog": false,
"number": 301,
"queueId": 189076,
"result": "SUCCESS",
"timestamp": 1583500786857,
"url": "http://somedomainname:8080/job/sampleJobName/301/",
"builtOn": "Server12345",
"changeSet": {
"_class": "hudson.scm.EmptyChangeLogSet",
"items": [],
"kind": null
},
"culprits": []
}
EDIT 1 : END
I have tried looking at several Stack Overflow issues, but still haven't been able to resolve it.
Please guide.
It's because you're not getting the actual JSON string, you're getting the toString() output on a groovyx.net.http.HttpResponseDecorator class.
You can see it printing it out here (it's easy to miss though... I missed it the first look 🙂):
Json String :---- groovyx.net.http.HttpResponseDecorator#6b063470
I think you need to call jsonResponseObject.data to get the parsed data, and it might even return you a Map parsed form the JSON (so you can get rid of all your JSONObject code). Test it by changing to:
def data = jsonResponseObject.data
println "\n\n\n\n\n Json ${data.getClass().name} :---- $data" jsonResponseObject.toString()
If it is a java.util.Map, you can simplify your second part from:
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonResponseObject.toString());
JSONArray upstreamJobInfoArray = jsonObject.getJSONArray("causes");
for (int i = 0; i < upstreamJobInfoArray.length(); i++) {
JSONObject jobCauses = upstreamJobInfoArray.getJSONObject(i);
String upstreamProjectName = jobCauses.getString("upstreamProject");
println upstreamProjectName
}
To (using data from above):
data.actions.causes.upstreamProject.flatten().each { println it }