Gatling: There were no requests sent during the simulation, reports won't be generated - jms

After successfully executing the JMS Gatling script I am facing the error:
Gatling: There were no requests sent during the simulation, reports won't be generated
I tried HTTP requests, and it's generating the reports properly.
However, for JMS reports are not generating.
Messages are properly producing and same are consumed.
Actual script taken from Gatling sample:
package com.msg.demo
import io.gatling.core.Predef._
import io.gatling.jms.Predef._
import javax.jms._
import scala.concurrent.duration._
import io.gatling.core.feeder.SourceFeederBuilder
import io.gatling.core.structure.ChainBuilder
import java.util.UUID
class TestJmsDsl extends Simulation {
// create a ConnectionFactory for ActiveMQ
// search the documentation of your JMS broker
val connectionFactory =
new org.apache.activemq.ActiveMQConnectionFactory("tcp://localhost:61616")
val jndiBasedConnectionFactory = jmsJndiConnectionFactory
.connectionFactoryName("ConnectionFactory")
.url("tcp://localhost:61616")
.credentials("user", "secret")
.contextFactory("org.apache.activemq.jndi.ActiveMQInitialContextFactory")
val jmsConfig = jms
.connectionFactory(connectionFactory)
.usePersistentDeliveryMode
val scn = scenario("JMS DSL test").repeat(0){
exec(jms("req reply testing").requestReply
.queue("jmstestq")
.replyQueue("jmstestq")
.textMessage("HELLO FROM GATLING JMS DSL")
.property("test_header", "test_value")
.jmsType("test_jms_type")
.check(simpleCheck(checkBodyTextCorrect)))
}
setUp(scn.inject(constantUsersPerSec(1) during (5 seconds)))
.protocols(jmsConfig)
.assertions(global.successfulRequests.percent.gte(10))
def checkBodyTextCorrect(m: Message) = {
// this assumes that the service just does an "uppercase" transform on the text
m match {
case tm: TextMessage => true //tm.getText == "HELLO FROM GATLING JMS DSL"
case _ => false
}
}
}

I was able to find the solution. solution found in: https://github.com/gatling/gatling/blob/master/gatling-jms/src/test/scala/io/gatling/jms/compile/JmsCompileTest.scala
adding below methods to jms solved the issue:
.messageMatcher(HeaderMatcher)
.matchByCorrelationId

Related

How to test the IBM WebSphere Message Broker in JMeter

I have a scenario where i need to test the IBM WebSphere Message Broker(JMS request) in JMeter.
Currently i have below details with me. Using this below information, may i know how to create this script in JMeter.
Example :
Queue manager name : ACE config SVR/TCP/localhost(1414),
Queue name : DNB LT.SRVC,
XML Payload
Also, Manual testing team is using the RHF utility to perform this testing.
I believe the best option is going for JSR223 Sampler and custom Groovy code.
Download the relevant version of com.ibm.mq.allclient and drop it to "lib" folder of your JMeter installation (or other location which is in JMeter Classpath)
Restart JMeter to pick the .jar up
Add JSR223 Sampler to your Test plan
Put the following code into "Script" area
import com.ibm.msg.client.jms.JmsConnectionFactory
import com.ibm.msg.client.jms.JmsFactoryFactory
import com.ibm.msg.client.wmq.WMQConstants
import javax.jms.Session
def hostName = "127.0.0.1"
def hostPort = 1414
def channelName = "DEV.APP.SVRCONN"
def queueManagerName = "QM1"
def queueName = "DNB LT.SRVC"
def ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER)
def cf = ff.createConnectionFactory()
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, hostPort)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channelName)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManagerName)
def conn = cf.createConnection("app", "test")
def sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE)
def destination = sess.createQueue(queueName)
conn.start()
def producer = sess.createProducer(destination)
def payload = 'Your XML payload here'
def msg = sess.createTextMessage(payload)
producer.send(msg)
producer.close()
conn.close()
sess.close()
Run your test and the message should be sent
More information: IBM MQ testing with JMeter - Learn How

How to catch okhttp3 WebSocket network activity using okhttp3.Interceptor?

I have an okhttp3 (3.9.1) WebSocket instance and would like to view all it's network requests and responses. I tried to add some okhttp3.Interceptor instances to OkHttpClient instance before creating WebSocket on it but had no luck in viewing network activity. Here's sample code which demonstrates what I've tried to do:
package sample
import okhttp3.*
import java.io.IOException
import java.lang.Thread.sleep
fun main(args: Array<String>) {
val listener = object : WebSocketListener() {
override fun onMessage(webSocket: WebSocket?, text: String?) {
println("Got server message: $text")
}
}
val dummyInterceptor = Interceptor { chain ->
val request = chain.request()
val response = chain.proceed(request)
println("Dummy interceptor fired!\n\nRequest: ${request.headers()}\nResponse: ${response.headers()}")
return#Interceptor response
}
val dummyNetworkInterceptor = Interceptor { chain ->
val request = chain.request()
val response = chain.proceed(request)
println("Dummy network interceptor fired!\n\nRequest: ${request.headers()}\nResponse: ${response.headers()}")
return#Interceptor response
}
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(dummyInterceptor)
.addNetworkInterceptor(dummyNetworkInterceptor)
.build()
val request = Request.Builder().url("ws://echo.websocket.org").build()
val webSocket = okHttpClient.newWebSocket(request, listener)
webSocket.send("Hello1!")
webSocket.send("Hello2!")
webSocket.send("Hello3!")
sleep(2000) //Just for this sample to ensure all WS requests done
println("\n\n\tSome network activity\n\n")
okHttpClient.newCall(Request.Builder().get().url("http://echo.websocket.org").build()).enqueue(object : Callback {
override fun onFailure(call: Call?, exc: IOException?) {
println("OnFailure: ${exc?.message}")
}
override fun onResponse(call: Call?, response: Response?) {
println("OnResponse: ${response?.headers()}")
}
})
}
I tried to dive into okhttp3 source code and didn't find any reason why any of my interceptors doesn't fire on WS requests but works perfectly for any OkHttpClient request.
Is it a bug in okhttp3 or am I doing something wrong or it's just not possible to monitor WS requests using okhttp3.Interceptor?
WebSocket calls made with OkHttp don't use the interceptor chains that HTTP calls do, therefore you can't monitor them through interceptors.
I've faced this issue before myself, and so I looked at the source code and found the following then:
The regular HTTP calls go through the getResponseWithInterceptorChain() method in the RealCall class, which quite clearly starts the chained call of interceptors for each request.
The okhttp3.internal.ws package that includes the implementation of the WebSocket handling contains no code related to interceptors.
And really, interceptors catching WebSocket requests wouldn't really make sense in the first place. The Request that you can obtain in an interceptor represents an HTTP request, which WebSocket messages are not.
It isn't possible at this point, there's a feature request open for OkHttp but it isn't getting much traction: https://github.com/square/okhttp/issues/4192

IllegalStateException when trying to run spark streaming with twitter

I am new to spark and scala. I am trying to run an example given in google. I am encounting following exception when running this program.
Exception is:
17/05/25 11:13:42 ERROR ReceiverTracker: Deregistered receiver for stream 0: Restarting receiver with delay 2000ms: Error starting Twitter stream - java.lang.IllegalStateException: Authentication credentials are missing.
Code that I am executing is as follows:
PrintTweets.scala
package example
import org.apache.spark._
import org.apache.spark.SparkContext._
import org.apache.spark.streaming._
import org.apache.spark.streaming.twitter._
import org.apache.spark.streaming.StreamingContext._
import org.apache.log4j.Level
import Utilities._
object PrintTweets {
def main(args: Array[String]) {
// Configure Twitter credentials using twitter.txt
setupTwitter()
val appName = "TwitterData"
val conf = new SparkConf()
conf.setAppName(appName).setMaster("local[3]")
val ssc = new StreamingContext(conf, Seconds(5))
//val ssc = new StreamingContext("local[*]", "PrintTweets", Seconds(10))
setupLogging()
// Create a DStream from Twitter using our streaming context
val tweets = TwitterUtils.createStream(ssc, None)
// Now extract the text of each status update into RDD's using map()
val statuses = tweets.map(status => status.getText())
statuses.print()
ssc.start()
ssc.awaitTermination()
}
}
Utilities.scala
package example
import org.apache.log4j.Level
import java.util.regex.Pattern
import java.util.regex.Matcher
object Utilities {
/** Makes sure only ERROR messages get logged to avoid log spam. */
def setupLogging() = {
import org.apache.log4j.{Level, Logger}
val rootLogger = Logger.getRootLogger()
rootLogger.setLevel(Level.ERROR)
}
/** Configures Twitter service credentials using twiter.txt in the main workspace directory */
def setupTwitter() = {
import scala.io.Source
for (line <- Source.fromFile("../twitter.txt").getLines) {
val fields = line.split(" ")
if (fields.length == 2) {
System.setProperty("twitter4j.oauth." + fields(0), fields(1))
}
}
}
/** Retrieves a regex Pattern for parsing Apache access logs. */
def apacheLogPattern():Pattern = {
val ddd = "\\d{1,3}"
val ip = s"($ddd\\.$ddd\\.$ddd\\.$ddd)?"
val client = "(\\S+)"
val user = "(\\S+)"
val dateTime = "(\\[.+?\\])"
val request = "\"(.*?)\""
val status = "(\\d{3})"
val bytes = "(\\S+)"
val referer = "\"(.*?)\""
val agent = "\"(.*?)\""
val regex = s"$ip $client $user $dateTime $request $status $bytes $referer $agent"
Pattern.compile(regex)
}
}
When I check using print statments I find the exception is happening at line
val tweets = TwitterUtils.createStream(ssc, None)
I am giving credentials in twitter.txt file which is read properly by program. When I don't place twitter.txt in appropriate directory it shows explicit error, It shows explicit error unauthorized access when I give blank keys for customer key and secret etc in twitter.txt
If you need more details about error related information or versions of software let me know.
Thanks,
Madhu.
I could reproduce the issue with your code. I believe its your problem.
You might have not configured twitter.txt properly. Your twitter.txt file should be like this ->
consumerKey your_consumerKey
consumerSecret your_consumerSecret
accessToken your_accessToken
accessTokenSecret your_accessTokenSecret
I hope it helps.
After changing twitter.txt file syntax to following , single space between key and value it worked
consumerKey your_consumerKey
consumerSecret your_consumerSecret
accessToken your_accessToken
accessTokenSecret your_accessTokenSecret

Using side effects in Akka Streams to implement commands received from a websocket

I want to be able to click a button on a website, have it represent a command, issue that command to my program via a websocket, have my program process that command (which will produce a side effect), and then return the results of that command to the website to be rendered.
The websocket would be responsible for updating state changes applied by different actors that are within the users view.
Example: Changing AI instructions via the website. This modifies some values, which would get reported back to the website. Other users might change other AI instructions, or the AI would react to current conditions changing position, requiring the client to update the screen.
I was thinking I could have an actor responsible for updating the client with changed information, and just have the receiving stream update the state with the changes?
Is this the right library to use? Is there a better method to achieve what I want?
You can use akka-streams and akka-http for this just fine. An example when using an actor as a handler:
package test
import akka.actor.{Actor, ActorRef, ActorSystem, Props, Stash, Status}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.http.scaladsl.server.Directives._
import akka.stream.scaladsl.{Flow, Sink, Source, SourceQueueWithComplete}
import akka.stream.{ActorMaterializer, OverflowStrategy, QueueOfferResult}
import akka.pattern.pipe
import scala.concurrent.{ExecutionContext, Future}
import scala.io.StdIn
object Test extends App {
implicit val actorSystem = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit def executionContext: ExecutionContext = actorSystem.dispatcher
val routes =
path("talk") {
get {
val handler = actorSystem.actorOf(Props[Handler])
val flow = Flow.fromSinkAndSource(
Flow[Message]
.filter(_.isText)
.mapAsync(4) {
case TextMessage.Strict(text) => Future.successful(text)
case TextMessage.Streamed(textStream) => textStream.runReduce(_ + _)
}
.to(Sink.actorRefWithAck[String](handler, Handler.Started, Handler.Ack, Handler.Completed)),
Source.queue[String](16, OverflowStrategy.backpressure)
.map(TextMessage.Strict)
.mapMaterializedValue { queue =>
handler ! Handler.OutputQueue(queue)
queue
}
)
handleWebSocketMessages(flow)
}
}
val bindingFuture = Http().bindAndHandle(routes, "localhost", 8080)
println("Started the server, press enter to shutdown")
StdIn.readLine()
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => actorSystem.terminate())
}
object Handler {
case object Started
case object Completed
case object Ack
case class OutputQueue(queue: SourceQueueWithComplete[String])
}
class Handler extends Actor with Stash {
import context.dispatcher
override def receive: Receive = initialReceive
def initialReceive: Receive = {
case Handler.Started =>
println("Client has connected, waiting for queue")
context.become(waitQueue)
sender() ! Handler.Ack
case Handler.OutputQueue(queue) =>
println("Queue received, waiting for client")
context.become(waitClient(queue))
}
def waitQueue: Receive = {
case Handler.OutputQueue(queue) =>
println("Queue received, starting")
context.become(running(queue))
unstashAll()
case _ =>
stash()
}
def waitClient(queue: SourceQueueWithComplete[String]): Receive = {
case Handler.Started =>
println("Client has connected, starting")
context.become(running(queue))
sender() ! Handler.Ack
unstashAll()
case _ =>
stash()
}
case class ResultWithSender(originalSender: ActorRef, result: QueueOfferResult)
def running(queue: SourceQueueWithComplete[String]): Receive = {
case s: String =>
// do whatever you want here with the received message
println(s"Received text: $s")
val originalSender = sender()
queue
.offer("some response to the client")
.map(ResultWithSender(originalSender, _))
.pipeTo(self)
case ResultWithSender(originalSender, result) =>
result match {
case QueueOfferResult.Enqueued => // okay
originalSender ! Handler.Ack
case QueueOfferResult.Dropped => // due to the OverflowStrategy.backpressure this should not happen
println("Could not send the response to the client")
originalSender ! Handler.Ack
case QueueOfferResult.Failure(e) =>
println(s"Could not send the response to the client: $e")
context.stop(self)
case QueueOfferResult.QueueClosed =>
println("Outgoing connection to the client has closed")
context.stop(self)
}
case Handler.Completed =>
println("Client has disconnected")
queue.complete()
context.stop(self)
case Status.Failure(e) =>
println(s"Client connection has failed: $e")
e.printStackTrace()
queue.fail(new RuntimeException("Upstream has failed", e))
context.stop(self)
}
}
There are lots of places here which could be tweaked, but the basic idea remains the same. Alternatively, you could implement the Flow[Message, Message, _] required by the handleWebSocketMessages() method by using GraphStage. Everything used above is also described in detail in akka-streams documentation.

Connection between js and akka-http websockets fails 95% of the time

I'm trying to setup a basic connection between an akka-http websocket server and simple javascript.
1 out of roughly 20 connections succeeds, the rest fails. I have no idea why the setup of the connection is so unreliable.
Application.scala:
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.stream.ActorMaterializer
import services.WebService
import scala.concurrent.Await
import scala.concurrent.duration._
import java.util.concurrent.TimeoutException
object Application extends App {
implicit val system = ActorSystem("api")
implicit val materializer = ActorMaterializer()
import system.dispatcher
val config = system.settings.config
val interface = config.getString("app.interface")
val port = config.getInt("app.port")
val service = new WebService
val binding = Http().bindAndHandle(service.route, interface, port)
try {
Await.result(binding, 1 second)
println(s"server online at http://$interface:$port/")
} catch {
case exc: TimeoutException =>
println("Server took to long to startup, shutting down")
system.shutdown()
}
}
WebService.scala:
import actors.{PublisherActor, SubscriberActor}
import akka.actor.{Props, ActorSystem}
import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.http.scaladsl.server.Directives
import akka.stream.Materializer
import akka.stream.scaladsl.{Source, Flow}
import scala.concurrent.duration._
class WebService(implicit fm: Materializer, system: ActorSystem) extends Directives {
import system.dispatcher
system.scheduler.schedule(15 second, 15 second) {
println("Timer message!")
}
def route =
get {
pathSingleSlash {
getFromResource("web/index.html")
} ~
path("helloworld") {
handleWebsocketMessages(websocketActorFlow)
}
}
def websocketActorFlow: Flow[Message, Message, Unit] =
Flow[Message].collect({
case TextMessage.Strict(msg) =>
println(msg)
TextMessage.Strict(msg.reverse)
})
}
client side:
<input type="text" id="inputMessage"/><br/>
<input type="button" value="Send!" onClick="sendMessage()"/><br/>
<span id="response"></span>
<script type="application/javascript">
var connection;
function sendMessage() {
connection.send(document.getElementById("inputMessage").value);
}
document.addEventListener("DOMContentLoaded", function (event) {
connection = new WebSocket("ws://localhost:8080/helloworld");
connection.onopen = function (event) {
connection.send("connection established");
};
connection.onmessage = function (event) {
console.log(event.data);
document.getElementById("response").innerHTML = event.data;
}
});
</script>
if the connection to the server fails I get a timeout message after 5 seconds which says the following:
[DEBUG] [07/23/2015 07:59:54.517] [api-akka.actor.default-dispatcher-27] [akka://api/user/$a/flow-76-3-publisherSource-prefixAndTail] Cancelling akka.stream.impl.MultiStreamOutputProcessor$SubstreamOutput#a54778 (after: 5000 ms)
No matter if the connection fails or succeeds, I always get the following log message:
[DEBUG] [07/23/2015 07:59:23.849] [api-akka.actor.default-dispatcher-4] [akka://api/system/IO-TCP/selectors/$a/0] New connection accepted
Look at that error message carefully... it is coming from a source I would not have expected, some "MultiStreamOutputProcessor" when I only expect to handle a single stream.
That tells me - along with the webSocketActorFlow - that maybe you are getting messages and they aren't being caught by the flow, and so you're ending up with substreams you never expected.
So instead of it "only working some of the time," maybe it is "working most of the time but unable to handle all of the input as you have demanded in the flow, and you are left with un-selectable streams that have to die first.
See if you can either a) make sure you get a grip on the streams so you don't end up with stragglers, b) bandaid adjust timeouts, and c) detect such occurences and cancel processing the downstream
https://groups.google.com/forum/#!topic/akka-user/x-tARRaJ0LQ
akka {
stream {
materializer {
subscription-timeout {
timeout=30s
}
}
}
}
http://grokbase.com/t/gg/akka-user/1561gr0jgt/debug-message-cancelling-akka-stream-impl-multistreamoutputprocessor-after-5000-ms

Resources