Posts by Tammo Sminia

Throttling in Akka and Spray

Posted on by  
Tammo Sminia

When you want to limit the amount of messages an actor gets, you can use the throttler in akka-contrib. This will let you limit the max transactions per second(tps). It will queue up the surplus. Here I'll describe another way. I'll reject all the surplus messages. This has the advantage that the requester knows it's sending too much and can act on that. Both methods have their advantages. And both have limits, since they still require resources to queue or reject the messages. In Akka we can create an Actor that sends messages through to the target actor, or rejects them when it exceeds the specified tps.

object ThrottleActor {
  object OneSecondLater
  object Accepted
  object ExceededMaxTps
}
import ThrottleActor._

class ThrottleActor (target: ActorRef, maxTps: Int) extends Actor with ActorLogging {
  implicit val executionContext: ExecutionContext = context.dispatcher
  context.system.scheduler.schedule(1.second, 1.second, self, OneSecondLater)

  var messagesThisSecond: Int = 0

  def receive = {
    case OneSecondLater =>
      log.info(s"OneSecondLater ${DateTime.now} $messagesThisSecond requests.")
      messagesThisSecond = 0
    case message if messagesThisSecond >= maxTps =>
      sender ! ExceededMaxTps
      messagesThisSecond += 1
      log.info(s"ExceededMaxTps ${DateTime.now} $messagesThisSecond requests.")
    case message =>
      sender ! Accepted
      target ! message
      messagesThisSecond += 1
  }
}

Continue reading →

Iterating over a Map in Scala

Posted on by  
Tammo Sminia

Iterating over a map is slightly more complex than over other collections, because a Map is the combination of 2 collections. The keys and the values.

val m: Map[Int, String] = Map(1 -> "a", 2 -> "b")

m.keys    // = Iterable[Int] = Set(1, 2)
m.values  // = Iterable[String] = MapLike("a", "b")

Continue reading →

Chaining Options

Posted on by  
Tammo Sminia

When we have multiple Options and only want to do something when they're all set. In this example we have a property file with multiple configurations for one thing. A host and a port, we only want to use them if they're both set.

//The individual properties
val stubHost: Option[String] = Some("host")
val stubPort: Option[Int] = Some(8090)

//The case class I'll turn them into
case class StubConfig(host: String, port: Int)

Continue reading →

JSON parsing in Scala

Posted on by  
Tammo Sminia

We can use the Spray JSON parser for uses other than a REST API. We add spray-json to our dependencies. Our build.gradle:

apply plugin: 'scala'
version = '1.0'
repositories {
    mavenCentral()
}
dependencies {
    compile group: 'io.spray', name: 'spray-json_2.11', version: '1.3.1'
}

Continue reading →

Keystore without a password

Posted on by  
Tammo Sminia

Both the JVM and keytool have problems dealing with keystores without a password. If you try to get a listing of the keystore it will think you didn't provide a password and output falsehoods:

$ keytool -list -storetype pkcs12 -keystore keystoreWithoutPassword.p12
Enter keystore password:

*****************  WARNING WARNING WARNING  *****************
* The integrity of the information stored in your keystore  *
* has NOT been verified!  In order to verify its integrity, *
* you must provide your keystore password.                  *
*****************  WARNING WARNING WARNING  *****************

Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

tammo, Oct 14, 2015, SecretKeyEntry,

Continue reading →

Load testing our robots API with Gatling

Posted on by  
Tammo Sminia

In a previous blog post we made an API with spray. Now we're going to load test it. For this, we will use http://gatling.io/#/. In a scala class we can write exactly what and how we want to run the test. In this test, we will do a post to our API and create a new robot called C3PO. We will do this 1000 times per second and keep doing this for 10 seconds. For a total of 10000 C3POs! RobotsLoadTest.scala:

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class RobotsLoadTest extends Simulation {
    val baseUrl = "http://localhost:8080" //We need to have our API running here

    val httpProtocol = http
        .baseURL(baseUrl)
        .inferHtmlResources()
        .acceptEncodingHeader("gzip,deflate")
        .contentTypeHeader("application/json")
        .userAgentHeader("Apache-HttpClient/4.1.1 (java 1.5)")

    val s = scenario("Simulation")
        .exec(http("request_0")
        .post("/robots")
        .body(StringBody("""{
                        |  "name": "C3PO",
                        |  "amountOfArms": 2
                        |}""".stripMargin))
        )

    setUp(s.inject(constantUsersPerSec(1000) during(10 seconds))).protocols(httpProtocol)
}

Continue reading →

Options with flatMap

Posted on by  
Tammo Sminia

Suppose I have a List of things on which I want to do something that may fail. In this example I have a List of Strings that I want to turn into a List of Integers.

val strings = List("1", "bla", "4")

Continue reading →

Building a REST client with Spray

Posted on by  
Tammo Sminia

In a previous blog I wrote how to make an API. See here.
Now we'll make a client to use that API. This can be done with spray-client. First we add dependencies for spray-client and spray-json:

apply plugin: 'scala'

version = '1.0'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.6'
    compile group: 'com.typesafe.akka', name: 'akka-actor_2.11', version: '2.3.9'
    compile group: 'com.typesafe.akka', name: 'akka-remote_2.11', version: '2.3.9'
    testCompile group: 'org.scalatest', name: 'scalatest_2.11', version: '2.2.4'
    compile group: 'io.spray', name: 'spray-http_2.11', version: '1.3.3'
    compile group: 'io.spray', name: 'spray-httpx_2.11', version: '1.3.3'
    compile group: 'io.spray', name: 'spray-json_2.11', version: '1.3.1'
    compile group: 'io.spray', name: 'spray-client_2.11', version: '1.3.3'
}

Continue reading →

Validating input in Spray

Posted on by  
Tammo Sminia

In Spray, you get a lot of input validations for free. If you have a model like this:

object RobotProtocol extends DefaultJsonProtocol {
  case class Robot(name: String, amountOfArms: Int)
  implicit val RobotFormat = jsonFormat2(Robot)
}

Continue reading →

Time libraries in Scala

Posted on by  
Tammo Sminia

Scala has no default way to deal with dates and times. We have a few options. java.util.Date and java.util.Calendar These come included with java, so they may do if you don't need to do much and don't want to add any dependencies. But they're horrible and it's best not to use them. Joda-Time http://www.joda.org/joda-time/ The de facto standard date and time library for Java. nscala-time https://github.com/nscala-time/nscala-time A thin scala layer around Joda-Time. This adds some implicit conversions to make it easier to use, like the + and < operators.

import com.github.nscala_time.time.Imports._
DateTime.now + 2.months // returns org.joda.time.DateTime

Continue reading →

Alternating between Spray-servlet and Spray-can

Posted on by  
Tammo Sminia

On a server you may want to deploy your application as a war. How to build a war with spray-servlet Locally it's easiest to run without an application server. We include both the spray-servlet and spray-can dependencies:

name := "sprayApiExample"

version := "1.0"

scalaVersion := "2.11.6"

libraryDependencies ++= {
  val akkaV = "2.3.9"
  val sprayV = "1.3.3"
  Seq(
    "io.spray"            %%  "spray-can"     % sprayV,
    "io.spray"            %%  "spray-servlet" % sprayV,
    "io.spray"            %%  "spray-routing" % sprayV,
    "io.spray"            %%  "spray-json"    % "1.3.1", //has not been updated yet
    "com.typesafe.akka"   %%  "akka-actor"    % akkaV
  )
}

//This adds tomcat dependencies, you can also use jetty()
tomcat()

Continue reading →

Building a war with spray-servlet

Posted on by  
Tammo Sminia

We will use spray-servlet to build a war file of our API. So we can run it in a java app server. I assume we already have a working REST API. We will need a web.xml, under src/main/webapp/WEB-INF/:

 spray.servlet.Initializer 

    SprayConnectorServlet
        spray.servlet.Servlet30ConnectorServlet
        true 

    SprayConnectorServlet
        /* 

Continue reading →

shadow-left