Pentaho HTTP Post using JSON - json

I'm brand new to Pentaho and I'm trying to do the following workflow:
read a bunch of lines out of a DB
do some transformations
POST them to a REST web service in JSON
I've got the first two figured out using an input step and the Json Output step.
However I have two problems doing the final step:
1) I can't get the JSON formatted how I want. It insists on doing {""=[{...}]} when I just want {...}. This isn't a big deal - I can work around this since I have control over the web service and I could relax the input requirements a bit. (Note: this page http://wiki.pentaho.com/display/EAI/JSON+output gives an example for the output I want by setting no. rows in a block=1 and an empty JSON block name, but it doesn't work as advertised.)
2) This is the critical one. I can't get the data to POST as JSON. It posts as key=value, where the key is the name I specify in the HTTP Post field name (on the 'Fields' tab) and the value is the encoded JSON. I just want to post the JSON as the request body. I've tried googling on this but can't find anyone else doing it, leading me to believe that I'm just approaching this wrong. Any pointers in the right direction?
Edit: I'm comfortable scripting (in Javascript or another language) but when I tried to use XmlHttpRequest in a custom javascript snippet I got an error that XmlHttpRequest is not defined.
Thanks!

This was trivial...just needed to use the REST Client (http://wiki.pentaho.com/display/EAI/Rest+Client) instead of the HTTP Post task. Somehow all my googling didn't discover that, so I'll leave this answer here in case someone else has the same problem as me.

You need to parse the JSON using a Modified JavaScript step. e.g. if the Output Value from the JSON Output is called result and its contents are {"data"=[{...}]}, you should call var plainJSON = JSON.stringify(JSON.parse(result).data[0]) to get the JSON.
In the HTTP Post step, the Request entity field should be plainJSON. Also, don't forget to add a header for Content-Type as application/json (you might have to add that as a constant)

Related

How to process Vue/Axios Json payload posted data on Yii2

It took me a while to understand this, being that it was a little obvious. I will answer myself, so other can benefit of the answer and ofcourse to see if there's a better way to do this. The problem was based on Axios/Yii2 but I guess this will apply equally to other frontend libraries/frameworks sending data to Yii2.
I needed to post data from a small form made on Vuejs, sending the request Axios to a Action/Controller on Yii2, so data is sent on a simple POST request and the post is getting to the controller, but I was not able to receive the data on the action, $_POST | $post arrives empty (checked using xdebug).
As much as I remember, this had something to do with security. But I already tried by disabling public $enableCsrfValidation, so that was not the problem.
public $enableCsrfValidation = false;
But no matter what, data was not being added to the request/post data inside Yii2.
The following Image, explains the problem you will find there:
The Axisos method that sends the post with test data.
The Yii2 Action stpoed at the place, I should be able to see data.
The capture of the xdebug variables and data for the request.
The capture of Chrome where you can check the payload is sent.
The answer is as I said "kind of obvious", but I could not see that, and I am sure some other devs will probably fall on this.
After searching like crazy and asking everyone, I tried sending the request by using Postman app, yup the best thing I know to test apis.
Dont forgue to add the xdebug cookie to be able to debug your PHP Endpoint.
There I found the first clue «the obvious part», I was not sending data as a form-data, Axios and other libraries, send the data as a raw (application/json) payload.
This means that Yii2 will no be able to find the data inside the post request, yes its there but Yii2 magic will not work, neither you will find this data inside $GLOBALS or in $_POST.
So reading the Yii2 documentation I found that inside request I can use a function that will help me recovering the Raw data, so to do this use the following line:
$raw_data = Yii::$app->request->getRawBody();
Now, that data gets to you as a simple, raw json string, so use the power of PHP to parse it to an object.
$object= json_decode($raw_data );
And finally use the data inside by calling the properties you look for, sent on the pay load:
Json Payload:
{
"msg":"This is my payload",
"id":"11"
}
To use it:
echo $object->{'msg'}; // prints: This is my payload
So that's the way to handle that, now I would like some other points of view to see if there's a better way or cleaner way to do this. Hope it helps.

Ajax Response Json data, are not always valid

My website is using ajax calls to add products to cart. Each time a customer presses "Add to Cart" button, there's an ajax request called. The Json data response is sometimes not valid or not formed correctly.
Using firefox developer tools, here's the response data in both ways:
Normal json response:
Not valid json data response:
1) What kind of issue is this?
2) Why is this happening in some cases and not other cases? Could it be the data itself causing this?
3) Possible solutions to this?
In general there are two possible cases where browser can't parse JSON data:
Wrong Content-Type header
Malformed JSON string
In your case, as it sometimes works and sometimes doesn't it's probably the second one. There must be some characters in your response that are escaped in your server side code which are not valid in browser. All server side language have options when converting objects to JSON strings. you can check the invalid response in a JSON linter like https://jsonlint.com/ to see which part causes the problem then search for options to disable this behaviour in your server side code.
1) What kind of issue is this?
Server side issue.
2) Why is this happening in some cases and not other cases?
Bad logic in the server side backend code.
Could it be the data itself causing this?
No
3) Possible solutions to this?
Fix the server side code's logic.
You should check if the datatype of your Ajax function is JSON and you should check your server side code, perhaps the response is not well formatted.
the problem in you post parameters sometimes sending value or sometimes not check the code of javascript and server code as well for validation.

How to change content of Post Body in JMeter HTTP Request

Please forgive my ignorance as I'm a jmeter noob. My webservice accepts JSON objects so I was able to write a rudimentary test where I create an HTTP Request with a JSON object in the "Post Body" portion of the http request.
Anyway, what I want to do is have the HTTP Request choose a different JSON object from a csv file or some other input mechanism so that I can randomize the types of queries that are being run during the load test. Is there a way to do this? The closest is probably using variables (section 4.11 in the user manual) but I have a feeling that's not how variables are used.
A second way I've theorized (although I haven't tried yet since I think the method above is easier) is to create a HTTP Request Default obj with a bunch of HTTP Requests with different JSON objects in them and then use a Random Controller to randomly go thru my multiple HTTP Requests on each pass.
If there's a third way, I'm all ears to learn how to use this tool. I'll continue to read and possibly experiment with plan B above. Thanks in advance for any help you can give me.
UPDATE: So I tried the second way and it seems to work. I had 3 different HTTP requests and the number of times each request gets hit varies from run to run. I still invite answers from the community since I'd like to see what the pros do for issues similar to mine.
You have partially answered your question yourself, by saying "csv file or". Here are the specifics.
You will have to use CSV data set config in your test plan to read data from CSV. In your post body, use the variables read from CSV.
Here is a screen cast showing how to use csv data set config.

Is is possible to Post a file and json body with RestSharp?

I'd like to post one file and a json object to my server. Posting as a Parameter works fine, so this works:
request.AddFile ("MyPic", organisation.Pic, "Pic.png", "image/png");
request.AddParameter ("name", "test name");
But if my JSON object is something with a nested structure like:
{organisation:{
'name':'test',
'address':{
'line1':'foo',
'line2':'foo2'
}
}}
How do I post this, while maintaining the json structure.
If I set it in the content body i.e.:
request.AddBody (organisation);
the content is posted, but the file is not posted.
Is it possible to post both a json body and file?
So, I figured out a workaround, which suits my purposes. What I was looking for was to do a single post of both the file and associated meta-data. In this instance I serialised the object to a JSON string, set that as my parameter and de-serialised on the server. This works in my case but I accept that this may not be ideal for others. Thought it might help someone.
No.
When you use AddFile you are actually addding a body to your request. You can't send a request with 2 bodies.
Actually this will be possible very soon. There's a pull request on the RestSharp library that addresses this. I've started maintaining the project and will be merging it into master in the next day or so. Once there's enough stuff, I'll release a new NuGet package as well.

How can I post JSON data in a way that results in a full page load?

I can already use jQuery.post to send JSON data to the server, but I can't find a way to have the response replace my current page just as a regular old POST would when using plain HTML.
The only way I know right now to come close is to create a dummy form, add the JSON data as a value, then trigger submit. This seems like a big hack and also requires the server side to know where to look for this value (whereas it automatically detects JSON when jQuery sends it).
Please tell me there's a better way!
Example desired usage (note that I don't want the data encoded in the URL):
magic_load_page('/page', {'foo':'bar', 'list':[1,4,9,16]}); // uses POST request