Browse Source

readded Fortunes test (now working), and associated re-refactoring to split out controllers again.

David Denton 8 years ago
parent
commit
7e49166480

+ 3 - 0
frameworks/Scala/fintrospect/Dockerfile

@@ -0,0 +1,3 @@
+FROM mysql
+
+ADD create.sql /docker-entrypoint-initdb.d/

+ 3 - 1
frameworks/Scala/fintrospect/build.sbt

@@ -16,7 +16,9 @@ mainClass in(Compile, run) := Some("FintrospectBenchmarkServer")
 
 
 libraryDependencies ++= Seq(
 libraryDependencies ++= Seq(
   "io.fintrospect" %% "fintrospect-core" % "13.11.0",
   "io.fintrospect" %% "fintrospect-core" % "13.11.0",
-  "io.fintrospect" %% "fintrospect-json4s" % "13.11.0"
+  "io.fintrospect" %% "fintrospect-json4s" % "13.11.0",
+  "io.fintrospect" %% "fintrospect-mustache" % "13.11.0",
+  "com.twitter" %% "finagle-mysql" % "6.38.0"
   )
   )
 
 
 resolvers += Resolver.sonatypeRepo("snapshots")
 resolvers += Resolver.sonatypeRepo("snapshots")

+ 11 - 0
frameworks/Scala/fintrospect/run_db.sh

@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+cp ../../../config/create.sql .
+
+docker build -t dbi .
+
+rm create.sql
+
+docker run --name db -d \
+  -e MYSQL_ROOT_PASSWORD=123 \
+  -p 3306:3306 dbi

+ 3 - 0
frameworks/Scala/fintrospect/source_code

@@ -1,2 +1,5 @@
 fintrospect/src/main/scala/
 fintrospect/src/main/scala/
+fintrospect/src/main/scala/Fortunes.scala
+fintrospect/src/main/scala/JsonHelloWorld.scala
+fintrospect/src/main/scala/PlainTextHelloWorld.scala
 fintrospect/src/main/scala/FintrospectBenchmarkServer.scala
 fintrospect/src/main/scala/FintrospectBenchmarkServer.scala

+ 14 - 25
frameworks/Scala/fintrospect/src/main/scala/FintrospectBenchmarkServer.scala

@@ -1,40 +1,29 @@
 import java.time.ZonedDateTime._
 import java.time.ZonedDateTime._
 import java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
 import java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
 
 
-import com.twitter.finagle.http.Method.Get
-import com.twitter.finagle.http.Request
-import com.twitter.finagle.http.Status._
 import com.twitter.finagle.http.path.Root
 import com.twitter.finagle.http.path.Root
+import com.twitter.finagle.http.{Request, Response}
 import com.twitter.finagle.stats.NullStatsReceiver
 import com.twitter.finagle.stats.NullStatsReceiver
 import com.twitter.finagle.tracing.NullTracer
 import com.twitter.finagle.tracing.NullTracer
-import com.twitter.finagle.{Http, Service}
-import com.twitter.io.Buf
+import com.twitter.finagle.{Filter, Http}
 import com.twitter.util.{Await, NullMonitor}
 import com.twitter.util.{Await, NullMonitor}
-import io.fintrospect.formats.Json4sJackson.JsonFormat._
-import io.fintrospect.{ModuleSpec, RouteSpec}
+import io.fintrospect.ModuleSpec
+import io.fintrospect.renderers.simplejson.SimpleJson
 
 
 object FintrospectBenchmarkServer extends App {
 object FintrospectBenchmarkServer extends App {
 
 
-  val preAllocatedHelloWorldText = Buf.Utf8("Hello, World!")
-
-  val plainTextHelloWorld = {
-    import io.fintrospect.formats.PlainText.ResponseBuilder.implicits._
-    Service.mk { r: Request =>
-      Ok(preAllocatedHelloWorldText)
-        .withHeaders("Server" -> "Example", "Date" -> RFC_1123_DATE_TIME.format(now()))
-    }
-  }
-
-  val jsonHelloWorld = {
-    import io.fintrospect.formats.Json4sJackson.ResponseBuilder.implicits._
-    Service.mk { r: Request => Ok(obj("message" -> string("Hello, World!")))
-      .withHeaders("Server" -> "Example", "Date" -> RFC_1123_DATE_TIME.format(now()))
-    }
+  val addServerAndDate = Filter.mk[Request, Response, Request, Response] { (req, svc) =>
+    svc(req).map(resp => {
+      resp.headerMap("Server") = "Example"
+      resp.headerMap("Date") = RFC_1123_DATE_TIME.format(now())
+      resp
+    })
   }
   }
 
 
-  val module = ModuleSpec(Root)
-    .withRoute(RouteSpec().at(Get) / "plaintext" bindTo plainTextHelloWorld)
-    .withRoute(RouteSpec().at(Get) / "json" bindTo jsonHelloWorld)
+  val module = ModuleSpec(Root, SimpleJson(), addServerAndDate)
+    .withRoute(JsonHelloWorld.route)
+    .withRoute(PlainTextHelloWorld.route)
+    .withRoute(Fortunes.route)
 
 
   Await.ready(
   Await.ready(
     Http.server
     Http.server

+ 52 - 0
frameworks/Scala/fintrospect/src/main/scala/Fortunes.scala

@@ -0,0 +1,52 @@
+import com.twitter.finagle.client.DefaultPool.Param
+import com.twitter.finagle.http.Method.Get
+import com.twitter.finagle.http.Request
+import com.twitter.finagle.mysql.{IntValue, Result, ResultSet, StringValue}
+import com.twitter.finagle.stats.NullStatsReceiver
+import com.twitter.finagle.tracing.NullTracer
+import com.twitter.finagle.{Mysql, Service}
+import com.twitter.util.Duration.fromSeconds
+import com.twitter.util.NullMonitor
+import io.fintrospect.RouteSpec
+import io.fintrospect.formats.Html
+import io.fintrospect.templating.MustacheTemplates.CachingClasspath
+import io.fintrospect.templating.{RenderView, View}
+
+case class Fortune(id: Int, message: String)
+
+case class FortunesList(items: Seq[Fortune]) extends View
+
+object Fortunes {
+  private val toFortunes: PartialFunction[Result, Seq[Fortune]] = {
+    case rs: ResultSet => rs.rows
+      .map(row => {
+        val IntValue(id) = row("id").get
+        val StringValue(message) = row("message").get
+        Fortune(id, message)
+      })
+    case _ => Seq.empty
+  }
+
+  private val dbClient = Mysql.client
+    .withCredentials("benchmarkdbuser", "benchmarkdbpass")
+    .withDatabase("hello_world")
+    .configured(Param(low = 0, high = 10, idleTime = fromSeconds(5 * 60), bufferSize = 0, maxWaiters = Int.MaxValue))
+    .withStatsReceiver(NullStatsReceiver)
+    .withMonitor(NullMonitor)
+    .withTracer(NullTracer)
+    .withMaxConcurrentPrepareStatements(256)
+    .newRichClient("localhost:3306")
+
+  private val statement = dbClient.prepare("SELECT * FROM fortune")
+
+  private val service = new RenderView(Html.ResponseBuilder, CachingClasspath()).andThen(
+    Service.mk {
+      r: Request =>
+        statement().map(toFortunes).map(f => {
+          val sortedFortunes = (Fortune(0, "Additional fortune added at request time.") +: f).sortBy(_.message)
+          FortunesList(sortedFortunes)
+        })
+    })
+
+  val route = RouteSpec().at(Get) / "fortunes" bindTo Fortunes.service
+}

+ 14 - 0
frameworks/Scala/fintrospect/src/main/scala/JsonHelloWorld.scala

@@ -0,0 +1,14 @@
+import com.twitter.finagle.Service
+import com.twitter.finagle.http.Method.Get
+import com.twitter.finagle.http.Request
+import com.twitter.finagle.http.Status.Ok
+import io.fintrospect.RouteSpec
+import io.fintrospect.formats.Json4sJackson.JsonFormat.{obj, string}
+import io.fintrospect.formats.Json4sJackson.ResponseBuilder.implicits._
+
+object JsonHelloWorld {
+
+  private val service = Service.mk { r: Request => Ok(obj("message" -> string("Hello, World!"))) }
+
+  val route = RouteSpec().at(Get) / "json" bindTo JsonHelloWorld.service
+}

+ 16 - 0
frameworks/Scala/fintrospect/src/main/scala/PlainTextHelloWorld.scala

@@ -0,0 +1,16 @@
+import com.twitter.finagle.Service
+import com.twitter.finagle.http.Method.Get
+import com.twitter.finagle.http.Request
+import com.twitter.finagle.http.Status.Ok
+import com.twitter.io.Buf
+import io.fintrospect.RouteSpec
+import io.fintrospect.formats.PlainText.ResponseBuilder.implicits._
+
+object PlainTextHelloWorld {
+
+  private val preallocatedMsgForPlainText = Buf.Utf8("Hello, World!")
+
+  private val service = Service.mk { r: Request => Ok(preallocatedMsgForPlainText) }
+
+  val route = RouteSpec().at(Get) / "plaintext" bindTo service
+}