Browse Source

Kotlin Hexagon: add test for new server adapter (Netty) (#7145)

* Fix error with URLs in JEE servers

* Clean up

* Avoid classpath URLs

* Fix template loading error

* Fix template loading error

* Chores

* Fix template loading error

* Delete MongoDB DB support

Storage support in Hexagon will be moved outside the Toolkit, and so, it will be left outside the benchmark.

* Fix runtime problem

* Update Hexagon version

* Make Jackson Blackbird module optional

* Add variation with Blackbird module enabled

* Upgrade Hexagon version

* Enable blackbird Jackson module by default

* Update dependencies

* Use Hexagon version 2.0.0-B1 (and a little cleanup)

* Use Hexagon version 2.0.0-B1 (and a little cleanup)

* Use Tomcat instead Resin to test JEE integration

* Remove unused environment variable

* Clean Tomcat dockerfile

* Minor improvements

* Minor improvements

* Update to release version

* Update to the latest Hexagon release

* Add Netty adapter test

* Remove Gradle Wrapper

* Update version

* Update version
Juanjo Aguililla 3 years ago
parent
commit
6baf8bd5b2

+ 24 - 1
frameworks/Kotlin/hexagon/benchmark_config.json

@@ -25,6 +25,29 @@
                 "notes": "http://hexagonkt.com",
                 "versus": "servlet"
             },
+            "netty": {
+                "json_url": "/json",
+                "db_url": "/postgresql/db",
+                "query_url": "/postgresql/query?queries=",
+                "fortune_url": "/postgresql/pebble/fortunes",
+                "update_url": "/postgresql/update?queries=",
+                "cached_query_url": "/postgresql/cached?count=",
+                "plaintext_url": "/plaintext",
+                "port": 9090,
+                "approach": "Realistic",
+                "classification": "Micro",
+                "database": "postgres",
+                "framework": "Hexagon",
+                "language": "Kotlin",
+                "orm": "Raw",
+                "platform": "Netty",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "Hexagon Netty PostgreSQL",
+                "notes": "http://hexagonkt.com",
+                "versus": "netty"
+            },
             "tomcat": {
                 "json_url": "/json",
                 "db_url": "/postgresql/db",
@@ -41,7 +64,7 @@
                 "language": "Kotlin",
                 "orm": "Raw",
                 "platform": "Servlet",
-                "webserver": "None",
+                "webserver": "Tomcat",
                 "os": "Linux",
                 "database_os": "Linux",
                 "display_name": "Hexagon Tomcat PostgreSQL",

+ 7 - 6
frameworks/Kotlin/hexagon/build.gradle

@@ -4,13 +4,13 @@ plugins {
 }
 
 ext {
-    gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.2/gradle"
-
-    hexagonVersion = "2.0.2"
+    hexagonVersion = "2.0.5"
     hikariVersion = "5.0.1"
-    jettyVersion = "11.0.7"
-    postgresqlVersion = "42.3.1"
-    cache2kVersion = "2.4.1.Final"
+    jettyVersion = "11.0.8"
+    postgresqlVersion = "42.3.3"
+    cache2kVersion = "2.6.1.Final"
+
+    gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle"
 }
 
 apply(from: "$gradleScripts/kotlin.gradle")
@@ -31,6 +31,7 @@ war {
 installDist.dependsOn("war")
 
 dependencies {
+    implementation("com.hexagonkt:http_server_netty:$hexagonVersion")
     implementation("com.hexagonkt:http_server_jetty:$hexagonVersion")
     implementation("com.hexagonkt:templates_pebble:$hexagonVersion")
     implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion")

+ 19 - 1
frameworks/Kotlin/hexagon/config.toml

@@ -19,6 +19,24 @@ platform = "Servlet"
 webserver = "None"
 versus = "servlet"
 
+[netty]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/postgresql/db"
+urls.query = "/postgresql/query?queries="
+urls.update = "/postgresql/update?queries="
+urls.fortune = "/postgresql/pebble/fortunes"
+urls.cached_query = "/postgresql/cached?count="
+approach = "Realistic"
+classification = "Micro"
+database = "postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "netty"
+
 [tomcat]
 urls.plaintext = "/plaintext"
 urls.json = "/json"
@@ -34,5 +52,5 @@ database_os = "Linux"
 os = "Linux"
 orm = "Raw"
 platform = "Servlet"
-webserver = "None"
+webserver = "Tomcat"
 versus = "servlet"

+ 0 - 183
frameworks/Kotlin/hexagon/gradlew

@@ -1,183 +0,0 @@
-#!/usr/bin/env sh
-
-#
-# Copyright 2015 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-##############################################################################
-##
-##  Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
-    echo "$*"
-}
-
-die () {
-    echo
-    echo "$*"
-    echo
-    exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-  NONSTOP* )
-    nonstop=true
-    ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
-        # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
-    else
-        JAVACMD="$JAVA_HOME/bin/java"
-    fi
-    if [ ! -x "$JAVACMD" ] ; then
-        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-    fi
-else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-    JAVACMD=`cygpath --unix "$JAVACMD"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=`expr $i + 1`
-    done
-    case $i in
-        0) set -- ;;
-        1) set -- "$args0" ;;
-        2) set -- "$args0" "$args1" ;;
-        3) set -- "$args0" "$args1" "$args2" ;;
-        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
-fi
-
-# Escape application args
-save () {
-    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
-    echo " "
-}
-APP_ARGS=`save "$@"`
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-exec "$JAVACMD" "$@"

+ 0 - 103
frameworks/Kotlin/hexagon/gradlew.bat

@@ -1,103 +0,0 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem      https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem  Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega

+ 25 - 0
frameworks/Kotlin/hexagon/hexagon-netty.dockerfile

@@ -0,0 +1,25 @@
+#
+# BUILD
+#
+FROM gradle:7.4-jdk11 AS gradle_build
+USER root
+WORKDIR /hexagon
+
+COPY src src
+COPY build.gradle build.gradle
+RUN gradle --quiet
+
+#
+# RUNTIME
+#
+FROM adoptopenjdk:11-jre-hotspot-bionic
+ENV DBSTORE postgresql
+ENV POSTGRESQL_DB_HOST tfb-database
+ENV WEBENGINE netty
+ENV PROJECT hexagon
+
+COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT
+
+EXPOSE 9090
+
+ENTRYPOINT /opt/$PROJECT/bin/$PROJECT

+ 1 - 1
frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile

@@ -1,7 +1,7 @@
 #
 # BUILD
 #
-FROM gradle:7.2-jdk11 AS gradle_build
+FROM gradle:7.4-jdk11 AS gradle_build
 USER root
 WORKDIR /hexagon
 

+ 1 - 1
frameworks/Kotlin/hexagon/hexagon.dockerfile

@@ -1,7 +1,7 @@
 #
 # BUILD
 #
-FROM gradle:7.3.3-jdk11 AS gradle_build
+FROM gradle:7.4-jdk11 AS gradle_build
 USER root
 WORKDIR /hexagon
 

+ 11 - 7
frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt

@@ -4,12 +4,15 @@ import com.hexagonkt.http.server.HttpServer
 import com.hexagonkt.http.server.HttpServerPort
 import com.hexagonkt.http.server.HttpServerSettings
 import com.hexagonkt.http.server.jetty.JettyServletAdapter
+import com.hexagonkt.http.server.netty.NettyServerAdapter
 import com.hexagonkt.store.BenchmarkSqlStore
 import com.hexagonkt.store.BenchmarkStore
 import com.hexagonkt.templates.TemplatePort
 import com.hexagonkt.templates.pebble.PebbleAdapter
 import java.net.InetAddress
 
+internal val settings = Settings()
+
 internal val stores: Map<String, BenchmarkStore> by lazy {
     mapOf("postgresql" to BenchmarkSqlStore("postgresql"))
 }
@@ -19,21 +22,22 @@ internal val templateEngines: Map<String, TemplatePort> by lazy {
 }
 
 private val engines: Map<String, HttpServerPort> by lazy {
-    mapOf("jetty" to JettyServletAdapter())
+    mapOf(
+        "jetty" to JettyServletAdapter(
+            sendDateHeader = settings.sendDateHeader,
+            sendServerVersion = settings.sendServerVersion,
+            sendXPoweredBy = settings.sendXPoweredBy,
+        ),
+        "netty" to NettyServerAdapter(),
+    )
 }
 
 private val server: HttpServer by lazy {
-    val settings = Settings()
     val engine = engines[settings.webEngine] ?: error("Unsupported server engine")
     val controller = Controller(settings, stores, templateEngines)
     val serverSettings = HttpServerSettings(
         bindAddress = InetAddress.getByName(settings.bindAddress),
         bindPort = settings.bindPort,
-        options = mapOf(
-            "sendDateHeader" to settings.sendDateHeader,
-            "sendServerVersion" to settings.sendServerVersion,
-            "sendXPoweredBy" to settings.sendXPoweredBy,
-        ),
     )
 
     HttpServer(engine, controller.path, serverSettings)

+ 12 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt

@@ -4,16 +4,19 @@ import com.hexagonkt.core.require
 import com.hexagonkt.core.media.ApplicationMedia.JSON
 import com.hexagonkt.core.media.TextMedia.HTML
 import com.hexagonkt.core.media.TextMedia.PLAIN
+import com.hexagonkt.core.multiMapOf
 import com.hexagonkt.http.model.ContentType
 import com.hexagonkt.http.server.handlers.HttpServerContext
 import com.hexagonkt.http.server.handlers.PathHandler
 import com.hexagonkt.http.server.handlers.path
+import com.hexagonkt.http.toHttpFormat
 import com.hexagonkt.serialization.jackson.json.Json
 import com.hexagonkt.serialization.serialize
 import com.hexagonkt.store.BenchmarkStore
 import com.hexagonkt.templates.TemplatePort
 
 import java.net.URL
+import java.time.LocalDateTime.now
 import java.util.concurrent.ThreadLocalRandom
 
 import kotlin.text.Charsets.UTF_8
@@ -37,6 +40,15 @@ class Controller(
 
     internal val path: PathHandler by lazy {
         path {
+            on("*") {
+                val headers = multiMapOf(
+                    "server" to "Hexagon",
+                    "date" to now().toHttpFormat(),
+                )
+
+                send(headers = headers)
+            }
+
             get("/plaintext") { ok(settings.textMessage, contentType = plain) }
             get("/json") { ok(Message(settings.textMessage).serialize(Json.raw), contentType = json) }
 

+ 2 - 2
frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt

@@ -22,8 +22,8 @@ data class Settings(
     val databaseName: String = systemSettingOrNull("database") ?: "hello_world",
     val databaseDriver: String = systemSettingOrNull("databaseDriver") ?: "org.postgresql.Driver",
 
-    val sendDateHeader: Boolean = systemSettingOrNull("sendDateHeader") ?: true,
-    val sendServerVersion: Boolean = systemSettingOrNull("sendServerVersion") ?: true,
+    val sendDateHeader: Boolean = systemSettingOrNull("sendDateHeader") ?: false,
+    val sendServerVersion: Boolean = systemSettingOrNull("sendServerVersion") ?: false,
     val sendXPoweredBy: Boolean = systemSettingOrNull("sendXPoweredBy") ?: false,
 
     val worldRows: Int = 10_000,