Jmeter how do I generate multiple HTTP request body in one session? - groovy

Here is my use case: I had a JSR223 post processor in place to store "account ID" that qualifies the condition into an array. And then I'll need to construct http request body using the accountId in the array one at a time to test the API. My question is that:
With the code right below, there was only one request body constructed with the last accountId in the array.. However I needed to generate multiple HTTP request bodies from the loop so that I could hit the api with every each accountId in the array. Is the simple controller able to accomplish this? If so, what shall I do? Thanks!
def accountIds = []
for (int i=0; i < territoryTableDataList.size(); i++) {
if (territoryTableDataList[i].change == "DROPPED") {
accountIds.add(territoryTableDataList[i].id)
}
}
for (int j=0; j < accountIds.size(); j++) {
vars.put("accountId", accountIds[j])
log.info("*******************The account ID is: " + accountIds[j])
}
HTTP Request Body:
{
"globalRequestId": "auto-perftest-00",
"challengeReasons": [
"other__c"
],
"feedbackRemoveAccountRequests": [
{
"requestId": "auto-perftest-001",
"accountId": "${accountId}"
}
]
}

for (int j=0; j < accountIds.size(); j++) {
vars.put("accountId", accountIds[j])
//^^^^^^^^^^^^^^^^^^^^
here you're overwriting the accountId JMeter Variable with the new value of accountIds[j] each iteration of the loop so it always contains the last value.
You need to replace this line with something like:
vars.put("accountId_" + (j+1), accountIds[j])
This way you will get the following JMeter Variables generated:
accountId_1=foo
accountId_2=bar
accountId_3=baz
etc.
And these variables can be iterated using ForEach Controller:
Demo:
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It

Related

Magento - How to pass value from template to js file?

I developed an extension where you can define a connection id for newsletter 2 go.
I need to pass this id to the script skin\frontend\base\default\fekete\Newsletter2Go\js\utils.js
Template:
My first approach was to pass it to the script by adding a get parameter to it.
{... Hint: I removed the rest code which is not relevant for this question ... }
(window,document,"script","skin/frontend/base/default/fekete/Newsletter2Go/js/utils.js?id=<?php echo $id ?>","n2g");
I checked if this worked like this:
alert(findGetParameter("id"));
function findGetParameter(parameterName) {
var result = null,
tmp = [];
var items = location.search.substr(1).split("&");
for (var index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
}
return result;
}
But it alerts null.
How can I pass the id to the script, without having to move the whole script to the template?
I solved it by creating a new extension. I developed a controller and then just made a XHR Request to my route, which just returns the needed value.

How to bind data to html in angular 2/4 by using thread or async

I have a Component, which have child component. at ngOnInit() I'm calling Web API and get list of data.
Initial point length of the list is 10, But it will have more.
Need to execute some method (task|process|job) in background to take rest of the data 10 by 10 in a loop which would run parallel to other task in background no matter what the user is currently doing, which component he/she is interacting with. And execute that method so that it doesn't block others.
What is the correct way to do this?
Seems like a recursive call to me !
firstResults: any[] = []; // First 10 results to show to your user
results: any[] = []; // All results
currentPosition = 0; // The current position of your last result fetched
getData() {
this.myService.getResults().subscribe(results => {
if(!this.firstResults.length) {
this.firstResults = results
}
this.results.push(...results);
this.currentPosition += results.length;
this.getData();
});
}
I don't imagine you're trying to do. But if the list is not so largger, you can get all the data and "paginate" the array
allData:any[];
page:number=0; //page is 0,1,2,3,4....
paginateData:any[]
this.httpClient.get("url").subscribe(res=>{
allData=res;
paginateData=allData.slice(10*this.page,10*(this.page+1));
}

How to get the number of clicks on a link from wikipedia?

Now we have the code that scrapes the links in an article. We need also the number of clicks on a link. Can some one help?
Sow far we have this code:
String[] articles = {"Abdominal_pain"};
void setup() {
for (int i = 0; i < articles.length; i++) {
String article = articles[i];
String start = "20160101"; // YYYYMMDD
String end = "20170101"; // YYYYMMDD
// documentation: https://wikimedia.org/api/rest_v1/?doc#!/Pageviews_data/get_metrics_pageviews_per_article_project_access_agent_article_granularity_start_end
// >> https://en.wikipedia.org/w/api.php?action=query&format=json&prop=links&meta=&titles=Albert+Einstein&pllimit=500
String query = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=links&meta=&titles="+article+"&pllimit=500";
String[] lines = loadStrings(query);
for (int j = 0; j < lines.length; j++) {
String line = lines[j];
if (line.contains("\"title\":")) {
println(line);
// java string split
}
}
}
}
The query you're using apparently gives you a bunch of articles that your main article "Abdominal_pain" links to.
You need to go a step further and loop through all of those links. You can make your life a lot easier by using JSONObjects instead of parsing Strings like you're currently doing. Check out the loadJSONArray() function for more info, but basically you'd do this:
JSONArray links = loadJSONArray(query);
for (int i = 0; i < values.size(); i++) {
JSONObject link = values.getJSONObject(i);
String title = link.getString("title");
//fetch the info for that title
}
Once you have the title, you can then fetch the information for that page. An example query url is https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia/all-access/all-agents/Abdominal_pain/daily/20151010/20151012 which returns this JSON:
{"items":[{"project":"en.wikipedia","article":"Abdominal_pain","granularity":"daily","timestamp":"2015101000","access":"all-access","agent":"all-agents","views":1134},{"project":"en.wikipedia","article":"Abdominal_pain","granularity":"daily","timestamp":"2015101100","access":"all-access","agent":"all-agents","views":1160},{"project":"en.wikipedia","article":"Abdominal_pain","granularity":"daily","timestamp":"2015101200","access":"all-access","agent":"all-agents","views":1313}]}
You'll have to do some aggregating to get the totals, or maybe the total is somewhere else in the API.
You're going to have to do a little bit of research on exactly what the API can return. Reading through the documentation is a big part of programming. Luckily the Wikipedia API has great documentation, and that's where you should be looking.
I'd recommend trying something out and posting another question, along with an MCVE, if you get stuck. Good luck.
See also: How to use Wikipedia API to get the page view statistics of a particular page in wikipedia?

Elastic Search: How to write multi statement scripts?

I have values stored on a document in an Elasticsearch index.
I need to do some date manipulation on the values and return a boolean value to be used in a filter.
The script covers several lines, and I can't get it to run.
I've written other single scripts that work fine, however I know less than nothing about Groovy and very little about Elastic search.
Each and every sample I can find with a script has one line and only one line.
So basically how would I take this perfectly valid script
"script": {
"script": "doc['state'].value == 'completed' && doc['lastStateUpdate'].value < doc['dueDate'].value"
}
And turn it into some thing like
"script": {
"script": "def isCompleted = doc['state'].value == 'completed'
def preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value
return isCompleted && preSLA"
}
I'm not mad about the idea of creating a write-only one liner that expresses the logic, I can see more of these coming down the line and while this one is relatively straight-forward, a "one liner" isn't going to cut it.
The alternative here is to do some preprocessing on the document before it's indexed, and add extra data to it. However this has drawbacks in that it's rather inflexible and we'd need to reindex all the data to change these aggregations, which we'd rather not do.
You simply need to separate each statement with a semicolon:
"script": {
"script": "isCompleted = doc['state'].value == 'completed'; preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value; return isCompleted && preSLA;"
}
Make sure to not add line breaks inside your script string, though, as it would not be valid JSON.
If you want to break your script into multiple lines you have to surrond your script with """ docs
`"query": {
"function_score": {
"script_score": {
"script": {
"lang": "painless",
"source": """
int total = 0;
for (int i = 0; i < doc['goals'].length; ++i) {
total += doc['goals'][i];
}
return total;
"""
}
}
}
}
}`
Update: For some versions of Elasticsearch source should be replaced with inline docs

NodeJS for-loop unsuccessful at trimming urls that end in with numbers

I'm trying to take a group of Facebook Page urls and extract only the entity title of the page. Ie for 'https://www.facebook.com/BalanceSpaBoca' I'm looking only for 'BalanceSpaBoca.' This script works great for most of the sample data I'm using (the testFBurls array), printing only the trimmed string. For others, though, it prints both the trimmed string and the original string. It seems like all of the urls that get printed twice end with a string of numbers, but I'm not sure why that should make any difference in how the program runs.
var testFBurls = [
'http://www.facebook.com/pages/A-Yoga-Way/361702000576231',
'http://www.facebook.com/aztigurbansalon',
'https://www.facebook.com/pages/Azzurri-Salon-Spa/542579982495983',
'https://www.facebook.com/BalanceSpaBoca',
'https://www.facebook.com/BocaAmericanNailsandSpa',
'http://www.facebook.com/beachyogagirl',
'https://www.facebook.com/pages/Beauty-of-Wax/156355679240',
'http://www.facebook.com/beehivefitness.boca',
'https://www.facebook.com/pages/Believe-Day-Spa-Boutique/197615685896',
'https://www.facebook.com/photo.php?fbid=10151725966640897&set=a.10151725965355897.1073741828.197615685896&type=1&theater',
'http://facebook.com/pages/bigfoot-spa/1486364798260300',
'http://www.facebook.com/bloheartsyou',
'http://www.facebook.com/pages/The-Wellness-Center-Of-Boca-Raton/170371382995576',
'https://www.facebook.com/TherapyBodyBalanced',
'https://www.facebook.com/pages/BodyVital-Massage/177664492277158',
'https://www.facebook.com/bodyworkmall',
'https://www.facebook.com/pages/The-Bombay-Room-Yoga-Studio/148731658497764',
];
var possibleFBurlStarts = [
"https://www.facebook.com/",
"http://www.facebook.com/",
"https://www.facebook.com/pages/",
"http://www.facebook.com/pages/",
];
for (var count=0; count<testFBurls.length; count++){
var currentURL = testFBurls[count];
if (currentURL.indexOf(".com/photo") > -1) {
testFBurls.splice(i, 1);
i--;
}
for (var i=0; i < possibleFBurlStarts.length; i++){
var indexOfSubstring = currentURL.indexOf(possibleFBurlStarts[i]);
if (indexOfSubstring > -1) {
var res = currentURL.replace(possibleFBurlStarts[i], "");
}
}
if (count == testFBurls.length-1){
console.log(testFBurls);
}
}
Here's my console output
pages/A-Yoga-Way/361702000576231
A-Yoga-Way/361702000576231
aztigurbansalon
pages/Azzurri-Salon-Spa/542579982495983
Azzurri-Salon-Spa/542579982495983
BalanceSpaBoca
BocaAmericanNailsandSpa
beachyogagirl
pages/Beauty-of-Wax/156355679240
Beauty-of-Wax/156355679240
beehivefitness.boca
pages/Believe-Day-Spa-Boutique/197615685896
Believe-Day-Spa-Boutique/197615685896
bloheartsyou
pages/The-Wellness-Center-Of-Boca-Raton/170371382995576
The-Wellness-Center-Of-Boca-Raton/170371382995576
TherapyBodyBalanced
pages/BodyVital-Massage/177664492277158
BodyVital-Massage/177664492277158
bodyworkmall
pages/The-Bombay-Room-Yoga-Studio/148731658497764
The-Bombay-Room-Yoga-Studio/148731658497764
Notice that the first url is listed twice (first in its original form, and secondly in its truncated form), but then the second url (the third line in the output) is listed in truncated form alone. Any ideas what is causing this disparity? Only the truncated url should be printed.
You're modifying the array you're iterating through while you're iterating through it: testFBurls.splice(i, 1); which is typically a not-great thing to do. In any case, I think you should be able to accomplish your goal a lot easier with a simple regular expression:
for (var count=0; count<testFBurls.length; count++){
var matches = testFBurls[count].match(/^https?\:\/\/www\.facebook\.com\/(?:pages\/)?([^\/]+)/);
if (matches) {
console.log('found it:', matches[1]);
}
}

Resources