Snaplogic - Expression Language Syntax - unique array value - expression

I am using following EL
jsonPath($, "$array.map({id: value.get('id'), type: value.get('type') })")
which produces the next variable ...
But the key(id) is not kept unique ?!
[{
"id": "1",
"type": "1"
},
{
"id": "1",
"type": "2"
},
{
"id": "2",
"type": "1"
}]
What can i use in snaplogic expression language or a snap to get the following unique key array :
[{
"id": "1",
"types": ["1", "2"],
{
"id": "2",
"type": ["1"]
}]
Any ideas?

Use Group By Fields snap to group based on id and then use a simple mapper to create the desired JSON. Please note that you have to sort the incoming documents by id before doing the group by.
Sample Pipeline
Final Mapper expressions
$groupBy.id mapped to id
jsonPath($, "$groups[*].type") mapped to types
Resulting output

Related

How to extract multiple json values from a Json response

I am trying to extract multiple values from a JSON response on my jmeter script. Below is sample of my response:
{
"startDate": "2018-12-10T15:36:34.400+0000",
"userId": "7211111-2fa90",
"createdBy": "TEST",
"note": {
"content": "Application Submitted "
},
"Type": "SUBMITTED"
},
"currentEventState": "CLOSED",
{
"Xxxx": "test",
"Loc": null,
"Zipcode": [],
"Locality": 82,
"Address": {
"Add": 12302,
"Add2": "place",
"Zip": {
"Phone": "home",
"Email": "test#test.com"
}
},
"state": "MD",
"Cost": "E "
},
"AppID": "cd8d98e6-c2a79",
"Status": "CLOSED",
}
I am trying to extract userid and AppID for the case if the TYPE is Submitted and Status is Closed.I tried using the Json extractor with $.[?(#.Type=="SUBMITTED")].[*].?(#.Status=="CLOSED").userid,APPID, but couldn't get the expected result. Could anyone guide me on this.
You need to use an inline predicate to combine 2 clausees and a semicolon in order to store results into 2 separate JMeter Variables.
Add JSON Extractor as a child of the request which returns above JSON
Configure it as follows:
Names of created variables: userid;appid
JSON Path Expressions: $..[?(#.Type=='SUBMITTED' && #.Status == 'CLOSED')].userId; $..[?(#.Type=='SUBMITTED' && #.Status == 'CLOSED')].AppID
Default values: NA;NA
Here is the demo of single expression working fine:
And here are extracted values reported by the Debug Sampler:

JMESPath current array index

In JMESPath with this query:
people[].{"index":#.index,"name":name, "state":state.name}
On this example data:
{
"people": [
{
"name": "a",
"state": {"name": "up"}
},
{
"name": "b",
"state": {"name": "down"}
},
{
"name": "c",
"state": {"name": "up"}
}
]
}
I get:
[
{
"index": null,
"name": "a",
"state": "up"
},
{
"index": null,
"name": "b",
"state": "down"
},
{
"index": null,
"name": "c",
"state": "up"
}
]
How do I get the index property to actually have the index of the array? I realize that #.index is not the correct syntax but have not been able to find a function that would return the index. Is there a way to include the current array index?
Use-case
Use Jmespath query syntax to extract the numeric index of the current array element, from a series of array elements.
Pitfalls
As of this writing (2019-03-22) this feature is not a part of the standard Jmespath specification.
Workaround
This is possible when running Jmespath from within any of various programming languages, however this must be done outside of Jmespath.
This is not exactly the form you requested but I have a possible answer for you:
people[].{"name":name, "state":state.name} | merge({count: length(#)}, #[*])
this request give this result:
{
"0": {
"name": "a",
"state": "up"
},
"1": {
"name": "b",
"state": "down"
},
"2": {
"name": "c",
"state": "up"
},
"count": 3
}
So each attribute of this object have a index except the last one count it just refer the number of attribute, so if you want to browse the attribute of the object with a loop for example you can do it because you know that the attribute count give the number of attribute to browse.

Parameterize POST body in JMeter HTTP POST

I am using Apache JMeter to run a few performance tests against RESTFUL API for an application that we have developed. I have an end point "api/create/empListJob", which basically adds one or more employee records in the MongoDB. The payload for the POST call looks like this:
{
"employeeList": [
{
"first_name": "josh",
"last_name": "don",
"age": "25",
"address": {
"street1": "xyz",
"street2": "apt-10",
"city" : "def",
"state" : "CA",
"zip" : "95055"
},
"deptType": {
"deptID": "1",
"deptName": "R&D"
}
},
{
"first_name": "mary",
"last_name": "jane",
"age": "22",
"address": {
"street1": "zzz",
"street2": "apt-15",
"city" : "yyy",
"state" : "CA",
"zip" : "95054"
},
"deptType": {
"deptID": "2",
"deptName": "HR"
}
}
]
}
As you can see, the payload takes a list of employee data, and it should have atleast one employee record. I have a requirement in which i want JMeter thread group to have 10 threads and each of these threads should make a concurrent POST to "api/create/empListJob" such that the body has 10 unique employee records, thus creating a total of 100 records. What is the best way that i could parameterize the payload?
Take a look at JMeter Functions, like:
__threadNum() - returns the number of current thread (virtual user)
__Random() - returns a random number in a given range
__RandomString() - returns a random string from specified input characters
__UUID() - returns random GUID structure
So for example if you change your JSON payload to look like:
"employeeList": [
{
"first_name": "josh-${__threadNum}",
"last_name": "don-${__threadNum}",
"age": "25",
"address": {
"street1": "xyz",
"street2": "apt-10",
"city" : "def",
"state" : "CA",
"zip" : "95055"
},
"deptType": {
"deptID": "1",
"deptName": "R&D"
}
},
{
"first_name": "mary-${__threadNum}",
"last_name": "jane-${__threadNum}",
"age": "22",
"address": {
"street1": "zzz",
"street2": "apt-15",
"city" : "yyy",
"state" : "CA",
"zip" : "95054"
},
"deptType": {
"deptID": "2",
"deptName": "HR"
}
}
]
}
JMeter will create:
- `josh-1` for 1st virtual user
- `josh-2` for 2nd virtual usre
- etc.
See Apache JMeter Functions - An Introduction to get familiarized with JMeter Functions concept.

Object name instead of OID in GoSNMP

Is it possible to return Object name instead of OID using gosnmp
For eg:
Instead of
".1.3.6.1.2.1.25.2.3.1.1.1": {
"type": "2",
"val": "1"
},
How can i get:
"hrStorageIndex": {
"type": "2",
"val": "1"
},
The answer is simple - use MIBs. GoSNMP doesn't have MIB support, but you can use the idea from https://github.com/soniah/gosnmp/issues/57

Elastic Search. Search by sub-collection value

Need help with specific ES query.
I have objects at Elastic Search index. Example of one of them (Participant):
{
"_id": null,
"ObjectID": 6008,
"EventID": null,
"IndexName": "crmws",
"version_id": 66244,
"ObjectData": {
"PARTICIPANTTYPE": "2",
"STATE": "ACTIVE",
"EXTERNALID": "01010111",
"CREATORID": 1006,
"partAttributeList":
[
{
"SYSNAME": "A",
"VALUE": "V1"
},
{
"SYSNAME": "B",
"VALUE": "V2"
},
{
"SYSNAME": "C",
"VALUE": "V2"
}
],
....
I need to find the only entity(s) by partAttributeList entities. For example whole Participant entity with SYSNAME=A, VALUE=V1 at the same entity of partAttributeList.
If i use usul matches:
{"match": {"ObjectData.partAttributeList.SYSNAME": "A"}},
{"match": {"ObjectData.partAttributeList.VALUE": "V1"}}
Of course I will find more objects than I really need. Example of redundant object that can be found:
...
{
"SYSNAME": "A",
"VALUE": "X"
},
{
"SYSNAME": "B",
"VALUE": "V1"
}..
What I get you are trying to do is to search multiple fields of the same object for exact matches of a piece of text so please try this out:
https://www.elastic.co/guide/en/elasticsearch/guide/current/multi-query-strings.html

Resources