Browse Source

Upgrades to http4k, and another Loom server :) (#7722)

* upgrade http4k, convert to using rocker instead of pebble

* upgrade us pgclient in apache, jetty and sun

* add sunhttploom server option

* remove templating from GraalVM as not compatible with templating framework for now)
David Denton 2 years ago
parent
commit
dd043f7890

+ 1 - 0
frameworks/Kotlin/http4k/.gitignore

@@ -4,6 +4,7 @@ docker
 .idea
 .gradle
 gradle/*
+**/generated/**
 gradle.properties
 /gradlew
 /gradlew.bat

+ 1 - 1
frameworks/Kotlin/http4k/apache4/build.gradle

@@ -1,5 +1,5 @@
 dependencies {
-    api(project(":core-jdbc"))
+    api(project(":core-pgclient"))
     api("org.http4k:http4k-server-apache4:$http4k_version")
 }
 

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

@@ -22,7 +22,30 @@
         "webserver": "None",
         "os": "Linux",
         "notes": "https://http4k.org",
-        "display_name": "http4k-core",
+        "display_name": "http4k-sunhttp",
+        "versus": "servlet"
+      },
+      "sunhttploom": {
+        "orm": "Raw",
+        "database_os": "Linux",
+        "cached_query_url": "/cached?queries=",
+        "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": "sunhttp",
+        "webserver": "None",
+        "os": "Linux",
+        "notes": "https://http4k.org",
+        "display_name": "http4k-sunhttploom",
         "versus": "servlet"
       },
       "apache": {
@@ -74,7 +97,6 @@
         "database_os": "Linux",
         "cached_query_url": "/cached?queries=",
         "db_url": "/db",
-        "fortune_url": "/fortunes",
         "query_url": "/queries?queries=",
         "update_url": "/updates?queries=",
         "database": "Postgres",

+ 3 - 5
frameworks/Kotlin/http4k/build.gradle

@@ -1,12 +1,10 @@
 buildscript {
-    ext.kotlin_version = "1.7.20"
-    ext.http4k_version = "4.33.3.0"
+    ext.kotlin_version = "1.7.21"
+    ext.http4k_version = "4.34.1.0"
 
     repositories {
         mavenCentral()
-        maven {
-            url "https://plugins.gradle.org/m2/"
-        }
+        gradlePluginPortal()
     }
 
     dependencies {

+ 18 - 1
frameworks/Kotlin/http4k/config.toml

@@ -73,6 +73,24 @@ platform = "sunhttp"
 webserver = "None"
 versus = "servlet"
 
+[sunhttploom]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+urls.cached_query = "/cached?queries="
+approach = "Realistic"
+classification = "Micro"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "sunhttp"
+webserver = "None"
+versus = "servlet"
+
 [apache4]
 urls.plaintext = "/plaintext"
 urls.json = "/json"
@@ -169,7 +187,6 @@ urls.json = "/json"
 urls.db = "/db"
 urls.query = "/queries?queries="
 urls.update = "/updates?queries="
-urls.fortune = "/fortunes"
 urls.cached_query = "/cached?queries="
 approach = "Realistic"
 classification = "Micro"

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

@@ -1,9 +1,29 @@
+plugins {
+    id 'nu.studer.rocker' version '3.0.4'
+    id 'java'
+}
+
 dependencies {
     api("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version")
     api("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version")
     api("org.http4k:http4k-core:$http4k_version")
     api("org.http4k:http4k-format-argo:$http4k_version")
-    api("org.http4k:http4k-template-pebble:$http4k_version")
+    api("org.http4k:http4k-template-rocker:$http4k_version")
     api("org.apache.commons:commons-lang3:3.12.0")
     api("org.cache2k:cache2k-core:2.6.1.Final")
+
+    compileOnly("com.fizzed:rocker-compiler:1.3.0")
+}
+
+rocker {
+    version.set("1.3.0")
+    configurations {
+        create("main") {
+            templateDir.set(file("src/main/resources"))
+            outputDir.set(file("src/main/generated/kotlin"))
+            classDir.set(file("out/main/classes"))
+            extendsModelClass.set("org.http4k.template.RockerViewModel")
+        }
+    }
 }
+

+ 3 - 6
frameworks/Kotlin/http4k/core/src/main/kotlin/FortunesRoute.kt

@@ -5,18 +5,15 @@ import org.http4k.core.Response
 import org.http4k.core.Status.Companion.OK
 import org.http4k.core.with
 import org.http4k.routing.bind
-import org.http4k.template.PebbleTemplates
-import org.http4k.template.ViewModel
+import org.http4k.template.RockerTemplates
 import org.http4k.template.viewModel
 
 data class Fortune(val id: Int, val message: String)
 
-data class FortunesList(val items: List<Fortune>) : ViewModel
-
 object FortunesRoute {
-    private val viewBody = Body.viewModel(PebbleTemplates().CachingClasspath(), TEXT_HTML).toLens()
+    private val viewBody = Body.viewModel(RockerTemplates().Caching(), TEXT_HTML).toLens()
 
     operator fun invoke(db: Database) = "/fortunes" bind GET to {
-        Response(OK).with(viewBody of FortunesList(db.fortunes()))
+        Response(OK).with(viewBody of FortunesList().items(db.fortunes()))
     }
 }

+ 0 - 1
frameworks/Kotlin/http4k/core/src/main/resources/FortunesList.peb

@@ -1 +0,0 @@
-<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>{% for item in model.items %}<tr><td>{{item.id}}</td><td>{{item.message}}</td></tr>{% endfor %}</table></body></html>

+ 2 - 0
frameworks/Kotlin/http4k/core/src/main/resources/FortunesList.rocker.html

@@ -0,0 +1,2 @@
+@args (Iterable<Fortune> items)
+<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>@for ((item) : items) {<tr><td>@item.getId()</td><td>@item.getMessage()</td></tr>}</table></body></html>

+ 49 - 0
frameworks/Kotlin/http4k/http4k-sunhttploom.dockerfile

@@ -0,0 +1,49 @@
+# START: WE ARE BUILDING A CUSTOM GRADLE IMAGE BECAUSE JAVA 19 IS NOT CURRENTLY SUPPORTED IN PUBLIC IMAGES
+FROM eclipse-temurin:19-jdk-alpine as gradle
+
+CMD ["gradle"]
+
+ENV GRADLE_HOME /opt/gradle
+
+RUN set -o errexit -o nounset \
+    && echo "Adding gradle user and group" \
+    && addgroup --system --gid 1000 gradle \
+    && adduser --system --ingroup gradle --uid 1000 --shell /bin/ash gradle \
+    && mkdir /home/gradle/.gradle \
+    && chown -R gradle:gradle /home/gradle \
+    \
+    && echo "Symlinking root Gradle cache to gradle Gradle cache" \
+    && ln -s /home/gradle/.gradle /root/.gradle
+
+VOLUME /home/gradle/.gradle
+
+WORKDIR /home/gradle
+
+ENV GRADLE_VERSION 7.6-milestone-1
+ARG GRADLE_DOWNLOAD_SHA256=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
+RUN set -o errexit -o nounset \
+    && wget --no-verbose --output-document=gradle.zip "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" \
+    && unzip -qq gradle.zip \
+    && rm gradle.zip \
+    && mv "gradle-${GRADLE_VERSION}" "${GRADLE_HOME}/" \
+    && ln -s "${GRADLE_HOME}/bin/gradle" /usr/bin/gradle \
+    && gradle --version
+# END : WE ARE BUILDING A CUSTOM GRADLE IMAGE BECAUSE JAVA 19 IS NOT CURRENTLY SUPPORTED IN PUBLIC IMAGES
+
+USER root
+WORKDIR /http4k
+COPY build.gradle build.gradle
+COPY settings.gradle settings.gradle
+COPY core core
+COPY core-pgclient core-pgclient
+COPY sunhttploom sunhttploom
+RUN gradle --quiet sunhttploom:shadowJar
+
+FROM openjdk:19-jdk-slim as java
+COPY --from=gradle /http4k/sunhttploom/build/libs/http4k-benchmark.jar /home/app/
+
+WORKDIR /home/app
+
+EXPOSE 9000
+
+CMD ["java", "-server", "-XX:+UseNUMA", "--enable-preview", "-XX:+UseParallelGC", "-XX:+AlwaysPreTouch", "-jar", "/home/app/http4k-benchmark.jar"]

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

@@ -1,5 +1,5 @@
 dependencies {
-    api(project(":core-jdbc"))
+    api(project(":core-pgclient"))
     api("org.http4k:http4k-server-jetty:$http4k_version")
 }
 

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

@@ -13,4 +13,5 @@ include 'ktornetty'
 include 'netty'
 include 'ratpack'
 include 'sunhttp'
+include 'sunhttploom'
 include 'undertow'

+ 1 - 1
frameworks/Kotlin/http4k/sunhttp/build.gradle

@@ -1,5 +1,5 @@
 dependencies {
-    api(project(":core-jdbc"))
+    api(project(":core-pgclient"))
 }
 
 apply plugin: 'application'

+ 13 - 0
frameworks/Kotlin/http4k/sunhttploom/build.gradle

@@ -0,0 +1,13 @@
+dependencies {
+    api(project(":core-pgclient"))
+}
+
+apply plugin: 'application'
+mainClassName = "Http4kSunHttpServerKt"
+apply plugin: 'com.github.johnrengelman.shadow'
+
+shadowJar {
+    baseName = "http4k-benchmark"
+    classifier = null
+    version = null
+}

+ 31 - 0
frameworks/Kotlin/http4k/sunhttploom/src/main/kotlin/Http4kSunHttpServer.kt

@@ -0,0 +1,31 @@
+import com.sun.net.httpserver.HttpServer
+import org.http4k.core.HttpHandler
+import org.http4k.server.Http4kServer
+import org.http4k.server.HttpExchangeHandler
+import org.http4k.server.ServerConfig
+import java.net.InetSocketAddress
+import java.util.concurrent.Executors
+
+fun main() {
+    Http4kBenchmarkServer(PostgresDatabase()).start(SunHttpLoom(9000))
+}
+
+class SunHttpLoom(val port: Int = 8000) : ServerConfig {
+    override val stopMode: ServerConfig.StopMode = ServerConfig.StopMode.Immediate
+
+    override fun toServer(http: HttpHandler): Http4kServer = object : Http4kServer {
+        override fun port(): Int = if (port > 0) port else server.address.port
+
+        private val executor = Executors.newVirtualThreadPerTaskExecutor()
+        private val server = HttpServer.create(InetSocketAddress(port), 1000)
+        override fun start(): Http4kServer = apply {
+            server.createContext("/", HttpExchangeHandler(http))
+            server.executor = executor
+            server.start()
+        }
+
+        override fun stop() = apply {
+            server.stop(0)
+        }
+    }
+}