项目作者: Logimethods

项目描述 :
A Gatling to NATS Connector
高级语言: Scala
项目地址: git://github.com/Logimethods/nats-connector-gatling.git
创建时间: 2016-05-24T13:53:42Z
项目社区:https://github.com/Logimethods/nats-connector-gatling

开源协议:MIT License

下载


NATS Gatling Connector

The NATS Gatling library provides a Gatling (an open-source load testing framework based on Scala, Akka and Netty) to NATS messaging system (a highly performant cloud native messaging system) Connector.

MIT License
Issues
wercker status
Scaladoc
Maven Central

Summary

Release Notes

Version 1.0.0

Version 0.4.0

  • Based on java-nats-streaming version 0.5.0
  • Based on Gatling 2.2.5

Version 0.3.0

  • Introduces the NatsMessage Trait:
    1. trait NatsMessage {
    2. def getSubject(): String
    3. def getPayload(): Array[Byte]
    4. }

    Version 0.2.0

  • Is based on Gatling version 2.2.2.
  • Requires JDK8

Version 0.1.0

Installation

Maven Central

Releases

To embed the NATS Gatling connector, add the following dependency to your project’s Scala build.sbt file.

  1. libraryDependencies += "com.logimethods" % "nats-connector-gatling_2.11" % "1.0.0"

If you don’t already have your build configured for using Maven releases from Sonatype / Nexus, you’ll also need to add the following repository.

  1. resolvers += "Sonatype OSS Release" at "https://oss.sonatype.org/content/groups/public/"

Snapshots

Snapshots are regularly uploaded to the Sonatype OSSRH (OSS Repository Hosting) using the same Maven coordinates.
If you are embedding the NATS Gatling connector, add the following dependency to your project’s build.sbt file.

  1. libraryDependencies += "com.logimethods" %% "nats-connector-gatling_2.11" % "1.0.0-SNAPSHOT"

If you don’t already have your build configured for using Maven snapshots, you’ll also need to add the following repository.

  1. resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"

Usage in Scala, from Gatling to NATS

Simple usage

  1. ...
  2. import com.logimethods.connector.gatling.to_nats._
  3. class NatsInjection extends Simulation {
  4. val properties = new Properties()
  5. properties.setProperty(io.nats.client.Constants.PROP_URL, "nats://localhost:4222")
  6. val natsProtocol = NatsProtocol(properties, "GatlingSubject")
  7. val natsScn = scenario("NATS call").exec(NatsBuilder("Message from Gatling!"))
  8. setUp(
  9. natsScn.inject(constantUsersPerSec(15) during (1 minute))
  10. ).protocols(natsProtocol)
  11. }

More complex usage

  1. import akka.actor.{ActorRef, Props}
  2. import io.gatling.core.Predef._
  3. import io.gatling.core.action.builder.ActionBuilder
  4. import io.gatling.core.config.{Protocol, Protocols}
  5. import scala.concurrent.duration._
  6. import java.util.Properties
  7. import io.nats.client.Constants.PROP_URL
  8. import com.logimethods.connector.gatling.to_nats._
  9. class NatsInjection extends Simulation {
  10. val properties = new Properties()
  11. // The URI of the NATS server is provided by an environment variable:
  12. // >export NATS_URI=nats://nats-main:4222
  13. println("System properties: " + System.getenv())
  14. val natsUrl = System.getenv("NATS_URI")
  15. properties.setProperty(io.nats.client.Constants.PROP_URL, natsUrl)
  16. // The NATS Subject is also provided by an environment variable:
  17. // >export GATLING.TO_NATS.SUBJECT=FROM_GATLING
  18. var subject = System.getenv("GATLING.TO_NATS.SUBJECT")
  19. if (subject == null) {
  20. println("No Subject has been defined through the 'GATLING.TO_NATS.SUBJECT' Environment Variable!!!")
  21. } else {
  22. println("Will emit messages to " + subject)
  23. val natsProtocol = NatsProtocol(properties, subject)
  24. // The messages sent to NATS will not be constant thanks to the ValueProvider.
  25. val natsScn = scenario("NATS call").exec(NatsBuilder(new ValueProvider()))
  26. setUp(
  27. natsScn.inject(constantUsersPerSec(15) during (1 minute))
  28. ).protocols(natsProtocol)
  29. }
  30. }
  31. /**
  32. * The ValueProvider will generate a loop of values: 100, 110, 120, 130, 140, 150, 100...
  33. */
  34. class ValueProvider {
  35. val incr = 10
  36. val basedValue = 100 -incr
  37. val maxIncr = 50
  38. var actualIncr = 0
  39. override def toString(): String = {
  40. actualIncr = (actualIncr % (maxIncr + incr)) + incr
  41. (basedValue + actualIncr).toString()
  42. }
  43. }

Usage in Scala, from Gatling to NATS STREAMING

  1. import scala.concurrent.duration._
  2. import java.util.Properties
  3. import io.nats.client.Constants.PROP_URL
  4. import akka.actor.{ActorRef, Props}
  5. import io.gatling.core.Predef._
  6. import io.gatling.core.action.builder.ActionBuilder
  7. import com.logimethods.connector.gatling.to_nats._
  8. class NatsStreamingInjection extends Simulation {
  9. val natsUrl = System.getenv("NATS_URI")
  10. val clusterID = System.getenv("NATS_CLUSTER_ID")
  11. var subject = System.getenv("GATLING_TO_NATS_SUBJECT")
  12. if (subject == null) {
  13. println("No Subject has been defined through the 'GATLING_TO_NATS_SUBJECT' Environment Variable!!!")
  14. } else {
  15. println("Will emit messages to " + subject)
  16. val natsProtocol = NatsStreamingProtocol(natsUrl, clusterID, subject)
  17. val natsScn = scenario("NATS call").exec(NatsStreamingBuilder(new ValueProvider()))
  18. setUp(
  19. natsScn.inject(constantUsersPerSec(15) during (1 minute))
  20. ).protocols(natsProtocol)
  21. }
  22. }

Complex NATS Messages

If you need to send NATS messages where the payload is different than String, or need to have non constant subjects, you have to provide NatsMessage Objects to the NatsBuilder.

  1. import com.logimethods.connector.gatling.to_nats.NatsMessage
  2. class MyMessage extends NatsMessage {
  3. def getSubject(): String = {
  4. return "MySubject"
  5. }
  6. def getPayload(): Array[Byte] = {
  7. val value: Float = ...
  8. var date:LocalDateTime = LocalDateTime.now()
  9. // https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html
  10. val buffer = ByteBuffer.allocate(8+4);
  11. buffer.putLong(date.atOffset(ZoneOffset.MIN).toEpochSecond())
  12. buffer.putFloat(value)
  13. return buffer.array()
  14. }
  15. }
  1. val natsScn = scenario("NATS call").exec(NatsBuilder(new MyMessage()))

Code Samples

License

(The MIT License)

Copyright (c) 2016 Logimethods.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.