Browse Source

Rework of http4k entry, bump to J11 etc.. (#4334)

* added ktor-cio module

* added ktor-cio module

* refactor, added module for ktorcio backend

* fix shadow for gradle 5

* jar names for archive

* tweak database to not use SSL

* adding async database version (apache only), remove db folder created in error

* add config for async db version

* remove sunhttp (development server) benchmark

* remove sunhttp (development server) benchmark

* fix dockerfiles to remove sunhttp and add apache-asyncdb

* fix name of main class

* fixed getting of columns, as the reactive result set gives lowercase only

* tidy database code

* fix updates call to update all rows

* sort fortunes

* readme updates for URIs

* readme

* adding the additional fortune
David Denton 6 years ago
parent
commit
5621775639
29 changed files with 346 additions and 145 deletions
  1. 14 5
      frameworks/Kotlin/http4k/README.md
  2. 15 0
      frameworks/Kotlin/http4k/apache-asyncdb/build.gradle
  3. 5 0
      frameworks/Kotlin/http4k/apache-asyncdb/src/main/kotlin/Http4kApacheAsyncDbServer.kt
  4. 9 1
      frameworks/Kotlin/http4k/apache/build.gradle
  5. 1 1
      frameworks/Kotlin/http4k/apache/src/main/kotlin/Http4kApacheServer.kt
  6. 23 2
      frameworks/Kotlin/http4k/benchmark_config.json
  7. 7 12
      frameworks/Kotlin/http4k/build.gradle
  8. 1 0
      frameworks/Kotlin/http4k/core/build.gradle
  9. 173 32
      frameworks/Kotlin/http4k/core/src/main/kotlin/Database.kt
  10. 2 10
      frameworks/Kotlin/http4k/core/src/main/kotlin/FortunesRoute.kt
  11. 1 1
      frameworks/Kotlin/http4k/core/src/main/kotlin/Http4kBenchmarkServer.kt
  12. 12 50
      frameworks/Kotlin/http4k/core/src/main/kotlin/WorldRoutes.kt
  13. 14 0
      frameworks/Kotlin/http4k/http4k-apache-asyncdb.dockerfile
  14. 3 2
      frameworks/Kotlin/http4k/http4k-apache.dockerfile
  15. 5 4
      frameworks/Kotlin/http4k/http4k-ktorcio.dockerfile
  16. 3 2
      frameworks/Kotlin/http4k/http4k-netty.dockerfile
  17. 3 2
      frameworks/Kotlin/http4k/http4k-undertow.dockerfile
  18. 3 2
      frameworks/Kotlin/http4k/http4k.dockerfile
  19. 9 1
      frameworks/Kotlin/http4k/jetty/build.gradle
  20. 1 1
      frameworks/Kotlin/http4k/jetty/src/main/kotlin/Http4kJettyServer.kt
  21. 15 0
      frameworks/Kotlin/http4k/ktorcio/build.gradle
  22. 5 0
      frameworks/Kotlin/http4k/ktorcio/src/main/kotlin/Http4kKtorCIOServer.kt
  23. 9 1
      frameworks/Kotlin/http4k/netty/build.gradle
  24. 1 1
      frameworks/Kotlin/http4k/netty/src/main/kotlin/Http4kNettyServer.kt
  25. 2 1
      frameworks/Kotlin/http4k/settings.gradle
  26. 0 6
      frameworks/Kotlin/http4k/sunhttp/build.gradle
  27. 0 6
      frameworks/Kotlin/http4k/sunhttp/src/main/kotlin/Http4kSunHttpServer.kt
  28. 9 1
      frameworks/Kotlin/http4k/undertow/build.gradle
  29. 1 1
      frameworks/Kotlin/http4k/undertow/src/main/kotlin/Http4kUndertowServer.kt

+ 14 - 5
frameworks/Kotlin/http4k/README.md

@@ -3,19 +3,28 @@
 ## Infrastructure Software Versions
 The tests were run with:
 
-* [Java Oracle 1.8.0_25](http://www.oracle.com/technetwork/java/javase)
+* JDK 11
 * [http4k](https://http4k.org)
 
 ## Test URLs
 
 - JSON Encoding: http://localhost:9000/json
+- Single query: http://localhost:9000/db
+- Multiple queries: http://localhost:9000/queries
+- Fortunes: http://localhost:9000/fortunes
+- Updates: http://localhost:9000/updates
 - Plaintext: http://localhost:9000/plaintext
 
+
 ## Supported backends
-- Jetty
+- Apache (w/ Postgres + Reactive PG clienta)
+- KtorCIO (w/ Postgres client)
+- Jetty (w/ Postgres client)
+- Netty (w/ Postgres client)
+- Undertow (w/ Postgres client)
 
-## How to run
+## How to run example
 ```bash
-gradle clean build jetty
-java -jar build/libs/http4k-standalone.jar
+gradle clean build jetty:shadowJar
+java -jar jetty/build/libs/http4k-jetty-benchmark.jar
 ```

+ 15 - 0
frameworks/Kotlin/http4k/apache-asyncdb/build.gradle

@@ -0,0 +1,15 @@
+dependencies {
+    compile project(":core")
+    compile "org.http4k:http4k-server-apache:$http4k_version"
+}
+
+apply plugin: 'application'
+mainClassName = "Http4kApacheAsyncDbServerKt"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+shadowJar {
+    baseName = "http4k-$project.name-benchmark"
+    classifier = null
+    version = null
+    mergeServiceFiles()
+}

+ 5 - 0
frameworks/Kotlin/http4k/apache-asyncdb/src/main/kotlin/Http4kApacheAsyncDbServer.kt

@@ -0,0 +1,5 @@
+import org.http4k.server.ApacheServer
+
+fun main(args: Array<String>) {
+    Http4kBenchmarkServer(ReactivePostgresDatabase("tfb-database")).start(ApacheServer(9000))
+}

+ 9 - 1
frameworks/Kotlin/http4k/apache/build.gradle

@@ -4,4 +4,12 @@ dependencies {
 }
 
 apply plugin: 'application'
-mainClassName = "Http4kApacheServerKt"
+mainClassName = "Http4kApacheServerKt"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+shadowJar {
+    baseName = "http4k-$project.name-benchmark"
+    classifier = null
+    version = null
+    mergeServiceFiles()
+}

+ 1 - 1
frameworks/Kotlin/http4k/apache/src/main/kotlin/Http4kApacheServer.kt

@@ -2,5 +2,5 @@
 import org.http4k.server.ApacheServer
 
 fun main(args: Array<String>) {
-    Http4kBenchmarkServer().start(ApacheServer(9000))
+    Http4kBenchmarkServer(PostgresDatabase("tfb-database")).start(ApacheServer(9000))
 }

+ 23 - 2
frameworks/Kotlin/http4k/benchmark_config.json

@@ -86,7 +86,7 @@
         "notes": "",
         "versus": "servlet"
       },
-      "sunhttp": {
+      "apache-asyncdb": {
         "orm": "Raw",
         "database_os": "Linux",
         "db_url": "/db",
@@ -101,11 +101,32 @@
         "classification": "Micro",
         "framework": "http4k",
         "language": "Kotlin",
-        "platform": "sun-http",
+        "platform": "apache-httpcore",
         "webserver": "None",
         "os": "Linux",
         "notes": "",
         "versus": "servlet"
+      },
+      "ktorcio": {
+        "orm": "Raw",
+        "database_os": "Linux",
+        "db_url": "/db",
+        "fortune_url": "/fortunes",
+        "query_url": "/queries?queries=",
+        "update_url": "/updates?queries=",
+        "database": "Postgres",
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 9000,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "framework": "http4k",
+        "language": "Kotlin",
+        "platform": "ktorcio",
+        "webserver": "None",
+        "os": "Linux",
+        "notes": "",
+        "versus": "ktor-cio"
       }
     }
   ]

+ 7 - 12
frameworks/Kotlin/http4k/build.gradle

@@ -1,6 +1,6 @@
 buildscript {
-    ext.kotlin_version = "1.2.50"
-    ext.http4k_version = "3.34.0"
+    ext.kotlin_version = "1.3.11"
+    ext.http4k_version = "3.106.0"
 
     repositories {
         mavenCentral()
@@ -21,7 +21,8 @@ allprojects {
     }
 
     apply plugin: "kotlin"
-    apply plugin: 'com.github.johnrengelman.shadow'
+
+    compileKotlin.kotlinOptions.jvmTarget = "1.8"
 
     sourceCompatibility = JavaVersion.VERSION_1_8
     targetCompatibility = JavaVersion.VERSION_1_8
@@ -29,16 +30,9 @@ allprojects {
     version = project.hasProperty('releaseVersion') ? project.releaseVersion : 'LOCAL'
     group = 'org.http4k'
 
-    shadowJar {
-        baseName = "http4k-${project.name}-benchmark"
-        classifier = null
-        version = null
-        mergeServiceFiles()
-    }
-
     compileTestKotlin {
         kotlinOptions {
-            languageVersion = "1.2"
+            languageVersion = "1.3"
         }
     }
 }
@@ -46,8 +40,9 @@ allprojects {
 dependencies {
     compile project(":core")
     compile project(":apache")
+    compile project(":apache-asyncdb")
     compile project(":jetty")
+    compile project(":ktorcio")
     compile project(":netty")
-    compile project(":sunhttp")
     compile project(":undertow")
 }

+ 1 - 0
frameworks/Kotlin/http4k/core/build.gradle

@@ -7,4 +7,5 @@ dependencies {
     compile "org.apache.commons:commons-lang3:3.7"
     compile "com.zaxxer:HikariCP:3.2.0"
     compile "org.postgresql:postgresql:42.2.2"
+    compile "io.reactiverse:reactive-pg-client:0.11.1"
 }

+ 173 - 32
frameworks/Kotlin/http4k/core/src/main/kotlin/Database.kt

@@ -1,52 +1,193 @@
+import com.fasterxml.jackson.databind.JsonNode
 import com.zaxxer.hikari.HikariConfig
 import com.zaxxer.hikari.HikariDataSource
+import io.reactiverse.pgclient.PgClient.pool
+import io.reactiverse.pgclient.PgPool
+import io.reactiverse.pgclient.PgPoolOptions
+import io.reactiverse.pgclient.Tuple
+import org.http4k.format.Jackson.number
+import org.http4k.format.Jackson.obj
 import java.sql.Connection
 import java.sql.PreparedStatement
 import java.sql.ResultSet
+import java.util.*
+import java.util.concurrent.CompletableFuture
 import javax.sql.DataSource
 
-open class Database(private val dataSource: DataSource) {
+
+interface Database {
+    fun findWorld(): JsonNode?
+    fun findWorlds(count: Int): List<JsonNode>
+    fun updateWorlds(count: Int): List<JsonNode>
+    fun fortunes(): List<Fortune>
+}
+
+class PostgresDatabase private constructor(private val dataSource: DataSource) : Database {
+
+    override fun findWorld() = withConnection {
+        findWorld(randomWorld())
+    }
+
+    override fun findWorlds(count: Int) = withConnection {
+        (1..count).mapNotNull { findWorld(randomWorld()) }
+    }
+
+    override fun updateWorlds(count: Int) = withConnection {
+        (1..count).mapNotNull {
+            val id = randomWorld()
+            updateWorld(id)
+            findWorld(id)
+        }
+    }
+
+    private fun Connection.updateWorld(id: Int) = withStatement("UPDATE world SET randomNumber = ? WHERE id = ?") {
+        setInt(1, randomWorld())
+        setInt(2, id)
+        executeUpdate()
+    }
+
+    override fun fortunes() = withConnection {
+        val original = withStatement("select * from fortune") { executeQuery().toResultsList { Fortune(getInt(1), getString(2)) } }
+        (original + Fortune(0, "Additional fortune added at request time.")).sortedBy { it.message }
+    }
 
     companion object {
         operator fun invoke(host: String): Database {
-            val postgresqlUrl = "jdbc:postgresql://$host:5432/hello_world?" +
-                    "jdbcCompliantTruncation=false&" +
-                    "elideSetAutoCommits=true&" +
-                    "useLocalSessionState=true&" +
-                    "cachePrepStmts=true&" +
-                    "cacheCallableStmts=true&" +
-                    "alwaysSendSetIsolation=false&" +
-                    "prepStmtCacheSize=4096&" +
-                    "cacheServerConfiguration=true&" +
-                    "prepStmtCacheSqlLimit=2048&" +
-                    "traceProtocol=false&" +
-                    "useUnbufferedInput=false&" +
-                    "useReadAheadInput=false&" +
-                    "maintainTimeStats=false&" +
-                    "useServerPrepStmts=true&" +
-                    "cacheRSMetadata=true"
-
-            val config = HikariConfig()
-            config.jdbcUrl = postgresqlUrl
-            config.maximumPoolSize = 100
-            config.username = "benchmarkdbuser"
-            config.password = "benchmarkdbpass"
-            return Database(HikariDataSource(config))
+            val dataSource = HikariConfig().run {
+                username = "benchmarkdbuser"
+                password = "benchmarkdbpass"
+                jdbcUrl = "jdbc:postgresql://$host:5432/hello_world?" +
+                        "useSSL=false&" +
+                        "jdbcCompliantTruncation=false&" +
+                        "elideSetAutoCommits=true&" +
+                        "useLocalSessionState=true&" +
+                        "cachePrepStmts=true&" +
+                        "cacheCallableStmts=true&" +
+                        "alwaysSendSetIsolation=false&" +
+                        "prepStmtCacheSize=4096&" +
+                        "cacheServerConfiguration=true&" +
+                        "prepStmtCacheSqlLimit=2048&" +
+                        "traceProtocol=false&" +
+                        "useUnbufferedInput=false&" +
+                        "useReadAheadInput=false&" +
+                        "maintainTimeStats=false&" +
+                        "useServerPrepStmts=true&" +
+                        "cacheRSMetadata=true"
+                maximumPoolSize = 100
+                HikariDataSource(this)
+            }
+            return PostgresDatabase(dataSource)
         }
     }
 
-    fun <T> withConnection(fn: Connection.() -> T): T = dataSource.connection.use(fn)
+    private fun <T> withConnection(fn: Connection.() -> T): T = dataSource.connection.use(fn)
+
+    private fun <T> Connection.withStatement(stmt: String, fn: PreparedStatement.() -> T): T = prepareStatement(stmt).use(fn)
+
+    private fun Connection.findWorld(id: Int) =
+            withStatement("SELECT * FROM world WHERE id = ?") {
+                setInt(1, id)
+                executeQuery().toResultsList {
+                    obj("id" to number(getInt("id")), "randomNumber" to number(getInt("randomNumber")))
+                }.firstOrNull()
+            }
 
-    fun <T> withStatement(stmt: String, fn: PreparedStatement.() -> T): T = withConnection { withStatement(stmt, fn) }
+    private fun <T> ResultSet.toResultsList(fn: ResultSet.() -> T): List<T> =
+            use {
+                mutableListOf<T>().apply {
+                    while (next()) {
+                        add(fn(this@toResultsList))
+                    }
+                }
+            }
 }
 
-fun <T> Connection.withStatement(stmt: String, fn: PreparedStatement.() -> T): T = prepareStatement(stmt).use(fn)
+class ReactivePostgresDatabase private constructor(private val client: PgPool, private val pool: PgPool) : Database {
+    companion object {
+        operator fun invoke(hostName: String): Database {
+            val options = PgPoolOptions().apply {
+                database = "hello_world"
+                host = hostName
+                port = 5432
+                user = "benchmarkdbuser"
+                password = "benchmarkdbpass"
+                maxSize = 64
+                cachePreparedStatements = true
+            }
+            return ReactivePostgresDatabase(
+                    pool(PgPoolOptions(options).apply { maxSize = 1 }),
+                    pool(PgPoolOptions(options).apply { maxSize = 4 }))
+        }
+    }
+
+    override fun findWorld(): JsonNode? {
+        val deferred = CompletableFuture<JsonNode?>()
+        client.preparedQuery("SELECT id, randomnumber from WORLD where id=$1", Tuple.of(randomWorld())) {
+            with(it.result().first()) {
+                deferred.complete(obj("id" to number(getInteger(0)), "randomNumber" to number(getInteger(1))))
+            }
+        }
+        return deferred.get()
+    }
+
+    override fun findWorlds(count: Int): List<JsonNode> {
+        val deferred = CompletableFuture<List<JsonNode>>()
+        val worlds = mutableListOf<JsonNode>()
 
-fun <T> ResultSet.toList(fn: ResultSet.() -> T): List<T> =
-        use {
-            mutableListOf<T>().apply {
-                while (next()) {
-                    add(fn(this@toList))
+        (1..count).forEach {
+            client.preparedQuery("SELECT id, randomnumber from WORLD where id=$1", Tuple.of(randomWorld())) {
+                with(it.result().first()) {
+                    worlds.add(obj("id" to number(getInteger(0)), "randomNumber" to number(getInteger(1))))
                 }
+                if (worlds.size == count) deferred.complete(worlds)
             }
         }
+
+        return deferred.get()
+    }
+
+    override fun updateWorlds(count: Int): List<JsonNode> {
+        val deferred = CompletableFuture<List<JsonNode>>()
+        val worlds = mutableListOf<Tuple>()
+        pool.getConnection { r ->
+            val conn = r.result()
+            (1..count).forEach {
+                conn.preparedQuery("SELECT id from WORLD where id=$1", Tuple.of(randomWorld())) { ar ->
+                    with(ar.result().first()) {
+                        worlds.add(Tuple.of(getInteger(0), randomWorld()))
+
+                        if(worlds.size == count) {
+                            conn.preparedBatch("UPDATE world SET randomnumber=$1 WHERE id=$2", worlds) {
+                                conn.close()
+                                deferred.complete(worlds.map {
+                                    obj("id" to number(it.getInteger(0)), "randomNumber" to number(it.getInteger(1)))
+                                })
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return deferred.get()
+    }
+
+    override fun fortunes(): List<Fortune> {
+        val deferred = CompletableFuture<List<Fortune>>()
+        val fortunes = mutableListOf<Fortune>()
+
+        client.preparedQuery("SELECT id, message from FORTUNE") {
+            with(it.result().iterator()) {
+                while (hasNext()) {
+                    with(next()) {
+                        fortunes.add(Fortune(getInteger(0), getString(1)))
+                    }
+                }
+                deferred.complete(fortunes + Fortune(0, "Additional fortune added at request time."))
+            }
+        }
+
+        return deferred.get().sortedBy { it.message }
+    }
+}
+
+private fun randomWorld() = Random().nextInt(9999) + 1

+ 2 - 10
frameworks/Kotlin/http4k/core/src/main/kotlin/FortunesRoute.kt

@@ -14,17 +14,9 @@ data class Fortune(val id: Int, val message: String)
 data class FortunesList(val items: List<Fortune>) : ViewModel
 
 object FortunesRoute {
-
     private val viewBody = Body.view(PebbleTemplates().CachingClasspath(), TEXT_HTML)
 
-    operator fun invoke(database: Database) = "/fortunes" bind GET to {
-        val items = database.withStatement("select * from fortune") {
-            executeQuery().toList {
-                Fortune(getInt(1), getString(2))
-            }
-        }
-            .plus(Fortune(0, "Additional fortune added at request time."))
-            .sortedBy { it.message }
-        Response(OK).with(viewBody of FortunesList(items))
+    operator fun invoke(db: Database) = "/fortunes" bind GET to {
+        Response(OK).with(viewBody of FortunesList(db.fortunes()))
     }
 }

+ 1 - 1
frameworks/Kotlin/http4k/core/src/main/kotlin/Http4kBenchmarkServer.kt

@@ -22,7 +22,7 @@ object Http4kBenchmarkServer {
         }
     }
 
-    operator fun invoke(addDateHeader: Boolean = true, database: Database = Database("tfb-database")) =
+    operator fun invoke(database: Database, addDateHeader: Boolean = true) =
             headers(addDateHeader).then(
                     routes(
                             JsonRoute(),

+ 12 - 50
frameworks/Kotlin/http4k/core/src/main/kotlin/WorldRoutes.kt

@@ -1,5 +1,3 @@
-
-import com.fasterxml.jackson.databind.JsonNode
 import org.http4k.core.Body
 import org.http4k.core.Method.GET
 import org.http4k.core.Response
@@ -8,67 +6,31 @@ import org.http4k.core.Status.Companion.OK
 import org.http4k.core.with
 import org.http4k.format.Jackson.array
 import org.http4k.format.Jackson.json
-import org.http4k.format.Jackson.number
-import org.http4k.format.Jackson.obj
 import org.http4k.lens.Query
 import org.http4k.routing.bind
 import java.lang.Math.max
 import java.lang.Math.min
-import java.sql.Connection
-import java.util.Random
-
 
 object WorldRoutes {
-
     private val jsonBody = Body.json().toLens()
 
-    private val numberOfQueries = Query
-        .map {
-            try {
-                min(max(it.toInt(), 1), 500)
-            } catch (e: Exception) {
-                1
-            }
+    private val numberOfQueries = Query.map {
+        try {
+            min(max(it.toInt(), 1), 500)
+        } catch (e: Exception) {
+            1
         }
-        .defaulted("queries", 1)
-
-    fun queryRoute(database: Database) = "/db" bind GET to {
-        database.withConnection {
-            findWorld(randomWorld())
-        }?.let { Response(OK).with(jsonBody of it) } ?: Response(NOT_FOUND)
-    }
+    }.defaulted("queries", 1)
 
-    fun multipleRoute(database: Database) = "/queries" bind GET to {
-        val worlds = database.withConnection {
-            (1..numberOfQueries(it)).mapNotNull { findWorld(randomWorld()) }
-        }
-        Response(OK).with(jsonBody of array(worlds))
+    fun queryRoute(db: Database) = "/db" bind GET to {
+        db.findWorld()?.let { Response(OK).with(jsonBody of it) } ?: Response(NOT_FOUND)
     }
 
-    fun updateRoute(database: Database) = "/updates" bind GET to {
-        val worlds = database.withConnection {
-            (1..numberOfQueries(it)).mapNotNull {
-                val id = randomWorld()
-                updateWorld(id)
-                findWorld(id)
-            }
-        }
-        Response(OK).with(jsonBody of array(worlds))
+    fun multipleRoute(db: Database) = "/queries" bind GET to {
+        Response(OK).with(jsonBody of array(db.findWorlds(numberOfQueries(it))))
     }
 
-    private fun Connection.findWorld(id: Int): JsonNode? =
-        withStatement("SELECT * FROM world WHERE id = ?") {
-            setInt(1, id)
-            executeQuery().toList {
-                obj("id" to number(getInt("id")), "randomNumber" to number(getInt("randomNumber")))
-            }.firstOrNull()
-        }
-
-    private fun Connection.updateWorld(id: Int) = withStatement("UPDATE world SET randomNumber = ? WHERE id = ?") {
-        setInt(1, randomWorld())
-        setInt(2, id)
-        executeUpdate()
+    fun updateRoute(db: Database) = "/updates" bind GET to {
+        Response(OK).with(jsonBody of array(db.updateWorlds(numberOfQueries(it))))
     }
-
-    private fun randomWorld() = Random().nextInt(9999) + 1
 }

+ 14 - 0
frameworks/Kotlin/http4k/http4k-apache-asyncdb.dockerfile

@@ -0,0 +1,14 @@
+FROM gradle:5.1.0-jdk11
+USER root
+WORKDIR /http4k
+COPY build.gradle build.gradle
+COPY settings.gradle settings.gradle
+COPY apache apache
+COPY apache-asyncdb apache-asyncdb
+COPY core core
+COPY jetty jetty
+COPY ktorcio ktorcio
+COPY netty netty
+COPY undertow undertow
+RUN gradle --quiet build apache-asyncdb:shadowJar
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-XX:+AlwaysPreTouch", "-jar", "apache-asyncdb/build/libs/http4k-apache-asyncdb-benchmark.jar"]

+ 3 - 2
frameworks/Kotlin/http4k/http4k-apache.dockerfile

@@ -1,13 +1,14 @@
-FROM gradle:4.7.0-jdk10
+FROM gradle:5.1.0-jdk11
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle
 COPY settings.gradle settings.gradle
 COPY apache apache
+COPY apache-asyncdb apache-asyncdb
 COPY core core
 COPY jetty jetty
+COPY ktorcio ktorcio
 COPY netty netty
-COPY sunhttp sunhttp
 COPY undertow undertow
 RUN gradle --quiet build apache:shadowJar
 CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-XX:+AlwaysPreTouch", "-jar", "apache/build/libs/http4k-apache-benchmark.jar"]

+ 5 - 4
frameworks/Kotlin/http4k/http4k-sunhttp.dockerfile → frameworks/Kotlin/http4k/http4k-ktorcio.dockerfile

@@ -1,13 +1,14 @@
-FROM gradle:4.7.0-jdk10
+FROM gradle:5.1.0-jdk11
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle
 COPY settings.gradle settings.gradle
 COPY apache apache
+COPY apache-asyncdb apache-asyncdb
 COPY core core
 COPY jetty jetty
+COPY ktorcio ktorcio
 COPY netty netty
-COPY sunhttp sunhttp
 COPY undertow undertow
-RUN gradle --quiet build sunhttp:shadowJar
-CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-XX:+AlwaysPreTouch", "-jar", "sunhttp/build/libs/http4k-sunhttp-benchmark.jar"]
+RUN gradle --quiet build ktorcio:shadowJar
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-XX:+AlwaysPreTouch", "-jar", "ktorcio/build/libs/http4k-ktorcio-benchmark.jar"]

+ 3 - 2
frameworks/Kotlin/http4k/http4k-netty.dockerfile

@@ -1,13 +1,14 @@
-FROM gradle:4.7.0-jdk10
+FROM gradle:5.1.0-jdk11
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle
 COPY settings.gradle settings.gradle
 COPY apache apache
+COPY apache-asyncdb apache-asyncdb
 COPY core core
 COPY jetty jetty
+COPY ktorcio ktorcio
 COPY netty netty
-COPY sunhttp sunhttp
 COPY undertow undertow
 RUN gradle --quiet build netty:shadowJar
 CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-XX:+AlwaysPreTouch", "-jar", "netty/build/libs/http4k-netty-benchmark.jar"]

+ 3 - 2
frameworks/Kotlin/http4k/http4k-undertow.dockerfile

@@ -1,13 +1,14 @@
-FROM gradle:4.7.0-jdk10
+FROM gradle:5.1.0-jdk11
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle
 COPY settings.gradle settings.gradle
 COPY apache apache
+COPY apache-asyncdb apache-asyncdb
 COPY core core
 COPY jetty jetty
+COPY ktorcio ktorcio
 COPY netty netty
-COPY sunhttp sunhttp
 COPY undertow undertow
 RUN gradle --quiet build undertow:shadowJar
 CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-XX:+AlwaysPreTouch", "-jar", "undertow/build/libs/http4k-undertow-benchmark.jar"]

+ 3 - 2
frameworks/Kotlin/http4k/http4k.dockerfile

@@ -1,13 +1,14 @@
-FROM gradle:4.7.0-jdk10
+FROM gradle:5.1.0-jdk11
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle
 COPY settings.gradle settings.gradle
 COPY apache apache
+COPY apache-asyncdb apache-asyncdb
 COPY core core
 COPY jetty jetty
+COPY ktorcio ktorcio
 COPY netty netty
-COPY sunhttp sunhttp
 COPY undertow undertow
 RUN gradle --quiet build jetty:shadowJar
 CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-XX:+AlwaysPreTouch", "-jar", "jetty/build/libs/http4k-jetty-benchmark.jar"]

+ 9 - 1
frameworks/Kotlin/http4k/jetty/build.gradle

@@ -4,4 +4,12 @@ dependencies {
 }
 
 apply plugin: 'application'
-mainClassName = "Http4kJettyServerKt"
+mainClassName = "Http4kJettyServerKt"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+shadowJar {
+    baseName = "http4k-$project.name-benchmark"
+    classifier = null
+    version = null
+    mergeServiceFiles()
+}

+ 1 - 1
frameworks/Kotlin/http4k/jetty/src/main/kotlin/Http4kJettyServer.kt

@@ -2,5 +2,5 @@
 import org.http4k.server.Jetty
 
 fun main(args: Array<String>) {
-    Http4kBenchmarkServer(false).start(Jetty(9000))
+    Http4kBenchmarkServer(PostgresDatabase("tfb-database"), false).start(Jetty(9000))
 }

+ 15 - 0
frameworks/Kotlin/http4k/ktorcio/build.gradle

@@ -0,0 +1,15 @@
+dependencies {
+    compile project(":core")
+    compile "org.http4k:http4k-server-ktorcio:$http4k_version"
+}
+
+apply plugin: 'application'
+mainClassName = "Http4kKtorCIOServerKt"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+shadowJar {
+    baseName = "http4k-$project.name-benchmark"
+    classifier = null
+    version = null
+    mergeServiceFiles()
+}

+ 5 - 0
frameworks/Kotlin/http4k/ktorcio/src/main/kotlin/Http4kKtorCIOServer.kt

@@ -0,0 +1,5 @@
+import org.http4k.server.KtorCIO
+
+fun main(args: Array<String>) {
+    Http4kBenchmarkServer(PostgresDatabase("tfb-database")).start(KtorCIO(9000))
+}

+ 9 - 1
frameworks/Kotlin/http4k/netty/build.gradle

@@ -4,4 +4,12 @@ dependencies {
 }
 
 apply plugin: 'application'
-mainClassName = "Http4kNettyServerKt"
+mainClassName = "Http4kNettyServerKt"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+shadowJar {
+    baseName = "http4k-$project.name-benchmark"
+    classifier = null
+    version = null
+    mergeServiceFiles()
+}

+ 1 - 1
frameworks/Kotlin/http4k/netty/src/main/kotlin/Http4kNettyServer.kt

@@ -2,5 +2,5 @@
 import org.http4k.server.Netty
 
 fun main(args: Array<String>) {
-    Http4kBenchmarkServer().start(Netty(9000))
+    Http4kBenchmarkServer(PostgresDatabase("tfb-database")).start(Netty(9000))
 }

+ 2 - 1
frameworks/Kotlin/http4k/settings.gradle

@@ -1,7 +1,8 @@
 rootProject.name = 'http4k-benchmark'
 include 'core'
 include 'apache'
+include 'apache-asyncdb'
 include 'jetty'
+include 'ktorcio'
 include 'netty'
-include 'sunhttp'
 include 'undertow'

+ 0 - 6
frameworks/Kotlin/http4k/sunhttp/build.gradle

@@ -1,6 +0,0 @@
-dependencies {
-    compile project(":core")
-}
-
-apply plugin: 'application'
-mainClassName = "Http4kSunHttpServerKt"

+ 0 - 6
frameworks/Kotlin/http4k/sunhttp/src/main/kotlin/Http4kSunHttpServer.kt

@@ -1,6 +0,0 @@
-
-import org.http4k.server.SunHttp
-
-fun main(args: Array<String>) {
-    Http4kBenchmarkServer().start(SunHttp(9000))
-}

+ 9 - 1
frameworks/Kotlin/http4k/undertow/build.gradle

@@ -4,4 +4,12 @@ dependencies {
 }
 
 apply plugin: 'application'
-mainClassName = "Http4kUndertowServerKt"
+mainClassName = "Http4kUndertowServerKt"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+shadowJar {
+    baseName = "http4k-$project.name-benchmark"
+    classifier = null
+    version = null
+    mergeServiceFiles()
+}

+ 1 - 1
frameworks/Kotlin/http4k/undertow/src/main/kotlin/Http4kUndertowServer.kt

@@ -2,5 +2,5 @@
 import org.http4k.server.Undertow
 
 fun main(args: Array<String>) {
-    Http4kBenchmarkServer().start(Undertow(9000))
+    Http4kBenchmarkServer(PostgresDatabase("tfb-database")).start(Undertow(9000))
 }