Azure Logic App - Parse JSON with dynamic key/name - json

just want to know if and how I can parse a HTTP response with a dynamic name in a JSON?
I used the Azure Management API to receive the managed identities (system- and user assigned managed identities) to receive all managed identities.
With a foreach I am iterating the results.
If a resource has a system assigned managed identity and user assigned managed identity, the response looks like this:
{
"principalId": "<principalId1>",
"tenantId": "<tenantId>",
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
"/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<userAssignedIdentitiesName>": {
"principalId": "<principalId2>",
"clientId": "<clientId>"
}
}
}
Now, I would like to get the <principalId2>.
Unfortunately, the Name of the object is dynamic related to the scope of the resource /subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<userAssignedIdentitiesName>.
How can I parse the JSON to receive the needed <principalId2>?
For all other responses I can easily use the Data operations Parse JSON with the payload I inserted from the HTTP response.
Is there a way to use a wildcard? Otherwise, could I somehow just select the first object of userAssignedIdentities to receive the needed value?

Ok, this should work for you. This is the flow I tested with ...
Initialise JSON
Your JSON as a string, how you do that in your solution may differ slightly.
Initialize XPath Result
Defined as an Array and the expression is ...
xpath(xml(json(concat('{ root: ', replace(variables('JSON'), 'PrincipalId', 'principalId'), '}'))), '(//principalId)[2]')
Initialize Result
A bit more work again but defined as a String and the expression is ...
array(xpath(xml(base64ToString(variables('XPath Result')[0]?['$content'])), '//text()'))[0]
The end result should be your value ...

Related

freeradius 3.0.17 rlm_rest parsing json response

I'm trying to authenticate RADIUS Requests against a RESTful API (provided by Customer) using rlm_rest.
The problem I am facing is that
response JSON format (of REST API provided by Customer), is different from rlm_rest default format (indicated in etc/raddb/mods-enabled/rest).
My Virtual Server configuration as below:
Default
authorize {
...
...
rest
if (ok) {
update control {
Auth-Type := rest
}
}
}
mods-enabled/rest
authorize {
uri = "https://3rd-party-API/auth"
method = 'post'
body = 'json'
chunk = 0
tls = ${..tls}
data = '{
"code": 1,
"identifier": %I,
"avps": {
"User-Name": ["%{User-Name}"],
"NAS-IP-Address": ["%{NAS-IP-Address}"],
"Called-Station-Id": ["%{Called-Station-Id}"],
"Calling-Station-Id": ["%{Calling-Station-Id}"],
"NAS-Identifier": ["%{NAS-Identifier}"]
}
}'
}
Result
/sbin/radiusd -Xxx
HTTP response code
200
JSON Body
{
"code": "2",
"identifier": "91",
"avps": {
"Customer-Attributes": "Hello"
...
...
"Acct-Interim-Interval": "300"
}
}
The JSON structure is different from the example, and xlat parse
"code"
"identifier"
"avps"
And, of course, xlat finds no attributes match with the dictionary, while it cannot find "avps" and won't dig deeper.
So I was wondering is there anyway to either
Define the response JSON structure for xlat to parsing
Insert a "is_json" or "do_xlat" flag into the JSON ("avps"), and hope xlat will then dig deeper
Save the JSON and parse with exec/rlm_exec (using JQ or any other bash/JSON tools)
Please advise if there is any workaround. Thanks!
In FreeRADIUS version 4, there's a rlm_json module, which implements a custom node query language based on xpath (jpath), it is extremely limited and only supports some very basic queries (feel free to enhance it via PR :) ).
Below is an example I pulled out of my library of customer configurations. You can see here it's pulling out two keys (externalID and macAddress) from the root level of the JSON doc and assigning them to a couple of custom attributes (Subscriber-ID and Provisioned-MAC).
map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
&Subscriber-ID := '$.externalId'
&Provisioned-MAC := '$.macAddress'
}
The xlat expansion can also be modified to send HTTP body data. Just put a space after the URL and pass your custom JSON blob.

Is there an alternative to "type": "undefined" in JSON?

I'm working with Amazon API Gateway. I am creating a model for an REST API. The model gets hung up on:
"tiers": {
"type": "array",
"items": {
"type": "undefined"
}
}
The API data model uses JSON schema draft 4.
The error returned is:
Invalid model specified: Validation Result: warnings : [], errors :
[Invalid model schema specified]
Anyone run into this before?
Things I've tried:
Removing this property = script creates model
Changing "Undefined" to "null" = script creates model
The "null" seems like the right option but, I've not been able to back it up. Some guidance and/or clarification would be greatly appreciated.
Thanks,
Todd
You don't seem to be actually defining a schema for your data, refer to the API gateway docs to re-define your model.
undefined is not a valid json value, even though it is valid in javascript. From the official json standard (ECMA-404, Section 5):
A JSON value can be an object, array, number, string, true, false, or
null.
For json, use null instead of undefined: { "something": null }
Using null instead of undefined is definitely not ideal, but it's a standard you can count on when consuming third-party services.

What is wrong with this Json array syntax?

I am sending a web request to Firebase Cloud Messaging to send a message. The raw data as sent with Content-Type:application/json" is:
{ "to":"ecO8y..._D", "data": [ {"msisdn":"+1111111" }, {"b":"c"} ] }
Firebase responds with this error message:
Field "data" must be a JSON array: [{"msisdn":"+1111111"},{"b":"c"}]
Is there something wrong with the text that I have entered for the data field?
I think the "JSON array" wording is confusing here. The data needs to be a JSON object with a single level of properties, so:
{
"to":"ecO8y..._D",
"data": {
"msisdn":"+1111111",
"b":"c"
}
}
When you try to send data from your application server to FCM, you will get 400 error, if data element contains hierarchical data or array of elements.
Data with one level of child element works.
{"message":{"topic":"users","data":{"name":"srao","pho":"38743"}}}
Data with array of element doesn't work.
{"message":{"topic":"users","data":[{"name":"grag","pho":"38743"},{"name":"boney","pho":"3899943"}]}}
Data with multiple levels or hierarchy doesn't work.
{"message":{"topic":"users","data": {"person" : {"name":"srao","pho":"38743"}}}}

Is it possible to send an array with the Postman Chrome extension?

I've been using Postman Chrome extension to test out my API and would like to send an array of IDs via post. Is there a way to send something list this as a parameter in Postman?
{
user_ids: ["1234", "5678"]
}
You need to suffix your variable name with [] like this:
If that doesn't work, try not putting indexes in brackets:
my_array[] value1
my_array[] value2
Note:
If you are using the postman packaged app, you can send an array by selecting raw / json (instead of form-data). Also, make sure to set Content-Type as application/json in Headers tab.
Here is example for raw data {"user_ids": ["123" "233"]}, don't forget the quotes!
If you are using the postman REST client you have to use the method I described above because passing data as raw (json) won't work. There is a bug in the postman REST client (At least I get the bug when I use 0.8.4.6).
For me did not work with array[0], array1, .. or array[], array[], ... .
It works more simply:
If you want an array of dicts, try this:
Here is my solution:
use form-data and edit as below:
Key Value
box[] a
box[n1] b
box[n2][] c
box[n2][] d
and you will get an array like this:
{"box":{"0":"a","n1":"b","n2":["c","d"]}}
It is important to know, that the VALUE box is only allowed to contain a numeral value (no specifiers).
If you want to send e.g. an array of "messages" with Postman, each having a list of key/value pairs, enter e.g. messages[][reason] into the KEY box and the value of reason into the VALUE box:
The server will receive:
{"messages"=>[{"reason"=>"scrolled", "tabid"=>"2"}, {"reason"=>"reload", "tabid"=>"1"}], "endpoint"=>{}}
I also had that problem, and solved it by doing the following:
1 - Going to the request header configuration and added the following:
Accept : application/json, text/plain, */*
Content-Type : application/json;charset=UTF-8
2 - To send the json array, I went to raw json format and set the user_ids to array:
user_ids: ["bbbbbbbbbb","aaaaaaaaaa","987654321","123456789"]
Set Body as raw and form the array as follows:
As mentioned by #pinouchon you can pass it with the help of array index
my_array[0] value
my_array[1] value
In addition to this, to pass list of hashes, you can follow something like:
my_array[0][key1] value1
my_array[0][key2] value2
Example:
To pass param1=[{name:test_name, value:test_value}, {...}]
param1[0][name] test_name
param1[0][value] test_value
Go to Header and select Content-Type = application/json then go to body and select raw and then pass an array.
this worked for me. to pass an array of Item object {ItemID,ColorID,SizeID,Quntity}
in headers set
content-type : application/x-www-form-urlencoded
In body select option
x-www-form-urlencoded
and insert data as json array
user_ids : ["1234", "5678"]
This also works for lists within the object:
Id:37
IdParent:26
Name:Poplet
Values[0].Id:1349
Values[0].Name:SomeName
Values[1].Id:1350
Values[1].Name:AnotherName
the equivalent JSON would be:
{
"Id": 37,
"IdParent": 26,
"Name": "Poplet",
"Values": [
{
"Id": 1349,
"Name": "SomeName"
},
{
"Id": 1350,
"Name": "AnotherName"
}
]
}
{
"data" : [
{
"key1" : "value1",
"key2" : "value2"
},
{
"key01" : "value01",
"key02" : "value02"
},
{
"key10" : "value10",
"key20" : "value20"
}
]
}
You can pass like this.
In form-data you can pass a array like this
and in backend you will fetch it like a
"tags"=>["aaaa", "bbb"]
In my case I've to pass two values in a array so I write it two times
Choose either form-data or urlencoded and use the same key "user_ids". The server should receive it as an array.
In form-data,
key value
user_ids[] 1234
user_ids[] 5678
My back-end is written in Ruby on Rails. This is how I sent the array params using Postman. It worked for me.
UPDATE
I'm using x-www-form-urlencoded. I believe it will work too for form-data.
To send an array using form data there's no need to use brackets.
Just send that specific array using the same name in multiple fields.
Like:
my_array:value_1
my_array:value_2
Although this question has already accepted a solution still that solution has a drawback that is we have to repeat the key (Array name) again and again as one key is accepting only one value. Like this:
Imagine we have 10 values or more, should we repeat the same Array name each time? The programmatic answer is NO. Then we should do the following that is a better approach.
Select the form-data as usual
Type Array name in the Key field
Pass the Array in Value field
Like this:
Now, you should be able to send the Array, but wait, this won't be stored in Database like that in my case with MongoDB. So what you have to do is, use the following piece of code to send it like an Array in the Database:
First, we need to parse it using JSON, like this
let user_ids = JSON.parse(body.user_ids);
Now, you can send user_ids variable to database like an Array
That's All!
I tried all solution here and in other posts, but nothing helped.
The only answer helped me:
Adding [FromBody] attribute before decleration of parameter in function signature:
[Route("MyFunc")]
public string MyFunc([FromBody] string[] obj)
Supposing you have the array of object below,
features: [
{
title: { type: String },
type: { type: String },
},
],
To add the values on the form data on the postman, add it this way
features[title]
features[type]
Check also the image below
Here is something that worked for me
{
"user_ids":["[1234, 5678]"]
}
I believe it depends on how the backend is setup most of the time.
N.B Now we are in 2022 if All of the above solutions didn't, just don't panic. pass array name with is value without a bracket and the add it multiple time, just link how the image below is showing. it should work just fine. If It does work, buy me some coffee, hhh
In my case I need to send array of objects, I sent it like this
Request header configuration and added the following
Accept: application/json
You need to suffix your key variable name with []
like key[0][name]
You can insert it in "bulk-edit" mode
Body section in form-data on right side click Bulk Edit and added the following
items[0][prod_id]:174336
items[0][item_weight]:3.400
items[0][item_qty]:1
items[0][item_selected_melting]:92
items[0][item_remarks]:
items[1][prod_id]:12345

Get custom JQGrid JSON data in gridComplete method

Here is a typical JQGrid JSON response:
{
"page":1,
"records":537,
"rows":[..],
"rowCount":10,
"total":54
}
Along with this, I want to send additional custom data. For example, I'd like to send the database time of the last search so that I can lazy-reload my grid whenever changes have occurred since then. Here is how I would like to send that data:
{
//Custom name-value pairs:
"nameValues":{"lastSearchTime":"2011/09/01:14:14:56"},
//Normal JSON data:
"page":1,
"records":537,
"rows":[..],
"rowCount":10,
"total":54
}
The problem is that JQGrid swallows up the JSON response rather than forwarding it to the gridComplete method. In other words, params is undefined in the following function:
function myGridComplete (params){
//params is undefined!
var JSONResponse = ?;//I need your help here!!!
globalGridVariables.lastSearchTime = JSONResponse.nameValues.lastSearchTime;
//Rest of grid complete method
..
}
Please let me know if there is a way to get access to the JSON response object in the gridComplete method, or if there is another supported way to add custom data to a JSON response.
Thanks much!
Note: I don't want to send this as a hidden column, because that would be inefficient.
You can use loadComplete instead of gridComplete. The loadComplete event has one parameter (for example data) which represent the full data from the server response inclusive all of your extensions.
Alternative you can rename the nameValues to userdata and use $('#list').jqGrid('getGridParam', 'userData') to get the value. See here for more information.
Moreover you can consider to use more HTTP caching (see here and here) for the aims which you described in your question.
You can use beforeProcessing that has the deserialized response and gets active before gridComplete and loadComplete.
For example:
beforeProcessing: function (data, status, xhr) {
myArray = data.rows;
}
And just to make it more clearer from the documentation:
Below is the execution order of the events when a ajax request is made
beforeRequest
loadBeforeSend
serializeGridData
loadError
beforeProcessing
gridComplete
loadComplete