Action to spawn multiple further actions in Gatling scenario

ndtreviv

Background

I'm currently working on a capability analysis set of stress-testing tools for which I'm using gatling.

Part of this involves loading up an elasticsearch with scroll queries followed by update API calls.

What I want to achieve

Step 1: Run the scroll initiator and save the _scroll_id where it can be used by further scroll queries

Step 2: Run a scroll query on repeat, as part of each scroll query make a modification to each hit returned and index it back into elasticsearch, effectively spawning up to 1000 Actions from the one scroll query action, and having the results sampled.

Step 1 is easy. Step 2 not so much.

What I've tried

I'm currently trying to achieve this via a ResponseTransformer that parses JSON-formatted results, makes modifications to each one and fires off a thread for each one that attempts another exec(http(...).post(...) etc) to index the changes back into elasticsearch.

Basically, I think I'm going about it the wrong way about it. The indexing threads never get run, let alone sampled by gatling.

Here's the main body of my scroll query action:

  ...

  val pool = Executors.newFixedThreadPool(parallelism)

  val query = exec(http("Scroll Query")
    .get(s"/_search/scroll")
    .body(ElFileBody("queries/scrollquery.json")).asJSON // Do the scroll query
    .check(jsonPath("$._scroll_id").saveAs("scroll_id")) // Get the scroll ID from the response
    .transformResponse { case response if response.isReceived =>
      new ResponseWrapper(response) {
        val responseJson = JSON.parseFull(response.body.string)
        // Get the hits and
        val hits = responseJson.get.asInstanceOf[Map[String, Any]]("hits").asInstanceOf[Map[String,Any]]("hits").asInstanceOf[List[Map[String, Any]]]
        for (hit <- hits) {
          val id = hit.get("_id").get.asInstanceOf[String]
          val immutableSource = hit.get("_source").get.asInstanceOf[Map[String, Any]]
          val source = collection.mutable.Map(immutableSource.toSeq: _*) // Make the map mutable
          source("newfield") = "testvalue" // Make a modification
          Thread.sleep(pause) // Pause to simulate topology throughput
          pool.execute(new DocumentIndexer(index, doctype, id, source)) // Create a new thread that executes the index request
        }
      }
    }) // Make some mods and re-index into elasticsearch

  ...

DocumentIndexer looks like this:

class DocumentIndexer(index: String, doctype: String, id: String, source: scala.collection.mutable.Map[String, Any]) extends Runnable {

  ...

  val httpConf = http
    .baseURL(s"http://$host:$port/${index}/${doctype}/${id}")
    .acceptHeader("application/json")
    .doNotTrackHeader("1")
    .disableWarmUp

  override def run() {

    val json = new ObjectMapper().writeValueAsString(source)

    exec(http(s"Index ${id}")
      .post("/_update")
      .body(StringBody(json)).asJSON)

  }

}

Questions

  1. Is this even possible using gatling?
  2. How can I achieve what I want to achieve?

Thanks for any help/suggestions!

ndtreviv

It's possible to achieve this by using jsonPath to extract the JSON hit array and saving the elements into the session and then, using a foreach in the action chain and exec-ing the index task in the loop you can perform the indexing accordingly.

ie:
ScrollQuery

...
  val query = exec(http("Scroll Query")
    .get(s"/_search/scroll")
    .body(ElFileBody("queries/scrollquery.json")).asJSON // Do the scroll query
    .check(jsonPath("$._scroll_id").saveAs("scroll_id")) // Get the scroll ID from the response
    .check(jsonPath("$.hits.hits[*]").ofType[Map[String,Any]].findAll.saveAs("hitsJson")) // Save a List of hit Maps into the session
  )
...

Simulation

...
    val scrollQueries = scenario("Enrichment Topologies").exec(ScrollQueryInitiator.query, repeat(numberOfPagesToScrollThrough, "scrollQueryCounter"){
        exec(ScrollQuery.query, pause(10 seconds).foreach("${hitsJson}", "hit"){ exec(HitProcessor.query) })
    })
...

HitProcessor

...
  def getBody(session: Session): String = {
    val hit = session("hit").as[Map[String,Any]]
    val id = hit("_id").asInstanceOf[String]
    val source = mapAsScalaMap(hit("_source").asInstanceOf[java.util.LinkedHashMap[String,Any]])
    source.put("newfield", "testvalue")
    val sourceJson = new ObjectMapper().writeValueAsString(mapAsJavaMap(source))
    val json = s"""{"doc":${sourceJson}}"""
    json
  }

  def getId(session: Session): String = {
    val hit = session("hit").as[Map[String,Any]]
    val id = URLEncoder.encode(hit("_id").asInstanceOf[String], "UTF-8")
    val uri = s"/${index}/${doctype}/${id}/_update"
    uri
  }

  val query = exec(http(s"Index Item")
    .post(session => getId(session))
    .body(StringBody(session => getBody(session))).asJSON)
...

Disclaimer: This code still needs optimising! And I haven't actually learnt much scala yet. Feel free to comment with better solutions

Having done this, what I really want to achieve now is to parallelise a given number of the indexing tasks. ie: I get 1000 hits back, I want to execute an index task for each individual hit, but rather than just iterating over them and doing them one after another, I want to do 10 at a time concurrently.

However, I think this is a separate question, really, so I'll present it as such.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Multiple actions with same action name

From Dev

Gatling scala script randomize scenario

From Dev

Gatling switch protocols during scenario

From Dev

Gatling: Concurrent execution within a scenario

From Dev

Gatling scala script randomize scenario

From Dev

Controller with multiple actions - wrong action called

From Dev

Dispatching further actions when handling actions

From Dev

xpages save / cancel actions scenario

From Dev

How to use saved variable values outside of gatling scenario in scala file

From Dev

Gatling: polling a webservice, and failing the scenario on incorrect response-messages

From Dev

How to use variable extracted in JSON path extractor for further steps of scenario?

From Dev

How to use variable extracted in JSON path extractor for further steps of scenario?

From Dev

Multiple Spawn/expect issue

From Dev

Spawn multiple children processes

From Dev

Actions Not Showing For UILocalNotification Action

From Dev

Gatling - Check multiple values with JsonPath

From Dev

In GameMaker, how to bounce object further with the Bounce action?

From Dev

Is there any need to take further action over ShellShock

From Dev

Play2 Java Action Composition - how do I string together multiple actions?

From Dev

How do I handle multiple actions in single form in WILDCARD action mapping?

From Dev

How do I make a action over ride multiple other actions if they are being called?

From Dev

Multiple actions were found that match the request error when adding a second GET action method to web api controller

From Dev

Why am I getting "Multiple actions were found ..." when I have exactly one Post action?

From Dev

Why multiple scenario are not working in Yii?

From Dev

Why multiple scenario are not working in Yii?

From Dev

Multiple expects within scenario test

From Dev

Spawn multiple std::thread and reuse it

From Dev

Use-case polling HttpService and performing further actions

From Dev

Actions not showing in android action bar

Related Related

  1. 1

    Multiple actions with same action name

  2. 2

    Gatling scala script randomize scenario

  3. 3

    Gatling switch protocols during scenario

  4. 4

    Gatling: Concurrent execution within a scenario

  5. 5

    Gatling scala script randomize scenario

  6. 6

    Controller with multiple actions - wrong action called

  7. 7

    Dispatching further actions when handling actions

  8. 8

    xpages save / cancel actions scenario

  9. 9

    How to use saved variable values outside of gatling scenario in scala file

  10. 10

    Gatling: polling a webservice, and failing the scenario on incorrect response-messages

  11. 11

    How to use variable extracted in JSON path extractor for further steps of scenario?

  12. 12

    How to use variable extracted in JSON path extractor for further steps of scenario?

  13. 13

    Multiple Spawn/expect issue

  14. 14

    Spawn multiple children processes

  15. 15

    Actions Not Showing For UILocalNotification Action

  16. 16

    Gatling - Check multiple values with JsonPath

  17. 17

    In GameMaker, how to bounce object further with the Bounce action?

  18. 18

    Is there any need to take further action over ShellShock

  19. 19

    Play2 Java Action Composition - how do I string together multiple actions?

  20. 20

    How do I handle multiple actions in single form in WILDCARD action mapping?

  21. 21

    How do I make a action over ride multiple other actions if they are being called?

  22. 22

    Multiple actions were found that match the request error when adding a second GET action method to web api controller

  23. 23

    Why am I getting "Multiple actions were found ..." when I have exactly one Post action?

  24. 24

    Why multiple scenario are not working in Yii?

  25. 25

    Why multiple scenario are not working in Yii?

  26. 26

    Multiple expects within scenario test

  27. 27

    Spawn multiple std::thread and reuse it

  28. 28

    Use-case polling HttpService and performing further actions

  29. 29

    Actions not showing in android action bar

HotTag

Archive