Getting a token and how to build the .exec

I want to do a call to a token-service like this in Gatling:

`

---- REQUEST: ----

POST http://idpt.company.com/ids/connect/token HTTP/1.1

Authorization: Basic bW9iaWxlX2NsaWVudDptb2JpbGVfc2VjcmV0

host: idpt.company.com

content-type: application/x-www-form-urlencoded; charset=utf-8

content-length: 103

Connection: keep-alive

username=theusername&password=thepassword&scope=small&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password

`

This (POST) request should respons with a token.

My question is how to I “translate” the request above into an .exec in Gatling?

The Authorization: Basic i.e. how can I state that in the .exec?
It is static and can be the same for every request I make.

Cheers

I solved this like this:

`

.exec(
  http("getToken")
    .post("https://id.company.com/ids/connect/token")
    .headers(Map("Content-Type" -> "application/x-www-form-urlencoded; charset=utf-8" , "Authorization" -> "Basic bW9iaWxlX2xxxxxxmV0"))
    .body(StringBody("username=theusername&password=thepassword&scope=small&proxy=http%3X%2F%2Flocalhost%3A8888&grant_type=password"))
    .asFormUrlEncoded
)

`

Actually, you shouldn’t craft the Authorization header yourself (nor hardcode it).
This is plain old Basic auth: http://gatling.io/docs/2.1.2/http/http_protocol.html#authentication

Ok.
I know how my Authorization header is made.
It is just a base64encode of two values, lets say:
c29tZV9jbGllbnQ6c29tZV9zZWNyZXQ=

which decodes to:
some_client:some_secret

Is there a way to decode ‘some_client’ and ‘some_secret’ on the fly?

Should I do it in the header-mapping

I had to do something similar where I had to dynamically create an Authorization and Content-MD5 header for each request that is computed based on the payload of the request. I created a SignatureCalculator and that works perfectly.

–Steve

Would it be possible to share the "calculator"?

Here, we’re talking about plain old Basic authentication.
As it’s a very very very very standard mechanism, of course Gatling supports it out of the box.
I already sent a pointer to the documentation in a previous mail in this very same thread!

Ok,

So then I have:

`

package com.site

import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation
import io.gatling.http.Predef._

class idpSimulation extends Simulation{

  val httpConf = http
    .baseURL("https://id.site.com/ids")
    .acceptEncodingHeader("gzip,deflate")
    .headers(Map("Content-Type" -> "application/x-www-form-urlencoded; charset=utf-8"))
    .authorizationHeader("Basic bW9PaWxlX2NsaWZudDptbpJpxVfc2VjcmV0")
    .disableUrlEscaping

  val scn = scenario("Scenario")

    .feed(csv("data/testdata.csv").random)

    .exec(
      http("getToken")
        .post("/connect/token").basicAuth("${MemberId}", "password")
        //.body(StringBody("username=${MemberId}&password=password&scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password"))
        .asFormUrlEncoded
        .check(jsonPath("$.access_token").exists.saveAs("token")))

  setUp(scn.inject(atOnceUsers(1)).protocols(httpConf))
}

`

But what do I do with the remaing part of the string body (commented out above). How do I define the part:

`

*...*scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password

`

in my simulation? still as a string body without the username and password?

If I remove the username and password from the string body and put it into a basicauth and run the simulation my logging says:

`

If you look at the logs, it shows that you have two authorization headers in your http request. You only need to send one.

one way would be

Yes but what do I do with the remaining part of the:

`

.body(StringBody("username=${MemberId}&password=password&scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password")

`

as in:

`

scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password"

`

I cannot just say:

`

.body(StringBody("scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password"))

`

That is what causing the error reported earlier.

I am not sure what exactly that is. But you can try following options

  1. Leave that as is. Since this is not part of the header, it may not give 400 error
  2. It could be a formParam - try using .formParam http://gatling.io/docs/2.1.2/http/http_request.html#query-parameters
  3. If it is a proxy then declare proxy setting globally - http://gatling.io/docs/2.1.2/http/http_protocol.html#proxy-parameters

Debug it.

I am getting the same token for login response like [ Authorization : Bearer fsdjflkajsfjlasjfjdsafjajfkafkdsajkfalj–> token value]i could able to capture the token.

this token is same for all further requests, i am unable to pass this header value to all the further requests.
the requests are like api call related http requests.

Can you help me with how to add this header to further request.

i tried with

val sessionHeaders = Map(“Authorization” → “Bearer ${token}”,
“Content-Type” → “application/json”)

i passed the same header value like below.

.get("/smee/common/categoryList") -----> this http request will trigger api call.
.headers(sessionHeaders)

please any one help me on this. Thanks in advance.

Hi Meena,

Please follow the below sample template/code for header implementation.

object xxxxx {
val xxxxxx =exec(http(“Main_Request”)
.post("/")
.headers(headers_2)
.header(“Authorization”,“Bearer ${Beaererid}”)
.body(StringBody("""<<<>>>"""))
.check(status.in(200))
)
}

or

val headers_2 = Map(
“Accept” → “/”,
“Accept-Encoding” → “gzip, deflate, br”,
“Connection” → “keep-alive”,
“content-type” → “application/json”,
“region” → “IN”,
“x-status” → “Auth”,
“X-APIKEY” → “<your api key”
)

Hi Madan,

import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._

class ChangeRecordedSimulation extends Simulation {

val sessionHeaders = Map(“Authorization” → “Bearer ${authToken1}”,
“Content-Type” → “application/json”)

val httpProtocol = http
.baseUrl(“https://xxxx.xxxxx.com”)
.inferHtmlResources()
.acceptHeader(“application/json, text/plain, /”)
.userAgentHeader(“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36”)

val headers_0 = Map(
“Accept” → “text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3”,
“Upgrade-Insecure-Requests” → “1”)

val headers_17 = Map(
“Content-Type” → “application/json;charset=UTF-8”,
“Origin” → “https://xxx.xxx.com”,
“X-Requested-With” → “XMLHttpRequest”)

val headers_18 = Map(
“X-Requested-With” → “XMLHttpRequest”,
“authorization” → “Bearer ${authToken1}”,
“content-type” → “application/json”)

val headers_20 = Map(
“X-Requested-With” → “XMLHttpRequest”,
“authorization” → “Bearer ${authToken1}”)

val headers_21 = Map(
“Content-Type” → “application/json;charset=UTF-8”,
“Origin” → “https://xxxx.xxxx.com”,
“X-Requested-With” → “XMLHttpRequest”,
“authorization” → “Bearer ${authToken1}”)

val headers_37 = Map(
“Origin” → “https://xxxx.xxxx.com”,
“X-Requested-With” → “XMLHttpRequest”,
“authorization” → “Bearer ${authToken1}”,
“content-type” → “application/json”)

val uri2 = “https://fonts.googleapis.com:443/css
val uri3 = “https://cdnjs.cloudflare.com:443/ajax/libs

val scn = scenario(“ChangeRecordedSimulation”)
.exec(http(“request_0”)
.get("/xxx/ui/")
.headers(headers_0))
.pause(1)
.exec(http(“request_1”)
.get(uri3 + “/ionicons/2.0.1/css/ionicons.min.css”)
.headers(headers_0)
.resources(http(“request_2”)
.get(uri3 + “/font-awesome/4.5.0/css/font-awesome.min.css”)
.headers(headers_0),
http(“request_3”)
.get(uri2 + “?family=Roboto+Condensed”)
.headers(headers_0),
http(“request_4”)
.get("/xxx/ui/static/css/_all-skins.min.css")
.headers(headers_0),
http(“request_5”)
.get("/xxxx/ui/static/css/AdminLTE.min.css")
.headers(headers_0),
http(“request_6”)
.get("/xxxx/ui/static/css/bootstrap.min.css")
.headers(headers_0),
http(“request_7”)
.get("/xxxx/ui/static/css/pace.min.css")
.headers(headers_0),
http(“request_8”)
.get("/xxxx/ui/static/js/jquery.slimscroll.min.js")
.headers(headers_0),
http(“request_9”)
.get("/xxxx/ui/static/js/manifest.31b3b1b0528463613ec1.js")
.headers(headers_0),
http(“request_10”)
.get(uri2 + “?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic”)
.headers(headers_0),
http(“request_11”)
.get("/xxxx/ui/static/js/jquery-2.2.3.min.js")
.headers(headers_0),
http(“request_12”)
.get("/xxxx/ui/static/js/bootstrap.min.js")
.headers(headers_0),
http(“request_13”)
.get("/xxxx/ui/static/css/app.176431924930ce0b6fc1f73d1f4795c0.css")
.headers(headers_0),
http(“request_14”)
.get("/xxxx/ui/static/js/pace.min.js")
.headers(headers_0),
http(“request_15”)
.get("/xxxx/ui/static/js/app.99a07150331050539321.js")
.headers(headers_0),
http(“request_16”)
.get("/xxxx/ui/static/js/vendor.c94789110b7f7b9fc3be.js")
.headers(headers_0),
http(“LogIn”)
.post("/xxxx/usermanagement/userCurrent")

.check(jsonPath("$…token").exists.saveAs(“authToken1”))

.headers(headers_17)
.body(RawFileBody(“ChangeRecordedSimulation_0017_request.txt”)),
http(“request_18”)
.get("/xxxx/common/clientUserInactiveTimeout")

.headers(headers_18),
http(“request_19”)
.get("/xxxx/common/help-menu2?userFunctionId=10")
.headers(sessionHeaders),
//.headers(headers_18),
http(“request_20”)
.get("/xxxx/notification/dashboardStatistics?userFunctionGroupId=10&categoryCodeList=")
.headers(sessionHeaders),
//.headers(headers_20),
http(“request_21”)
.post("/xxxx/changemanagement/api/checkUserHierarchyMapping")
.headers(sessionHeaders)
//.headers(headers_21)
.body(RawFileBody(“ChangeRecordedSimulation_0021_request.txt”)),
http(“request_22”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-From-Datatable1&userSid=17")
.headers(sessionHeaders),
//.headers(headers_20),
http(“request_23”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-To-Datatable1&userSid=17")
.headers(headers_20),
http(“request_24”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-From-Datatable5&userSid=17")
.headers(headers_20),
http(“request_25”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-To-Datatable5&userSid=17")
.headers(headers_20),
http(“request_26”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable5&userSid=17")
.headers(headers_20),
http(“request_27”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable1&userSid=17")
.headers(headers_20),
http(“request_28”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step4-Datatable1&userSid=17")
.headers(headers_20),
http(“request_29”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable4&userSid=17")
.headers(headers_20),
http(“request_30”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-From-Datatable2&userSid=17")
.headers(headers_20),
http(“request_31”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-To-Datatable2&userSid=17")
.headers(headers_20),
http(“request_32”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable2&userSid=17")
.headers(headers_20),
http(“request_33”)
.get("/xxxx/common/dataTablePreferences?dataTableCode=Datatable-PCL-CreateByExcelNewChase&userSid=17")
.headers(headers_20),
http(“request_34”)
.get("/xxxx/common/searchPanelUserPreferences?userSid=17&searchPanelCode=chaseSearchPanel")
.headers(headers_18),
http(“request_35”)
.get("/xxxx/common/searchPanelUserPreferences?userSid=17&searchPanelCode=chaseTagSearchPanel")
.headers(headers_18),
http(“Search”)
.post("/xxxx/changemanagement/api/newChaseCreateSearch")
.headers(headers_21)
.body(RawFileBody(“ChangeRecordedSimulation_0036_request.txt”)),
http(“request_37”)
.put("/xxxx/common/searchPanelUserPreferences")
.headers(headers_37)
.body(RawFileBody(“ChangeRecordedSimulation_0037_request.txt”)),
http(“request_38”)
.post("/xxxx/changemanagement/api/newChaseCreateSearchStep3")
.headers(headers_21)
.body(RawFileBody(“ChangeRecordedSimulation_0038_request.txt”)),
http(“request_39”)
.post("/xxxx/changemanagement/api/newChaseRequestSave")
.headers(headers_21)
.body(RawFileBody(“ChangeRecordedSimulation_0039_request.txt”)))
//
)
.exec { session =>
println()
println(“authToken1”)
println()
println( session(“authToken1”).as[String] )
session
}

setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}

Note:
Under UserCurrent request using JasonPath i could able to capture the token, which is generating as a response for login page.
when i am replacing the token in headers : authorization : bearer {authtoken1}

getting an error like :

request_18: Failed to build request: No attribute named ‘authToken1’ is defined.

what i want:
i want to pass the token to all the further request by replacing in all the authorization header value at the top, but it is not working for me.

i even tried : https://gist.github.com/alanphil/52d03338ba85c9ee0bd894b73ee3f999 ----> still failed.

please help me on this, i am really blocked.

Thanks in advance.