Is it possible to load AWS SQS queues using Gatling?

I tried to google but did't find any info regarding connecting Gatling and SQS. I would appreciate any advice or example of how it could be done.

Thanks in advance:)

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-java-message-service-jms-client.html
https://gatling.io/docs/current/jms/

Thank you, Stephane! I didnt think about it myself :slight_smile: I was thinking about using SQS directly but you are right - it should work with JMS

I need help… I am getting exception while trying to send messages using amazon jms client

Do you have any idea what I did wrong, please?

16:38:56.857 [main] INFO io.gatling.core.config.GatlingConfiguration$ - Gatling will try to use ‘gatling.conf’ as custom config file.
16:38:57.290 [GatlingSystem-akka.actor.default-dispatcher-2] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
16:38:57.611 [GatlingSystem-akka.actor.default-dispatcher-4] INFO io.gatling.core.stats.writer.ConsoleDataWriter - Initializing
16:38:57.611 [GatlingSystem-akka.actor.default-dispatcher-3] INFO io.gatling.core.stats.writer.LogFileDataWriter - Initializing
16:38:57.616 [GatlingSystem-akka.actor.default-dispatcher-4] INFO io.gatling.core.stats.writer.ConsoleDataWriter - Initialized
16:38:57.624 [GatlingSystem-akka.actor.default-dispatcher-3] INFO io.gatling.core.stats.writer.LogFileDataWriter - Initialized
16:38:57.763 [main] ERROR io.gatling.app.Gatling$ - Run crashed
javax.jms.JMSException: Unsupported Method
at com.amazon.sqs.javamessaging.SQSSession.createTemporaryQueue(SQSSession.java:776)
at io.gatling.jms.client.JmsConnection.destination(JmsConnection.scala:49)
at io.gatling.jms.action.RequestReply.(RequestReply.scala:54)
at io.gatling.jms.action.RequestReplyBuilder.build(RequestReplyBuilder.scala:37)
at io.gatling.core.structure.StructureBuilder.$anonfun$build$1(StructureBuilder.scala:35)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:89)
at io.gatling.core.structure.StructureBuilder.build(StructureBuilder.scala:34)
at io.gatling.core.structure.StructureBuilder.build$(StructureBuilder.scala:33)
at io.gatling.core.structure.ChainBuilder.build(ChainBuilder.scala:31)
at io.gatling.core.action.builder.LoopBuilder.build(LoopBuilder.scala:61)
at io.gatling.core.structure.StructureBuilder.$anonfun$build$1(StructureBuilder.scala:35)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:89)
at io.gatling.core.structure.StructureBuilder.build(StructureBuilder.scala:34)
at io.gatling.core.structure.StructureBuilder.build$(StructureBuilder.scala:33)
at io.gatling.core.structure.ScenarioBuilder.build(ScenarioBuilder.scala:38)
at io.gatling.core.structure.PopulationBuilder.build(ScenarioBuilder.scala:100)
at io.gatling.core.scenario.SimulationParams.$anonfun$scenarios$1(Simulation.scala:194)
at scala.collection.immutable.List.map(List.scala:286)
at io.gatling.core.scenario.SimulationParams.scenarios(Simulation.scala:194)
at io.gatling.app.Runner.run0(Runner.scala:92)
at io.gatling.app.Runner.run(Runner.scala:61)
at io.gatling.app.Gatling$.start(Gatling.scala:74)
at io.gatling.app.Gatling$.fromMap(Gatling.scala:42)
at common.GatlingRunner$.run(GatlingRunner.scala:16)
at simulation.TapsSimulation$.main(TapsSimulation.scala:51)
at simulation.TapsSimulation.main(TapsSimulation.scala)
Jan 26, 2019 4:38:57 PM com.amazon.sqs.javamessaging.SQSSession doClose
INFO: Shutting down SessionCallBackScheduler executor
Exception in thread “main” javax.jms.JMSException: Unsupported Method
at com.amazon.sqs.javamessaging.SQSSession.createTemporaryQueue(SQSSession.java:776)
at io.gatling.jms.client.JmsConnection.destination(JmsConnection.scala:49)
at io.gatling.jms.action.RequestReply.(RequestReply.scala:54)
at io.gatling.jms.action.RequestReplyBuilder.build(RequestReplyBuilder.scala:37)
at io.gatling.core.structure.StructureBuilder.$anonfun$build$1(StructureBuilder.scala:35)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:89)
at io.gatling.core.structure.StructureBuilder.build(StructureBuilder.scala:34)
at io.gatling.core.structure.StructureBuilder.build$(StructureBuilder.scala:33)
at io.gatling.core.structure.ChainBuilder.build(ChainBuilder.scala:31)
at io.gatling.core.action.builder.LoopBuilder.build(LoopBuilder.scala:61)
at io.gatling.core.structure.StructureBuilder.$anonfun$build$1(StructureBuilder.scala:35)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:89)
at io.gatling.core.structure.StructureBuilder.build(StructureBuilder.scala:34)
at io.gatling.core.structure.StructureBuilder.build$(StructureBuilder.scala:33)
at io.gatling.core.structure.ScenarioBuilder.build(ScenarioBuilder.scala:38)
at io.gatling.core.structure.PopulationBuilder.build(ScenarioBuilder.scala:100)
at io.gatling.core.scenario.SimulationParams.$anonfun$scenarios$1(Simulation.scala:194)
at scala.collection.immutable.List.map(List.scala:286)
at io.gatling.core.scenario.SimulationParams.scenarios(Simulation.scala:194)
at io.gatling.app.Runner.run0(Runner.scala:92)
at io.gatling.app.Runner.run(Runner.scala:61)
at io.gatling.app.Gatling$.start(Gatling.scala:74)
at io.gatling.app.Gatling$.fromMap(Gatling.scala:42)
at common.GatlingRunner$.run(GatlingRunner.scala:16)
at simulation.TapsSimulation$.main(TapsSimulation.scala:51)
at simulation.TapsSimulation.main(TapsSimulation.scala)

Process finished with exit code 1

My simulation is here):

package simulation

import io.gatling.core.Predef._
import io.gatling.jms.Predef._
import javax.jms._

import scala.concurrent.duration._
import com.amazon.sqs.javamessaging.{SQSConnectionFactory}
import com.amazonaws.auth.{AWSStaticCredentialsProvider, BasicAWSCredentials}
import com.amazonaws.regions.{Region, Regions}
import common.GatlingRunner

object TapsSimulation {

class TapsToWhisperSimulation extends Simulation {
setUp(scn.inject(constantUsersPerSec(1) during (1 minutes)))
.protocols(jmsConfig)
}

val SIM_QUEUE = “https://sqs.ap-southeast-2.amazonaws.com/XXXXX/XXXXX
val DEFAULT_REGION: Region = Region.getRegion(Regions.AP_SOUTHEAST_2)
val credentialsProvider = new AWSStaticCredentialsProvider(new BasicAWSCredentials(“XXXXX”, “XXXXX”))
val connectionFactory = SQSConnectionFactory.builder()
.withRegion(DEFAULT_REGION)
.withAWSCredentialsProvider(credentialsProvider)
.build();

val jmsConfig = jms.connectionFactory(connectionFactory)

val scn = scenario(“JMS DSL test”).repeat(1) {
exec(jms(“req reply testing”).requestReply
.queue(SIM_QUEUE)
.textMessage(ElFileBody(“SendTap.json”))
.property(“test_header”, “test_value”)
.jmsType(“test_jms_type”)
.check(simpleCheck(checkBodyTextCorrect)))
}

def checkBodyTextCorrect(m: Message) = {
// this assumes that the service just does an “uppercase” transform on the text
m match {
case tm: TextMessage => tm.getText == “HELLO FROM GATLING JMS DSL”
case _ => false
}
}

def main(args: Array[String]): Unit = GatlingRunner.run(classOf[TapsToWhisperSimulation])
}

You didn’t specify a reply queue, so Gatling tries to create a temporary one, but SQS doesn’t support temporary queues.
You have to specify the replyQueue.

I don’t need replyQueue at this stage, so simplified the call:

val SIM_QUEUE = “https://sqs.ap-southeast-2.amazonaws.com/X/Y

val DEFAULT_REGION: Region = Region.getRegion(Regions.AP_SOUTHEAST_2)
val credentialsProvider = new AWSStaticCredentialsProvider(new BasicAWSCredentials(“X”, “Y”))

val connectionFactory = SQSConnectionFactory.builder()
.withAWSCredentialsProvider(new DefaultAWSCredentialsProviderChain())
.withAWSCredentialsProvider(credentialsProvider)
.withRegion(DEFAULT_REGION)
.withClientConfiguration(new ClientConfiguration())
.build()

val jmsConfig = jms.connectionFactory(connectionFactory)

val scn = scenario(“SQS Taps test”).repeat(1) {
exec(jms(“SendMessage”).send
.queue(SIM_QUEUE)
.objectMessage(body))
}

But getting another issue now - “The specified queue does not exist for this wsdl version” :frowning:

10:42:05.391 [GatlingSystem-akka.actor.default-dispatcher-5] INFO io.gatling.core.stats.writer.LogFileDataWriter - Initialized
Simulation simulation.TapsSimulation$TapsToWhisperSimulation started…
Jan 27, 2019 10:42:06 AM com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper logAndGetAmazonServiceException
SEVERE: AmazonServiceException: getQueueUrl. RequestId: 681c0294-cc52-517c-984f-5653d0ecf867
HTTPStatusCode: 400 AmazonErrorCode: AWS.SimpleQueueService.NonExistentQueue
com.amazonaws.services.sqs.model.QueueDoesNotExistException: The specified queue does not exist for this wsdl version. (Service: AmazonSQS; Status Code: 400; Error Code: AWS.SimpleQueueService.NonExistentQueue; Request ID: 681c0294-cc52-517c-984f-5653d0ecf867)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)

I created a simple class for sending messages to SQS and it works but I failed to create my own custom protocol for it:

class SQSTestBase {
val sqsClient = SqsClient.builder().region(Region.AP_SOUTHEAST_2).credentialsProvider(SystemPropertyCredentialsProvider.create).build

val body = “test text”
val queueUrl = “https://sqs.ap-southeast-2.amazonaws.com/X/Y

def sendMessage(queueUrl: String, body: String): Unit = {
sqsClient.sendMessage(SendMessageRequest.builder.queueUrl(queueUrl).messageBody(body).build)
}

def main(args: Array[String]): Unit = {

sendMessage(queueUrl, body)
}
}

Do you have any idea what could be wrong and where to look next? Thank you in advance for your advice :slight_smile:

When using the JMS wrapper, you must pass a queue name, not a queue url: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-general-identifiers.html

Thank you, Stephane! You are my last hope :slight_smile: Now it looks like connectionFactory is correct though Gatling fails with NPE when sending JMS :frowning: Sorry for asking so many silly questions… hopefully it will work and will publish the full code example for other people

17:42:57.630 [GatlingSystem-akka.actor.default-dispatcher-4] INFO io.gatling.core.stats.writer.LogFileDataWriter - Initialized
Simulation simulation.TapsSimulation$TapsToWhisperSimulation started…
17:42:58.511 [GatlingSystem-akka.actor.default-dispatcher-2] DEBUG io.gatling.jms.action.Send - Message sent JMSMessageID=null
17:42:58.518 [GatlingSystem-akka.actor.default-dispatcher-2] ERROR io.gatling.jms.action.Send - ‘jmsSend-2’ crashed on session Session(SQS Taps test,1,1548582177858,Map(f2440d13-bc26-452f-8b0f-abf47d81b969 → 0),0,OK,List(ExitOnCompleteLoopBlock(f2440d13-bc26-452f-8b0f-abf47d81b969)),io.gatling.core.protocol.ProtocolComponentsRegistry$$Lambda$299/1890287843@393fe524), forwarding to the next one
java.lang.NullPointerException: null
at io.gatling.jms.action.Send.$anonfun$aroundSend$1(Send.scala:67)
at io.gatling.jms.action.Around.apply(JmsAction.scala:33)
at io.gatling.jms.action.JmsAction.$anonfun$sendRequest$6(JmsAction.scala:68)
at io.gatling.jms.action.JmsAction.$anonfun$sendRequest$6$adapted(JmsAction.scala:60)
at io.gatling.commons.validation.Success.map(Validation.scala:42)
at io.gatling.jms.action.JmsAction.$anonfun$sendRequest$5(JmsAction.scala:60)
at io.gatling.commons.validation.Success.flatMap(Validation.scala:43)
at io.gatling.jms.action.JmsAction.$anonfun$sendRequest$4(JmsAction.scala:59)
at io.gatling.commons.validation.Success.flatMap(Validation.scala:43)
at io.gatling.jms.action.JmsAction.$anonfun$sendRequest$2(JmsAction.scala:57)
at io.gatling.commons.validation.Success.flatMap(Validation.scala:43)
at io.gatling.jms.action.JmsAction.$anonfun$sendRequest$1(JmsAction.scala:56)
at io.gatling.commons.validation.Success.flatMap(Validation.scala:43)
at io.gatling.jms.action.JmsAction.sendRequest(JmsAction.scala:55)
at io.gatling.core.action.RequestAction.$anonfun$execute$1(Action.scala:98)
at io.gatling.commons.validation.Success.flatMap(Validation.scala:43)
at io.gatling.core.action.RequestAction.execute(Action.scala:95)
at io.gatling.core.action.RequestAction.execute$(Action.scala:94)
at io.gatling.jms.action.JmsAction.execute(JmsAction.scala:39)
at io.gatling.core.action.Action.$bang(Action.scala:38)
at io.gatling.core.action.Action.$bang$(Action.scala:38)
at io.gatling.jms.action.JmsAction.io$gatling$core$action$ChainableAction$$super$$bang(JmsAction.scala:39)
at io.gatling.core.action.ChainableAction.$bang(Action.scala:63)
at io.gatling.core.action.ChainableAction.$bang$(Action.scala:61)
at io.gatling.jms.action.JmsAction.io$gatling$core$action$ExitableAction$$super$$bang(JmsAction.scala:39)
at io.gatling.core.action.ExitableAction.$bang(BlockExit.scala:138)
at io.gatling.core.action.ExitableAction.$bang$(BlockExit.scala:136)
at io.gatling.jms.action.JmsAction.$bang(JmsAction.scala:39)
at io.gatling.core.action.InnerLoop.execute(Loop.scala:94)
at io.gatling.core.action.Action.$bang(Action.scala:38)
at io.gatling.core.action.Action.$bang$(Action.scala:38)
at io.gatling.core.action.InnerLoop.io$gatling$core$action$ChainableAction$$super$$bang(Loop.scala:58)
at io.gatling.core.action.ChainableAction.$bang(Action.scala:63)
at io.gatling.core.action.ChainableAction.$bang$(Action.scala:61)
at io.gatling.core.action.InnerLoop.$bang(Loop.scala:58)
at io.gatling.core.action.Loop.execute(Loop.scala:54)
at io.gatling.core.action.Action.$bang(Action.scala:38)
at io.gatling.core.action.Action.$bang$(Action.scala:38)
at io.gatling.core.action.Loop.$bang(Loop.scala:25)
at io.gatling.core.controller.inject.Workload.startUser(Workload.scala:55)
at io.gatling.core.controller.inject.Workload.injectUser(Workload.scala:64)
at io.gatling.core.controller.inject.open.OpenWorkload.$anonfun$injectBatch$1(OpenWorkload.scala:35)
at io.gatling.core.controller.inject.open.OpenWorkload.$anonfun$injectBatch$1$adapted(OpenWorkload.scala:35)
at io.gatling.core.controller.inject.open.UserStream.withStream(UserStream.scala:58)
at io.gatling.core.controller.inject.open.OpenWorkload.injectBatch(OpenWorkload.scala:35)
at io.gatling.core.controller.inject.Injector.$anonfun$inject$1(Injector.scala:60)
at io.gatling.core.controller.inject.Injector.$anonfun$inject$1$adapted(Injector.scala:59)
at scala.collection.Iterator.foreach(Iterator.scala:941)
at scala.collection.Iterator.foreach$(Iterator.scala:941)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
at scala.collection.MapLike$DefaultValuesIterable.foreach(MapLike.scala:213)
at io.gatling.core.controller.inject.Injector.io$gatling$core$controller$inject$Injector$$inject(Injector.scala:59)
at io.gatling.core.controller.inject.Injector$$anonfun$1.applyOrElse(Injector.scala:92)
at io.gatling.core.controller.inject.Injector$$anonfun$1.applyOrElse(Injector.scala:82)
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:38)
at akka.actor.FSM.processEvent(FSM.scala:684)
at akka.actor.FSM.processEvent$(FSM.scala:681)
at io.gatling.core.controller.inject.InjectorFSM.processEvent(InjectorFSM.scala:37)
at akka.actor.FSM.akka$actor$FSM$$processMsg(FSM.scala:678)
at akka.actor.FSM$$anonfun$receive$1.applyOrElse(FSM.scala:672)
at akka.actor.Actor.aroundReceive(Actor.scala:517)
at akka.actor.Actor.aroundReceive$(Actor.scala:515)
at io.gatling.core.akka.BaseActor.aroundReceive(BaseActor.scala:25)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:588)
at akka.actor.ActorCell.invoke(ActorCell.scala:557)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:258)
at akka.dispatch.Mailbox.run(Mailbox.scala:225)
at akka.dispatch.Mailbox.exec(Mailbox.scala:235)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Code is here:

val connectionFactory = SQSConnectionFactory.builder()
.withAWSCredentialsProvider(credentialsProvider)
.withEndpoint(“https://sqs.ap-southeast-2.amazonaws.com/694103411108”)
.withRegion(DEFAULT_REGION)
.withClientConfiguration(new ClientConfiguration())
.build()

val jmsConfig = jms.connectionFactory(connectionFactory)

val scn = scenario(“SQS Taps test”).repeat(1) {
exec(jms(“SendMessage”)
.send
.queue(SIM_QUEUE)
.objectMessage(body))
}

Are you sure you haven’t forked Gatling? Which version do you use?
I fail to so how this NPE is possible?!

I didn’t fork Gatlling… I use Maven and this is my POM file. I can share the project but really its just 2 classes for now (Runner and Simulation)

<?xml version="1.0" encoding="UTF-8"?>

4.0.0
com.xx.yyyy
load-testing
1.0-SNAPSHOT

UTF-8 1.8 1.8 3.0.3 3.4.4 3.0.1 io.gatling.highcharts gatling-charts-highcharts ${gatling.version} test com.amazonaws amazon-sqs-java-messaging-lib 1.0.2 jar software.amazon.awssdk sqs 2.3.2 net.alchim31.maven scala-maven-plugin ${scala-maven-plugin.version} io.gatling gatling-maven-plugin ${gatling-plugin.version}

Gatling Runner:

package common

import io.gatling.app.Gatling
import io.gatling.core.config.GatlingPropertiesBuilder

object GatlingRunner extends App {

def run[T](clazz: Class[T]) = {
val props = new GatlingPropertiesBuilder()
.resourcesDirectory("./src/test/resources")
.resultsDirectory(“target/gatling”)
.binariesDirectory("./target/test-classes")
.simulationClass(clazz.getName)
.runDescription(clazz.getName)

Gatling.fromMap(props.build)
}
}

Simulation:

package simulation

import io.gatling.core.Predef._
import io.gatling.jms.Predef._

import scala.concurrent.duration._
import com.amazon.sqs.javamessaging.SQSConnectionFactory
import com.amazonaws.ClientConfiguration
import com.amazonaws.auth.{AWSStaticCredentialsProvider, BasicAWSCredentials, DefaultAWSCredentialsProviderChain}
import com.amazonaws.regions.{Region, Regions}
import common.GatlingRunner

object TapsSimulation {

class TapsToWhisperSimulation extends Simulation {
setUp(scn.inject(constantUsersPerSec(1) during (1 minutes)))
.protocols(jmsConfig)
}
val body = “{\n\t"sequence” : [\n\t\t{\n\t\t\t"inherits": [“tap.0” ],\n\t\t\t"gps_x": 48798735\n\t\t}\n\t],\n\t"tap" : {\n\t\t"0" : {\n\t\t\t"agency_id" : 0,\n\t\t\t"card_type" : 1,\n\t\t\t"cd_version" : 0,\n\t\t\t"currency_indicator" : “gbp”,\n\t\t\t"decode" : {\n\t\t\t\t"SysComHdr.formatVersion" : 2622208,\n\t\t\t\t"SysComHdr.reconciliationDate" : 0,\n\t\t\t\t"SysComHdr.samId" : 55,\n\t\t\t\t"timestamp" : “2019-01-22T10:49:44”,\n\t\t\t\t"ud_decoder" : “techgp-00154”,\n\t\t\t\t"udsn" : 384\n\t\t\t},\n\t\t\t"device_id" : 197988,\n\t\t\t"device_location_id" : 1004,\n\t\t\t"direction" : 0,\n\t\t\t"discount" : 0,\n\t\t\t"emv" : {\n\t\t\t\t"4F" : “A0000000031010”,\n\t\t\t\t"57" : “4761733265988759D30122010098800000001F”,\n\t\t\t\t"5A" : “4761733265988759”,\n\t\t\t\t"5F24" : “301231”,\n\t\t\t\t"5F34" : “01”,\n\t\t\t\t"82" : “2000”,\n\t\t\t\t"84" : “A0000000031010”,\n\t\t\t\t"95" : “0000000000”,\n\t\t\t\t"9C" : “00”,\n\t\t\t\t"9F02" : “000000000000”,\n\t\t\t\t"9F03" : “000000000000”,\n\t\t\t\t"9F06" : “A0000000031010”,\n\t\t\t\t"9F09" : “0002”,\n\t\t\t\t"9F10" : “06011103A00000”,\n\t\t\t\t"9F1A" : “0826”,\n\t\t\t\t"9F26" : “F27370F3A9086E90”,\n\t\t\t\t"9F27" : “80”,\n\t\t\t\t"9F34" : “000000”,\n\t\t\t\t"9F35" : “25”,\n\t\t\t\t"9F36" : “0003”,\n\t\t\t\t"9F37" : “AAB4D15A”,\n\t\t\t\t"9F6E" : “20700000”\n\t\t\t},\n\t\t\t"fare_model" : “1”,\n\t\t\t"finalisation_disposition" : “as_per_outcome”,\n\t\t\t"gps_x" : 56546667,\n\t\t\t"gps_y" : 65546667,\n\t\t\t"location_id" : 1104,\n\t\t\t"location_id_name" : “tes”,\n\t\t\t"route_id" : 110,\n\t\t\t"sales_tax" : 0,\n\t\t\t"service_participant_id" : 0,\n\t\t\t"service_type" : 1,\n\t\t\t"source_participant_id" : 0,\n\t\t\t"tax_rate_perc" : 0,\n\t\t\t"test_mode" : false,\n\t\t\t"transact_outcome" : “approved”,\n\t\t\t"transact_result" : 8005,\n\t\t\t"transaction_value" : 0,\n\t\t\t"transit_cd_version" : 0,\n\t\t\t"transit_device_id" : 1,\n\t\t\t"type" : “offline_approved”\n\t\t}\n\t}\n}"

val SIM_QUEUE = “my_queue_name”

val DEFAULT_REGION: Region = Region.getRegion(Regions.AP_SOUTHEAST_2)
val credentialsProvider = new AWSStaticCredentialsProvider(new BasicAWSCredentials(“myKey”, “myToken”))

val connectionFactory = SQSConnectionFactory.builder()
.withAWSCredentialsProvider(credentialsProvider)
.withEndpoint(“https://sqs.ap-southeast-2.amazonaws.com/697703411668”)
.withRegion(DEFAULT_REGION)
.withClientConfiguration(new ClientConfiguration())
.build()

val jmsConfig = jms.connectionFactory(connectionFactory)

val scn = scenario(“SQS Taps test”).repeat(1) {
exec(jms(“SendMessage”)
.send
.queue(SIM_QUEUE)
.objectMessage(body))
}

def main(args: Array[String]): Unit = GatlingRunner.run(classOf[TapsToWhisperSimulation])
}

Your runner looks very suspicious to me: cyclic references between TapsSimulation and your GatlingRunner that might cause initialisation order issues.
What happens if you launch from a official and supported launcher, such as mvn gatling:test?

OMG! It works!

Stephane, I am so grateful for your help! Thank you very much for helping me with this

So to summarize, I launched solution described above directly by Maven command line (not from Intellij Idea) using command mvn gatling:test and it works just perfectly

That’s great news!
I think I’ll write a blog post about it.

This is a great idea. Many projects use Amazon SQS, so this info might be very useful for them.

BTW, do you have any idea whats wrong with my Gatling Runner? It works perfectly with http but fails in case if jms protocol :frowning: i would love to use something like this runner because it is so convenient to launch simulations directly from Intellij Idea (when I design new load profiles and debug then) instead of switching to cmd each time

I found how to fix it. Now I have class “AllRequestsSimuation” (where I define load profiles) which calls “RequestTypeSimulation” classes (describing each type of request), both have main fun def main(args: Array[String]): Unit = GatlingRunner.run(classOf[AllWhisperApiRequests]) and everything works fine.

Hi Stephane,

I managed to setup the gatling test to send SQS messages for Standard queues as you suggested

val scn = scenario("SQS test")
  .exec(jms("SendMessage")
    .send
    .queue(SQS_QUEUE)
    .textMessage("SomeText"))

This works fine for Standard SQS queues, the problem is that we use FIFO queues and in that case I get this error:

SEVERE: AmazonServiceException: sendMessage. RequestId: 088a0c4e-5c79-566a-aace-589273b6d9ae

HTTPStatusCode: 400 AmazonErrorCode: MissingParameter

com.amazonaws.services.sqs.model.AmazonSQSException: The request must contain the parameter MessageGroupId. (Service: AmazonSQS; Status Code: 400; Error Code: MissingParameter; Request ID: 088a0c4e-5c79-566a-aace-589273b6d9ae)

at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1701)

Basically when for FIFO queues we need to pass the MessageGroupId.

Is there a work around to use JMS / SQS / Gatling for FIFO queues?

Regards.

For SQS FIFO queues we have to pass additional properties :

JMSXGroupID

Hi Ricardo,

What is the maximum load you manages to get from one Gatling instance? I am getting 3-4 requests per seconds max when using .requestReply and 7 rps when using .send... I dont understand why :frowning: If I load from simple java class using native Amazon SQS Client then I get thousands per sec... Maybe JMS doesn't work well with SQS?

Hi Maria,

In my case we are dealing with a FIFO SQS queue that allows max 3K messages / second with batching (10 messages per batch)

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html

This batching is not supported by JMS lib so I finally had to write a custom gatling protocol to use the native Amazon SQS client.
(based on this post https://callistaenterprise.se/blogg/teknik/2016/11/26/gatling-custom-protocol/ )

This way I was able to send about 500K messages in a few minutes. (We are using gatling frontline though with 8 nodes/ec2 intances)

Tha’s what my story so far with gatling and sqs.

Do you mind to share your SQS solution with the community? :slight_smile: I am not so good in Scala to make my own new protocol :frowning: But JMS definitely doesn’t work well for SQS in Gatling… I tried my way and also the one which Stephane suggested in his blog and got the same results - max 3-4 requests per second