I'm unable to perform check when using jsonPath (or any other matcher).
When using message I'm able to save whole JSON message in session
.check(wsAwait
.within(6 seconds)
.until(1)
.message.exists
//.jsonpJsonPath("$.data").exists
.saveAs("CID"))
And later in scenario I'm able to print whole message
{"event":"ConversationCreated",
"data":"{"conversationId":"0e21f93d-6b0c-441f-a01d-8b0aa4e14769",
"customerInfo":null,"deviceInfo":null}"}
But when using pathJson matcher, my check times out
.check(wsAwait
.within(6 seconds)
.until(1)
// .message.exists
.jsonpJsonPath("$.data").exists
.saveAs("CID"))
When run will produce
...
12:09:32.248 [ERROR] i.g.c.a.b.SessionHookBuilder$$anon$1 - 'hook-2' crashed with 'java.util.NoSuchElementException: key not found: CID', forwarding to the next one
...
---- Errors --------------------------------------------------------------------
> Check failed: Timeout 1 (100,0%)
I've managed to make it "work".
The issue was lack of esceping JSON inside JSON.
Whene you send some data trough sse your clients receive both data and event type. And Gatling provides it as Json Object. If data you send is also Json Gatling will just pass it in as simple string, without any modification, which creates improper Json
Actuall:
{"event":"ConversationCreated",
"data":"{"conversationId":"0e21f93d-6b0c-441f-a01d-8b0aa4e19",
"customerInfo":null,"deviceInfo":null}"}
Proper:
{"event":"ConversationCreated",
"data":"{\"conversationI\d":\"0e21f93d-6b0c-441f-a01d-8b0aa4e19\",
\"customerInfo\":null,\"deviceInfo\":null}\"}
Or, rather than keeping message in Json, it could be kept as object:
case class Message(event: String, data: String)
Related
I want to make http requests from my elm program.
I use the openapi-generator https://eriktim.github.io/openapi-elm for the http requests:
https://github.com/eriktim/openapi-elm,
The only example I could find is this:
https://github.com/eriktim/openapi-elm/tree/master/example
There, a request has e.g. type Api.Request Api.Data.PlanetList and is converted with the send function: (Result Http.Error a -> msg) -> Request a -> Cmd msg.
The send function takes a function to convert the Request result to msg but but returns it wrapped in Cmd.
The update function has type
update : Msg -> Model -> ( Model, Cmd Msg )
So as long as the request is made in the update function and the result is put in the return value the framework will get msg out of Cmd.
Now I want to make requests in my program, but I'm using playground game as my main function (example) where the update function is update : Computer -> Model -> Model so the "trick" from the example project is not applicable. How can I still get the values from my request call then?
A Http request is a piece of data for the runtime to execute. If the Cmd is not passed to the runtime through the main update, the actual http call will never happen.
This is why you cannot have side-effects in simple programs (Playground and Browser.sandbox).
I'm not really sure what elm-playground is, but that's not the right starting point for a webapp such as you want to create, as it does not support Commands, such as Http requests.
You want to be using normal / standard Elm - see https://guide.elm-lang.org/install/elm.html and then you want to be building a Program based on Browser.document - https://guide.elm-lang.org/webapps/
Hope that gets you on your way
I want to write a generic function in cpp that gets JSON data using cpprestsdk and copy the http status response code and the JSON data. The calling method will use the json_resp and http_status codes. Later on, I want to further make this function more generic by passing the URL and use it to get data from different web services. Please let me know how I can accomplish this.
pplx::task<void> handleWebServerRequest( web::json::value json_resp, int *http_status)
{
..
http_client client(L"http://weburl.com:8000/getjsondata");
return client.request(methods::GET).then([](http_response response) -> pplx::task<json::value> {
// Store the http status code to be returned to calling function
*http_status = response.status_code();
..
if(response.status_code() == status_codes::OK) {
return response.extract_json();
}
return pplx::task_from_result(json::value()); }).then([](pplx::task<json::value> previousTask) {
try {
// capture json response to json_resp
json_resp = previousTask.get();
}
catch( const http_exception& e) {
// print error
}
});
}
In my research I have found that the only difference between using cpprest api to consume a PHP web service and a WCF web service is the function parameter. When consuming a PHP web service you can set the function parameter to an empty string. Where as when consuming a WCF service you need to pass it a function parameter-because the protocol for receiving requests and issuing responses in a WCF service is very different, but the process of sending requests and receiving responses is asynchronous so there will always be at least three modules, functions or tasks involved. One to make the request. The other to wait and receive the response and another to parse the data which is called asynchronously by the function that receives the response. I suppose you could put all three tasks into one function and use go to statements to execute each task, perhaps use some inline assembly to capture the response, and use pointers in place of parameters - but it is still three tasks anyway you slice it. The two others run in a thread and do not have access to the application data, but the last function that parses the data (the json object) which is called asynchronously you could make generic. I don't know which web services you want to consume, but I posted two samples on github-Example of Casablanca (cpprestsdk 2.9.1) consuming a PHP web service and Example of Casablanca (cpprestsdk 2.9.1) consuming a WCF (.net) web service. I believe this should get you off to a good start. To capture the json values you can convert your json values to std strings (as shown below) and then you can store them respectively in a local hashmap by adding a hashmap pointer argument to all three functions and passing a reference to the local hashmap variable from which ever function you are calling it from where they can be converted to what ever data type you need.
void get_field_map_json(json::value & jvalue, unordered_map <string, string> * hashmap)
{
if (!jvalue.is_null())
{
for (auto const & e : jvalue.as_object())
{
std::string key(conversions::to_utf8string(e.first));
std::string value(conversions::to_utf8string(e.second.as_string()));
(*hashmap)[key] = value;
}
}
I'm trying to set up some tests for an API made by a coworker with spray.io, and I'm encountering some odd behavior. When a request results in an error for any reason, we want to return a JSON value along the lines of:
{"status":false,"message":"useful message here"}
This happens just fine in the actual browser. I have navigated to an unhandled route in the web browser, and I get the desired JSON value. So, I want to test this. Now, since I'm new to spray.io, I started off with the very simple test:
"leave GET requests to root path unhandled" in {
Get() ~> myRoute ~> check {
handled must beFalse
}
}
This went fine, no problems. Since it's my first time playing with spray.io, I looked at some of the sample tests for testing false routes, and wrapped myRoute with sealRoute() so I could check the response without failing tests:
"leave GET requests to root path unhandled" in {
Get() ~> sealRoute(myRoute) ~> check {
handled must beTrue
}
}
This also works fine. So, I decided to just make sure the text of the response was usable with this, before I went to the trouble of parsing JSON and verifying individual values:
"leave GET requests to root path unhandled" in {
Get() ~> sealRoute(myRoute) ~> check {
responseAs[String] contains "false"
}
}
This is failing. To investigate, I threw a simple line of code in to log the actual value of responseAs[String] to a file, and I got this:
The requested resource could not be found.
Can anyone tell me what I'm doing wrong? I'm thinking that one of the following is occurring:
responseAs[String] is doing more than taking the exact response and giving it back to me, applying some type of filter along the way
The framework itself is not fully evaluating the query, but rather making a mockup object for the test framework to evaluate, and therefore not executing the desired 'turn errors to json' methods that my co-worker has implemented
I have tried searching google and stack overflow specifically for similar issues, but I'm either not putting in the right queries, or most other people are content to have the default error messages and aren't trying to test them beyond checking handled must beFalse.
Edit - This is the relevant part of the RejectionHandler:
case MissingQueryParamRejection(paramName) :: _=>
respondWithMediaType(`application/json`) {
complete(BadRequest, toJson(Map("status" -> false, "message" -> s"Missing parameter $paramName, request denied")))
}
Okay, so with insight from here and a coworker, the problem has been found:
Basically, the custom RejectionHandler was defined within our custom Actor object, and it wasn't coming into scope in the tests. To resolve this, the following steps were taken:
Moved the definition for the custom RejectionHandler into its own object in a separate file (as it had to do its own imports, it was causing a "encountered unrecoverable cycle resolving import" error)
Imported this new object into both the original file and the test spec.
(fun fact - http://spray.io/documentation/1.2.2/spray-routing/key-concepts/rejections/#rejectionhandler seems to demonstrate the RejectionHandler as a top-level object but you can't have top-level implicit vals in Scala, hence the need for an object)
i am confused on how to combine the json library in dispatch and lift to parse my json response.
I am apparently a scala newbie.
I have written this code :
val status = {
val httpPackage = http(Status(screenName).timeline)
val json1 = httpPackage
json1
}
Now i am stuck on how to parse the twitter json response
I've tried to use the JsonParser:
val status1 = JsonParser.parse(status)
but got this error:
<console>:38: error: overloaded method value parse with alternatives:
(s: java.io.Reader)net.liftweb.json.JsonAST.JValue<and>
(s: String)net.liftweb.json.JsonAST.JValue
cannot be applied to (http.HttpPackage[List[dispatch.json.JsObject]])
val status1 = JsonParser.parse(status1)
I unsure and can't figure out what to do next in order to iterate through the data, extract it and render it to my web page.
Here's another way to use Dispatch HTTP with Lift-JSON. This example fetches JSON document from google, parses all "titles" from it and prints them.
import dispatch._
import net.liftweb.json.JsonParser
import net.liftweb.json.JsonAST._
object App extends Application {
val http = new Http
val req = :/("www.google.com") / "base" / "feeds" / "snippets" <<? Map("bq" -> "scala", "alt" -> "json")
val json = http(req >- JsonParser.parse)
val titles = for {
JField("title", title) <- json
JField("$t", JString(name)) <- title
} yield name
titles.foreach(println)
}
The error that you are getting back is letting your know that the type of status is neither a String or java.io.Reader. Instead, what you have is a List of already parsed JSON responses as Dispatch has already done all of the hard work in parsing the response into a JSON response. Dispatch has a very compact syntax which is nice when you are used to it but it can be very obtuse initially, especially when you are first approaching Scala. Often times, you'll find that you have to dive into the source code of the library when you are first learning to see what is going on. For instance, if you look into the dispatch-twitter source code, you can see that the timeline method actually performs a JSON extraction on the response:
def timeline = this ># (list ! obj)
What this method is defining is a Dispatch Handler which converts the Response object into a JsonResponse object, and then parses the response into a list of JSON Objects. That's quite a bit going on in one line. You can see the definition for the operand ># in the JsHttp.scala file in the http+json Dispatch module. Dispatch defines lots of Handlers that do a conversion behind the scenes into different types of data which you can then pass to block to work with. Check out the StdOut Walkthrough and the Common Tasks pages for some of the handlers but you'll need to dive into the various modules source code or Scaladoc to see what else is there.
All of this is a long way to get to what you want, which I believe is essentially this:
val statuses = http(Status(screenName).timeline)
statuses.map(Status.text).foreach(println _)
Only instead of doing a println, you can push it out to your web page in whatever way you want. Check out the Status object for some of the various pre-built extractors to pull information out of the status response.
I am trying to read a soap response twice and I got the error message already read ... There are some examples how to avoid this BUT ... they are using the CreateBufferedCopy method and I cannot find it on the silverlight2 Message object:
Microsoft has also this sentence in the silverlight doc :
http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.getreaderatbodycontents(VS.95).aspx
"If you want to access the body multiple times, use CreateBufferedCopy(Int32) to create a MessageBuffer instance."