Run http tests until AMQ msgs consumed - scala

We're running Gatling/Scala to load test an application in the following manner:
Post a ton of messages to AMQ.
Run a number of REST calls while messages are being consumed.
The Gatling setup looks like this:
setUp(
JmsScenario.run inject(atOnceUsers(events)) protocols(JmsScenario.jmsConnect),
HttpScenario.run inject(constantUsersPerSec(httpThroughput) during(httpDuration)) protocols(HttpScenario.protocol),
)
But instead of using during(...) I'd like to use something like untilAmqMessageQueueIsEmpty(). Is there some (fairly easy) way to accomplish this?

Use asLongAs and call some custom code (in Java if you don't know Scala).
See https://gatling.io/docs/current/general/scenario/#aslongas.
// isAmqMessageQueueIsEmpty is something only you can code
// It has to return a Boolean
asLongAs(session => isAmqMessageQueueIsEmpty()) {
???
}

Related

Using `delay` in Sidekiq with dynamic class/method names

Let's say I have some internal business logic that determines what mailer needs to be sent.
The output of this business logic is a Hash in the following format -
{ mailer_class: SomeMailer, mailer_method: "foo_email" }
{ mailer_class: OtherMailer, mailer_method: "bar_email" }
# etc...
I need to call the appropriate mailer based on the info above so I try something like this with Sidekiq's built in delay -
data = { mailer_class: ..., mailer_method: "..." }
data[:mailer_class].delay.send(mailer[:method])
This results in Sidekiq queueing up the send method which will eventually be called on my mailer.
Functionally it might work correctly, because that class after all will receive the appropriate method. But it feels a bit dirty and it interrupts other processes that watch the sidekiq queue because they expect to see a mailer method name but find :send instead.
Is there a good way around this or am I stuck modifying the rest of my application logic to work with this?
Thanks!
Why not pass that Hash to a Sidekiq Worker which knows how to send emails with that class/method combo?
def perform(hash)
hash['mailer_class'].constantize.send(hash['mailer_method'])
end

How to run filter on demand scala play framework

I'm developing a scala application with play frame work, i have created a filter that filters every request coming from outside server,but now i'm stuck on how can i run a filter on demand since two days,i have 80 APIs 30 of them needs to run a specific filter, how can i read the request route template while the requests like this
GET /api/v1/:locale/:uuid core.controllers.MyClass.myAction1(locale: String)
GET /api/v1/:locale/:uuid/MyRoute core.controllers.MyClass.myAction2(locale: String)
GET /api/v1/:locale/:uuid/Foo core.controllers.MyClass.myAction3(locale: String)
GET /api/v1/:locale/orders/:orderId core.controllers.MyClass.myAction4(locale: String)
well, those routes are placed in routes file,
in filter i need to check weather if the route has :uuid variable or :orderId in order to run its specific filter, because both of their ids, i getting them as uuid so i couldn't expect the request, could i read the route template ?
You can access to some routing information from the RequestHeader#attrs:
// in your filter
val handlerDef: Option[HandlerDef] = request.attrs.get(Router.Attrs.HandlerDef)
See HandlerDef api
If you want to choose 30 out of 80 actions to run some common logic, you could also consider using "action builders" to provide that logic.
When you use Action { ... } you get a vanilla action. You can also make your own MyAction { ... } that wraps a normal Action and runs custom logic. This is an ActionBuilder. If you use this approach you just need to update your 30 actions to use that custom action builder.
See: https://www.playframework.com/documentation/2.6.x/ScalaActionsComposition#Custom-action-builders

how to log the response data in grails

Grails 2.5. I need to log the request and the response to log file.
This is to log REST/JSON api calls. I need to log both the request JSON (which is easy with a filter), and the response JSON (Which is looking impossible)
an api call looks like this:
class myController {
def myMethod() {
def json = request.JSON
:
render(status:200, contentType:'application/json' {
['something': "something",'sometingElse' : 42]
}
Tried creating a filter, e.g:
class LoggingFilters {
def filters = {
after = { Map model ->
log.debug "${response.???"
}
The question is, how do you get a handle on the output? Tried respose.outputStream.toString() etc, but it says something has already got the output stream.
I saw one suggestion which said don't use render, return a model with a map with a single item: data, and render this outside against some dummy jsp. Then you can get the model in the filter. The problem with this is that we have many hundreds of render statements, and we dont really want to retest everything (we have no automated testing).
Another other work around is to use tomcat request dumper filter, but this would not meet our requirements (e.g. we need to scrub certain output, such as passwords, want to be able to log to db, only want to log very specific things etc).
We tried this plugin: https://grails.org/plugin/httplogger , but it doesnt work with grails 2.5.

How to fail a Gatling test from within "exec"?

A Gatling scenario with an exec chain. After a request, returned data is saved. Later it's processed and depending on the processing result, it should either fail or pass the test.
This seems like the simplest possible scenario, yet I can't find any reliable info how to fail a test from within an exec block. assert breaks the scenario and seemingly Gatling (as in: the exception throw doesn't just fail the test).
Example:
// The scenario consists of a single test with two exec creating the execChain
val scn = scenario("MyAwesomeScenario").exec(reportableTest(
// Send the request
exec(http("127.0.0.1/Request").get(requestUrl).check(status.is(200)).check(bodyString.saveAs("MyData")
// Process the data
.exec(session => {
assert(processData(session.attributes("MyData")) == true, "Invalid data");
})
))
Above the scenario somewhere along the line "guardian failed, shutting down system".
Now this seems a useful, often-used thing to do - I'm possibly missing something simple. How to do it?
You have to abide by Gatling APIs.
With checks, you don't "fail" the test, but the request. If you're looking for failing the whole test, you should have a look at the Assertions API and the Jenkins plugin.
You can only perform a Check at the request site, not later. One of the very good reasons is that if you store the bodyString in the Sessions like you're doing, you'll end using a lot of memory and maybe crashing (still referenced, so not garbage collectable). You have to perform your processData in the check, typically in the transform optional step.
were you looking for something like
.exec(http("getRequest")
.get("/request/123")
.headers(headers)
.check(status.is(200))
.check(jsonPath("$.request_id").is("123")))
Since the edit queue is already full.
This is already resolved in the new version of Gatling. Release 3.4.0
They added
exitHereIf
exitHereIf("${myBoolean}")
exitHereIf(session => true)
Make the user exit the scenario from this point if the condition holds. Condition parameter is an Expression[Boolean].
I implemented something using exitHereIfFailed that sounds like exactly what you were trying to accomplish. I normally use this after a virtual user attempts to sign in.
exitHereIfFailed is used this way
val scn = scenario("MyAwesomeScenario")
.exec(http("Get data from endpoint 1")
.get(request1Url)
.check(status.is(200))
.check(bodyString.saveAs("MyData"))
.check(processData(session.attributes("MyData")).is(true)))
.exitHereIfFailed // If we weren't able to get the data, don't continue
.exec(http("Send the data to endpoint 2")
.post(request2Url)
.body(StringBody("${MyData}"))
This scenario will abort gracefully at exitHereIfFailed if any of the checks prior to exitHereIfFailed have failed.

setTracing on Camel with SCALA DSL

How do I set up tracing (getContext.setTracing) for all routes when using scala DSL.
I can not see anything on console or logs by doing this:
class RouteSendEmailWS extends RouteBuilder {
getContext.setStreamCaching(true)
getContext.setTracing(true)
from("direct:x) ==> { to("mock:onX") }
}
Where should I see the output.
And you are sending data to that route? eg you send data to "direct:x"?.
If you do not send an data, then there is nothing to trace.
You can read about the tracer here
http://camel.apache.org/tracer
If you want something to happen, you can use a timer instead of "direct:x" as the timer will trigger every second by default.