io.gatling.core.session.Session Scala Examples
The following examples show how to use io.gatling.core.session.Session.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: MongoInsertAction.scala From gatling-mongodb-protocol with MIT License | 5 votes |
package com.ringcentral.gatling.mongo.action import com.ringcentral.gatling.mongo.command.MongoInsertCommand import com.ringcentral.gatling.mongo.response.MongoCountResponse import io.gatling.commons.stats.KO import io.gatling.commons.util.TimeHelper.nowMillis import io.gatling.commons.validation.Validation import io.gatling.core.action.Action import io.gatling.core.config.GatlingConfiguration import io.gatling.core.session.{Expression, Session} import io.gatling.core.stats.StatsEngine import reactivemongo.api.DefaultDB import reactivemongo.play.json.ImplicitBSONHandlers._ import reactivemongo.play.json.collection.JSONCollection import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} class MongoInsertAction(command: MongoInsertCommand, database: DefaultDB, val statsEngine: StatsEngine, configuration: GatlingConfiguration, val next: Action) extends MongoAction(database) { override def name: String = genName("Mongo insert command") override def commandName: Expression[String] = command.commandName override def executeCommand(commandName: String, session: Session): Validation[Unit] = for { collectionName <- command.collection(session) resolvedDocument <- command.document(session) document <- string2JsObject(resolvedDocument) } yield { val sent = nowMillis database.collection[JSONCollection](collectionName).insert(document).onComplete { case Success(result) => if (result.ok) { processResult(session, sent, nowMillis, command.checks, MongoCountResponse(result.n), next, commandName) } else { executeNext(session, sent, nowMillis, KO, next, commandName, Some(result.writeErrors.map(we => s"[${we.code}] ${we.errmsg}").mkString(", "))) } case Failure(err) => executeNext(session, sent, nowMillis, KO, next, commandName, Some(err.getMessage)) } } }
Example 2
Source File: AmqpAction.scala From gatling-amqp-plugin with Apache License 2.0 | 5 votes |
package ru.tinkoff.gatling.amqp.action import io.gatling.commons.validation.{Validation, _} import io.gatling.core.action.RequestAction import io.gatling.core.controller.throttle.Throttler import io.gatling.core.session.{Expression, Session} import io.gatling.core.util.NameGen import ru.tinkoff.gatling.amqp.client.AmqpPublisher import ru.tinkoff.gatling.amqp.protocol.AmqpComponents import ru.tinkoff.gatling.amqp.request.{AmqpAttributes, AmqpProtocolMessage} abstract class AmqpAction( attributes: AmqpAttributes, components: AmqpComponents, throttler: Throttler, throttled: Boolean ) extends RequestAction with AmqpLogging with NameGen { override val requestName: Expression[String] = attributes.requestName private val publisher = new AmqpPublisher(attributes.destination, components) override def sendRequest(requestName: String, session: Session): Validation[Unit] = { for { props <- resolveProperties(attributes.messageProperties, session) message <- attributes.message .amqpProtocolMessage(session) .map(_.mergeProperties(props + ("deliveryMode" -> components.protocol.deliveryMode))) around <- aroundPublish(requestName, session, message) } yield { if (throttled) { throttler.throttle( session.scenario, () => publisher.publish(message, around, session) ) } else publisher.publish(message, around, session) } } private def resolveProperties( properties: Map[Expression[String], Expression[Any]], session: Session ): Validation[Map[String, Any]] = properties.foldLeft(Map.empty[String, Any].success) { case (resolvedProperties, (key, value)) => for { key <- key(session) value <- value(session) resolvedProperties <- resolvedProperties } yield resolvedProperties + (key -> value) } protected def aroundPublish(requestName: String, session: Session, message: AmqpProtocolMessage): Validation[Around] }
Example 3
Source File: RequestReply.scala From gatling-amqp-plugin with Apache License 2.0 | 5 votes |
package ru.tinkoff.gatling.amqp.action import io.gatling.commons.util.Clock import io.gatling.commons.validation.Validation import io.gatling.core.action.Action import io.gatling.core.controller.throttle.Throttler import io.gatling.core.session.Session import io.gatling.core.stats.StatsEngine import ru.tinkoff.gatling.amqp.protocol.AmqpComponents import ru.tinkoff.gatling.amqp.request.{AmqpAttributes, AmqpProtocolMessage, _} class RequestReply( attributes: AmqpAttributes, replyDestination: AmqpExchange, setAmqpReplyTo: Boolean, trackerDestination: Option[AmqpExchange], components: AmqpComponents, val statsEngine: StatsEngine, val clock: Clock, val next: Action, throttler: Throttler, throttled: Boolean ) extends AmqpAction(attributes, components, throttler, throttled) { private val replyTimeout = components.protocol.replyTimeout.getOrElse(0L) override def name: String = genName("amqpRequestReply") override protected def aroundPublish(requestName: String, session: Session, message: AmqpProtocolMessage): Validation[Around] = { resolveDestination(replyDestination, session).map { qName => val tracker = components.trackerPool.tracker(qName, components.protocol.consumersThreadCount, components.protocol.messageMatcher, components.protocol.responseTransformer) val id = components.protocol.messageMatcher.requestMatchId(message) Around( before = { if (logger.underlying.isDebugEnabled) { logMessage(s"Message sent matchId=$id", message) } tracker.track(id, clock.nowMillis, replyTimeout, attributes.checks, session, next, requestName) }, after = {} ) } } def resolveDestination(dest: AmqpExchange, session: Session): Validation[String] = dest match { case AmqpDirectExchange(name, _, _) => name(session) case AmqpQueueExchange(name, _) => name(session) } }
Example 4
Source File: Publish.scala From gatling-amqp-plugin with Apache License 2.0 | 5 votes |
package ru.tinkoff.gatling.amqp.action import io.gatling.commons.stats.OK import io.gatling.commons.util.Clock import io.gatling.commons.validation.{Validation, _} import io.gatling.core.action.Action import io.gatling.core.config.GatlingConfiguration import io.gatling.core.controller.throttle.Throttler import io.gatling.core.session.Session import io.gatling.core.stats.StatsEngine import ru.tinkoff.gatling.amqp.protocol.AmqpComponents import ru.tinkoff.gatling.amqp.request.{AmqpAttributes, AmqpProtocolMessage} class Publish(attributes: AmqpAttributes, components: AmqpComponents, val statsEngine: StatsEngine, val clock: Clock, configuration: GatlingConfiguration, val next: Action, throttler: Throttler, throttled: Boolean) extends AmqpAction(attributes, components, throttler, throttled) { override val name: String = genName("amqpPublish") override protected def aroundPublish(requestName: String, session: Session, message: AmqpProtocolMessage): Validation[Around] = Around( before = { if (logger.underlying.isDebugEnabled) { logMessage(s"Message sent user=${session.userId} AMQPMessageID=${message.messageId}", message) } val now = clock.nowMillis statsEngine.logResponse(session, requestName, now, now, OK, None, None) next ! session }, after = () ).success }
Example 5
Source File: SqlProtocol.scala From gatling-sql with Apache License 2.0 | 5 votes |
package io.github.gatling.sql.protocol import java.sql.Connection import akka.actor.ActorSystem import io.gatling.core import io.gatling.core.CoreComponents import io.gatling.core.config.GatlingConfiguration import io.gatling.core.protocol.{Protocol, ProtocolComponents, ProtocolKey} import io.gatling.core.session.Session case class SqlProtocol(connection: Connection) extends Protocol { type Components = SqlComponents } object SqlProtocol { val SqlProtocolKey = new ProtocolKey { type Protocol = SqlProtocol type Components = SqlComponents override def protocolClass: Class[core.protocol.Protocol] = classOf[SqlProtocol].asInstanceOf[Class[io.gatling.core.protocol.Protocol]] override def defaultProtocolValue(configuration: GatlingConfiguration): SqlProtocol = throw new IllegalStateException("Can't provide a default value for SqlProtocol") override def newComponents(system: ActorSystem, coreComponents: CoreComponents): SqlProtocol => SqlComponents = { sqlProtocol => SqlComponents(sqlProtocol) } } } case class SqlComponents(sqlProtocol: SqlProtocol) extends ProtocolComponents { def onStart: Option[Session => Session] = None def onExit: Option[Session => Unit] = None } case class SqlProtocolBuilder(connection: Connection) { def build() = SqlProtocol(connection) } object SqlProtocolBuilder { def connection(connection: Connection) = SqlProtocolBuilder(connection) }
Example 6
Source File: SqlActionBuilder.scala From gatling-sql with Apache License 2.0 | 5 votes |
package io.github.gatling.sql.action import io.github.gatling.sql.protocol.SqlProtocol import io.github.gatling.sql.request.SqlAttributes import io.gatling.commons.stats.{KO, OK} import io.gatling.commons.util.ClockSingleton.nowMillis import io.gatling.commons.validation.Validation import io.gatling.core.action.builder.ActionBuilder import io.gatling.core.action.{Action, ExitableAction} import io.gatling.core.protocol.ProtocolComponentsRegistry import io.gatling.core.session.Session import io.gatling.core.stats.StatsEngine import io.gatling.core.stats.message.ResponseTimings import io.gatling.core.structure.ScenarioContext import io.gatling.core.util.NameGen import java.sql.PreparedStatement import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future class SqlActionBuilder(attr: SqlAttributes) extends ActionBuilder with NameGen { private def components(protocolComponentsRegistry: ProtocolComponentsRegistry) = protocolComponentsRegistry.components(SqlProtocol.SqlProtocolKey) override def build(ctx: ScenarioContext, next: Action): Action = { import ctx._ val statsEngine = coreComponents.statsEngine val sqlComponents = components(protocolComponentsRegistry) new SqlAction(genName(s"SQL: ${attr.tag}"), sqlComponents.sqlProtocol, statsEngine, next, attr) } } class SqlAction(val name: String, protocol: SqlProtocol, val statsEngine: StatsEngine, val next: Action, val attr: SqlAttributes) extends ExitableAction { def execute(session: Session): Unit = { val stmt: Validation[PreparedStatement] = attr.statement(session) stmt.onFailure(err => { statsEngine.logResponse(session, name, ResponseTimings(nowMillis, nowMillis), KO, None, Some("Error setting up statement: " + err), Nil) next ! session.markAsFailed }) stmt.onSuccess({ stmt => val start = nowMillis val result = Future { stmt.execute() } result.onFailure { case t => statsEngine.reportUnbuildableRequest(session, name, t.getMessage) } result.onSuccess { case result => val requestEndDate = nowMillis statsEngine.logResponse( session, name, ResponseTimings(startTimestamp = start, endTimestamp = requestEndDate), if (result) OK else KO, None, if (result) None else Some("Failed... TBD") ) next ! session.markAsSucceeded } }) } }
Example 7
Source File: SqlStatement.scala From gatling-sql with Apache License 2.0 | 5 votes |
package io.github.gatling.sql import java.sql.{Connection, PreparedStatement} import com.typesafe.scalalogging.StrictLogging import io.github.gatling.sql.db.ConnectionPool import io.gatling.commons.validation.Validation import io.gatling.core.session.{Expression, Session} import io.gatling.commons.validation._ trait SqlStatement extends StrictLogging { def apply(session:Session): Validation[PreparedStatement] def connection = ConnectionPool.connection } case class SimpleSqlStatement(statement: Expression[String]) extends SqlStatement { def apply(session: Session): Validation[PreparedStatement] = statement(session).flatMap { stmt => logger.debug(s"STMT: ${stmt}") connection.prepareStatement(stmt).success } }
Example 8
Source File: MongoRawCommandAction.scala From gatling-mongodb-protocol with MIT License | 5 votes |
package com.ringcentral.gatling.mongo.action import com.ringcentral.gatling.mongo.command.MongoRawCommand import com.ringcentral.gatling.mongo.response.MongoStringResponse import io.gatling.commons.stats.KO import io.gatling.commons.util.TimeHelper.nowMillis import io.gatling.commons.validation.Validation import io.gatling.core.action.Action import io.gatling.core.config.GatlingConfiguration import io.gatling.core.session.{Expression, Session} import io.gatling.core.stats.StatsEngine import play.api.libs.json.JsObject import reactivemongo.api.commands.Command import reactivemongo.api.{DefaultDB, FailoverStrategy, ReadPreference} import reactivemongo.play.json.ImplicitBSONHandlers._ import reactivemongo.play.json.JSONSerializationPack import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} class MongoRawCommandAction(command: MongoRawCommand, database: DefaultDB, val statsEngine: StatsEngine, configuration: GatlingConfiguration, val next: Action) extends MongoAction(database) { override def name: String = genName("Mongo raw command") override def commandName: Expression[String] = command.commandName override def executeCommand(commandName: String, session: Session): Validation[Unit] = for { commandText <- command.command(session) commandDocument <- string2JsObject(commandText) } yield { val sent = nowMillis val runner = Command.run(JSONSerializationPack, FailoverStrategy.default) runner.apply(database, runner.rawCommand(commandDocument)).one[JsObject](ReadPreference.primaryPreferred).onComplete { case Success(result) => processResult(session, sent, nowMillis, command.checks, MongoStringResponse(result.toString()), next, commandName) case Failure(err) => executeNext(session, sent, nowMillis, KO, next, commandName, Some(err.getMessage)) } } }
Example 9
Source File: MongoUpdateAction.scala From gatling-mongodb-protocol with MIT License | 5 votes |
package com.ringcentral.gatling.mongo.action import com.ringcentral.gatling.mongo.command.MongoUpdateCommand import com.ringcentral.gatling.mongo.response.MongoCountResponse import io.gatling.commons.stats.KO import io.gatling.commons.util.TimeHelper.nowMillis import io.gatling.commons.validation.Validation import io.gatling.core.action.Action import io.gatling.core.config.GatlingConfiguration import io.gatling.core.session.{Expression, Session} import io.gatling.core.stats.StatsEngine import reactivemongo.api.DefaultDB import reactivemongo.play.json.ImplicitBSONHandlers._ import reactivemongo.play.json.collection.JSONCollection import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} class MongoUpdateAction(command: MongoUpdateCommand, database: DefaultDB, val statsEngine: StatsEngine, configuration: GatlingConfiguration, val next: Action) extends MongoAction(database) { override def name: String = genName("Mongo update command") override def commandName: Expression[String] = command.commandName override def executeCommand(commandName: String, session: Session): Validation[Unit] = for { collectionName <- command.collection(session) resolvedSelector <- command.selector(session) resolvedModifier <- command.modifier(session) upsert <- command.upsert(session) multi <- command.multi(session) selector <- string2JsObject(resolvedSelector) modifier <- string2JsObject(resolvedModifier) } yield { val sent = nowMillis database.collection[JSONCollection](collectionName).update(selector, modifier, upsert = upsert, multi = multi).onComplete { case Success(result) => if (result.ok) { processResult(session, sent, nowMillis, command.checks, MongoCountResponse(result.n), next, commandName) } else { executeNext(session, sent, nowMillis, KO, next, commandName, Some(result.writeErrors.map(we => s"[${we.code}] ${we.errmsg}").mkString(", "))) } case Failure(err) => executeNext(session, sent, nowMillis, KO, next, commandName, Some(err.getMessage)) } } }
Example 10
Source File: MongoAction.scala From gatling-mongodb-protocol with MIT License | 5 votes |
package com.ringcentral.gatling.mongo.action import com.ringcentral.gatling.mongo.check.MongoCheck import com.ringcentral.gatling.mongo.response.MongoResponse import io.gatling.commons.stats.{KO, OK, Status} import io.gatling.commons.validation import io.gatling.commons.validation.{NoneSuccess, Validation} import io.gatling.core.action.{Action, ExitableAction} import io.gatling.core.check.Check import io.gatling.core.session.{Expression, Session} import io.gatling.core.stats.message.ResponseTimings import io.gatling.core.util.NameGen import play.api.libs.json._ import reactivemongo.api.DefaultDB import reactivemongo.api.collections.GenericQueryBuilder import reactivemongo.play.json.JSONSerializationPack import scala.util.{Failure, Success, Try} abstract class MongoAction(database: DefaultDB) extends ExitableAction with NameGen { def commandName: Expression[String] def executeCommand(commandName: String, session: Session): Validation[Unit] override def execute(session: Session): Unit = recover(session) { commandName(session).flatMap { resolvedCommandName => val outcome = executeCommand(resolvedCommandName, session) outcome.onFailure(errorMessage => statsEngine.reportUnbuildableRequest(session, resolvedCommandName, errorMessage)) outcome } } def string2JsObject(string: String): Validation[JsObject] = { Try[JsObject](Json.parse(string).as[JsObject]) match { case Success(json) => validation.SuccessWrapper(json).success case Failure(err) => validation.FailureWrapper(s"Error parse JSON string: $string. ${err.getMessage}").failure } } def string2JsObject(optionString: Option[String]): Validation[Option[JsObject]] = optionString match { case Some(string) => string2JsObject(string).map(Some.apply) case None => NoneSuccess } protected def executeNext(session: Session, sent: Long, received: Long, status: Status, next: Action, requestName: String, message: Option[String]): Unit = { val timings = ResponseTimings(sent, received) statsEngine.logResponse(session, requestName, timings, status, None, message) next ! session } protected def processResult(session: Session, sent: Long, received: Long, checks: List[MongoCheck], response: MongoResponse, next: Action, requestName: String): Unit = { // run all the checks, advise the Gatling API that it is complete and move to next val (checkSaveUpdate, error) = Check.check(response, session, checks) val newSession = checkSaveUpdate(session) error match { case Some(validation.Failure(errorMessage)) => executeNext(newSession.markAsFailed, sent, received, KO, next, requestName, Some(errorMessage)) case _ => executeNext(newSession, sent, received, OK, next, requestName, None) } } implicit class GenericQueryBuilderExt(b: GenericQueryBuilder[JSONSerializationPack.type]) { def sort(sort: Option[JsObject]): GenericQueryBuilder[JSONSerializationPack.type] = { sort.map(b.sort).getOrElse(b) } def hint(sort: Option[JsObject]): GenericQueryBuilder[JSONSerializationPack.type] = { sort.map(b.hint).getOrElse(b) } } }
Example 11
Source File: AmqpMessageTracker.scala From gatling-amqp-plugin with Apache License 2.0 | 5 votes |
package ru.tinkoff.gatling.amqp.client import akka.actor.ActorRef import io.gatling.core.action.Action import io.gatling.core.session.Session import ru.tinkoff.gatling.amqp.AmqpCheck import ru.tinkoff.gatling.amqp.client.AmqpMessageTrackerActor.MessagePublished class AmqpMessageTracker(actor: ActorRef) { def track( matchId: String, sent: Long, replyTimeout: Long, checks: List[AmqpCheck], session: Session, next: Action, requestName: String ): Unit = actor ! MessagePublished( matchId, sent, replyTimeout, checks, session, next, requestName ) }
Example 12
Source File: MongoCountAction.scala From gatling-mongodb-protocol with MIT License | 5 votes |
package com.ringcentral.gatling.mongo.action import com.ringcentral.gatling.mongo.command.MongoCountCommand import com.ringcentral.gatling.mongo.response.MongoCountResponse import io.gatling.commons.stats.KO import io.gatling.commons.util.TimeHelper.nowMillis import io.gatling.commons.validation._ import io.gatling.core.action.Action import io.gatling.core.config.GatlingConfiguration import io.gatling.core.session.{Expression, Session, _} import io.gatling.core.stats.StatsEngine import reactivemongo.api.DefaultDB import reactivemongo.play.json.collection.JSONCollection //TODO remove global context everywhere import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} class MongoCountAction(command: MongoCountCommand, database: DefaultDB, val statsEngine: StatsEngine, configuration: GatlingConfiguration, val next: Action) extends MongoAction(database) { override def name: String = genName("Mongo count command") override def commandName: Expression[String] = command.commandName override def executeCommand(commandName: String, session: Session): Validation[Unit] = for { collectionName <- command.collection(session) selectorDocument <- resolveOptionalExpression(command.selector, session) hint <- resolveOptionalExpression(command.hint, session) selector <- selectorDocument match { case Some(d) => string2JsObject(d).map(Some.apply) case None => NoneSuccess } } yield { val sent = nowMillis val collection: JSONCollection = database.collection[JSONCollection](collectionName) collection.count(selector, command.limit, command.skip, hint).onComplete { case Success(result) => processResult(session, sent, nowMillis, command.checks, MongoCountResponse(result), next, commandName) case Failure(err) => executeNext(session, sent, nowMillis, KO, next, commandName, Some(err.getMessage)) } } }
Example 13
Source File: MongoRemoveAction.scala From gatling-mongodb-protocol with MIT License | 5 votes |
package com.ringcentral.gatling.mongo.action import com.ringcentral.gatling.mongo.command.MongoRemoveCommand import com.ringcentral.gatling.mongo.response.MongoCountResponse import io.gatling.commons.stats.KO import io.gatling.commons.util.TimeHelper.nowMillis import io.gatling.commons.validation.Validation import io.gatling.core.action.Action import io.gatling.core.config.GatlingConfiguration import io.gatling.core.session.{Expression, Session} import io.gatling.core.stats.StatsEngine import reactivemongo.api.DefaultDB import reactivemongo.play.json.ImplicitBSONHandlers._ import reactivemongo.play.json.collection.JSONCollection import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} class MongoRemoveAction(command: MongoRemoveCommand, database: DefaultDB, val statsEngine: StatsEngine, configuration: GatlingConfiguration, val next: Action) extends MongoAction(database) { override def name: String = genName("Mongo find command") override def commandName: Expression[String] = command.commandName override def executeCommand(commandName: String, session: Session): Validation[Unit] = for { collectionName <- command.collection(session) resolvedSelector <- command.selector(session) selector <- string2JsObject(resolvedSelector) } yield { val sent = nowMillis database.collection[JSONCollection](collectionName).remove(selector).onComplete { case Success(result) => if (result.ok) { processResult(session, sent, nowMillis, command.checks, MongoCountResponse(result.n), next, commandName) } else { executeNext(session, sent, nowMillis, KO, next, commandName, Some(result.writeErrors.map(we => s"[${we.code}] ${we.errmsg}").mkString(", "))) } case Failure(err) => executeNext(session, sent, nowMillis, KO, next, commandName, Some(err.getMessage)) } } }
Example 14
Source File: MongoFindAction.scala From gatling-mongodb-protocol with MIT License | 5 votes |
package com.ringcentral.gatling.mongo.action import com.ringcentral.gatling.mongo.command.MongoFindCommand import com.ringcentral.gatling.mongo.response.MongoStringResponse import io.gatling.commons.stats.KO import io.gatling.commons.util.TimeHelper.nowMillis import io.gatling.commons.validation.Validation import io.gatling.core.action.Action import io.gatling.core.config.GatlingConfiguration import io.gatling.core.session.{Expression, Session, resolveOptionalExpression} import io.gatling.core.stats.StatsEngine import play.api.libs.json.JsObject import reactivemongo.api.{DefaultDB, QueryOpts, ReadPreference} import reactivemongo.play.json.ImplicitBSONHandlers._ import reactivemongo.play.json.collection.JSONCollection import reactivemongo.play.json.collection.JsCursor._ import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} class MongoFindAction(command: MongoFindCommand, database: DefaultDB, val statsEngine: StatsEngine, configuration: GatlingConfiguration, val next: Action) extends MongoAction(database) { override def name: String = genName("Mongo find command") override def commandName: Expression[String] = command.commandName override def executeCommand(commandName: String, session: Session): Validation[Unit] = for { collectionName <- command.collection(session) resolvedFilter <- command.query(session) filter <- string2JsObject(resolvedFilter) resolvedHint <- resolveOptionalExpression(command.hint, session) hint <- string2JsObject(resolvedHint) resolvedSort <- resolveOptionalExpression(command.sort, session) sort <- string2JsObject(resolvedSort) } yield { val sent = nowMillis database.collection[JSONCollection](collectionName).find(filter).options(QueryOpts().batchSize(command.limit)).sort(sort).hint(hint) .cursor[JsObject](ReadPreference.primary).jsArray(command.limit).onComplete { case Success(result) => processResult(session, sent, nowMillis, command.checks, MongoStringResponse(result.toString()), next, commandName) case Failure(err) => executeNext(session, sent, nowMillis, KO, next, commandName, Some(err.getMessage)) } } }
Example 15
Source File: package.scala From gatling-grpc with Apache License 2.0 | 5 votes |
package com.github.phisgr.gatling import com.google.protobuf.Message import io.gatling.commons.validation.{Failure, Success, Validation} import io.gatling.core.Predef.value2Expression import io.gatling.core.session.{Expression, Session} package object javapb { private type BuilderMutation[B] = (B, Session) => Failure // nullable private case class MutationWithExpression[B <: Message.Builder, F](setter: B => F => Message.Builder, e: Expression[F]) extends BuilderMutation[B] { override def apply(builder: B, session: Session): Failure = { e(session) match { case Success(value) => setter(builder)(value) null case f@Failure(_) => f } } } private[javapb] class MessageExpressionUpdater[M <: Message, B <: Message.Builder]( private[javapb] val original: Expression[M], private[javapb] val reversedMutations: List[BuilderMutation[B]] ) { def update[Field](setter: B => Field => Message.Builder)(value: Expression[Field]) = new MessageExpressionUpdater[M, B](original, MutationWithExpression(setter, value) :: reversedMutations) } implicit def toExpression[M <: Message, B <: Message.Builder](u: MessageExpressionUpdater[M, B]): Expression[M] = { val mutations = u.reversedMutations.reverse.toArray val size = mutations.length val original = u.original s => original(s) match { case Success(message) => val builder = message.toBuilder.asInstanceOf[B] var ret: Validation[M] = null var i = 0 do { if (i < size) { ret = mutations(i)(builder, s) i += 1 } else { ret = Success(builder.build().asInstanceOf[M]) } } while (ret eq null) ret case f@Failure(_) => f } } type BuilderOf[M <: Message] = {def build(): M} implicit def message2ExprUpdater[M <: Message, B <: Message.Builder with BuilderOf[M]](e: M)(implicit evidence: BuilderEvidence[M, B]): MessageExpressionUpdater[M, B] = expr2exprUpdater(value2Expression(e)) implicit def expr2exprUpdater[M <: Message, B <: Message.Builder with BuilderOf[M]](e: Expression[M])(implicit evidence: BuilderEvidence[M, B]): MessageExpressionUpdater[M, B] = new MessageExpressionUpdater[M, B](e, Nil) implicit def builderEvidence[M <: Message, B]: BuilderEvidence[M, B] = macro BuilderEvidence.impl[M, B] }
Example 16
Source File: TestUpdateExpr.scala From gatling-grpc with Apache License 2.0 | 5 votes |
package com.github.phisgr.gatling.pb.bench import java.util.concurrent.TimeUnit import com.github.phisgr.gatling.grpc.Predef._ import com.github.phisgr.gatling.javapb._ import com.github.phisgr.gatling.pb.Test import com.github.phisgr.gatling.pb.test._ import io.gatling.commons.validation.Validation import io.gatling.core.session.{Expression, Session} import org.openjdk.jmh.annotations.{Benchmark, OutputTimeUnit} @OutputTimeUnit(TimeUnit.MILLISECONDS) class TestUpdateExpr { import TestUpdateExpr._ @Benchmark def updateSimpleExpr(): Validation[SimpleMessage] = { SimpleExpr(Session1) } @Benchmark def updateComplexExpr(): Validation[ComplexMessage] = { ComplexExpr(Session1) } @Benchmark def updateSimpleExprJava(): Validation[Test.SimpleMessage] = { SimpleExprJava(Session1) } @Benchmark def updateComplexExprJava(): Validation[Test.ComplexMessage] = { ComplexExprJava(Session1) } @Benchmark def lambdaSimpleExprJava(): Validation[Test.SimpleMessage] = { SimpleExprJavaLambda(Session1) } @Benchmark def lambdaComplexExprJava(): Validation[Test.ComplexMessage] = { ComplexExprJavaLambda(Session1) } } object TestUpdateExpr { private val SimpleExpr = SimpleMessage.defaultInstance.updateExpr( _.s :~ $("name") ) private val SimpleExprJava: Expression[Test.SimpleMessage] = Test.SimpleMessage.getDefaultInstance .update(_.setS)($("name")) private val SimpleExprJavaLambda: Expression[Test.SimpleMessage] = { s: Session => for { name <- s("name").validate[String] } yield { val builder = Test.SimpleMessage.newBuilder() builder.setS(name) builder.build() } } private val ComplexExpr = ComplexMessage.defaultInstance.updateExpr( _.m.s :~ $("name"), _.i :~ $("count"), ) private val ComplexExprJava: Expression[Test.ComplexMessage] = Test.ComplexMessage.getDefaultInstance .update(_.getMBuilder.setS)($("name")) .update(_.setI)($("count")) private val ComplexExprJavaLambda: Expression[Test.ComplexMessage] = { s: Session => for { name <- s("name").validate[String] count <- s("count").validate[Int] } yield { val builder = Test.ComplexMessage.newBuilder() builder.getMBuilder.setS(name) builder.setI(count) builder.build() } } private val Session1 = Session( scenario = "Scenario", userId = 1L, attributes = Map( "name" -> "Asdf Qwer", "count" -> 123 ), startDate = System.currentTimeMillis() ) }
Example 17
Source File: GrpcCallActionBuilder.scala From gatling-grpc with Apache License 2.0 | 5 votes |
package com.github.phisgr.gatling.grpc.action import com.github.phisgr.gatling.grpc.HeaderPair import com.github.phisgr.gatling.grpc.check.{GrpcCheck, ResponseExtract} import com.github.phisgr.gatling.grpc.protocol.GrpcProtocol import io.gatling.commons.validation.Success import io.gatling.core.action.Action import io.gatling.core.action.builder.ActionBuilder import io.gatling.core.check.{MultipleFindCheckBuilder, ValidatorCheckBuilder} import io.gatling.core.session.{Expression, ExpressionSuccessWrapper, Session} import io.gatling.core.structure.ScenarioContext import io.grpc.{CallOptions, Metadata, MethodDescriptor} import scala.collection.breakOut case class GrpcCallActionBuilder[Req, Res]( requestName: Expression[String], method: MethodDescriptor[Req, Res], payload: Expression[Req], callOptions: Expression[CallOptions] = CallOptions.DEFAULT.expressionSuccess, reversedHeaders: List[HeaderPair[_]] = Nil, checks: List[GrpcCheck[Res]] = Nil, protocolOverride: Option[GrpcProtocol] = None, isSilent: Boolean = false ) extends ActionBuilder { override def build(ctx: ScenarioContext, next: Action): Action = GrpcCallAction(this, ctx, next) def callOptions(callOptions: Expression[CallOptions]) = copy( callOptions = callOptions ) def callOptions(callOptions: => CallOptions) = copy( callOptions = { _: Session => Success(callOptions) } ) def header[T](key: Metadata.Key[T])(value: Expression[T]) = copy( reversedHeaders = HeaderPair(key, value) :: reversedHeaders ) private def mapToList[T, U](s: Seq[T])(f: T => U) = s.map[U, List[U]](f)(breakOut) def check(checks: GrpcCheck[Res]*) = copy( checks = this.checks ::: checks.toList ) // In fact they can be added to checks using .check // but the type Res cannot be inferred there def extract[X]( f: Res => Option[X])( ts: (ValidatorCheckBuilder[ResponseExtract, Res, X] => GrpcCheck[Res])* ) = { val e = ResponseExtract.extract(f) copy( checks = checks ::: mapToList(ts)(_.apply(e)) ) } def exists[X](f: Res => Option[X]) = extract(f)(_.exists.build(ResponseExtract.materializer)) def extractMultiple[X]( f: Res => Option[Seq[X]])( ts: (MultipleFindCheckBuilder[ResponseExtract, Res, X] => GrpcCheck[Res])* ) = { val e = ResponseExtract.extractMultiple[Res, X](f) copy( checks = checks ::: mapToList(ts)(_.apply(e)) ) } def target(protocol: GrpcProtocol) = copy(protocolOverride = Some(protocol)) def silent = copy(isSilent = true) }
Example 18
Source File: ConnectionSettings.scala From gatling-mqtt-protocol with Apache License 2.0 | 5 votes |
package com.github.jeanadrien.gatling.mqtt.protocol import com.github.jeanadrien.gatling.mqtt.client.MqttQoS.MqttQoS import com.github.jeanadrien.gatling.mqtt.client.{MqttClientConfiguration, Will} import io.gatling.commons.validation.{Failure, Success, Validation} import io.gatling.core.session.{Session, _} import com.github.jeanadrien.gatling.mqtt.client.ConfigurationUtils._ case class ConnectionSettings( clientId : Option[Expression[String]], cleanSession : Option[Boolean], userName : Option[Expression[String]], password : Option[Expression[String]], willTopic : Option[Expression[String]], willMessage : Option[Expression[String]], willQos : Option[MqttQoS], willRetain : Option[Boolean] ) { private def configureWill(session : Session) (mqtt1 : MqttClientConfiguration) : Validation[MqttClientConfiguration] = (willTopic, willMessage) match { case (Some(wte), Some(wme)) => for { wt <- wte(session) wm <- wme(session) } yield { var will = Will( topic = wt, message = wm ) will = willQos.map(qos => will.copy(qos = qos)).getOrElse(will) will = willRetain.map(r => will.copy(willRetain = r)).getOrElse(will) mqtt1.copy(will = Some(will)) } case (None, None) => Success(mqtt1) case _ => Failure("Both will topic and message must be defined") } private[protocol] def configureMqtt(session : Session) (mqtt1 : MqttClientConfiguration) : Validation[MqttClientConfiguration] = { var mqtt = mqtt1 mqtt = cleanSession.map(cs => mqtt.copy(cleanSession = cs)).getOrElse(mqtt) Success(mqtt).flatMap { mqtt => realize[String, MqttClientConfiguration](clientId) { (config, value) => config.copy(clientId = value) }(mqtt, session) } flatMap { mqtt => realize[String, MqttClientConfiguration](userName) { (config, value) => config.copy(username = value) }(mqtt, session) } flatMap { mqtt => realize[String, MqttClientConfiguration](password) { (config, value) => config.copy(password = value) }(mqtt, session) } flatMap { configureWill(session) } } }
Example 19
Source File: WaitForMessagesAction.scala From gatling-mqtt-protocol with Apache License 2.0 | 5 votes |
package com.github.jeanadrien.gatling.mqtt.actions import akka.actor.ActorRef import akka.pattern.AskTimeoutException import akka.util.Timeout import com.github.jeanadrien.gatling.mqtt.client.MqttCommands import com.github.jeanadrien.gatling.mqtt.protocol.MqttComponents import io.gatling.core.CoreComponents import io.gatling.core.action.Action import io.gatling.core.session.Session import scala.concurrent.duration.FiniteDuration import scala.util.{Failure, Success} class WaitForMessagesAction( mqttComponents : MqttComponents, coreComponents : CoreComponents, timeout : FiniteDuration, val next : Action ) extends MqttAction(mqttComponents, coreComponents) { import akka.pattern.ask import mqttComponents.system.dispatcher override val name = genName("mqttWaitForMessage") override def execute(session : Session) : Unit = recover(session)(for { connection <- session("engine").validate[ActorRef] connectionId <- session("connectionId").validate[String] } yield { implicit val messageTimeout = Timeout(timeout) logger.debug(s"Wait for message action started... Timeout: ${timeout}") (connection ? MqttCommands.WaitForMessages).mapTo[MqttCommands] onComplete { case Success(MqttCommands.WaitForMessagesDone) => logger.info(s"${connectionId} : Done waitForMessage.") next ! session case Failure(t) if t.isInstanceOf[AskTimeoutException] => logger.warn("Wait for remaining messages timed out") next ! session.markAsFailed case Failure(t) => logger.warn("Wait for remaining messages error:", t) next ! session.markAsFailed } }) }
Example 20
Source File: AmqpEvent.scala From gatling-amqp with MIT License | 5 votes |
package io.gatling.amqp.event import io.gatling.amqp.data._ import io.gatling.core.session.Session sealed trait AmqpAction object AmqpPublishAction extends AmqpAction object AmqpConsumeAction extends AmqpAction sealed trait AmqpEvent { def action: AmqpAction } abstract class AmqpConsumevent extends AmqpEvent { def action: AmqpAction = AmqpConsumeAction } case class AmqpConsumeRequest(req: ConsumeRequest, session: Session) extends AmqpConsumevent case class AmqpConsuming(consumerName: String, no: Int, startedAt: Long, req: ConsumeRequest, session: Session) extends AmqpConsumevent { def eventId: String = s"$consumerName-$no" } case class AmqpConsumed(consumerName: String, no: Int, stoppedAt: Long, event: AmqpConsuming) extends AmqpConsumevent { def eventId: String = s"$consumerName-$no" } case class AmqpConsumeFailed(consumerName: String, no: Int, stoppedAt: Long, e: Throwable) extends AmqpConsumevent { def eventId: String = s"$consumerName-$no" } case class AmqpConsumeAcked(consumerName: String, no: Int, multiple: Boolean, stoppedAt: Long) extends AmqpConsumevent { def eventId: String = s"$consumerName-$no" } case class AmqpConsumeNacked(consumerName: String, no: Int, multiple: Boolean, stoppedAt: Long) extends AmqpConsumevent { def eventId: String = s"$consumerName-$no" }
Example 21
Source File: FindUser.scala From keycloak-benchmark with Apache License 2.0 | 5 votes |
package io.gatling.keycloak import akka.actor.ActorRef import akka.actor.ActorDSL._ import io.gatling.core.action.builder.ActionBuilder import io.gatling.core.action.Interruptable import io.gatling.core.config.Protocols import io.gatling.core.result.writer.DataWriterClient import io.gatling.core.session.{Expression, Session} import io.gatling.core.validation.Validation import org.keycloak.admin.client.resource.RealmResource import org.keycloak.representations.idm.UserRepresentation import scala.collection.JavaConversions._ case class FindUserAttributes( requestName: Expression[String], realm: Expression[RealmResource], username: Option[Expression[String]] = None, firstName: Option[Expression[String]] = None, lastName: Option[Expression[String]] = None, email: Option[Expression[String]] = None, firstResult: Option[Expression[Integer]] = None, maxResults: Option[Expression[Integer]] = None, use: Option[(Session, List[UserRepresentation]) => Session] = None ) {} object FindUserBuilder { implicit def toActionBuilder(builder: FindUserBuilder) = new FindUserActionBuilder(builder.attributes) } class FindUserBuilder(private val attributes: FindUserAttributes) { def username(username: Expression[String]) = new FindUserBuilder(attributes.copy(username = Some(username))) def firstName(firstName: Expression[String]) = new FindUserBuilder(attributes.copy(firstName = Some(firstName))) def lastName(lastName: Expression[String]) = new FindUserBuilder(attributes.copy(lastName = Some(lastName))) def email(email: Expression[String]) = new FindUserBuilder(attributes.copy(email = Some(email))) def firstResult(firstResult: Expression[Integer]) = new FindUserBuilder(attributes.copy(firstResult = Some(firstResult))) def maxResults(maxResults: Expression[Integer]) = new FindUserBuilder(attributes.copy(maxResults = Some(maxResults))) def use(use: (Session, List[UserRepresentation]) => Session) = new FindUserActionBuilder(attributes.copy(use = Some(use))) } class FindUserActionBuilder(attributes: FindUserAttributes) extends ActionBuilder { override def build(next: ActorRef, protocols: Protocols): ActorRef = actor(actorName("find-user"))(new FindUserAction(attributes, next)) } class FindUserAction( attributes: FindUserAttributes, val next: ActorRef ) extends Interruptable with ExitOnFailure with DataWriterClient { override def executeOrFail(session: Session): Validation[_] = attributes.realm(session).flatMap(realm => Blocking(() => Stopwatch(() => { realm.users().search( attributes.username.map(a => a(session).get).orNull, attributes.firstName.map(a => a(session).get).orNull, attributes.lastName.map(a => a(session).get).orNull, attributes.email.map(a => a(session).get).orNull, attributes.firstResult.map(a => a(session).get).orNull, attributes.maxResults.map(a => a(session).get).orNull) }) .recordAndContinue(this, session, attributes.requestName(session).get, users => { attributes.use.map(use => use(session, users.toList)).getOrElse(session) }) ) ) }
Example 22
Source File: RemoveUserAction.scala From keycloak-benchmark with Apache License 2.0 | 5 votes |
package io.gatling.keycloak import akka.actor.ActorRef import io.gatling.core.action.Interruptable import io.gatling.core.result.writer.DataWriterClient import io.gatling.core.session.{Expression, Session} import io.gatling.core.validation.Validation import org.keycloak.admin.client.resource.RealmResource class RemoveUserAction( requestName: Expression[String], realm: Expression[RealmResource], userId: Expression[String], val next: ActorRef ) extends Interruptable with ExitOnFailure with DataWriterClient { override def executeOrFail(session: Session): Validation[_] = { realm(session).map(realm => Blocking(() => Stopwatch(() => realm.users.get(userId(session).get).remove()) .recordAndContinue(this, session, requestName(session).get) ) ) } }
Example 23
Source File: AddUser.scala From keycloak-benchmark with Apache License 2.0 | 5 votes |
package io.gatling.keycloak import javax.ws.rs.core.{HttpHeaders, Response} import akka.actor.ActorDSL._ import akka.actor.ActorRef import io.gatling.core.action.Interruptable import io.gatling.core.action.builder.ActionBuilder import io.gatling.core.config.Protocols import io.gatling.core.result.writer.DataWriterClient import io.gatling.core.session.{Expression, Session} import io.gatling.core.validation.{Success, Validation} import org.keycloak.admin.client.resource.RealmResource import org.keycloak.representations.idm.{CredentialRepresentation, UserRepresentation} case class AddUserAttributes( requestName: Expression[String], realm: Expression[RealmResource], username: Expression[String], enabled: Expression[Boolean] = _ => Success(true), firstName: Option[Expression[String]] = None, lastName: Option[Expression[String]] = None, email: Option[Expression[String]] = None, password: Option[Expression[String]] = None, passwordTemporary: Option[Expression[Boolean]] = None, save: Option[(Session, String) => Session] = None ) {} case class AddUserActionBuilder( attributes: AddUserAttributes ) extends ActionBuilder { def newInstance(attributes: AddUserAttributes) = new AddUserActionBuilder(attributes) def enabled(enabled: Expression[Boolean]) = newInstance(attributes.copy(enabled = enabled)) def password(password: Expression[String], temporary: Expression[Boolean]) = newInstance(attributes.copy(password = Some(password), passwordTemporary = Some(temporary))) def firstName(firstName: Expression[String]) = newInstance(attributes.copy(firstName = Some(firstName))) def lastName(lastName: Expression[String]) = newInstance(attributes.copy(lastName = Some(lastName))) def email(email: Expression[String]) = newInstance(attributes.copy(email = Some(email))) def saveWith[T](save: (Session, String) => Session) = newInstance(attributes.copy(save = Some(save))) def saveAs(name: String) = saveWith((session, id) => session.set(name, id)) override def build(next: ActorRef, protocols: Protocols): ActorRef = { actor(actorName("add-user"))(new AddUserAction(attributes, next)) } } class AddUserAction( attributes: AddUserAttributes, val next: ActorRef ) extends Interruptable with ExitOnFailure with DataWriterClient { override def executeOrFail(session: Session): Validation[_] = { val user = new UserRepresentation user.setUsername(attributes.username(session).get) user.setEnabled(attributes.enabled(session).get) attributes.firstName.map(fn => user.setFirstName(fn(session).get)) attributes.lastName.map(ln => user.setLastName(ln(session).get)) attributes.email.map(e => user.setEmail(e(session).get)) attributes.realm(session).map(realm => Blocking(() => Stopwatch(() => realm.users.create(user)) .check(response => response.getStatus == 201, response => { val status = response.getStatusInfo.toString response.close() status }) .recordAndStopOnFailure(this, session, attributes.requestName(session).get + ".create-user") .onSuccess(response => { val id = getUserId(response) response.close() val newSession = attributes.save.map(s => s(session, id)).getOrElse(session) attributes.password.map(password => { val credentials = new CredentialRepresentation credentials.setType(CredentialRepresentation.PASSWORD) credentials.setValue(password(newSession).get) attributes.passwordTemporary.map(a => credentials.setTemporary(a(newSession).get)) Stopwatch(() => realm.users.get(id).resetPassword(credentials)) .recordAndContinue(this, newSession, attributes.requestName(session).get + ".reset-password") }).getOrElse(next ! newSession) }) ) ) } def getUserId(u: Response): String = { val location = u.getHeaderString(HttpHeaders.LOCATION) val lastSlash = location.lastIndexOf('/'); if (lastSlash < 0) null else location.substring(lastSlash + 1) } }
Example 24
Source File: RefreshToken.scala From keycloak-benchmark with Apache License 2.0 | 5 votes |
package io.gatling.keycloak import akka.actor.ActorDSL._ import akka.actor.ActorRef import io.gatling.core.action.Interruptable import io.gatling.core.action.builder.ActionBuilder import io.gatling.core.config.Protocols import io.gatling.core.result.writer.DataWriterClient import io.gatling.core.session.{Session, Expression} import io.gatling.core.validation.Validation class RefreshTokenActionBuilder(requestName: Expression[String]) extends ActionBuilder{ override def build(next: ActorRef, protocols: Protocols): ActorRef = { actor(actorName("refresh-token"))(new RefreshTokenAction(requestName, next)) } } class RefreshTokenAction( requestName: Expression[String], val next: ActorRef ) extends Interruptable with ExitOnFailure with DataWriterClient { override def executeOrFail(session: Session): Validation[_] = { val requestAuth: MockRequestAuthenticator = session(MockRequestAuthenticator.KEY).as[MockRequestAuthenticator] Blocking(() => Stopwatch(() => requestAuth.getKeycloakSecurityContext.refreshExpiredToken(false)) .check(identity, _ => "Could not refresh token") .recordAndContinue(this, session, requestName(session).get) ) } }
Example 25
Source File: Stats.scala From gatling-amqp with MIT License | 5 votes |
package io.gatling.amqp.infra import io.gatling.amqp.config._ import io.gatling.core.result.message.{KO, OK} import io.gatling.core.session.Session trait Stats { this: AmqpActor => implicit val amqp: AmqpProtocol private lazy val statsEngine = amqp.statsEngine protected def statsOk(session: Session, startedAt: Long, stoppedAt: Long, title: String, code: Option[String] = None): Unit = { amqp.tracer ! WriteStat(session, startedAt, stoppedAt, title, OK, code, None) } protected def statsNg(session: Session, startedAt: Long, stoppedAt: Long, title: String, code: Option[String], mes: String): Unit = { amqp.tracer ! WriteStat(session, startedAt, stoppedAt, title, KO, code, Some(mes)) } }
Example 26
Source File: AmqpTracer.scala From gatling-amqp with MIT License | 5 votes |
package io.gatling.amqp.infra import akka.actor._ import io.gatling.amqp.config._ import io.gatling.amqp.event._ import io.gatling.core.result.message.{KO, OK, ResponseTimings, Status} import io.gatling.core.result.writer.StatsEngine import io.gatling.core.session.Session case class MessageOk(event: AmqpPublishing, stoppedAt: Long, title: String) case class MessageNg(event: AmqpPublishing, stoppedAt: Long, title: String, message: Option[String]) case class WriteStat(session: Session, startedAt: Long, stoppedAt: Long, title: String, status: Status, code: Option[String], mes: Option[String]) class AmqpTracer(statsEngine: StatsEngine)(implicit amqp: AmqpProtocol) extends Actor with Logging { def receive = { case WriteStat(session, startedAt, stoppedAt, title, status, code, mes) => val timings = ResponseTimings(startedAt, stoppedAt, stoppedAt, stoppedAt) statsEngine.logResponse(session, title, timings, OK, code, mes) case MessageOk(event, stoppedAt, title) => import event._ val timings = ResponseTimings(startedAt, stoppedAt, stoppedAt, stoppedAt) statsEngine.logResponse(session, title, timings, OK, None, None) case MessageNg(event, stoppedAt, title, message) => import event._ val timings = ResponseTimings(startedAt, stoppedAt, stoppedAt, stoppedAt) statsEngine.logResponse(session, title, timings, KO, None, message) } } object AmqpTracer { def props(statsEngine : StatsEngine, amqp: AmqpProtocol) = Props(classOf[AmqpTracer], statsEngine, amqp) }
Example 27
Source File: AmqpRouter.scala From gatling-amqp with MIT License | 5 votes |
package io.gatling.amqp.infra import akka.actor._ import akka.routing._ import io.gatling.amqp.config._ import io.gatling.amqp.data._ import io.gatling.amqp.event._ import io.gatling.core.result.writer.StatsEngine import io.gatling.core.session.Session import scala.collection.mutable import scala.util._ class AmqpRouter(statsEngine: StatsEngine)(implicit amqp: AmqpProtocol) extends Actor with Logging { private var publishers = Router(RoundRobinRoutingLogic(), Vector[Routee]()) // create one consumer for one session private val consumerActors = mutable.HashMap[String, ActorRef]() // UserId -> ref(AmqpConsumer) private def consumerActorFor(session: Session): ActorRef = { val name = s"AmqpConsumer-user-${session.userId}" consumerActors.getOrElseUpdate(session.userId, context.actorOf(AmqpConsumer.props(name, session, amqp), name)) } override def preStart(): Unit = { super.preStart() } private def initializePublishersOnce(): Unit = { if (publishers.routees.isEmpty) { for(i <- 1 to amqp.connection.poolSize) { addPublisher(i) } } } def receive: Receive = { case m: AmqpPublishRequest => initializePublishersOnce() publishers.route(m, sender()) case m: AmqpConsumeRequest => consumerActorFor(m.session).forward(m) case m: WaitTermination if consumerActors.isEmpty => sender() ! Success("no consumers") case m: WaitTermination => consumerActorFor(m.session).forward(m) case Terminated(ref) => publishers = publishers.removeRoutee(ref) } private def addPublisher(i: Int): Unit = { val name = s"AmqpPublisher-$i" val ref = context.actorOf(AmqpPublisher.props(name, amqp), name) context watch ref publishers = publishers.addRoutee(ref) } } object AmqpRouter { def props(statsEngine : StatsEngine, amqp: AmqpProtocol) = Props(classOf[AmqpRouter], statsEngine, amqp) }
Example 28
Source File: AmqpPublisher.scala From gatling-amqp with MIT License | 5 votes |
package io.gatling.amqp.infra import java.util.concurrent.atomic._ import akka.actor.Props import com.rabbitmq.client._ import io.gatling.amqp.config._ import io.gatling.amqp.data._ import io.gatling.amqp.event._ import io.gatling.core.result.writer.StatsEngine import io.gatling.core.session.Session import io.gatling.core.util.TimeHelper.nowMillis import scala.util._ class AmqpPublisher(actorName: String)(implicit amqp: AmqpProtocol) extends AmqpActor { private val nacker = amqp.nacker private val isConfirmMode = amqp.isConfirmMode private def sendEvent(event: AmqpEvent): Unit = nacker ! event // private def sendEvent(event: AmqpEvent): Unit = amqp.event.publish(event) override def preStart(): Unit = { super.preStart() if (isConfirmMode) { channel.confirmSelect() channel.addConfirmListener(new ConfirmListener() { def handleAck (no: Long, multi: Boolean): Unit = { sendEvent(AmqpPublishAcked (actorName, no.toInt, multi, nowMillis)) } def handleNack(no: Long, multi: Boolean): Unit = sendEvent(AmqpPublishNacked(actorName, no.toInt, multi, nowMillis)) }) } } private val localPublishSeqNoCounter = new AtomicInteger(1) private def getNextPublishSeqNo: Int = { if (isConfirmMode) channel.getNextPublishSeqNo.toInt else localPublishSeqNoCounter.getAndIncrement } override def receive = { case AmqpPublishRequest(req, session) if isConfirmMode => publishAsync(req, session) case AmqpPublishRequest(req, session) => publishSync(req, session) } protected def publishSync(req: PublishRequest, session: Session): Unit = { import req._ val startedAt = nowMillis val no: Int = getNextPublishSeqNo val event = AmqpPublishing(actorName, no, nowMillis, req, session) Try { channel.basicPublish(exchange.name, routingKey, props, bytes) } match { case Success(_) => sendEvent(AmqpPublished(actorName, no, nowMillis, event)) case Failure(e) => sendEvent(AmqpPublishFailed(actorName, no, nowMillis, e)) log.error(s"basicPublish($exchange) failed", e) } } protected def publishAsync(req: PublishRequest, session: Session): Unit = { import req._ val no: Int = getNextPublishSeqNo sendEvent(AmqpPublishing(actorName, no, nowMillis, req, session)) try { channel.basicPublish(exchange.name, routingKey, props, bytes) } catch { case e: Exception => sendEvent(AmqpPublishFailed(actorName, no, nowMillis, e)) log.error(s"basicPublish($exchange) failed", e) } } } object AmqpPublisher { def props(name: String, amqp: AmqpProtocol) = Props(classOf[AmqpPublisher], name, amqp) }
Example 29
Source File: Stopwatch.scala From keycloak-benchmark with Apache License 2.0 | 5 votes |
package io.gatling.keycloak import com.typesafe.scalalogging.StrictLogging import io.gatling.core.action.{UserEnd, Chainable} import io.gatling.core.akka.GatlingActorSystem import io.gatling.core.result.message.{OK, KO, Status} import io.gatling.core.result.writer.{DataWriter, DataWriterClient} import io.gatling.core.session.Session import io.gatling.core.util.TimeHelper import io.gatling.core.validation.{Validation, Success, Failure} object Stopwatch extends StrictLogging { @volatile var recording: Boolean = true; GatlingActorSystem.instance.registerOnTermination(() => recording = true) def apply[T](f: () => T): Result[T] = { val start = TimeHelper.nowMillis try { val result = f() Result(Success(result), OK, start, TimeHelper.nowMillis, false) } catch { case ie: InterruptedException => { Result(Failure("Interrupted"), KO, start, start, true) } case e: Throwable => { Stopwatch.log.error("Operation failed with exception", e) Result(Failure(e.toString), KO, start, TimeHelper.nowMillis, false) } } } def log = logger; } case class Result[T]( val value: Validation[T], val status: Status, val startTime: Long, val endTime: Long, val interrupted: Boolean ) { def check(check: T => Boolean, fail: T => String): Result[T] = { value match { case Success(v) => if (!check(v)) { Result(Failure(fail(v)), KO, startTime, endTime, interrupted); } else { this } case _ => this } } def isSuccess = value match { case Success(_) => true case _ => false } private def record(client: DataWriterClient, session: Session, name: String): Validation[T] = { if (!interrupted && Stopwatch.recording) { client.writeRequestData(session, name, startTime, startTime, endTime, endTime, status) } value } def recordAndStopOnFailure(client: DataWriterClient with Chainable, session: Session, name: String): Validation[T] = { val validation = record(client, session, name) validation.onFailure(message => { Stopwatch.log.error(s"'${client.self.path.name}', ${session.userId} failed to execute: $message") UserEnd.instance ! session.markAsFailed }) validation } def recordAndContinue(client: DataWriterClient with Chainable, session: Session, name: String): Unit = { // can't specify follow function as default arg since it uses another parameter recordAndContinue(client, session, name, _ => session); } def recordAndContinue(client: DataWriterClient with Chainable, session: Session, name: String, follow: T => Session): Unit = { // 'follow' intentionally does not get session as arg, since caller site already has the reference record(client, session, name) match { case Success(value) => try { client.next ! follow(value) } catch { case t: Throwable => { Stopwatch.log.error(s"'${client.self.path.name}' failed processing", t) UserEnd.instance ! session.markAsFailed } } case Failure(message) => { Stopwatch.log.error(s"'${client.self.path.name}' failed to execute: $message") UserEnd.instance ! session.markAsFailed } } } }
Example 30
Source File: AmqpTermination.scala From gatling-amqp with MIT License | 5 votes |
package io.gatling.amqp.config import akka.pattern.ask import akka.util.Timeout import io.gatling.amqp.data._ import io.gatling.core.session.Session import pl.project13.scala.rainbow._ import scala.concurrent.Await import scala.concurrent.duration._ import scala.util._ trait AmqpTermination { this: AmqpProtocol => private val publishTimeout: Timeout = Timeout(1 hour) private val consumeTimeout: Timeout = Timeout(1 hour) protected def awaitTerminationFor(session: Session): Unit = { // wait nacker to ensure all confirms has been fired Await.result((nacker ask WaitTermination(session))(publishTimeout), Duration.Inf) match { case Success(m) => logger.debug(s"amqp: $m".green) case Failure(e) => throw e } // wait consumers Await.result((router ask WaitTermination(session))(consumeTimeout), Duration.Inf) match { case Success(m) => logger.debug(s"amqp: $m".green) case Failure(e) => throw e } } }
Example 31
Source File: GrcpActionActor.scala From grpc-gatling with MIT License | 5 votes |
package ch.tamedia.gatling.actions import akka.actor.Props import ch.tamedia.gatling.GrpcProtocol import ch.tamedia.gatling.grpc.GrpcCheck import com.trueaccord.scalapb.GeneratedMessage import io.gatling.commons.stats.{KO, OK} import io.gatling.commons.util.TimeHelper import io.gatling.commons.validation.Failure import io.gatling.core.action.{Action, ActionActor} import io.gatling.core.check.Check import io.gatling.core.session.Session import io.gatling.core.stats.StatsEngine import io.gatling.core.stats.message.ResponseTimings import scala.concurrent.Future def logResult(maybeResult: Option[GeneratedMessage], error: Option[Throwable] = None) = { val endTime = TimeHelper.nowMillis val timings = ResponseTimings(startTime, endTime) if (error.isEmpty) { val result = maybeResult.get if (Option(result).nonEmpty) { val (newSession, error) = Check.check(result, session, checks) error match { case None => { statsEngine.logResponse(session, action.name, timings, OK, None, None) next ! newSession(session) } case Some(Failure(errorMessage)) => { statsEngine.logResponse(session, action.name, timings, KO, None, Some(errorMessage)) next ! newSession(session).markAsFailed } } } else { statsEngine.logResponse(session, action.name, timings, KO, None, Some(s"Error during the call!")) next ! session.markAsFailed } } else { val throwable = error.get statsEngine.logResponse(session, action.name, timings, KO, None, Some(throwable.getMessage)) next ! session.markAsFailed } } } }
Example 32
Source File: ImapSimpleCheck.scala From gatling-imap with GNU Affero General Public License v3.0 | 5 votes |
package com.linagora.gatling.imap.check import java.util import com.linagora.gatling.imap.protocol.ImapResponses import io.gatling.commons.validation.{Failure, Validation} import io.gatling.core.check.CheckResult import io.gatling.core.session.Session object ImapSimpleCheck { val DefaultMessage = "Imap check failed" } case class ImapSimpleCheck(validate: ImapResponses => Boolean, errorMessage: ImapResponses => String = _ => ImapSimpleCheck.DefaultMessage) extends ImapCheck { override def check(responses: ImapResponses, session: Session)(implicit preparedCache: util.Map[Any, Any]): Validation[CheckResult] = { if (validate(responses)) CheckResult.NoopCheckResultSuccess else Failure(errorMessage(responses)) } }
Example 33
Source File: ImapProtocol.scala From gatling-imap with GNU Affero General Public License v3.0 | 5 votes |
package com.linagora.gatling.imap.protocol import java.util.Properties import java.util.UUID.randomUUID import akka.actor.ActorRef import com.linagora.gatling.imap.protocol.Command.Disconnect import io.gatling.core.CoreComponents import io.gatling.core.config.GatlingConfiguration import io.gatling.core.protocol.{Protocol, ProtocolComponents, ProtocolKey} import io.gatling.core.session.Session object ImapProtocol { val ImapProtocolKey = new ProtocolKey[ImapProtocol, ImapComponents] { override def protocolClass: Class[io.gatling.core.protocol.Protocol] = classOf[ImapProtocol].asInstanceOf[Class[io.gatling.core.protocol.Protocol]] override def defaultProtocolValue(configuration: GatlingConfiguration): ImapProtocol = throw new IllegalStateException("Can't provide a default value for ImapProtocol") override def newComponents(coreComponents: CoreComponents): ImapProtocol => ImapComponents = { protocol => val sessions: ActorRef = coreComponents.actorSystem.actorOf(ImapSessions.props(protocol), "imapsessions_" + randomUUID().toString) ImapComponents(protocol, sessions) } } } case class ImapComponents(protocol: ImapProtocol, sessions: ActorRef) extends ProtocolComponents { override def onStart: Session => Session = s => s override def onExit: Session => Unit = session => sessions ! Disconnect(UserId(session.userId)) } case class ImapProtocol(host: String, port: Int = 143, config: Properties = new Properties() ) extends Protocol
Example 34
Source File: ImapResponseHandler.scala From gatling-imap with GNU Affero General Public License v3.0 | 5 votes |
package com.linagora.gatling.imap.action import akka.actor.Props import com.linagora.gatling.imap.protocol.Response.Disconnected import com.linagora.gatling.imap.protocol.{ImapResponses, Response} import io.gatling.commons.stats.{KO, OK} import io.gatling.commons.validation.Failure import io.gatling.core.akka.BaseActor import io.gatling.core.check.Check import io.gatling.core.session.Session import scala.collection.immutable.Seq object ImapResponseHandler { def props(imapActionContext: ImapActionContext, requestName: String, session: Session, start: Long, checks: Seq[Check[ImapResponses]]): Props = { Props(new ImapResponseHandler(imapActionContext, requestName, session, start, checks)) } } class ImapResponseHandler(imapActionContext: ImapActionContext, requestName: String, session: Session, start: Long, checks: Seq[Check[ImapResponses]]) extends BaseActor { private val statsEngine = imapActionContext.statsEngine private val next = imapActionContext.next override def receive: Receive = { case Response(responses) => val (newSession, error) = Check.check(responses, session, checks.toList) error.fold(ok(newSession, start))(ko(session, start)) case e: Exception => ko(session, start)(Failure(e.getMessage)) case Disconnected(e) => ko(session, start)(Failure(e.getMessage)) case msg => logger.error(s"received unexpected message $msg") } def ko(session: Session, start: Long)(failure: Failure) = { statsEngine.logResponse(session, requestName, start, imapActionContext.clock.nowMillis, KO, None, Some(failure.message)) next ! session.markAsFailed context.stop(self) } def ok(session: Session, start: Long) = { statsEngine.logResponse(session, requestName, start, imapActionContext.clock.nowMillis, OK, None, None) next ! session context.stop(self) } }
Example 35
Source File: AmqpMessageCheck.scala From gatling-amqp-plugin with Apache License 2.0 | 5 votes |
package ru.tinkoff.gatling.amqp.checks import java.util.{Map => JMap} import io.gatling.commons.validation._ import io.gatling.core.check.CheckResult import io.gatling.core.session.Session import ru.tinkoff.gatling.amqp.AmqpCheck import ru.tinkoff.gatling.amqp.request.AmqpProtocolMessage object AmqpMessageCheck { private val AmqpMessageCheckFailure = "AMQP check failed".failure } case class AmqpMessageCheck(func: AmqpProtocolMessage => Boolean) extends AmqpCheck { override def check(response: AmqpProtocolMessage, session: Session, preparedCache: JMap[Any, Any]): Validation[CheckResult] = if (func(response)) { CheckResult.NoopCheckResultSuccess } else { AmqpMessageCheck.AmqpMessageCheckFailure } }
Example 36
Source File: package.scala From gatling-amqp-plugin with Apache License 2.0 | 5 votes |
package ru.tinkoff.gatling.amqp import com.rabbitmq.client.MessageProperties import io.gatling.commons.validation.Validation import io.gatling.core.session.{Expression, Session} package object request { sealed trait AmqpExchange case class AmqpDirectExchange(name: Expression[String], routingKey: Expression[String], durable: Boolean = false) extends AmqpExchange case class AmqpQueueExchange(name: Expression[String], durable: Boolean = false) extends AmqpExchange sealed trait AmqpMessage { private[amqp] def amqpProtocolMessage(session: Session): Validation[AmqpProtocolMessage] } case class TextAmqpMessage(text: Expression[String]) extends AmqpMessage { override private[amqp] def amqpProtocolMessage(session: Session) = text(session).map(str => AmqpProtocolMessage(MessageProperties.MINIMAL_BASIC, str.getBytes())) } case class BytesAmqpMessage(bytes: Expression[Array[Byte]]) extends AmqpMessage { override private[amqp] def amqpProtocolMessage(session: Session) = bytes(session).map(AmqpProtocolMessage(MessageProperties.MINIMAL_BASIC, _)) } }
Example 37
Source File: AmqpPublisher.scala From gatling-amqp-plugin with Apache License 2.0 | 5 votes |
package ru.tinkoff.gatling.amqp.client import io.gatling.core.session.Session import javax.jms.DeliveryMode import ru.tinkoff.gatling.amqp.action.Around import ru.tinkoff.gatling.amqp.protocol.AmqpComponents import ru.tinkoff.gatling.amqp.request.{AmqpDirectExchange, AmqpExchange, AmqpProtocolMessage, AmqpQueueExchange} import scala.collection.JavaConverters._ class AmqpPublisher(destination: AmqpExchange, components: AmqpComponents) extends WithAmqpChannel { def publish(message: AmqpProtocolMessage, around: Around, session: Session): Unit = { val protocolDurable = components.protocol.deliveryMode == DeliveryMode.PERSISTENT destination match { case AmqpDirectExchange(name, routingKey, durable) => for { exName <- name(session) exKey <- routingKey(session) } withChannel { channel => channel.exchangeDeclare(exName, "direct", durable || protocolDurable) around(channel.basicPublish(exName, exKey, message.amqpProperties, message.payload)) } case AmqpQueueExchange(name, durable) => name(session).foreach(qName => withChannel { channel => channel.queueDeclare(qName, durable || protocolDurable, false, false, Map.empty[String, Object].asJava) around(channel.basicPublish("", qName, message.amqpProperties, message.payload)) }) } } override protected val pool: AmqpConnectionPool = components.connectionPool }