Azure CI/CD Json transformation on array - json

When I'm creating a Task for an Azure DevOps release, can I transform the value of an object in an array, based on the "key" of the object?
As an example, I'm copying the example Json file from this article, which is this.
{
"Data": {
"DefaultConnection": {
"ConnectionString": "Data Source=(LocalDb)\\MSDB;AttachDbFilename=aspcore-local.mdf;"
},
"DebugMode": "enabled",
"DBAccess": {
"Administrators": ["Admin-1", "Admin-2"],
"Users": ["Vendor-1", "vendor-3"]
},
"FeatureFlags": {
"Preview": [
{
"newUI": "AllAccounts"
},
{
"NewWelcomeMessage": "Newusers"
}
]
}
}
}
What I have is something more like this, look at the "FeatureFlags" array. My array contains a list of "key"/"value" objects similar to this. I need to be able to transform the object in the array that matches a key, and have the transform process replace the "value" property value.
{
"Data": {
"DefaultConnection": {
"ConnectionString": "Data Source=(LocalDb)\\MSDB;AttachDbFilename=aspcore-local.mdf;"
},
"DebugMode": "enabled",
"DBAccess": {
"Administrators": ["Admin-1", "Admin-2"],
"Users": ["Vendor-1", "vendor-3"]
},
"FeatureFlags": {
"Preview": [
{
"key": "newUI",
"value": "AllAccounts"
},
{
"key": "NewWelcomeMessage",
"value": "Newusers"
}
]
}
}
}
For example, I want to change the value of "Newusers" in the object with a key of NewWelcomeMessage, to "AllUsers".
In the Azure Release "Variables" tab, can I simply use this as the "Name", Data.FeatureFlags.Preview.NewWelcomeMessage, and AllUsers as the value for it to transform the value for the correct object, or will this fail?
This pattern seems to work with XML, see this.

Related

Can't access property from JSON file, why?

Here's the JSON:
data = {
"company_name": "חברה לדוגמה",
"audit_period_begin": "01/01/2021",
"audit_period_end": "31/12/2021",
"reports": [
{
"type": {
"he": "מאזן",
"en": "Balance Sheets"
},
"fin_statement": "BS",
"sections": [
{
"section_name": {
"he": "נכסים שוטפים",
"en": "Current Assets"
},
"totals": {
"2020": {
"final_total_local": 100000,
"final_total_foreign": 0
},
"2021": {
"final_total_local": 110000,
"final_total_foreign": 0
}
},
"subsections": [
{......(the rest is irrelevant)
and I'm trying to call:
data.reports[0].sections[0]['totals']
but I get an error:
Element implicitly has an 'any' type because expression of type '"totals"' can't be used to index type
and can't read the property, why?
After you acquire data.reports[0].sections[0].totals probably successfully you are accessing it as if it was an array, whereas it's an object. try data.reports[0].sections[0]['totals']["2020"] instead of data.reports[0].sections[0]['totals'][2020]. This is just a guess as you didn't provide enough code.

How to select JSON array (JSON substring) in JasperReport with JSONQL?

I want to create a report using Jaspersoft Studio with a json file as datasource. I want to select some fields from this json and also a substring of the original json. This should be done by jsonql.
First, an example with the "JSON language" in JasperSoftStudio:
gives the following result:
This is exactly what I want to have, the delivery note number as a field, and the barcodes as an array of objects / json substring.
What I am not able to do is, to achieve this with jsonql. The following query
gives the result
The following json was used for this example
{
"tour": {
"shipments": [
{
"containers": [
{
"boxes": [
{
"customerModule": "DEFG",
"deliveryDateTime": "2022-04-25 11:49:24.834000",
"boxNumber": 2
},
{
"customerModule": "ABCD",
"deliveryDateTime": "2022-04-25 11:50:24.810000",
"boxNumber": 1
}
],
"licensePlate": "123"
}
],
"deliveryNoteNumber": "6785000",
"barcodes": [
{
"content": "barcode_01_04"
},
{
"content": "barcode_03_04"
},
{
"content": "barcode_04_04"
}
]
},
{
"containers": [
{
"boxes": [
{
"customerModule": "ZXYV",
"deliveryDateTime": "2022-04-25 11:51:24.834000",
"boxNumber": 1
},
{
"customerModule": "UHGI",
"deliveryDateTime": "2022-04-25 11:52:24.834000",
"boxNumber": 2
}
],
"licensePlate": "987"
}
],
"deliveryNoteNumber": "6785001",
"barcodes": [
{
"content": "Barcode_01_04"
},
{
"content": "Barcode_02_04"
},
{
"content": "Barcode_04_04"
}
]
}
],
"handlingDateTime": "2022-04-25 11:50:24.883000"
}
I tried to use this documentation, but I could not get it working.
The JSONQL data source doesn't properly convert arrays to Strings for some reason.
What you can do is change the barcodes field from java.lang.String to java.lang.Object. You can do that by clicking Edit in the Fields tab and changing the Class Type for the field.
With java.lang.Object as field type, the field value will be the underlying JSON (Jackson) model array object. You can do $F{barcodes}.toString() if you need to explicitly convert it to a String in an expression.

How to feed a value into a field in a json array in Gatling?

I am using Gatling to test an API that accepts a json body like below:
{
"data": {
"fields": [
{
"rank": 1
},
{
"name": "Jack"
}
]
}
}
I have created a file feeder.json that contains array of json objects like above.
Below is the feeder.json
[
{
"data": {
"fields": [
{
"rank": 1
},
{
"name": "Jack"
}
]
}
}
]
I have created another file template.txt that contains the template of above json.
Below is the template.txt
{
"data": {
"fields": [
{
"rank": ${data.fields[0].rank} //this is not working
},
{
"name": "Jack"
}
]
}
}
val jsonFeeder = jsonFile("feeder.json").circular
scenario("Test scenario")
.feed(jsonFeeder)
.exec(http("API call test")
.post("/data")
.body(ElFileBody("template.txt"))
.asJson
.check(status is 200))
I am feeding the feeder.json and also sending json body from template.json. The 'rank' property values should get set from feeder into the json body. But I am getting an error 'Map named 'data' does not contain key 'fields[0]'. Stuck with this.
Access by index syntax uses parens, not square braces.
#{data.fields(0).rank}

jmespath :select json object element based on other (array) element in the object

I have this JSON
{
"srv_config": [{
"name": "db1",
"servers": ["srv1", "srv2"],
"prop": [{"source":"aa"},"destination":"bb"},{"source":"cc"},"destination":"cc"},]
}, {
"name": "db2",
"servers": ["srv2", "srv2"],
"prop": [{"source":"dd"},"destination":"dd"},{"source":"ee"},"destination":"ee"},]
}
]
}
I try to build a JMESPath expression to select the prop application in each object in the main array, but based on the existence of a string in the servers element.
To select all props, I can do:
*.props [*]
But how do I add condition that says "select only if srv1 is in servers list"?
You can use the contains function in order to filter based on a array containing something.
Given the query:
*[?contains(servers, `srv1`)].prop | [][]
This gives us:
[
{
"source": "aa",
"destination": "bb"
},
{
"source": "cc",
"destination": "cc"
}
]
Please mind that I am also using a bit of flattening here.
All this run towards a corrected version of you JSON:
{
"srv_config":[
{
"name":"db1",
"servers":[
"srv1",
"srv2"
],
"prop":[
{
"source":"aa",
"destination":"bb"
},
{
"source":"cc",
"destination":"cc"
}
]
},
{
"name":"db2",
"servers":[
"srv2",
"srv2"
],
"prop":[
{
"source":"dd",
"destination":"dd"
},
{
"source":"ee",
"destination":"ee"
}
]
}
]
}

Insert whole json to the field in Dynamo DB using AWS Step Functions

I am trying to PutItem into the DynamoDB using the AWS Step Functions.
I managed to save Item with simple string fields (S), but one of the fields should store the whole JSON payload. So it should be the Map (M).
But my payload includes nested Maps also.
Example JSON:
{
"firstMap": {
"field": "something",
},
"secondMap": {
"nestedMap": {
"field": "something",
},
"anotherNestedMap": [
{
"field": "something",
"oneMoreNestedMap": {
"andOneMore": {
"field": "something",
},
"arrayComesHere": [
{
"andAgainNestedMap": {
"field": "something",
},
"andAgain": [
{
"field": "something",
"alsoNestedArray": [
{
"field": "something"
}
]
}
]
}
]
},
"letItBeFinalOne": [
{
"field": "something"
}
]
}
]
...
What I want to do is to just say, hey Step Function, insert please this whole JSON into the item field like this
"Item": {
...
"whole_payload": {
"M.$": "$"
},
} ...
But it fails, cause it accepts only one Map to be handled.
So I need to directly iterate over all nested maps and mark them with 'M'.
Is there a way to make it resolve it by itself?
Like in Typescript I can use aws.DynamoDB.DocumentClient() and just put a whole JSON to the field and it resolves all the maps by itself
Came across a thread for similar request to AWS Step functions team. New feature enhanced allows something closer to what you are looking for.
Sample snippet:
...
"Parameters": {
"TableName" : "dynamodb-table",
"Item":{
"requestId" : {
"S.$": "$.requestId"
},
"payload": {
"S.$":"States.JsonToString($)"
}
}
...
AWS Reference