Search code examples
scalagrpcgatling

Passing a response value from GRPC response to a REST API in Scala Gatling


hope you are doing good today

Cut to the chase that I keep on asking fun-to-dumb questions, this time before I raise something, I look into it very closely before ask to avoid tiredness. Ngl this is a fun-with-pain experience for me

My new update code block

val speaker = scenario("BasicSimu")
  .exec(
    fromClientSide
      .start(thePayload)
      .header(Authorization)(s"Bearer $TokenKey")
      .extract(.pk.some)(_ saveAs "theString")
      .sessionCombiner(SessionCombiner.pick("theString"))
      .endCheck(statusCode is Status.Code.OK)
  )
  .exec{
      session => 
        val responseString = session.attributes.get("theString").toString().slice(21,28)
        val newKeyVar = session.set("myKey",responseString)
      newKeyVar
  }
  .exec(
        http("Complete_Pairing") //the little body I made here
          .post(s"url")
          .header("Content-Type","application/json")
          .body(StringBody(s"""{
                      "pk": {"pairingKey": "#{newKeyVar}"}
                      }"""))
          .check(status.is(200))
  )
  .exec(fromClientSide.reconciliate(waitFor = StreamEnd))

As this code block introduce, I need the pairingKey to get it out, so I cast it to a String, then slice it, holy moly the key returned.

Continue to investigate, I have myself answered some questions, beside that there are some that I can't self-answer, so I bring up here.

1/ Needlessly to say the pairingKey (aka responseString keeping it, inside a session) has its purpose, and it is used to pass into body for a POST REST calling, is it possible to get the responseString out? With the code block above aspect, responseString not found (understandable, it's inside a session bruh), In example code you can cast it directly by using session.attributes.get to get the value, but when plug to REST, I think session.attributes.get cannot be casted directly.

Brief: I see the session.set, I will see more on this

2/ Following the first question, I have in mind two ways to approach, one is to save data down to csv and other one, calls the value directly. Should I just go call it directly to avoid slow processing ?

3/ Yesterday I did ask a way to keep the stream alive to view result, but now that I need the stream to run until it get a response 0 OK, it will pop up immediately when the REST API is made, tried with reconciliate(waitFor = NextMessage) but it seems the stream cancelled immediately, not sure if I cast it right.

4/ Out of topic, just a concern, that can I push my demo (if somehow I manage to achieve this with your support), to your Github ?


Solution

  • So days of investigating, I have completed a full code for a ServerStream combining with REST, this is a simple made, since there are many ways to interact with data, I'm just too noobie to improve it, for now.

    val speaker = scenario("BasicSimulation")
      .exec(
        fromClientSide //read my prev questions to know my configuration
          .start(thePayload)
          .header(Authorization)(s"Bearer $TokenKey") 
          .extract(."yourParam".some)(_ saveAs "theString")
          .sessionCombiner(SessionCombiner.pick("theString"))
          .endCheck(statusCode is Status.Code.OK)
      ) 
      .exec(fromClientSide.reconciliate(waitFor = NextMessage)) //tell the stream to wait
      .exec{
        session => 
            //Extract will return a Some type data, cast it to String type, then slice it to get the key
            val responseString = session.attributes.get("theString").toString().slice(your, position)
    
            // Print out to verify see the value of the key, comment it later if no use
            println(s"the pairingKey is: ${responseString}")
    
            // Init a new session to get the value
            val newKeyVar = session.set("myKey", responseString)
        newKeyVar
      }
    
      .exec(  
          http("Complete_Pairing")
            .post("your url")
            
            //sample header
            .header("Authorization", s"$tokenREST")
            .header("Content-Type","application/json")
            
            //sample Body
            .body(StringBody("""{"pk": {"pairingKey": "#{myKey}"}"}"""))
            .check(status.is(200))
            .check(bodyString.saveAs("responseBody"))
            .check(jsonPath("$.session.id").saveAs("sessionID"))
            .check(jsonPath("$.at.token").saveAs("unpairToken"))
      )
      //uncomment this block to check your response
      // .exec{
      //     session => 
      //       val responseBody = session("responseBody").as[String]
      //       println(s"Response Body: $responseBody")
      //     session
      // }
    

    Some of my comment could be false understanding, mostly you have to build on your ownm so some variable/object can be abstract, so if something needs to be fixed, please let me know so that I can fix immediately