Wiremock response depending on request body parameter - json

I am sending Wiremock (Standalone, 2.21) a request with the body
{
"attribute1": "value1",
"attribute2": "value2",
...
"attributen": "valuen"
}
to the URL /test/test-url , no query parameters, with POST.
I would like it to do the following:
respond with "response1.json" when attribute1 equals "text1"
respond with "response2.json" when attribute1 equals "text2"
respond with "response_general.json" when attribute1 equals something else than "text1" or "text2"
The other attributes dont matter regarding the answer.
I would like to do this by only using .json files. Thank you!

The answer was to have check for body patterns and have 3 mappings for the 3 different cases:
One for the case when text1 is detected:
"request": {
"method": "POST",
"urlPattern":"/.*",
"bodyPatterns": [
{
"contains":"\"attribute1\": \"text1\""
}
]
},
"response": {
"status": 200,
"bodyFileName": "response_text1.json",
"headers": {
"Content-Type": "application/json"
}
}
One for the case when text2 is detected:
"request": {
"method": "POST",
"urlPattern":"/.*",
"bodyPatterns": [
{
"contains":"\"attribute1\": \"text2\""
}
]
},
"response": {
"status": 200,
"bodyFileName": "response_text2.json",
"headers": {
"Content-Type": "application/json"
}
}
One for the case when neither is detected. In this case a general answer is given back.
"request": {
"method": "POST",
"urlPattern": "/.*"
},
"response": {
"status": 200,
"bodyFileName": "response_general.json",
"headers": {
"Content-Type": "application/json"
}
}

In the more recent versions of WireMock (2.19+) there is support for HandleBars processing in the BodyFileName attribute. This then allows you to do put a (partial) name in the JSON request body and then reuse it's value for the filename reference.
{
"request" : {
"urlPathPattern" : "/jpathFile",
"method" : "GET",
"headers": {
"Content-Type": {
"equalTo": "application/json"
}
}
},
"response" : {
"status" : 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName" : "/{{jsonPath request.body '$.attribute2'}}",
"transformers": ["response-template"]
}
}
Input message:
{
"attribute1": "value1",
"attribute2": "response.json",
"attributen": "valuen"
}
the response.json in the /__files/response.json location:
{
"hello": "World!"
}

Instead of using "contains" or "equalTo" i would suggest to use "matchesJsonPath"
"bodyPatterns": [
{
"matchesJsonPath": "$[?(#.attribute1 == 'value1')]"
}
]

Related

Getting an error "Can not deserialize instance of java.lang.String out of START_OBJECT " even though the Json code is from Docs

I took this syntax for the payload from the formal docs of jira, yet i am still getting an error. I am using either python or curl both give the same error. I supppose this is a Json related issue , could you find what is wrong with the jason/payload and how do i go about fixing it?
import requests
import json
url = "https://jira.company.io/rest/api/latest/issue/ISS-37424/transitions"
payload = json.dumps({
"update": {
"comment": [
{
"add": {
"body": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [
{
"text": "Bug has been fixed",
"type": "text"
}
]
}
]
}
}
}
]
},
"transition": {
"id": "2"
}
})
headers = {
'Authorization': 'Basic YmVzQ=LKKJYTFTgfg','
Accept': 'application/json',
'Content-Type': 'application/json',
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)

Wiremock Capture path param and return in the response body after "=" symbol only

I am trying to create dynamic mocks using WireMock. My URL is like :
http://localhost:8080/manage/classids/query1=ns1/query2=id1
then I want output as
{
"yourId":"id1"
}
I try do like this way
{
"name": "Req_GET",
"request": {
"urlPathPattern": "/manage/classids/query1=([a-zA-Z0-9]*)/query2=([a-zA-Z0-9]*)",
"method": "GET"
},
"response": {
"status": 200,
"jsonBody": {
"yourId": "{{request.path.[3]}}"
},
"transformers": [
"response-template"
],
"headers": {
"Content-Type": "application/json"
}
}
}
but I am not able to split response after "=" it is coming whole after "/"
{
"yourId":"query2=id1"
}
You can reference the query parameter directly using WireMock's request model
...
"yourId": "{{request.query.query1}}"
...

404 error in using REST API in neo4j

Here I am trying to execute shortestPath algorithm in neo4j.
{
method: 'POST',
json:true,
url: 'http://neo4j:admin#localhost:7474/db/data/81/path',
body:{
"to" : '/db/data/84',
"max_depth" : 2,
"relationships" : {
"type" : "Meet",
"direction" : "out"
},
"algorithm" : "shortestPath"
}
},
Obtained response:
error: null
body:
{
"statusCode":404,
"headers":
{
"date":"Wed, 24 May 2017 05:10:51 GMT",
"access-control-allow-origin":"*",
"connection":"close",
"server":"Jetty(9.2.9.v20150224)"
},
"request":
{
"uri":
{
"protocol":"http:",
"slashes":true,
"auth":"neo4j:admin",
"host":"localhost:7474",
"port":"7474",
"hostname":"localhost",
"hash":null,
"search":null,
"query":null,
"pathname":"/db/data/81/path",
"path":"/db/data/81/path",
"href":"http://neo4j:admin#localhost:7474/db/data/81/path"
},
"method":"POST",
"headers":
{
"authorization":"Basic bmVvNGo6YWRtaW4=",
"accept":"application/json",
"content-type":"application/json",
"content-length":144
}
}
}
Please, can anyone help me out with this?
You are missing /node from your url and to paths.
Try this:
{
method: 'POST',
json:true,
url: 'http://neo4j:admin#localhost:7474/db/data/node/81/path',
body:{
"to" : '/node/84',
"max_depth" : 2,
"relationships" : {
"type" : "Meet",
"direction" : "out"
},
"algorithm" : "shortestPath"
}
}

Cannot Transform Correctly with Elasticsearch Watcher {{ctx.payload.hits.hits}}

I have a watcher configuration as follows:
{
"trigger": {
"schedule": {
"interval": "5s"
}
},
"input" : {
"search" : {
"request" : {
"indices" : [ "my_index" ],
"types" : [ "my_type" ],
"body" : {
"query" : {
"match_all" : {}
}
}
}
}
},
"transform" : {
"script" : "return [ body: groovy.json.JsonOutput.toJson(ctx.payload.hits.hits)]"
},
"actions" : {
"hbase_webhook" : {
"webhook" : {
"method" : "POST",
"host" : "<some_ip>",
"port" : <some_port>,
"path": "/v0.1/_events",
"body" : "data: {{ctx.payload.body}}"
}
}
}
}
The data posted in the body is not a valid JSON: Something like:
{ 'data: ': { '{"_index":"my_index","_type":"my_type","_source":{"key":"val"}},"_id":"<some_id>","_score":1.0}': '' } }
I don't know how to parse this output as JSON.parse in Node.js won't correctly parse it anyway.
Never. Forget. Headers.
I was forgetting:
"headers" {
"Content-type": "application/json"
}
So it was impossible to parse with any tool.
Ran into this while creating an alert for an endpoint where we just wanted to send off the actual records that matched specific criteria. See sample below:
"actions": {
"my_webhook": {
"webhook": {
"scheme": "https",
"host": "webhook.site",
"port": 443,
"method": "post",
"path": "/webhooksiteguidwouldbehere",
"params": {},
"headers": {
"Content-type": "application/json"
},
"body": "{{#toJson}}ctx.payload.hits.hits{{/toJson}}"
}
}
}
Second Note:
If the body size is set to 0 your hits will be returned as null. :)

Wiremock variable substitution in JSON response

I am trying to configure Wiremock mappings to return a JSON response with a value from the request.
The request is simply
{ "clientTag": "123" }
And the mapping for it is:
{
"priority": 4,
"request": {
"method": "POST",
"urlPattern": "/test"
},
"response": {
"status": 200,
"body": "{ \"loginId\": \"${loginId}\" }",
"headers": {
"Content-Type": "application/json"
}
},
"captures" : [ {
"source" : "BODY",
"target" : "loginId",
"pattern" : "$..clientTag",
"captureGroup" : 1
} ]
}
I receive the response:
{ "loginId": "" }
while the expected one is:
{ "loginId": "123" }
If I switch to XML requests, everything works fine with the pattern <clientTag>(.*?)</clientTag>, but I would like to stick to JSON.
Unfortunately Wiremock documentation is scarce hence the question. Any ideas?
UPDATE: If someone is reading this later, you'd do best to use the transforms in the code, which are available in the later Wiremock versions.
This seems like a perfect use-case for OpenTable's Wiremock Body Transformer.
It can be easily integrated with the Standalone Server like this:
java -cp "wiremock-body-transformer-1.1.6.jar:wiremock-2.3.1-standalone.jar" com.github.tomakehurst.wiremock.standalone.WireMockServerRunner --verbose --extensions com.opentable.extension.BodyTransformer
This extension allows you to easily specify a variable in the request that you would want to match in the response.
{
"request": {
"method": "POST",
"urlPath": "/transform",
"bodyPatterns": [
{
"matchesJsonPath": "$.name"
}
]
},
"response": {
"status": 200,
"body": "{\"responseName\": \"$(name)\"}",
"headers": {
"Content-Type": "application/json"
},
"transformers": ["body-transformer"]
}
}
It also easily allows you to generate a random integer in the response as seen here:
{
"request": {
"method": "POST",
"urlPath": "/transform",
},
"response": {
"status": 200,
"body": "{\"randomInteger\": \"$(!RandomInteger)\"}",
"headers": {
"Content-Type": "application/json"
},
"transformers": ["body-transformer"]
}
}
Unless you've added an extension you haven't mentioned, this can't work - there's no "captures" element in the JSON API, and no way (without extensions) to do variable substitution in responses.
WireMock.Net does support this now.
When sending a request like:
{
"username": "stef"
}
And using mapping like:
{
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/test"
}
]
},
"Methods": [
"post"
]
},
"Response": {
"StatusCode": 200,
"BodyAsJson": {
"path": "{{request.path}}",
"result": "{{JsonPath.SelectToken request.bodyAsJson \"username\"}}"
},
"UseTransformer": true,
"Headers": {
"Content-Type": "application/json"
}
}
}
The response will be like:
{
"path": "/test",
"result": "stef"
}
Note that this functionality is currently in preview mode, see NuGet package version 1.0.4.8-preview-01.
If you have any questions, just create an issue on this github project.