Json extract unique data - Jmeter - jmeter

I am having a set of request in my Thread Group in which first request will feed inputs for the second request. I am using json extractor (match No.0) to extract the value from the list. I want to ensure that same data extracted in the Thread 1 is not been fetched in the subsequent thread runs. Can you please suggest how handle that.

As per JSON Extractor documentation
If the JSON Path query leads to many results, you can choose which one(s) to extract as Variables:
0 : means random (Default Value)
The "random" doesn't guarantee uniqueness so if you need the data to be unique - consider providing an incremented value to this "Match No" field.
Example setup:
Given the following JSON
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
Let's assume you want to use unique book title, i.e.
Sayings of the Century - for 1st iteration
Sword of Honour - for 2nd iteration
etc.
Amend "Match No" field value to look like:
${__intSum(${__jm__Thread Group__idx},1,)}
where __jm__Thread Group__idx is a pre-defined variable available since JMeter 4.0 which returns current Thread Group iteration and __intSum() is the JMeter Function which adds 1 to the iteration number (as it's zero-based)
the full JSON Extractor configuration would be something like:
That's basically it, now you have the confidence that the new value is being picked up for each Thread Group iteration, it can be checked using i.e. View Results Tree listener.

Related

Get files from Sharepoint after doing a Filter on Array

The problem I am having is :
Sharepoint Get File Files (Properties Only) can only do one filter for ODATA, not a a second AND clause so I need to use Filter Array to make secondary filter work. And it does work....
But now I need to take my filtered array and somehow get the {FullPath} property and get the file content via passing a path and I get this error...
[ {
"#odata.etag": ""1"",
"ItemInternalId": "120",
"ID": 120,
"Modified": "2022-03-21T15:03:31Z",
"Editor": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|dev#email.com",
"DisplayName": "Bob dole",
"Email": "dev#email.com",
"Picture": "https://company.sharepoint.us/sites/devtest/_layouts/15/UserPhoto.aspx?Size=L&AccountName=dev#email.com",
"Department": "Information Technology",
"JobTitle": "Senior Applications Developer II"
},
"Editor#Claims": "data",
"Created": "2022-03-21T15:03:31Z",
"Author": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|dev#email.com",
"DisplayName": "Bob Dole",
"Email": "dev#email.com",
"Picture": "https://company.sharepoint.us/sites/devtest/_layouts/15/UserPhoto.aspx?Size=L&AccountName=dev#email.com",
"Department": "Information Technology",
"JobTitle": "Senior Applications Developer II"
},
"Author#Claims": "i:0#.f|membership|dev#email.com",
"OData__DisplayName": "",
"{Identifier}": "Shared%2bDocuments%252fSDS%252fFiles%252fA10_NICKEL%2bVANADIUM%2bPRODUCT_PIS-USA_French.pdf",
"{IsFolder}": false,
"{Thumbnail}": ...DATA,
"{Link}": "https://company.sharepoint.us/sites/devtest/Shared%20Documents/SDS/Files/A10_NICKEL%20VANADIUM%20PRODUCT_PIS-USA_French.pdf",
"{Name}": "A10_NICKEL VANADIUM PRODUCT_PIS-USA_French",
"{FilenameWithExtension}": "A10_NICKEL VANADIUM PRODUCT_PIS-USA_French.pdf",
"{Path}": "Shared Documents/SDS/Files/",
"{FullPath}": "Shared Documents/SDS/Files/A10_NICKEL VANADIUM PRODUCT_PIS-USA_French.pdf",
"{IsCheckedOut}": false,
"{VersionNumber}": "1.0" } ]
So from what I can see, I think it's what I thought. Even though you're filtering an array down to a single element, you need to treat it like an array.
I'm going to make an assumption that you're always going to retrieve a single item as a result of your filter step.
I created a variable (SharePoint Documents) to store your "filtered" array so I could then do the work to extract the {FullPath} property.
I then created variable that is initialised with the first (again, I'm making the assumption that your filter will only ever return a single element) and used this expression ...
variables('SharePoint Documents')?[0]['{FullPath}']
This is the result and you can use that in your next step to get the file content from SharePoint ...
If my assumption is wrong and you can have more than one then you'll need to throw it in a loop and do the same sort of thing ...
This is the expression contained within ...
items('For_Each_in_Array')['{FullPath}']
Result ...
I actually ended up doing this and it works.

FHIR CodableConcept - All elements must be from ValueSet - Writing Profile Differential

I want to create a profile from base Observation, in that all code elements must be from the ValueSet. For example:
{
"resourceType": "Observation",
"id": "example",
"meta": {
"profile": ["http://my.own.profile/StructureDefinition/custom-observation-profile"]
}
...
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8867-4",
"display": "Body Weight"
},
{
"system": "http://loinc.org",
"code": "9843-4",
"display": "Body Weight"
}
]
},
...
All the elements from code.coding should be from a valueset, lets say http://my.value.set
In the differential, I have the following:
{
"id": "Observation.code",
"path": "Observation.code",
"short": "Body Weight",
"type": [
{
"code": "CodeableConcept"
}
],
"binding": {
"strength": "required",
"description": "All LOINC values whose SCALE is DOC in the LOINC database and the HL7 v3 Code System NullFlavor concept 'unknown'",
"valueSet": "http://my.value.set"
}
},
But this one is validating only the first element in the list. It does not validate the other ones. It ignores even if they are invalid.
The list can be 1..*, and I want all of them should be from the valueSet.
How do I write differential for this one?
The expectation when there's a required binding on a CodeableConcept is that one of the CodeableConcept.coding repetitions must come from the binding. There's no requirement that the others must - and the primary use for additional codings is that you don't want them to be from the same value set. The purpose of additional codings is to convey other codes from other code systems that also convey the same meaning (so that other recipients of the instance who might not necessarily recognize the code preferred by your profile can still find a code they recognize - and also so that the 'original' coding can be retained in cases where that isn't from the bound value set).
If you truly want to force all CodeableConcept.coding repetitions to be from a single value set (strongly discouraged and likely to impede interoperability), you could declare a binding on Observation.code.coding.

Parallel execution of Samplers in JMeter with different URL parameters

There is "ForEach" controller in JMeter which takes an array of items and executes a sampler with each item. This is very useful when you need to execute a sampler with different parameters based on data received in previous request. However, "ForEach" controller runs samplers one after the other.
What I am looking for is, execute the samples in parallel. There is a plug in available in JMeter called, "bzm - Parallel Controller". However, this doesn't accept any input variable like "ForEach" controller does.
For example, I have following data in database. Author along with their books.
[
{
"firstName": "William",
"lastName":"Shakespeare",
"Title": "Mr",
"id": "1",
"books": [
{
"id": "WS1",
"title": "King John",
"year":"1596"
},
{
"id": "WS2",
"title": "Julius Caesar",
"year": "1599"
},
{
"id": "WS3",
"title": "Romeo and Juliet",
"year": "1595"
}
],
"Nationality": "English"
},
{
"firstName": "Sidney",
"lastName":"Sheldon",
"Title": "Mr",
"id": "2",
"books": [
{
"id": "SS1",
"title": "The Naked Face",
"year":"1969"
},
{
"id": "SS2",
"title": "A Stranger in the Mirror",
"year": "1976"
},
{
"id": "SS3",
"title": "Bloodline",
"year": "1977"
}
],
"Nationality": "American"
},
{
"firstName": "Eiichiro",
"lastName":"Oda",
"Title": "Mr",
"id": "3",
"books": [
{
"id": "EO1",
"title": "Wanted",
"year":"1992"
},
{
"id": "EO2",
"title": "Ikki Yako",
"year": "1993"
},
{
"id": "EO3",
"title": "Monsters",
"year": "1994"
}
],
"Nationality": "Japanese"
}
]
In my JMeter Test plan, I have defined a CSV Data Set Config file to store the ids of all authors in my system.
And then, there is a Thread Group. Inside thread group, I have a HTTP Sampler, GET /authors/{id}/books. for Example GET /authors/1/books. This will get all the books written by author "William Shakespeare".
Using JSON Extractor, I can capture the array of book ids returned by GET /authors/{id}/books.
There are 3 books with ids WS1, WS2 and WS3. Now for each of the books, I need to run another HTTP Sampler
PUT /books/WS1
PUT /books/WS2
PUT /books/WS3.
When I use ForEach controller, I can specify the input variable which was captured from previous JSON extractor. And it loops through each PUT request, for each book id. I want to do the same, but in PARALLEL, not sequential.
Does anyone know how to achieve this? or we have to write custom groovy/BeanShell script for this? If custom Groovy/BeanShell script is the only way, can you please tell me how to write this
Many thanks
You can do that by placing each test in a separate threadGroup.
You have a flag in the main test plan that controls if threads are executed in parallel or consecutively.
You're using not very correct test element, consider switching to Parallel Sampler instead.
Given you have the following JMeter Variables:
book_1=WS1
book_2=WS2
book_3=WS3
book_matchNr=3
You can add a Parallel Sampler and configure it to hit URLs containing ${book_1}, ${book_2} and ${book_3}
All the URLs to Retrieve will be executed in parallel:
More information: How to Use the Parallel Controller in JMeter
You could dynamically add URLs to Parallel HTTP Requests sampler.
Add JSR223 PreProcessor like a child to Parallel HTTP Requests sampler.
To script area add something like that:
String url = "https://examle.url.com/?book=";
1.upto(vars.get('book_matchNr') as int, {
index -> {
sampler.addURL(url + vars.get('book_' + index))
}
});

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.

Jmeter : How to extract first element from json array

I am trying to extract first element from a json array. Below mentioned is json array
[
{
"cohortDefinition": {
"Key": 1151,
"id": 1798,
"srcId": "3526",
"pcKey": -1,
"userName": "CHROME_USER",
"name": "JMeter2017-01-06-1483749546167",
"Type": "SUBJECT",
"tool": "CB",
"count": 32757,
"extractionStatus": "",
"dateCreated": "2017-05-10T17:48:45Z"
},
"datasource": {
"id": 2,
"name": "health",
"subjectCount": 116352
},
"project": {
"id": 747,
"name": "Jmeter Project"
}
},
{
"cohortDefinition": {
"Key": 1150,
"id": 1796,
"srcId": "3525",
"pcKey": -1,
"userName": "CHROME_USER",
"name": "JMeter2016-10-27-1477620919644",
"Type": "SUBJECT",
"tool": "CB",
"count": 32757,
"extractionStatus": "",
"dateCreated": "2017-05-10T16:57:11Z"
},
"datasource": {
"id": 2,
"name": "health",
"subjectCount": 116352
},
"project": {
"id": 747,
"name": "Jmeter Project"
}
}
]
From above json i would like to extract first value ie. srcId": "3526".
I tried doing following expression in Jmeter extractor
$..cohortDefinition.srcId[1]
However it is not working. If anyone know how to do this please do let me know.
After JMeter 3.0, you can use JSON Extractor, see:
https://stackoverflow.com/a/47043204/460802
Before JMeter 3.0:
Please follow the below steps to retrieve srcId.
Add a JSON Path Extractor to your request and configure below values.
Destination Variable Name - myVar
JSON Path Expression - $..cohortDefinition.srcId - this will extract all the srcIDs from the JSON.
Default Value - Not Found or Err
Add a Debug Sampler and View Results Tree to your test plan.
Save it and execute.
In Debug Sampler, you can view all the srcId as shown below.
You can now use myVar_1 and myVar_2 in your test plan
using ${myVar_1} ${myVar_2}
No need for Plugin, JMeter has a JSON Extractor that will provide this feature:
Notice:
JSON Path Expression is: $..cohortDefinition.srcId
Match No : 1

Resources