Say that I use such code:
ElasticClient client = ...
client.execute{search in "places"->"cities" query "paris" start 5 limit 10}
How to see what json request was been sent to Elasticsearch?
In Elastic4s 1.6.2 you can use the show typeclass on a number of requests to get the JSON equivilent.
It's pretty straightforward.
val req = search in "index" / "type" query "kate bush"
logger.debug(s"Search request ${req.show}")
The .show method will render JSON output. It works on most of the request types.
In Elastic4s 5.2.0+, you use the show method on the client.
val req = search("index" / "type").query("kate bush")
client.show(req)
I did not find build-in feature to track every request via elastic4s client, but there is a _builder variable in elastic4s which you can use to print request before execute it:
println(search in "places"->"cities" query "paris" start 5 limit 10 _builder) toString
{
"from" : 5,
"size" : 10,
"query" : {
"query_string" : {
"query" : "paris"
}
}
}
Related
Using the Spring WebClient I am calling a Rest API that gives me a response as a JSON, following is a structure of the response -
{
"vehicles":[
{ "name":"veh1", "type":"car", "age": 5 },
{ "name":"veh2", "type":"speedboat", "age":12},
.....
]
"metadata": {
"token":"abcd",
"days":120
}
}
I am a newbie to reactive programming, I have written the following code, which works fine ..
Mono<VehicleResponse> = webclient.get()
.uri("/legacy/vehicles")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.empty())
.onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.empty())
.bodyToMono(VehicleResponse.class);
But, actually what I am interested in is, only the vehicles array (don't want the metadata information.) Is it possible to obtain / read only the vehicles (array) as a Flux of Vehicle ?
I'm trying to authenticate RADIUS Requests against a RESTful API (provided by Customer) using rlm_rest.
The problem I am facing is that
response JSON format (of REST API provided by Customer), is different from rlm_rest default format (indicated in etc/raddb/mods-enabled/rest).
My Virtual Server configuration as below:
Default
authorize {
...
...
rest
if (ok) {
update control {
Auth-Type := rest
}
}
}
mods-enabled/rest
authorize {
uri = "https://3rd-party-API/auth"
method = 'post'
body = 'json'
chunk = 0
tls = ${..tls}
data = '{
"code": 1,
"identifier": %I,
"avps": {
"User-Name": ["%{User-Name}"],
"NAS-IP-Address": ["%{NAS-IP-Address}"],
"Called-Station-Id": ["%{Called-Station-Id}"],
"Calling-Station-Id": ["%{Calling-Station-Id}"],
"NAS-Identifier": ["%{NAS-Identifier}"]
}
}'
}
Result
/sbin/radiusd -Xxx
HTTP response code
200
JSON Body
{
"code": "2",
"identifier": "91",
"avps": {
"Customer-Attributes": "Hello"
...
...
"Acct-Interim-Interval": "300"
}
}
The JSON structure is different from the example, and xlat parse
"code"
"identifier"
"avps"
And, of course, xlat finds no attributes match with the dictionary, while it cannot find "avps" and won't dig deeper.
So I was wondering is there anyway to either
Define the response JSON structure for xlat to parsing
Insert a "is_json" or "do_xlat" flag into the JSON ("avps"), and hope xlat will then dig deeper
Save the JSON and parse with exec/rlm_exec (using JQ or any other bash/JSON tools)
Please advise if there is any workaround. Thanks!
In FreeRADIUS version 4, there's a rlm_json module, which implements a custom node query language based on xpath (jpath), it is extremely limited and only supports some very basic queries (feel free to enhance it via PR :) ).
Below is an example I pulled out of my library of customer configurations. You can see here it's pulling out two keys (externalID and macAddress) from the root level of the JSON doc and assigning them to a couple of custom attributes (Subscriber-ID and Provisioned-MAC).
map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
&Subscriber-ID := '$.externalId'
&Provisioned-MAC := '$.macAddress'
}
The xlat expansion can also be modified to send HTTP body data. Just put a space after the URL and pass your custom JSON blob.
Question: How to extract entire restAPI response and modify it with some values and use the updated response for sub-sequent rest call. I am using Jmeter
Question Scenario:
I have one POST call ex: "/check1/id1/post"
POST body :
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz"
}
}
POST call RESPONSE :
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz"
"status":"updated"
}
}
=====================================================================
QUESTION: Now, I have to use entire above RESPONSE in next POST Call body as below, BUT, I wanted to update "id" value as 2 and then need to POST rest call.
REST CALL: ------ > "/check1/id2/post"
POST BODY as below : ------->
{
"test":"rest",
"check" :{
"id":2,
"name": "xyz"
"status":"updated"
}
}
=============================================================
Can anyone please guide on this? , I am clueless about how to solve this issue?, I need to solve this using Jmeter.
To store entire response:
add Regular Expression Extractor as a child of the request which response you want to capture
configure it as follows:
Reference name: anything meaningful, i.e. response
Regular Expression: (?s)(^.*)
Template: $1$
To replace 1 with 2 you can go for __strReplace() function like ${__strReplace(${response},1,2,)}. Note that you need to install Custom JMeter Functions bundle using JMeter Plugins Manager in order get it.
You can do this using beanshell or JSR223 PreProcessor
Assuming a valid JSON
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz",
"status":"updated"
}
}
Here are the steps
Add a JSR223 preprocessor to the 2nd post request.
Add the following code to the preprocessor
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def slurped = new JsonSlurper().parse(prev.getResponseData())
def builder = new JsonBuilder(slurped)
builder.content.check.id = '2'
vars.put("POSTDATA",builder.toPrettyString())
Above code will update ID value with 2 and stores the JSON in POSTDATA , you can use ${POSTDATA} to post the JSON FILE
In my pre processor i'm saving the response using prev.getResponseData() , that means this pre processor must included with the sampler right next to the first sampler.
For more information on beanshell Please follow this link
I'm trying to use Alamofire 3.3 with the Nutritionix API.
I was able to get a few requests going however i'm having issues to get usda_fields.
var params = [
"appId" : MY_APP_ID,
"appKey" : MY_APP_KEY,
"fields" : ["item_name", "brand_name", "keywords", "usda_fields"],
"limit" : "50",
"query" : searchString,
"filters" : ["exists":["usda_fields": true]]
]
Alamofire.request(.GET, "https://api.nutritionix.com/v1_1/search/", parameters: params)
.responseData { response in
print(response.request)
print(response.response)
print(response.result)
}
For some reason I realized that 'fields' shouldn't be in an array and just follow each others separated by a coma. Then the query return something however the filter doesn't seem to work.
Any help appreciated thanks!
If you are still looking to solve this, I recommend trying the 2.0 version of our API instead of the 1.1 version. Here are the details:
https://developer.nutritionix.com/docs/v2
Feel free to email us at api at nutritionix dot com if you have more questions about the API!
I have a block of code which needs to loop through a JSON array which is obtained from response of a REST service. (Full gist available here.)
.exec(http("Request_1")
.post("/endPoint")
.headers(headers_1)
.body(StringBody("""REQUEST_BODY""")).asJSON
.check(jsonPath("$.result").is("SUCCESS"))
.check(jsonPath("$.data[*]").findAll.saveAs("pList")))
.exec(session => {
println(session)
session
})
.foreach("${pList}", "player"){
exec(session => {
val playerId = JsonPath.query("$.playerId", "${player}")
session.set("playerId", playerId)
})
.exec(http("Request_1")
.post("/endPoint")
.headers(headers_1)
.body(StringBody("""{"playerId":"${playerId}"}""")).asJSON
.check(jsonPath("$.result").is("SUCCESS")))
}
The response format of the first request was
{
"result": "SUCCESS",
"data": [
{
"playerId": 2
},
{
"playerId": 3
},
{
"playerId": 4
}
]
}
And playerId shows up in the session as
pList -> Vector({playerId=2, score=200}, {playerId=3, score=200}
I am seeing in the second request the body is
{"playerId":"Right(empty iterator)}
Expected : 3 requests with body as
{"playerId":1}
{"playerId":2}
{"playerId":3}
I can loop over the resulting array successfully if I save just the playerIds:
.check(jsonPath("$.data[*].playerId").findAll.saveAs("pList")))
I managed to get the requests you're looking for sent out (although still getting a 404, but that might be server-side or the request your gist is sending might be missing something). The trick was to give up on JsonPath entirely:
.exec(http("Request_10")
.get("gatling1")
.headers(headers_10)
.check(jsonPath("$.result").is("SUCCESS"),
jsonPath("$.data[*]").ofType[Map[String,Any]].findAll.saveAs("pList")))
.foreach("${pList}", "player") {
exec(session => {
val playerMap = session("player").as[Map[String,Any]]
val playerId = playerMap("playerId")
session.set("playerId", playerId)
})
Here, the jsonPath check can automatically store your JSON object as a map, and then you can access the player ID by key. The value type doesn't have to be Any, you could use Int or Long if all your values are numbers. If you want more info on what went wrong with JsonPath, read on.
Your first problem is that JsonPath.query() doesn't just return the value you're looking for. From the JsonPath readme:
JsonPath.query("$.a", jsonSample) gives you Right(non-empty iterator). This will allow you to iterate over all possible solutions to the query.
Now, when it says Right(non-empty iterator), I assumed that meant the iterator was not empty. However, if you try this:
val playerId = JsonPath.query("$.playerId", session("player").as[String]).right.get
println(playerId)
...it prints "empty iterator". I'm not sure whether it's a problem with JsonPath, the jsonPath check, or usage somewhere in between, but there's not quite enough documentation for me to want to dig into it.