How to read query parameter with ^ in the URL - spring

I'm trying to implement a callback endpoint for eBay. This endpoint is called by eBay to hand the application a user token.
I can define my endpoint as expected
http://localhost:8080/api/ebay/auth
Nothing unusual here. My enpoint looks like this, really basic:
#RestController
#RequestMapping(path = ["/api/ebay/auth"])
class EbayAuthController {
#GetMapping(path = [""])
fun getAccessToken(#RequestParam code: String) {
println("Auth code: $code")
}
}
Now eBay passes the parameter code with the value
?code=v^1.1%23i^1%23r^1%23p^3%23I^3%23f^0%23t^[excluded_user_token]&expires_in=299
When I call my endpoint with this data set, it returns 400 Bad Request. I can reproduce this by adding ^ to any request. I read it's an unsafe character to use - but the issue is: Ebay uses this character to return the user token, so I must read it.
When I pass a sample with http://localhost:8080/api/ebay/auth?code=123 it prints the code as expected.
I've never encountered that problem, can anyone help me or point me in the right direction how to solve this?

According to this answer by Dirk Deyne to the question Spring-boot controller error when url contains braces character, you can specify server.tomcat.relaxed-query-chars in your application.properties:
server.tomcat.relaxed-query-chars=^

Related

Use Jmeter function value as variable in request

I'm trying to wrap my head around Jmeter functions and how to actually use them in an HTTP JSON request. All examples I've found on function use them as titles in HTTP requests, which is not helpful.
All I want to do is this, and then use that variable in my POST request. But that doesn't work and I have no clue why not.
...
"dates": {
"invoiceDate": ${testdate},
...
In all examples I've seen, the function is set as the HTTP sampler name, like so:
This is not helpful at all since I can't use that as a variable.
I don't think 20211 is the valid year, do you mean 2021?
If you put the function inside User Defined Variables - it will be evaluated only once and won't be random, you should rather inline it into the request body as User Defined Variables are evaluated only once, when the test starts
If you're trying to post JSON - I think you should surround the function with quotation marks, otherwise the JSON will be invalid. Suggested change:
{
"dates" : {
"invoiceDate": "${__RandomDate(,,2021-06-20,,)}"
}
}

How to make Get Request with Request param in Postman

I have created an endpoint that accepts a string in its request param
#GetMapping(value = "/validate")
private void validateExpression(#RequestParam(value = "expression") String expression) {
System.out.println(expression);
// code to validate the input string
}
While sending the request from postman as
https://localhost:8443/validate?expression=Y07607=Curr_month:Y07606/Curr_month:Y07608
// lets say this is a valid input
console displays as
Y07607=Curr_month:Y07606/Curr_month:Y07608 Valid
But when i send
https://localhost:8443/validate?expression=Y07607=Curr_month:Y07606+Curr_month:Y07608
//which is also an valid input
console displays as
Y07607=Curr_month:Y07606 Curr_month:Y07608 Invalid
I am not understanding why "+" is not accepted as parameter.
"+" just vanishes till it reaches the api! Why?
I suggest to add this regular expression to your code to handle '+' char :
#GetMapping(value = "/validate")
private void validateExpression(#RequestParam(value = "expression:.+") String expression) {
System.out.println(expression);
// code to validate the input string
}
I didn't find any solution but the reason is because + is a special character in a URL escape for spaces. Thats why it is replacing + with a " " i.e. a space.
So apparently I have to encode it from my front-end
Its wise to encode special characters in a URL. Characters like \ or :, etc.
For + the format or value is %2. You can read more about URL encoding here. This is actually the preferred method because these special characters can sometimes cause unintended events to occur, like / or = which can mean something else in the URL.
And you need not worry about manually decoding it in the backend or server because it is automatically decoded, in most cases and frameworks. In your case, I assume you are using Spring Boot, so you don't need to worry about decoding.

QuerySchedule WebAPI function call

I am using Web API calls to Dynamics 365 to get result for function QuerySchedule. I have tried using this as a bound function as well. But none of them returns the expected result. Below is documentation on this:
https://learn.microsoft.com/en-us/dynamics365/customer-engagement/web-api/queryschedule?view=dynamics-ce-odata-9
I have tried different resource id, different ways to specify the enum type in the call, fully qualified function name, etc but I always get error.
Following is my call:
https://mycrm.com/api/data/v9.0/QuerySchedule(ResourceId=#p1,Start=#p2,End=#p3,TimeCodes=#p4)?#p1=resourceguid&#p2=2019-01-05T09:27:39Z&#p3=2019-01-05T21:27:39Z&#p4=Available
The output is expected to be QueryScheduleResponse as mentioned in below link:
https://learn.microsoft.com/en-us/dynamics365/customer-engagement/web-api/queryscheduleresponse?view=dynamics-ce-odata-9
But I keep getting error message:
Object reference not set to an instance of an object.
Could anyone who has done web api calls to Dynamics 365 using OData or has any experience with this kindly help?
Quickly did a browser console test, the code snippet from this blog post works fine.
Pasting part of the snippet from the blog, your code may break as you are passing "Available" instead of ['0'] for TimeCodes.
var requestUrl = "/api/data/v9.0/QuerySchedule(ResourceId=#p1,Start=#p2,End=#p3,TimeCodes=#p4)";
requestUrl += "?#p1=" + context.getUserId().replace("{", "").replace("}", "");
//put Id of resource you want get data for as parameter 1
requestUrl += "&#p2=" + JSON.stringify(start).replace(/"/g, "");
requestUrl += "&#p3=" + JSON.stringify(end).replace(/"/g, "");
requestUrl += "&#p4=" + JSON.stringify(['0']);
Even you can paste this url in your browser address bar to smart test:
Request:
https://test.crm.dynamics.com/api/data/v9.0/QuerySchedule(ResourceId=#p1,Start=#p2,End=#p3,TimeCodes=#p4)?#p1=0EEE678F-C4FF-E711-A959-000D3A1A941E&#p2=2019-01-15T09:27:39Z&#p3=2019-01-15T21:27:39Z&#p4=['0']
You may notice ['0'] turn into [%270%27] but the below expected response will appear.
Response:
{"#odata.context":"https://test.crm.dynamics.com/api/data/v9.0/$metadata#Microsoft.Dynamics.CRM.QueryScheduleResponse","TimeInfos":[{"Start":"2019-01-15T00:00:00Z","End":"2019-01-16T00:00:00Z","TimeCode":"Available","SubCode":"Schedulable","SourceId":"15f40c32-1609-46db-93da-1bbb8eb19c9d","CalendarId":"69b0ee2b-bad7-4b8e-9bcc-d03e76b45a03","SourceTypeCode":4004,"IsActivity":false,"ActivityStatusCode":-1,"Effort":1.0,"DisplayText":""}]}

Youtube API V3 Insert Comment Issue

I'm essentially using the sample code provided by the docs here but I'm getting an error that reads ArgumentError - unknown keyword: snippet. Does anyone else have this problem as well? I'm not sure if this is a valid bug but intuitively the sample code they provide should work right?
properties = {
'snippet.parentId': '123',
'snippet.textOriginal': message
}
resource = create_resource(properties)
response = service.insert_comment('snippet', resource)
Upon digging through the actual library, I discovered that the way to pass in the snippet part is as follows:
snippet = Google::Apis::YoutubeV3::CommentSnippet.new(parent_id: parent_id, text_original: message)
comment = Google::Apis::YoutubeV3::Comment.new(snippet: snippet)
response = service.insert_comment('snippet', comment)
Hope this saves someone from a huge headache of having to chase through their docs

I want to check if a response attribute of one http request exits in another http request as well. How can I do that?

HTTP request
.. regular expression to pick up a token "PostID"
HTTP request
..Beanshell assertion to verify if ${PostID} exists in the response
I am using the while controller to loop the request till PostID is found
while condition being ${__javaScript("${count}" != 1)}
Beanshell assertion is failing though I see the PostID in the response of "FetchSentPost" request
I need the while loop to end on the first encounter of Post ID in the HTTP request "FetchSentPost"
Where Am I going wrong?
You have a syntax error in your Beanshell script:
String ID = vars.get(PostID);
^^^^^^
should be
String ID = vars.get("PostID");
Going forward you can add debug(); directive to the beginning of your JMeter script for troubleshooting. I would also recommend switching to JSR223 Assertion and Groovy language, Groovy performs much better and more Java-compliant.
There are several mistakes made in the script.
Condition must be changed to ${__javaScript(${count} != 1)}. No double quotes.
In BeanShell Assertion, instead of count += 1, you must assign count value using vars.put as follows vars.put("count", 1);
As Dmitri mentioned, other mistake is:
String ID = vars.get("PostID");
Related to contains vs regex matching, try both after making above changes. I tried with contains, it is working.
Using contains:
while(!str.contains(ID)){
vars.put("count", 1);
}
created a user defined variable 'PostIdFound' with value 'False' outside the while loop.
Changed the while condition to ${__javaScript(${PostIdFound} != true)}
and then changed the BeanShell script as follows
import java.util.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String ID = vars.get("PostID");
String str= SampleResult.getResponseDataAsString();
vars.get("PostIdFound");
if(str.contains(ID)){
vars.put("PostIdFound","true");
}
Issue Resolved. Thankyou #Dmitri T and #Naveen for the help

Resources