I want to understand how priorities work. More specifically, what is the expected output of setting priorities to stub. There's limited documentation on this and the ones available doesn't really explain what the output would look like so I'm unable to verify if I have implemented it correctly.
This is my current code:
stubFor(post(urlMatching("/user/test\\?(and)\\=(que).*")).atPriority(1)
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "text/plain")
.withBody("This stub is testing for Title ")
)
);
System.out.println("About to execute the second stub");
stubFor(post(urlMatching("/user/test\\?(and)\\=(que).*")).atPriority(2)
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "text/plain")
.withBody("This stub is testing Author ID ")
)
);
System.out.println("Second stub executed");
I'm sending the following request from SOAPUI:
/user/test?and=query
Therefore both stubs should be executed and I should receive two responses correct?
I'm currently receiving only one response and that is from the stub that has priority 1. I'm not getting any response from the stub that has priority 2/
Can someone please help me on this?
What exactly do you want to achieve?
You normally have Wiremock configurations which have different request parameters or overlapping. In your case they are exactly the same. In which case should be the first and which case should the second be shown?
Wiremock will always return only exactly one answer. This answer is normally determined by evaluation of the request parameters you defined in your Wiremock configuration.
please refer to this description on how Wiremock and priorities work: Wiremock Stubbing and priorities
In case there are overlapping parameters, Wiremock will choose the configuration you added most recently (in your case the second).
Or you can guide Wiremock by setting priorities. A priority which is lower will be used in preference.
Normally you have a more general case (with less request parameters - as catch-up) and a more specific case. The first will get a higher prio (e.g. 9) and the latter a lower one (e.q. 5).
So the latter will be choosen in preference if request parameters match and in other cases the second one.
As #monsIgnore stated, for overlapping parameters the most recently added mapping that matches those parameters will be chosen.
When I initially looked at the request matching in wiremock I thought that the most exact match would be chosen.
By 'most exact' I mean the one that matched the most number of elements in the request. For example, given these two mappings (added in this order):
Mapping 1
"request" : {
"url" : "/oauth2/rest/consent",
"method" : "GET",
"headers" : {
"Cookie" : {
"equalTo" : "OAM_ID=VERSION_5"
}
}
}
Mapping 2
"request" : {
"url" : "/oauth2/rest/consent",
"method" : "GET"
}
If a request is received for url /oauth2/rest/consent and an OAM_ID cookie of VERSION_5 then the mapping that matches the most elements is Mapping 1.
However Mapping 2 is chosen since it matches and it was the most recently added.
In this case by adding priorities to the Mappings you can ensure that the request with the cookie is matched against Mapping 1.
Priorities are necessary because it's not always obvious what the most exact match is. For example if there was a third mapping:
Mapping 3
"request" : {
"url" : "/oauth2/rest/consent",
"method" : "GET",
"headers" : {
"Authorization" : {
"equalTo" : "Basic dXNlcjpwYXNzd29yZA=="
}
},
}
If a request arrived that had the cookie from Mapping 1 and the Authorization header from Mapping 3, then it's not possible to determine the most exact match for the request.
They both match 3 elements each. This is where priorities come in.
Setting stub priority is supported in WireMock.
By default, WireMock will use the most recently added matching stub to satisfy the request.
You can add priority in Java code by using atPriority:
stubFor(get(urlMatching("/api/.*")).atPriority(5)
or in JSON by adding:
"priority": 1
Read more on this here
Related
I've got a JMeter issue... The problem is: i'm sending a http request by POST method to a website and then the page returns me 100 responses, for example one of the answers:
Answer:
{
"Category": "XX",
"NumberX": 5100051,
"Class": "CLASS_1",
"NumberY": 5100136,
"arrivalDate": "2022-06-22T04:36:00",
"departureDate": "2022-06-21T23:58:00"
},
and then i have to save some of the values with a JSON extractor to variables.
Then I have second one http request by POST method, where in the body i have to use these variables. And my problem is that i don't how to count these variables in the body... With one data it's working, for more i don't know how to iterate it... Body in the second request:
{
"vehicleCategory": "${Category}",
"NumberOfTasks": "${NumberX}",
"departureDate": "${departureDate}",
"arrivalDate": "${arrivalDate_}"
}
I want to see query responses to each of the previous 100 values...
I hope i I clearly described the problem... Is there anybody who can help me to do it?
If you give "Match No" as -1 in the JSON Extractor:
it will generate the following JMeter Variables:
Category_1=first match
Category_2=second match
....
Category_matchNr=100 (or whatever is the number of matches)
So you will be able to iterate these values by:
Adding a Loop Controller with "Loop Count" set to ${Category_matchNr}
In the HTTP Request body reference the variables as:
{
"vehicleCategory": "${__V(Category_${__intSum(${__jm__Loop Controller__idx},1,)},)}",
"NumberOfTasks": "${__V(NumberX_${__intSum(${__jm__Loop Controller__idx},1,)},)}",
"departureDate": "${__V(departureDate_${__intSum(${__jm__Loop Controller__idx},1,)},)}",
"arrivalDate": "${__V(arrivalDate__${__intSum(${__jm__Loop Controller__idx},1,)},)}"
}
More information: Here’s What to Do to Combine Multiple JMeter Variables
I'm using Spring Cloud Contracts version 2.1.1.
I understand that I can use some value from the original request to validate against some value in the response, and I can use it within another string (i.e. not as is, but concatenated with other strings):
response {
status 200
body(
message: "Hello, ${fromRequest().body('$.name')}!",
)
}
What if I wanted to used some arithmetic on a numeric json value from the request, i.e. validate that response has this value incremented:
response {
status 200
body(
result: ${fromRequest().body('$.count')} + 1
)
}
Or, maybe even two numeric values added, e.g.:
response {
status 200
body(
result: ${fromRequest().query('num1')} + ${fromRequest().query('num2')}
)
}
Obviously the two last snippets are not valid, but illustrate what I'm looking for. Is this somehow possible with current Spring Cloud Contracts?
No it's not valid. The question is why do you want to test that logic. From the point of view of contract testing you should maybe only check that there's a number there?
I'm trying to use Wiremock 2.24.1 to dynamically return different bodies files, depending on request path, and if not found locally I would like to call an external resource (as a proxy).
I'm using this mapping file:
{
"priority": 1,
"request" : {
"urlPattern" : "/rest/v2/name/.*",
"method" : "GET"
},
"response" : {
"status" : 200,
"bodyFileName" : "rest_v2_name_{{request.requestLine.pathSegments.[3]}}_body.json",
"headers" : {
"Content-Type" : "application/json;charset=utf-8"
},
"transformers": ["response-template"]
}
}
And I have one file named rest_v2_name_springfield_body.json with this content
[
{
"name": "Springfield",
"now": "{{now}}",
"yesterday"; "{{now offset='-1 days' format='yyyy-MM-dd HH:mm:ssZ'}},
"tomorrow"; "{{now offset='1 days' format='yyyy-MM-dd HH:mm:ssZ'}}
}
]
returned when I call curl http://localhost:8099/rest/v2/name/springfield :
[
{
"name": "Springfield",
"now": "2019-08-17T00:23:12Z",
"yesterday"; "2019-08-15 21:23:12-0300,
"tomorrow"; "2019-08-17 21:23:12-0300
}
]
If I call with another path value (like http://localhost:8099/rest/v2/name/brasil) I want to be handled by this other mapping:
{
"priority": 10,
"request" : {
"urlPattern" : "/rest/v2/name/.*",
"method" : "GET"
},
"response" : {
"proxyBaseUrl" : "http://restcountries.eu"
}
}
But instead of answering the response of http://restcountries.eu/rest/v2/name/brasil, I'm getting a local HTTP 500 Error with this message (I believe it's from the first matching mapping):
java.io.FileNotFoundException: ./__files/rest_v2_name_brasil_body.json
I tried this alternatives
I disabled the first mapping (just for sure), and wiremock worked as a proxy as expected.
I tried a broader urlPattern ".*" on proxy mapping file, but didn't worked, first mapping still answered the call.
I switched the priorities (1 to proxy and 10 to local mapping), but all the calls where answered by the proxy, including the "springfield".
Is there a way to solve this scenario without coding ?
Regardless of the proxy on/off, Wiremock will always follow the priorities.
Considering that you have the same request pattern,
Case-I : When you have Proxy(brasil) at priority 1 and stub-mapping(spingfield) at priority 10 : You will be getting all the responses through Proxy only. There is no failover check for other mappings kind of thing.
Case-I : When you have Proxy(brasil) at priority 10 and stub-mapping(spingfield) at priority 1 : You will be getting the same response as stub-mapping you have configured since every request will be going to satisfy the springfield rule.
To solve this, you need to record every request when you are on Proxy.
Once you stop the recording, you can check for the mappings and add additional mappings as per you requirement !
How can I make a Spring #Controller return a 400 status code if the client sends any unexpected request parameters?
For example, I have this
public ResponseEntity<String> recommend(
#RequestParam(value = "max-age-seconds", required = false) Long maxAgeSeconds) {
...
}
And the client may have a typo in max-age-seconds, which my application won't recognise and then fallback to the default max age I chose at a later time.
I know I could get the list of all the request parameters with request.getParameterNames() and check one by one, but I'm looking for a neater and more efficient solution.
EDIT: I just found out that 4 years ago it didn't have a built-in solution, I wonder if it's still the case.
How about you call the method request.getParameterMap() and then check that the size of your Map is 1 the key equals "max-age-seconds" and you can even validate the value if you wish. if any of your validations goes wrong then return 400 (or may be 300 with error message "This is Sparta!"). (the last part is a joke...)
http://struts.apache.org/release/2.3.x/struts2-core/apidocs/org/apache/struts2/dispatcher/ServletDispatcherResult.html
The above links says that dispatcher result type, takes only 2 params location & parse, but I need to set the httpStatusCode of the response being sent.
I have also gone through http://struts.apache.org/release/2.3.x/docs/result-types.html and http://struts.apache.org/release/2.3.x/docs/httpheader-result.html
but then httpheader doesn't take location. The goal is to have features of both, any idea on how it can be done ?
The actual requirement is :
If the URL invocation is ajax, I need to return 401 and if that's hit directly, I have to show "Unauthorized Access" message. So, if somehow I can return a JSP along with status-code, then it'll do the job.
This kind of logic is better to implement in interceptor not in the result. Create custom interceptor that checks whether current request is AJAX or not and return different results from it.