Wiremock variable substitution in JSON response - json

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.

Related

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}}"
...

Wiremock response depending on request body parameter

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')]"
}
]

Logic Apps - Http+Swagger - Header attribute for token based authentication

I am trying to add headers to a Http+Swagger action in Logic App.
When I add a simple Http Action, I can clearly see the Headers in the designer.
However, with Swagger+Http action it disappears.
I am using token based authentication and need to add Header to this API call.
Hence, I modified the code view like below but it does not seem to help!
Cannot find much resources with regards to this. Any help is appreciated.
Thank You.
"Information_Process": {
"inputs": {
"body": {
"fileId": "Test.json",
"items": [
{
"item": {
"prop1": "#items('For_each')?['Item']?['prop1']",
"prop2": "#items('For_each')?['Item']?['prop2']",
"prop3": "#items('For_each')?['Item']?['prop3']"
}
}
]
},
"headers": {
"Authorization": "#{concat('Bearer ',variables('BearerTokenValue'))}"
},
"method": "post",
"uri": "https://appone.azurewebsites.net/api/information/proccessing"
},
"metadata": {
"apiDefinitionUrl": "https://appone.azurewebsites.net//swagger/docs/v1",
"swaggerSource": "custom"
},
"type": "Http"
}
The official documentation states to make use of the parameters to send and receive a token.
"parameters": {
"secret": {
"type": "SecureString"
}
}
Or you can try like this
"HTTP": {
"inputs": {
"headers': {
"Authorization": "#concat('Basic ', base64('username:password'))",
"Content-Type ": "application/json"
},
"method ": "GET ",
"uri": "someurl"
},
"runAfter": (),
"type": "Http"
}

Solr update with Rest API Json data

I'm using solr 6.5.1. I have json data in Rest url;
For example:
POST : http://localhost:8484/api/cloud/list-users
is_user: xxx
is_key : pqxqxaweqweqx14123
I can able to fetch data via postman rest client. Is there anyway to post data to solr collection via above rest post url? Please tell me how do i implement this feature in solr.
Try this:
POST /api/cloud/list-users/update/json/docs?commit=true HTTP/1.1
Host: localhost:8484
Content-Type: application/json
{
"is_user": "xxx",
"is_key": "pqxqxaweqweqx14123"
}
And if you want to import it into Postman, here's a json (save it to a .json and then import it as a collection into Postman)
{
"variables": [],
"info": {
"name": "Solr Post New Document",
"_postman_id": "291f6b0e-6aad-7778-c29d-f194ce45c5de",
"description": "",
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
},
"item": [
{
"name": "Solr Post New Document",
"request": {
"url": "http://localhost:8983/solr/test/update/json/docs?commit=true",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\n\"is_user\": \"xxx\",\n\"is_key\": \"pqxqxaweqweqx14123\"\n}\n"
},
"description": ""
},
"response": []
}
]}
For more details, see the solr documentation:
https://cwiki.apache.org/confluence/display/solr/Uploading+Data+with+Index+Handlers#UploadingDatawithIndexHandlers-JSONFormattedIndexUpdates

Returning json in Wiremock using JSONPath based on attribute value

I'm trying to do stubbing with Wiremock to provide a response based upon the body that is sent in the post request.
For example, when sending this json:
{
"person": {
"firstName": "paul",
"age": "50"
}
}
I want to send pauldata.json
This is my request/ response json below:
{
"request": {
"method": "POST",
"url": "/api/test1",
"bodyPatterns": [
{
"matchesJsonPath": "$.person[?(#.firstName=='paul')]"
}
]
},
"response": {
"status": 200,
"bodyFileName": "pauldata.json",
"headers": {
"Content-Type": "application/json"
}
}
}
However this results in an error:
JSON path expression '$.person[?(#.firstName=='paul')]' failed to match document because of error 'net.minidev.json.JSONObject cannot be cast to java.util.List
this expression: $.person[?(#.firstName=='paul')] matches the json with the Jayway implementatin at http://jsonpath.herokuapp.com/, but not the Goessner implementation which Wiremock uses.
I noticed that if I just do $.person.firstName in jayway it returns "paul",
but when I do the same thing in Goessner I get ["paul"].
How can I match on the value of key using the Goessner implementation of JSONPath so I can return a custom json based on the value of a key in my data?
WireMock does not accept all JSONPath expressions, although they do work in online testers. I had the same problem, and solved it using the following:
{
"request": {
"method": "POST",
"url": "/api/test1",
"bodyPatterns": [
{
"matchesJsonPath": "$..[?(#.firstName=='paul')]"
}
]
},
"response": {
"status": 200,
"bodyFileName": "pauldata.json",
"headers": {
"Content-Type": "application/json"
}
}
}
The only thing that changed is from:
$.person[?(#.firstName=='paul')]
To:
$..[?(#.firstName=='paul')]
This is because .. notation searches through all input recursively.
In case you need to query a root element, meaning one that doesn't have a parent element, the same JSONPath will do. For example, imagine you have another element like so:
{
"person": {
"firstName": "paul",
"age": "50"
},
"test": "true"
}
In case you want to match for "test": "true" you would need JSONPath as follows:
$..[?(#.test=='true')]
I tested everything in my WireMock so it should work.