how to judge whether the parameters in URL in bottle? - bottle

for example, the URL:
http://localhost:8080/company?a=1
and how can i know whether the URL contains parameters a .

Here's how you access a:
#route('/company')
def company():
if bottle.request.params.get('a') is not None:
# param "a" was present in the URI's query string

Related

How to set different protocol for each user (threads running) in gatling

I am trying to create a performance test suite where i have array of ID's that will be picked in random. For each ID , there is a designated auth_token assigned .
In the protocol , if i pass the method where the random ID's would take , it always sets it to that particular ID for the entire operation .
I am expecting something like , i am defining 10 virtual users and for each user the protocol should change the ID and continue the scenario execution .
Currently Gatling is setting the protocol at the first and uses the same protocol for all the 10 users.
id = random.generate //generate random id
authHeader = Method(id);
def method (id:String) : String{
if(id=="id1")
return token1
else if(id=="id2")
return token2
""
}
val httpProtocol = http.baseUrl(baseURI)
.acceptHeader(header)
.authorizationHeader(authHeader)
.contentTypeHeader(contentType)
.userAgentHeader(agentHeader)
val scn1: ScenarioBuilder = scenario("name")
.exec(http("scenario1")
.post(device_context)
.body(payload)
.check(status.is(202)))
setUp(scn1.inject(atOnceUsers(2)).protocols(httpProtocol))```
In the above code i need the suite to run for 2 different id.
To make this work, you're going to have to use a session variable to hold your authHeader. The DSL methods define builders that are only executed once - which explains what you're seeing.
The best way to do this would be to construct a feeder to hold your ids and auth tokens (I'm assuming you're not using the id anywhere else)
So define a feeder that maps a key (just a string) to a map that contains the id and auth token
//a list of strings to hold the auth tokens
private val ids = List(Map("id" -> "id1", "auth" -> "token1"), Map("id" -> "id2", "auth" -> "token2"), ...)
//the feeder to put a random token into the session
private val idFeeder = Iterator.continually(Map("id" -> Random.shuffle(ids).head))
now when you call .feed on idFeeder you get a random Map that has keys for "id" and "auth" in the session variable "id"
so update your scenario to use the feeder and set an Authorization header (and remove .authorizationHeader from your protocol definition)
val scn1: ScenarioBuilder = scenario("name")
.feed(idFeeder)
.exec(http("scenario1")
.header("Authorization", "${id.auth})"
.post(device_context)
.body(payload)
.check(status.is(202)))
in your body you can access the user id string with "${id.id}"
alternatively you could update your protocol definition to have the ${id} reference, but I find it nicer to have the feeder value used in the same block as the call to .feed

How to pass response body field to other request's body (Gatling)

I have two end point.
-/authenticate
-/authenticate/verification
/authenticate return guid field on response body.
and /authenticate/verification requires that field on request body.
I have tried to get guid like this :
jsonPath("$..guid").saveAs("verificationGuid")
and pass it to other body :
.body(StringBody(s"{\"guid\":${verificationGuid}, \"code\":\"123456\"}"))
this is the code block:
def login = {
exec(http("Authenticate")
.post("/authenticate")
.body(StringBody(userString))
.headers(headerLogin)
.check(status is 200)
.check(jsonPath("$..guid").saveAs("verificationGuid"))
)
.exec(http( "Authenticate verify")
.post("/authenticate/verify")
.headers(headerLogin)
.body(StringBody(s"{\"guid\":${verificationGuid}, \"code\":\"123456\"}"))
.check(status is 200)
)
}
But it doesnt work, how can I do this?
Remove s from s"{\"guid\":${verificationGuid}, \"code\":\"123456\"}"). If s is in front of string every ${something} placeholder will be treated as Scala built in string interpolation and compiler will try to replace it with Scala variable, which in your case does not exist. Without s it will be treated as literal string and than caught by Gatling EL Parser and replaced with previously saved Gatling session attribute.

RestAssured response validation using body and array as parameter

I am trying to validate a REST response. Is it possible to use an array as parameter to containsonly?
Ex:
String values[] = line.split(",");
given().
when().
then().
statusCode(200).
body("value", containsOnly(values));
Also, can we use variables as parameters to other methods like HasItems, equalTo etc?
Ex: body(HasItems(values))
Yes, You could use any appropriate matcher to check whole body or just part of it. Just take attention on a object type returned by pecified path - first argument of body().
Try this :
Response resp = RestAssured.given()
.header("Content-Type", "application/vnd.dpd.public.v1+json")
.body(FixtureHelpers.fixture("request/request.json"))
.post("/");
resp
.then()
.statusCode(200)
.body("random.object", CoreMatchers.equalTo("value"));
This would work for request.json object like :
{"random":{"object": "value"}}

How do I access the full path of a request in Akka HTTP request?

In some contexts I can match on the remaining path using a PathDirective to get the information I need about the path. For example, when route below is directly bound and handled by Akka HTTP, every request will echo back the requested path as desired.
val route =
path(Remaining) { path =>
complete(path)
}
However, when the above route is combined elsewhere in the application, the path variable above may only hold part of the requested path not giving the desired results.
For example if the actual bound route is be,
val actualRoute = pathPrefix("echo") { route }
The "echo/" part of the overall path will be missing from the response given to the user.
How can the complete path be reliably accessed?
Directives extractMatchedPath and extractUnmatchedPath let you access the path without matching the path like you path directive does above. These two can be combined to construct the full path:
val route =
extractMatchedPath { matched =>
extractUnmatchedPath { unmatched =>
complete((matched.dropChars(1) ++ unmatched).toString)
}
}
However it is probably cleaner just to extract the Path from the URI directly:
val route =
extractUri { uri =>
complete(uri.toRelative.path.dropChars(1).toString)
}
Note that in both cases we needed to call .dropChars(1) to drop the initial forward slash and be consistent with the output you got using the path directive.

Play Framework 2.4 how to use return statement in Action controller

is there a way to return a value inside Action controller.
I have a method in my User model which returns the number of friends of a given user.
def nrOfFriends(current_user: Long): Int = {
DB.withConnection{ implicit connection =>
var nr: Int = SQL("select count(*) from friend where user_id_1=" + current_user + " or user_id_2=" + current_user).as(scalar[Int].single)
nr
}
}
In my controller, I just want to return the value from the model
def freunde() = IsAuthenticated { username => _ =>
User.findByUsername(username).map { user =>
var nr: Int = Friend.nrOfFriends(user.id.get)
Ok(""+nr)
}.getOrElse(Forbidden)
}
But in the way that is written, it will print "empty string " concatenated with the number
If I replace Ok(""+nr) with Ok(nr) I receive the following error:
"Cannot write an instance of Int to HTTP response. Try to define a Writeable[Int]"
I need for my action to return a value so that I can pass the value from the action to header.views.html inside the navbar something like that
#Freund.freunde Friends
if you want your response to just be the value of nr you can simply call nr.toString:
def freunde() = IsAuthenticated { username => _ =>
User.findByUsername(username).map { user =>
var nr: Int = Friend.nrOfFriends(user.id.get)
Ok(nr.toString)
}.getOrElse(Forbidden)
}
The error you're getting makes reference to the fact that Int doesn't have an implicit Writeable[Int] in scope. So play doesn't know how display an Int in an http response.
You can add make Int writeable by putting this in scope:
implicit val intWriteable = play.api.http.Writeable[Int](_.toString.getBytes, None)
Then you would be able to just say:
Ok(nr)
without error.
However, it sounds like you just want the result of nrOfFriends inside an unrelated template. If that's the case, you should be using an Action at all. Instead just call your model function inside the template where you need the data.
#User.nrOfFriends(user.id) Friends
Of course you would need to pass in the user to the template as well.
You didn't post a full sample of all the code involved in what you are trying to accomplish so I think this is the best I can do for now. Perhaps try posting the base template that your <a> is in.
An important point is that Actions are for production an HTTP response, and not just plain data internally to the application.
An action of a controller handles a request and generates a result to be sent to the client. In other words, an action returns a play.api.mvc.Result value, representing the HTTP response to send to the web client. In your example Ok constructs a 200 OK response. The body of the response must be one of the predefined types, including text/plain, json, and html. The number of a friends is an integer and is NOT an acceptable type of the body. Therefore, a simple way to address this problem is to convert it into a text/plain using .toString().
On the other hand, you can define a writer for Int that lets Play know how to convert an integer into a json format.
For more details, please take a look at this https://www.playframework.com/documentation/2.2.x/ScalaActions.