diff --git a/frameworks/Java/quarkus/README.md b/frameworks/Java/quarkus/README.md
index 317a4be1aa5..899ca69a984 100644
--- a/frameworks/Java/quarkus/README.md
+++ b/frameworks/Java/quarkus/README.md
@@ -4,24 +4,19 @@ This is the Quarkus portion of a [benchmarking test suite](../) comparing a vari
## Implementations
-There are currently two repository implementations.
+There are currently 6 repository implementations:
-### JAX-RS and Hibernate via JPA
-* [Plaintext test source](hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java)
-* [JSON test source](hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java)
-* [Query, Queries, Update test source](hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/WorldRepository.java)
-* [Fortunes test source](hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/FortuneRepository.java)
-
-### Reactive Routes and Asynchronous DB accesses via pgclient
-* [Plaintext test source](pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/PlaintextResource.java)
-* [JSON test source](pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/JsonResource.java)
-* [Query, Queries, Update test source](pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/WorldRepository.java)
-* [Fortunes test source](pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/FortuneRepository.java)
+- RESTEasy and Hibernate ORM
+- RESTEasy Reactive and Hibernate ORM
+- RESTEasy Reactive and Hibernate Reactive
+- RESTEasy Reactive and Vert.x PG Client
+- Reactive Routes and Hibernate Reactive
+- Reactive Routes and Vert.x PG Client
## Versions
* [Java OpenJDK 11](http://openjdk.java.net/)
-* [Quarkus 1.1.1](https://quarkus.io)
+* [Quarkus 1.11.0.Beta1](https://quarkus.io)
## Test URLs
diff --git a/frameworks/Java/quarkus/base/pom.xml b/frameworks/Java/quarkus/base/pom.xml
deleted file mode 100644
index e25d2214540..00000000000
--- a/frameworks/Java/quarkus/base/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
- 4.0.0
-
-
- io.quarkus
- benchmark
- 1.0-SNAPSHOT
- ../
-
-
- io.quarkus.benchmark
- base
-
-
-
- io.quarkus
- quarkus-scheduler
-
-
-
-
-
-
- org.jboss.jandex
- jandex-maven-plugin
- 1.0.7
-
-
- make-index
-
- jandex
-
-
-
-
-
-
-
-
diff --git a/frameworks/Java/quarkus/benchmark_config.json b/frameworks/Java/quarkus/benchmark_config.json
index 6fe21b23483..faed66a8183 100644
--- a/frameworks/Java/quarkus/benchmark_config.json
+++ b/frameworks/Java/quarkus/benchmark_config.json
@@ -21,11 +21,34 @@
"webserver": "Undertow",
"os": "Linux",
"database_os": "Linux",
- "display_name": "Quarkus + Hibernate ORM",
+ "display_name": "Quarkus + RESTEasy + Hibernate ORM",
"notes": "",
"versus": "Netty"
},
- "pgclient": {
+ "reactive-routes-hibernate-reactive": {
+ "json_url": "/json",
+ "db_url": "/db",
+ "query_url": "/queries?queries=",
+ "update_url": "/updates?queries=",
+ "fortune_url": "/fortunes",
+ "plaintext_url": "/plaintext",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "fullstack",
+ "database": "Postgres",
+ "framework": "Quarkus",
+ "language": "Java",
+ "flavor": "None",
+ "orm": "Full",
+ "platform": "Vertx-Web",
+ "webserver": "Vertx",
+ "os": "Linux",
+ "database_os": "Linux",
+ "display_name": "Quarkus + Reactive Routes + Hibernate Reactive",
+ "notes": "",
+ "versus": "Netty"
+ },
+ "reactive-routes-pgclient": {
"json_url": "/json",
"db_url": "/db",
"query_url": "/queries?queries=",
@@ -40,11 +63,80 @@
"language": "Java",
"flavor": "None",
"orm": "Micro",
- "platform": "JAX-RS",
- "webserver": "Undertow",
+ "platform": "Vertx-Web",
+ "webserver": "Vertx",
+ "os": "Linux",
+ "database_os": "Linux",
+ "display_name": "Quarkus + Reactive Routes + PgClient",
+ "notes": "",
+ "versus": "Netty"
+ },
+ "resteasy-reactive-pgclient": {
+ "json_url": "/json",
+ "db_url": "/db",
+ "query_url": "/queries?queries=",
+ "update_url": "/updates?queries=",
+ "fortune_url": "/fortunes",
+ "plaintext_url": "/plaintext",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "fullstack",
+ "database": "Postgres",
+ "framework": "Quarkus",
+ "language": "Java",
+ "flavor": "None",
+ "orm": "Micro",
+ "platform": "RESTEasy Reactive",
+ "webserver": "Vertx",
+ "os": "Linux",
+ "database_os": "Linux",
+ "display_name": "Quarkus RESTEasy Reactive + PgClient",
+ "notes": "",
+ "versus": "Netty"
+ },
+ "resteasy-reactive-hibernate": {
+ "json_url": "/json",
+ "db_url": "/db",
+ "query_url": "/queries?queries=",
+ "update_url": "/updates?queries=",
+ "fortune_url": "/fortunes",
+ "plaintext_url": "/plaintext",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "fullstack",
+ "database": "Postgres",
+ "framework": "Quarkus",
+ "language": "Java",
+ "flavor": "None",
+ "orm": "Micro",
+ "platform": "RESTEasy Reactive",
+ "webserver": "Vertx",
+ "os": "Linux",
+ "database_os": "Linux",
+ "display_name": "Quarkus RESTEasy Reactive + Hibernate",
+ "notes": "",
+ "versus": "Netty"
+ },
+ "resteasy-reactive-hibernate-reactive": {
+ "json_url": "/json",
+ "db_url": "/db",
+ "query_url": "/queries?queries=",
+ "update_url": "/updates?queries=",
+ "fortune_url": "/fortunes",
+ "plaintext_url": "/plaintext",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "fullstack",
+ "database": "Postgres",
+ "framework": "Quarkus",
+ "language": "Java",
+ "flavor": "None",
+ "orm": "Micro",
+ "platform": "RESTEasy Reactive",
+ "webserver": "Vertx",
"os": "Linux",
"database_os": "Linux",
- "display_name": "quarkus-pgclient",
+ "display_name": "Quarkus RESTEasy Reactive + Hibernate Reactive",
"notes": "",
"versus": "Netty"
}
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/FortuneResource.java b/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/FortuneResource.java
deleted file mode 100644
index 7597c085c2a..00000000000
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/FortuneResource.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package io.quarkus.benchmark.resource.pgclient;
-
-import io.quarkus.benchmark.model.Fortune;
-import io.quarkus.benchmark.repository.pgclient.FortuneRepository;
-import io.quarkus.vertx.web.Route;
-import io.vertx.core.http.HttpHeaders;
-import io.vertx.ext.web.RoutingContext;
-import io.vertx.reactivex.ext.web.templ.rocker.RockerTemplateEngine;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import java.util.Comparator;
-
-@ApplicationScoped
-public class FortuneResource extends BaseResource {
-
- @Inject
- FortuneRepository repository;
-
- private final RockerTemplateEngine templeEngine;
-
- public FortuneResource() {
- templeEngine = RockerTemplateEngine.create();
- }
-
- @Route(path = "fortunes")
- public void fortunes(RoutingContext rc) {
- repository.findAll()
- .subscribe().with(fortunes -> {
- fortunes.add(new Fortune(0, "Additional fortune added at request time."));
- fortunes.sort(Comparator.comparing(fortune -> fortune.getMessage()));
- rc.put("fortunes", fortunes);
- templeEngine.render(rc.data(), "templates/Fortunes.rocker.html", res -> {
- if (res.succeeded()) {
- rc.response()
- .putHeader(HttpHeaders.CONTENT_TYPE, "text/html; charset=UTF-8")
- .end(res.result().toString());
- } else {
- rc.fail(res.cause());
- }
- });
- },
- t -> handleFail(rc, t));
- }
-}
diff --git a/frameworks/Java/quarkus/pgclient/src/main/resources/templates/Fortunes.rocker.html b/frameworks/Java/quarkus/pgclient/src/main/resources/templates/Fortunes.rocker.html
deleted file mode 100644
index c3cf547f319..00000000000
--- a/frameworks/Java/quarkus/pgclient/src/main/resources/templates/Fortunes.rocker.html
+++ /dev/null
@@ -1,21 +0,0 @@
-@import java.util.*
-@import io.quarkus.benchmark.model.*
-@args(List fortunes)
-
-
-
Fortunes
-
-
-
- id |
- message |
-
- @for ((ForIterator i, Fortune fortune) : fortunes) {
-
- @fortune.getId() |
- @fortune.getMessage() |
-
- }
-
-
-
diff --git a/frameworks/Java/quarkus/pom.xml b/frameworks/Java/quarkus/pom.xml
index a7d9e7cd0f1..792344c0fb9 100644
--- a/frameworks/Java/quarkus/pom.xml
+++ b/frameworks/Java/quarkus/pom.xml
@@ -8,16 +8,19 @@
pom
- 1.5.2.Final
+ 1.11.0.Beta1
UTF-8
11
11
- base
- hibernate
- pgclient
+ resteasy-hibernate
+ reactive-routes-hibernate-reactive
+ reactive-routes-pgclient
+ resteasy-reactive-pgclient
+ resteasy-reactive-hibernate
+ resteasy-reactive-hibernate-reactive
@@ -34,28 +37,24 @@
base
${project.version}
+
+ io.vertx
+ vertx-pg-client
+ 3.9.0
+
+
+ io.vertx
+ vertx-sql-client
+ 3.9.0
+
+
+ io.vertx
+ vertx-web
+ 3.9.3
+
-
-
- io.quarkus
- quarkus-resteasy
-
-
- io.quarkus
- quarkus-resteasy-jackson
-
-
- io.quarkus
- quarkus-arc
-
-
- io.quarkus
- quarkus-jdbc-postgresql
-
-
-
@@ -90,6 +89,11 @@
+
+ io.quarkus
+ quarkus-bootstrap-maven-plugin
+ ${quarkus.version}
+
diff --git a/frameworks/Java/quarkus/quarkus-reactive-routes-hibernate-reactive.dockerfile b/frameworks/Java/quarkus/quarkus-reactive-routes-hibernate-reactive.dockerfile
new file mode 100644
index 00000000000..3673b27f988
--- /dev/null
+++ b/frameworks/Java/quarkus/quarkus-reactive-routes-hibernate-reactive.dockerfile
@@ -0,0 +1,28 @@
+FROM maven:3.6.3-jdk-11-slim as maven
+WORKDIR /quarkus
+ENV MODULE=reactive-routes-hibernate-reactive
+
+COPY pom.xml pom.xml
+COPY $MODULE/pom.xml $MODULE/pom.xml
+
+# Uncomment to test pre-release quarkus
+#RUN mkdir -p /root/.m2/repository/io
+#COPY m2-quarkus /root/.m2/repository/io/quarkus
+
+WORKDIR /quarkus/$MODULE
+RUN mvn dependency:go-offline -q
+WORKDIR /quarkus
+
+COPY $MODULE/src $MODULE/src
+
+WORKDIR /quarkus/$MODULE
+RUN mvn package -q
+WORKDIR /quarkus
+
+FROM openjdk:11.0.6-jdk-slim
+WORKDIR /quarkus
+ENV MODULE=reactive-routes-hibernate-reactive
+
+COPY --from=maven /quarkus/$MODULE/target/lib lib
+COPY --from=maven /quarkus/$MODULE/target/$MODULE-1.0-SNAPSHOT-runner.jar app.jar
+CMD ["java", "-server", "-XX:-UseBiasedLocking", "-XX:+UseStringDeduplication", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-Djava.lang.Integer.IntegerCache.high=10000", "-Dvertx.disableHttpHeadersValidation=true", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dhibernate.allow_update_outside_transaction=true", "-Djboss.threads.eqe.statistics=false", "-jar", "app.jar"]
diff --git a/frameworks/Java/quarkus/quarkus-pgclient.dockerfile b/frameworks/Java/quarkus/quarkus-reactive-routes-pgclient.dockerfile
similarity index 55%
rename from frameworks/Java/quarkus/quarkus-pgclient.dockerfile
rename to frameworks/Java/quarkus/quarkus-reactive-routes-pgclient.dockerfile
index 67b2141f84d..a2c818db68e 100644
--- a/frameworks/Java/quarkus/quarkus-pgclient.dockerfile
+++ b/frameworks/Java/quarkus/quarkus-reactive-routes-pgclient.dockerfile
@@ -1,18 +1,28 @@
FROM maven:3.6.3-jdk-11-slim as maven
WORKDIR /quarkus
+ENV MODULE=reactive-routes-pgclient
+
COPY pom.xml pom.xml
-COPY base/pom.xml base/pom.xml
-COPY hibernate/pom.xml hibernate/pom.xml
-COPY pgclient/pom.xml pgclient/pom.xml
-RUN mvn dependency:go-offline -q -pl base
-COPY base/src/main/resources base/src/main/resources
-COPY hibernate/src hibernate/src
-COPY pgclient/src pgclient/src
+COPY $MODULE/pom.xml $MODULE/pom.xml
+
+# Uncomment to test pre-release quarkus
+#RUN mkdir -p /root/.m2/repository/io
+#COPY m2-quarkus /root/.m2/repository/io/quarkus
+
+WORKDIR /quarkus/$MODULE
+RUN mvn dependency:go-offline -q
+WORKDIR /quarkus
-RUN mvn package -q -pl pgclient -am
+COPY $MODULE/src $MODULE/src
+
+WORKDIR /quarkus/$MODULE
+RUN mvn package -q
+WORKDIR /quarkus
FROM openjdk:11.0.6-jdk-slim
WORKDIR /quarkus
-COPY --from=maven /quarkus/pgclient/target/lib lib
-COPY --from=maven /quarkus/pgclient/target/pgclient-1.0-SNAPSHOT-runner.jar app.jar
+ENV MODULE=reactive-routes-pgclient
+
+COPY --from=maven /quarkus/$MODULE/target/lib lib
+COPY --from=maven /quarkus/$MODULE/target/$MODULE-1.0-SNAPSHOT-runner.jar app.jar
CMD ["java", "-server", "-XX:-UseBiasedLocking", "-XX:+UseStringDeduplication", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-Djava.lang.Integer.IntegerCache.high=10000", "-Dvertx.disableHttpHeadersValidation=true", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dhibernate.allow_update_outside_transaction=true", "-Djboss.threads.eqe.statistics=false", "-jar", "app.jar"]
diff --git a/frameworks/Java/quarkus/quarkus-resteasy-reactive-hibernate-reactive.dockerfile b/frameworks/Java/quarkus/quarkus-resteasy-reactive-hibernate-reactive.dockerfile
new file mode 100644
index 00000000000..cfe13c666ae
--- /dev/null
+++ b/frameworks/Java/quarkus/quarkus-resteasy-reactive-hibernate-reactive.dockerfile
@@ -0,0 +1,28 @@
+FROM maven:3.6.3-jdk-11-slim as maven
+WORKDIR /quarkus
+ENV MODULE=resteasy-reactive-hibernate-reactive
+
+COPY pom.xml pom.xml
+COPY $MODULE/pom.xml $MODULE/pom.xml
+
+# Uncomment to test pre-release quarkus
+#RUN mkdir -p /root/.m2/repository/io
+#COPY m2-quarkus /root/.m2/repository/io/quarkus
+
+WORKDIR /quarkus/$MODULE
+RUN mvn dependency:go-offline -q
+WORKDIR /quarkus
+
+COPY $MODULE/src $MODULE/src
+
+WORKDIR /quarkus/$MODULE
+RUN mvn package -q
+WORKDIR /quarkus
+
+FROM openjdk:11.0.6-jdk-slim
+WORKDIR /quarkus
+ENV MODULE=resteasy-reactive-hibernate-reactive
+
+COPY --from=maven /quarkus/$MODULE/target/lib lib
+COPY --from=maven /quarkus/$MODULE/target/$MODULE-1.0-SNAPSHOT-runner.jar app.jar
+CMD ["java", "-server", "-XX:-UseBiasedLocking", "-XX:+UseStringDeduplication", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-Djava.lang.Integer.IntegerCache.high=10000", "-Dvertx.disableHttpHeadersValidation=true", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dhibernate.allow_update_outside_transaction=true", "-Djboss.threads.eqe.statistics=false", "-jar", "app.jar"]
diff --git a/frameworks/Java/quarkus/quarkus-resteasy-reactive-hibernate.dockerfile b/frameworks/Java/quarkus/quarkus-resteasy-reactive-hibernate.dockerfile
new file mode 100644
index 00000000000..cd718579906
--- /dev/null
+++ b/frameworks/Java/quarkus/quarkus-resteasy-reactive-hibernate.dockerfile
@@ -0,0 +1,28 @@
+FROM maven:3.6.3-jdk-11-slim as maven
+WORKDIR /quarkus
+ENV MODULE=resteasy-reactive-hibernate
+
+COPY pom.xml pom.xml
+COPY $MODULE/pom.xml $MODULE/pom.xml
+
+# Uncomment to test pre-release quarkus
+#RUN mkdir -p /root/.m2/repository/io
+#COPY m2-quarkus /root/.m2/repository/io/quarkus
+
+WORKDIR /quarkus/$MODULE
+RUN mvn dependency:go-offline -q
+WORKDIR /quarkus
+
+COPY $MODULE/src $MODULE/src
+
+WORKDIR /quarkus/$MODULE
+RUN mvn package -q
+WORKDIR /quarkus
+
+FROM openjdk:11.0.6-jdk-slim
+WORKDIR /quarkus
+ENV MODULE=resteasy-reactive-hibernate
+
+COPY --from=maven /quarkus/$MODULE/target/lib lib
+COPY --from=maven /quarkus/$MODULE/target/$MODULE-1.0-SNAPSHOT-runner.jar app.jar
+CMD ["java", "-server", "-XX:-UseBiasedLocking", "-XX:+UseStringDeduplication", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-Djava.lang.Integer.IntegerCache.high=10000", "-Dvertx.disableHttpHeadersValidation=true", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dhibernate.allow_update_outside_transaction=true", "-Djboss.threads.eqe.statistics=false", "-jar", "app.jar"]
diff --git a/frameworks/Java/quarkus/quarkus-resteasy-reactive-pgclient.dockerfile b/frameworks/Java/quarkus/quarkus-resteasy-reactive-pgclient.dockerfile
new file mode 100644
index 00000000000..a08a8de190f
--- /dev/null
+++ b/frameworks/Java/quarkus/quarkus-resteasy-reactive-pgclient.dockerfile
@@ -0,0 +1,28 @@
+FROM maven:3.6.3-jdk-11-slim as maven
+WORKDIR /quarkus
+ENV MODULE=resteasy-reactive-pgclient
+
+COPY pom.xml pom.xml
+COPY $MODULE/pom.xml $MODULE/pom.xml
+
+# Uncomment to test pre-release quarkus
+#RUN mkdir -p /root/.m2/repository/io
+#COPY m2-quarkus /root/.m2/repository/io/quarkus
+
+WORKDIR /quarkus/$MODULE
+RUN mvn dependency:go-offline -q
+WORKDIR /quarkus
+
+COPY $MODULE/src $MODULE/src
+
+WORKDIR /quarkus/$MODULE
+RUN mvn package -q
+WORKDIR /quarkus
+
+FROM openjdk:11.0.6-jdk-slim
+WORKDIR /quarkus
+ENV MODULE=resteasy-reactive-pgclient
+
+COPY --from=maven /quarkus/$MODULE/target/lib lib
+COPY --from=maven /quarkus/$MODULE/target/$MODULE-1.0-SNAPSHOT-runner.jar app.jar
+CMD ["java", "-server", "-XX:-UseBiasedLocking", "-XX:+UseStringDeduplication", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-Djava.lang.Integer.IntegerCache.high=10000", "-Dvertx.disableHttpHeadersValidation=true", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dhibernate.allow_update_outside_transaction=true", "-Djboss.threads.eqe.statistics=false", "-jar", "app.jar"]
diff --git a/frameworks/Java/quarkus/quarkus.dockerfile b/frameworks/Java/quarkus/quarkus.dockerfile
index e32d6be7407..39bc4931343 100644
--- a/frameworks/Java/quarkus/quarkus.dockerfile
+++ b/frameworks/Java/quarkus/quarkus.dockerfile
@@ -1,18 +1,28 @@
FROM maven:3.6.3-jdk-11-slim as maven
WORKDIR /quarkus
+ENV MODULE=resteasy-hibernate
+
COPY pom.xml pom.xml
-COPY base/pom.xml base/pom.xml
-COPY hibernate/pom.xml hibernate/pom.xml
-COPY pgclient/pom.xml pgclient/pom.xml
-RUN mvn dependency:go-offline -q -pl base
-COPY base/src base/src
-COPY hibernate/src hibernate/src
-COPY pgclient/src pgclient/src
+COPY $MODULE/pom.xml $MODULE/pom.xml
+
+# Uncomment to test pre-release quarkus
+#RUN mkdir -p /root/.m2/repository/io
+#COPY m2-quarkus /root/.m2/repository/io/quarkus
+
+WORKDIR /quarkus/$MODULE
+RUN mvn dependency:go-offline -q
+WORKDIR /quarkus
-RUN mvn package -q -pl hibernate -am
+COPY $MODULE/src $MODULE/src
+
+WORKDIR /quarkus/$MODULE
+RUN mvn package -q
+WORKDIR /quarkus
FROM openjdk:11.0.6-jdk-slim
WORKDIR /quarkus
-COPY --from=maven /quarkus/hibernate/target/lib lib
-COPY --from=maven /quarkus/hibernate/target/hibernate-1.0-SNAPSHOT-runner.jar app.jar
+ENV MODULE=resteasy-hibernate
+
+COPY --from=maven /quarkus/$MODULE/target/lib lib
+COPY --from=maven /quarkus/$MODULE/target/$MODULE-1.0-SNAPSHOT-runner.jar app.jar
CMD ["java", "-server", "-XX:-UseBiasedLocking", "-XX:+UseStringDeduplication", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-Djava.lang.Integer.IntegerCache.high=10000", "-Dvertx.disableHttpHeadersValidation=true", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dhibernate.allow_update_outside_transaction=true", "-Djboss.threads.eqe.statistics=false", "-jar", "app.jar"]
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/pom.xml b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/pom.xml
new file mode 100644
index 00000000000..c955632ae41
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+
+ io.quarkus
+ benchmark
+ 1.0-SNAPSHOT
+ ../
+
+
+ io.quarkus.benchmark
+ reactive-routes-hibernate-reactive
+
+
+
+ io.quarkus
+ quarkus-reactive-pg-client
+
+
+ io.quarkus
+ quarkus-scheduler
+
+
+ io.quarkus
+ quarkus-hibernate-reactive
+
+
+ io.quarkus
+ quarkus-vertx-web
+
+
+ com.github.spullara.mustache.java
+ compiler
+ 0.9.6
+
+
+ io.vertx
+ vertx-pg-client
+
+
+ io.vertx
+ vertx-sql-client
+
+
+
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/ServerHeaderFilter.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
similarity index 92%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/ServerHeaderFilter.java
rename to frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
index 85a11a802dd..c46279cc783 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/ServerHeaderFilter.java
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.resource.pgclient;
+package io.quarkus.benchmark.filter;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/model/hibernate/Fortune.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/Fortune.java
similarity index 95%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/model/hibernate/Fortune.java
rename to frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/Fortune.java
index 8180aa312d1..5228080b02b 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/model/hibernate/Fortune.java
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/Fortune.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.model.hibernate;
+package io.quarkus.benchmark.model;
import org.hibernate.annotations.Immutable;
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/model/hibernate/World.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/World.java
similarity index 90%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/model/hibernate/World.java
rename to frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/World.java
index e49b245ba46..a9a2acc4a82 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/model/hibernate/World.java
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/World.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.model.hibernate;
+package io.quarkus.benchmark.model;
import javax.persistence.Entity;
import javax.persistence.Id;
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/BaseRepository.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/BaseRepository.java
new file mode 100644
index 00000000000..8cc1e2e9a01
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/BaseRepository.java
@@ -0,0 +1,19 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.function.Function;
+
+import javax.inject.Inject;
+
+import org.hibernate.reactive.mutiny.Mutiny;
+
+import io.smallrye.mutiny.Uni;
+
+public class BaseRepository {
+ @Inject
+ protected Mutiny.SessionFactory sf;
+
+ public Uni inSession(Function> work){
+ return sf.withSession(session -> work.apply(session));
+ }
+
+}
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
new file mode 100644
index 00000000000..a34254a0825
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
@@ -0,0 +1,25 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.smallrye.mutiny.Uni;
+
+@ApplicationScoped
+public class FortuneRepository extends BaseRepository {
+
+ public Uni> findAll() {
+ return inSession(s -> {
+ CriteriaBuilder criteriaBuilder = sf.getCriteriaBuilder();
+ CriteriaQuery fortuneQuery = criteriaBuilder.createQuery(Fortune.class);
+ Root from = fortuneQuery.from(Fortune.class);
+ fortuneQuery.select(from);
+ return s.createQuery(fortuneQuery).getResultList();
+ });
+ }
+}
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
new file mode 100644
index 00000000000..bc236b0e4ca
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
@@ -0,0 +1,65 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Singleton;
+
+import org.hibernate.reactive.mutiny.Mutiny;
+import org.hibernate.reactive.mutiny.Mutiny.Session;
+
+import io.quarkus.benchmark.model.World;
+import io.smallrye.mutiny.Uni;
+
+
+@Singleton
+public class WorldRepository extends BaseRepository {
+
+ /**
+ * This method is not required (nor specified) by the benchmark rules,
+ * but is quite handy to seed a local database and be able to experiment
+ * with the app locally.
+ */
+ public Uni createData() {
+ return inSession(s -> {
+ final ThreadLocalRandom random = ThreadLocalRandom.current();
+ int MAX = 10000;
+ Uni[] unis = new Uni[MAX];
+ for (int i=0; i null);
+ }
+ return Uni.combine().all().unis(unis).combinedWith(l -> null)
+ .flatMap(v -> s.flush())
+ .map(v -> null);
+ });
+ }
+
+ public Uni find(int id) {
+ return inSession(session -> singleFind(session, id));
+ }
+
+ public Uni> update(Mutiny.Session s, Collection worlds) {
+ return s.flush()
+ .map(v -> worlds);
+ }
+
+ public Uni> find(Session s, Set ids) {
+ //The rules require individual load: we can't use the Hibernate feature which allows load by multiple IDs as one single operation
+ ArrayList> l = new ArrayList<>(ids.size());
+ for (Integer id : ids) {
+ l.add(singleFind(s, id));
+ }
+ return Uni.combine().all().unis(l).combinedWith(list -> (List)list);
+ }
+
+ private static Uni singleFind(final Mutiny.Session ss, final Integer id) {
+ return ss.find(World.class, id);
+ }
+
+}
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/BaseResource.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/BaseResource.java
new file mode 100644
index 00000000000..b9ba205a368
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/BaseResource.java
@@ -0,0 +1,34 @@
+package io.quarkus.benchmark.resource;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.inject.Inject;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import io.vertx.ext.web.RoutingContext;
+
+public abstract class BaseResource {
+
+ @Inject
+ ObjectMapper mapper;
+
+ void sendJson(RoutingContext rc, Object value) {
+ try {
+ rc.response().putHeader("Content-Type", "application/json");
+ rc.response().end(mapper.writeValueAsString(value));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ Void handleFail(RoutingContext rc, Throwable t) {
+ var sw = new StringWriter();
+ t.printStackTrace(new PrintWriter(sw));
+ rc.response().setStatusCode(500).end(sw.toString());
+ return null;
+ }
+
+}
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java
new file mode 100644
index 00000000000..70ccb75946b
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java
@@ -0,0 +1,130 @@
+package io.quarkus.benchmark.resource;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import org.hibernate.FlushMode;
+import org.hibernate.reactive.mutiny.Mutiny;
+
+import io.quarkus.benchmark.model.World;
+import io.quarkus.benchmark.repository.WorldRepository;
+import io.quarkus.vertx.web.Route;
+import io.smallrye.mutiny.Uni;
+import io.vertx.ext.web.RoutingContext;
+
+
+@ApplicationScoped
+public class DbResource extends BaseResource {
+
+ @Inject
+ WorldRepository worldRepository;
+
+ @Route(path = "db")
+ public void db(RoutingContext rc) {
+ randomWorld().subscribe().with(world -> sendJson(rc, world),
+ t -> handleFail(rc, t));
+ }
+
+ @Route(path = "queries")
+ public void queries(RoutingContext rc) {
+ var queries = rc.request().getParam("queries");
+ worldRepository.inSession(session -> randomWorldForRead(session, parseQueryCount(queries)))
+ .subscribe().with(list -> sendJson(rc, list),
+ t -> handleFail(rc, t));
+ }
+
+ //Rules: https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#database-updates
+ //N.B. the benchmark seems to be designed to get in deadlocks when using a "safe pattern" of updating
+ // the entity within the same transaction as the one which read it.
+ // We therefore need to do a "read then write" while relinquishing the transaction between the two operations, as
+ // all other tested frameworks seem to do.
+ @Route(path = "updates")
+ public void updates(RoutingContext rc) {
+ var queries = rc.request().getParam("queries");
+ worldRepository.inSession(session -> {
+ // FIXME: not supported
+ // session.setJdbcBatchSize(worlds.size());
+ session.setFlushMode(FlushMode.MANUAL);
+
+ var worlds = randomWorldForRead(session, parseQueryCount(queries));
+ return worlds.flatMap(worldsCollection -> {
+ worldsCollection.forEach( w -> {
+ //Read the one field, as required by the following rule:
+ // # vi. At least the randomNumber field must be read from the database result set.
+ final int previousRead = w.getRandomNumber();
+ //Update it, but make sure to exclude the current number as Hibernate optimisations would have us "fail"
+ //the verification:
+ w.setRandomNumber(randomWorldNumber(previousRead));
+ } );
+
+ return worldRepository.update(session, worldsCollection);
+ });
+ }).subscribe().with(list -> sendJson(rc, list),
+ t -> handleFail(rc, t));
+ }
+
+ private Uni> randomWorldForRead(Mutiny.Session session, int count) {
+ Set ids = new HashSet<>(count);
+ int counter = 0;
+ while (counter < count) {
+ counter += ids.add(Integer.valueOf(randomWorldNumber())) ? 1 : 0;
+ }
+ return worldRepository.find(session, ids);
+ }
+
+ @Route(path = "createdata")
+ public void createData(RoutingContext rc) {
+ worldRepository.createData().subscribe().with(v -> rc.response().end("Data created"),
+ t -> handleFail(rc, t));
+ }
+
+ private Uni randomWorld() {
+ int i = randomWorldNumber();
+ return worldRepository.find(i);
+ }
+
+ private int randomWorldNumber() {
+ return 1 + ThreadLocalRandom.current().nextInt(10000);
+ }
+
+ /**
+ * Also according to benchmark requirements, except that in this special case
+ * of the update test we need to ensure we'll actually generate an update operation:
+ * for this we need to generate a random number between 1 to 10000, but different
+ * from the current field value.
+ * @param previousRead
+ * @return
+ */
+ private int randomWorldNumber(final int previousRead) {
+ //conceptually split the random space in those before previousRead,
+ //and those after: this approach makes sure to not affect the random characteristics.
+ final int trueRandom = ThreadLocalRandom.current().nextInt(9999) + 2;
+ if (trueRandom<=previousRead) {
+ //all figures equal or before the current field read need to be shifted back by one
+ //so to avoid hitting the same number while not affecting the distribution.
+ return trueRandom - 1;
+ }
+ else {
+ //Those after are generated by taking the generated value 2...10000 as is.
+ return trueRandom;
+ }
+ }
+
+ private int parseQueryCount(String textValue) {
+ if (textValue == null) {
+ return 1;
+ }
+ int parsedValue;
+ try {
+ parsedValue = Integer.parseInt(textValue);
+ } catch (NumberFormatException e) {
+ return 1;
+ }
+ return Math.min(500, Math.max(1, parsedValue));
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
new file mode 100644
index 00000000000..d430ef31122
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
@@ -0,0 +1,47 @@
+package io.quarkus.benchmark.resource;
+
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Comparator;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.quarkus.benchmark.repository.FortuneRepository;
+import io.quarkus.vertx.web.Route;
+import io.vertx.ext.web.RoutingContext;
+
+@ApplicationScoped
+public class FortuneResource extends BaseResource {
+
+ @Inject
+ FortuneRepository repository;
+
+ private final Mustache template;
+ private Comparator fortuneComparator;
+
+ public FortuneResource() {
+ MustacheFactory mf = new DefaultMustacheFactory();
+ template = mf.compile("fortunes.mustache");
+ fortuneComparator = Comparator.comparing(fortune -> fortune.getMessage());
+ }
+
+ @Route(path = "fortunes")
+ public void fortunes(RoutingContext rc) {
+ repository.findAll()
+ .subscribe().with( fortunes -> {
+ fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+ fortunes.sort(fortuneComparator);
+ StringWriter writer = new StringWriter();
+ template.execute(writer, Collections.singletonMap("fortunes", fortunes));
+ rc.response().putHeader("Content-Type", "text/html;charset=UTF-8");
+ rc.response().end(writer.toString());
+ },
+ t -> handleFail(rc, t));
+ }
+}
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/JsonResource.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
new file mode 100644
index 00000000000..9d932a13639
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
@@ -0,0 +1,21 @@
+package io.quarkus.benchmark.resource;
+
+import java.util.Collections;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import io.quarkus.vertx.web.Route;
+import io.vertx.ext.web.RoutingContext;
+
+@ApplicationScoped
+public class JsonResource extends BaseResource {
+
+ private static final String MESSAGE = "message";
+ private static final String HELLO = "Hello, World!";
+
+ @Route(path = "json")
+ public void json(RoutingContext rc) {
+ sendJson(rc, Collections.singletonMap( MESSAGE, HELLO ));
+ }
+}
+
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/PlaintextResource.java b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
similarity index 70%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/PlaintextResource.java
rename to frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
index 639c90e915b..c8649b551c2 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/PlaintextResource.java
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
@@ -1,14 +1,13 @@
-package io.quarkus.benchmark.resource.pgclient;
+package io.quarkus.benchmark.resource;
import javax.enterprise.context.ApplicationScoped;
import io.quarkus.vertx.web.Route;
-import io.vertx.core.buffer.Buffer;
import io.vertx.ext.web.RoutingContext;
@ApplicationScoped
public class PlaintextResource {
- private static final Buffer HELLO = Buffer.buffer("Hello, World!");
+ private static final String HELLO = "Hello, World!";
@Route(path = "plaintext")
public void plaintext(RoutingContext rc) {
diff --git a/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/resources/application.properties b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/resources/application.properties
new file mode 100644
index 00000000000..18e5ae2367b
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/resources/application.properties
@@ -0,0 +1,20 @@
+quarkus.datasource.db-kind=postgresql
+quarkus.datasource.username=benchmarkdbuser
+quarkus.datasource.password=benchmarkdbpass
+#quarkus.datasource.max-size=64
+
+# Reactive config
+quarkus.datasource.reactive=true
+quarkus.datasource.reactive.url=postgresql://tfb-database:5432/hello_world
+%dev.quarkus.datasource.reactive.url=postgresql://localhost:5432/hello_world
+
+quarkus.datasource.reactive.thread-local=true
+quarkus.datasource.reactive.cache-prepared-statements=true
+quarkus.datasource.reactive.max-size=4
+
+#quarkus.vertx.storage=false
+
+quarkus.log.console.enable=true
+quarkus.log.console.level=INFO
+quarkus.log.file.enable=false
+quarkus.log.level=INFO
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/base/src/main/resources/fortunes.mustache b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/resources/fortunes.mustache
similarity index 100%
rename from frameworks/Java/quarkus/base/src/main/resources/fortunes.mustache
rename to frameworks/Java/quarkus/reactive-routes-hibernate-reactive/src/main/resources/fortunes.mustache
diff --git a/frameworks/Java/quarkus/pgclient/start-app.sh b/frameworks/Java/quarkus/reactive-routes-hibernate-reactive/start-app.sh
similarity index 100%
rename from frameworks/Java/quarkus/pgclient/start-app.sh
rename to frameworks/Java/quarkus/reactive-routes-hibernate-reactive/start-app.sh
diff --git a/frameworks/Java/quarkus/pgclient/pom.xml b/frameworks/Java/quarkus/reactive-routes-pgclient/pom.xml
similarity index 51%
rename from frameworks/Java/quarkus/pgclient/pom.xml
rename to frameworks/Java/quarkus/reactive-routes-pgclient/pom.xml
index 6e92cb1eaa2..d9425b9128d 100644
--- a/frameworks/Java/quarkus/pgclient/pom.xml
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/pom.xml
@@ -10,12 +10,12 @@
io.quarkus.benchmark
- pgclient
+ reactive-routes-pgclient
- io.quarkus.benchmark
- base
+ io.quarkus
+ quarkus-scheduler
io.quarkus
@@ -34,28 +34,10 @@
netty-transport-native-epoll
linux-x86_64
+
+ com.github.spullara.mustache.java
+ compiler
+ 0.9.6
+
-
-
-
- com.fizzed
- rocker-maven-plugin
- 1.3.0
-
-
- generate-rocker-templates
- generate-sources
-
- generate
-
-
- ${project.basedir}/src/main/resources
- true
-
-
-
-
-
-
-
diff --git a/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
new file mode 100644
index 00000000000..aa7c7fda4f9
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
@@ -0,0 +1,33 @@
+package io.quarkus.benchmark.filter;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import javax.inject.Singleton;
+
+import io.quarkus.scheduler.Scheduled;
+import io.quarkus.vertx.web.RouteFilter;
+import io.vertx.core.http.HttpHeaders;
+import io.vertx.ext.web.RoutingContext;
+
+@Singleton
+public class ServerHeaderFilter {
+
+ private static final CharSequence SERVER_HEADER_NAME = HttpHeaders.createOptimized("Server");
+ private static final CharSequence SERVER_HEADER_VALUE = HttpHeaders.createOptimized("Quarkus");
+ private static final CharSequence DATE_HEADER_NAME = HttpHeaders.createOptimized("Date");
+
+ private CharSequence date;
+
+ @Scheduled(every="1s")
+ void increment() {
+ date = HttpHeaders.createOptimized(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
+ }
+
+ @RouteFilter(100)
+ void myFilter(RoutingContext rc) {
+ rc.response().putHeader( SERVER_HEADER_NAME, SERVER_HEADER_VALUE);
+ rc.response().putHeader( DATE_HEADER_NAME, date);
+ rc.next();
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/model/Fortune.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/model/Fortune.java
similarity index 100%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/model/Fortune.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/model/Fortune.java
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/model/World.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/model/World.java
similarity index 100%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/model/World.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/model/World.java
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/FortuneRepository.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
similarity index 94%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/FortuneRepository.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
index 22cdd9bbdaf..4415583fa1d 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/FortuneRepository.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.repository.pgclient;
+package io.quarkus.benchmark.repository;
import java.util.ArrayList;
import java.util.List;
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/PgClientFactory.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClientFactory.java
similarity index 96%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/PgClientFactory.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClientFactory.java
index b3c0fdf3eee..ef99489cb26 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/PgClientFactory.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClientFactory.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.repository.pgclient;
+package io.quarkus.benchmark.repository;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/PgClients.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClients.java
similarity index 94%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/PgClients.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClients.java
index 8f48963c965..871e9b75a6e 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/PgClients.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClients.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.repository.pgclient;
+package io.quarkus.benchmark.repository;
import io.vertx.mutiny.pgclient.PgPool;
import io.vertx.mutiny.sqlclient.SqlClient;
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/WorldRepository.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
similarity index 95%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/WorldRepository.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
index d3b94cc21c3..2d9c71d1259 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/repository/pgclient/WorldRepository.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.repository.pgclient;
+package io.quarkus.benchmark.repository;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/BaseResource.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/BaseResource.java
similarity index 91%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/BaseResource.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/BaseResource.java
index 3dc9cad2eb2..22e9965f777 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/BaseResource.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/BaseResource.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.resource.pgclient;
+package io.quarkus.benchmark.resource;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.json.Json;
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/DbResource.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/DbResource.java
similarity index 90%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/DbResource.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/DbResource.java
index 941251499fa..6333ea49331 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/DbResource.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/DbResource.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.resource.pgclient;
+package io.quarkus.benchmark.resource;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
@@ -7,7 +7,7 @@
import javax.inject.Inject;
import io.quarkus.benchmark.model.World;
-import io.quarkus.benchmark.repository.pgclient.WorldRepository;
+import io.quarkus.benchmark.repository.WorldRepository;
import io.quarkus.vertx.web.Route;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.groups.UniAndGroupIterable;
@@ -35,7 +35,7 @@ public void queries(RoutingContext rc) {
return randomWorld().map(w -> ret[i] = w);
});
- ((UniAndGroupIterable)Uni.combine().all().unis(worlds))
+ Uni.combine().all().unis(worlds)
.combinedWith(v -> Arrays.asList(ret))
.subscribe().with(list -> sendJson(rc, list),
t -> handleFail(rc, t));
@@ -54,7 +54,7 @@ public void updates(RoutingContext rc) {
});
});
- ((UniAndGroupIterable)Uni.combine().all().unis(worlds))
+ Uni.combine().all().unis(worlds)
.combinedWith(v -> null)
.flatMap(v -> worldRepository.update(ret))
.map(v -> Arrays.asList(ret))
diff --git a/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
new file mode 100644
index 00000000000..acaf98b5487
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
@@ -0,0 +1,49 @@
+package io.quarkus.benchmark.resource;
+
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Comparator;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.quarkus.benchmark.repository.FortuneRepository;
+import io.quarkus.vertx.web.Route;
+import io.vertx.core.http.HttpHeaders;
+import io.vertx.ext.web.RoutingContext;
+
+@ApplicationScoped
+public class FortuneResource extends BaseResource {
+
+ @Inject
+ FortuneRepository repository;
+ private Mustache template;
+ private Comparator fortuneComparator;
+
+
+ public FortuneResource() {
+ MustacheFactory mf = new DefaultMustacheFactory();
+ template = mf.compile("fortunes.mustache");
+ fortuneComparator = Comparator.comparing(fortune -> fortune.getMessage());
+ }
+
+ @Route(path = "fortunes")
+ public void fortunes(RoutingContext rc) {
+ repository.findAll()
+ .subscribe().with(fortunes -> {
+ fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+ fortunes.sort(fortuneComparator);
+ StringWriter writer = new StringWriter();
+ template.execute(writer, Collections.singletonMap("fortunes", fortunes));
+ rc.response()
+ .putHeader(HttpHeaders.CONTENT_TYPE, "text/html; charset=UTF-8")
+ .end(writer.toString());
+ },
+ t -> handleFail(rc, t));
+ }
+}
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/JsonResource.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
similarity index 88%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/JsonResource.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
index 2495db317ec..f6eb41e21e6 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/JsonResource.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.resource.pgclient;
+package io.quarkus.benchmark.resource;
import javax.enterprise.context.ApplicationScoped;
diff --git a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/Message.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/Message.java
similarity index 79%
rename from frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/Message.java
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/Message.java
index 64e63d0f018..73f0ffefb8a 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/java/io/quarkus/benchmark/resource/pgclient/Message.java
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/Message.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.resource.pgclient;
+package io.quarkus.benchmark.resource;
public class Message {
private final String message;
diff --git a/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
new file mode 100644
index 00000000000..3e6291c98f6
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
@@ -0,0 +1,23 @@
+package io.quarkus.benchmark.resource;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import io.quarkus.vertx.web.Route;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.HttpHeaders;
+import io.vertx.ext.web.RoutingContext;
+
+@ApplicationScoped
+public class PlaintextResource {
+ private static final String HELLO_WORLD = "Hello, world!";
+ private static final Buffer HELLO_WORLD_BUFFER = Buffer.factory.directBuffer(HELLO_WORLD, "UTF-8");
+
+ private static final CharSequence CONTENT_TYPE_HEADER_NAME = HttpHeaders.createOptimized("Content-Type");
+ private static final CharSequence CONTENT_TYPE_HEADER_VALUE = HttpHeaders.createOptimized("text/plain");
+
+ @Route(path = "plaintext")
+ public void plaintext(RoutingContext rc) {
+ rc.response().putHeader(CONTENT_TYPE_HEADER_NAME, CONTENT_TYPE_HEADER_VALUE);
+ rc.response().end(HELLO_WORLD_BUFFER);
+ }
+}
diff --git a/frameworks/Java/quarkus/pgclient/src/main/resources/application.properties b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/resources/application.properties
similarity index 89%
rename from frameworks/Java/quarkus/pgclient/src/main/resources/application.properties
rename to frameworks/Java/quarkus/reactive-routes-pgclient/src/main/resources/application.properties
index 727eacaa47f..4d99cfbc4ec 100644
--- a/frameworks/Java/quarkus/pgclient/src/main/resources/application.properties
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/resources/application.properties
@@ -1,7 +1,7 @@
quarkus.datasource.url=vertx-reactive:postgresql://tfb-database:5432/hello_world
quarkus.datasource.username=benchmarkdbuser
quarkus.datasource.password=benchmarkdbpass
-quarkus.datasource.max-size=64
+quarkus.datasource.reactive.max-size=64
quarkus.log.console.enable=true
quarkus.log.console.level=INFO
quarkus.log.file.enable=false
diff --git a/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/resources/fortunes.mustache b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/resources/fortunes.mustache
new file mode 100644
index 00000000000..f9664a72eee
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/src/main/resources/fortunes.mustache
@@ -0,0 +1,20 @@
+
+
+
+ Fortunes
+
+
+
+
+ id |
+ message |
+
+ {{#fortunes}}
+
+ {{id}} |
+ {{message}} |
+
+ {{/fortunes}}
+
+
+
diff --git a/frameworks/Java/quarkus/reactive-routes-pgclient/start-app.sh b/frameworks/Java/quarkus/reactive-routes-pgclient/start-app.sh
new file mode 100755
index 00000000000..01b3e22ea2c
--- /dev/null
+++ b/frameworks/Java/quarkus/reactive-routes-pgclient/start-app.sh
@@ -0,0 +1,2 @@
+java -XX:+FlightRecorder -XX:+UseParallelGC -Dquarkus.datasource.url=vertx-reactive:postgresql://localhost:5432/hello_world -Dquarkus.http.host=127.0.0.1 -Djava.lang.Integer.IntegerCache.high=10000 -Dvertx.disableHttpHeadersValidation=true -Dvertx.disableMetrics=true -Dvertx.disableH2c=true -Dvertx.disableWebsockets=true -Dvertx.flashPolicyHandler=false -Dvertx.threadChecks=false -Dvertx.disableContextTimings=true -Dvertx.disableTCCL=true -Dhibernate.allow_update_outside_transaction=true -Djboss.threads.eqe.statistics=false -jar target/pgclient-1.0-SNAPSHOT-runner.jar
+
diff --git a/frameworks/Java/quarkus/hibernate/README.md b/frameworks/Java/quarkus/resteasy-hibernate/README.md
similarity index 100%
rename from frameworks/Java/quarkus/hibernate/README.md
rename to frameworks/Java/quarkus/resteasy-hibernate/README.md
diff --git a/frameworks/Java/quarkus/hibernate/pom.xml b/frameworks/Java/quarkus/resteasy-hibernate/pom.xml
similarity index 56%
rename from frameworks/Java/quarkus/hibernate/pom.xml
rename to frameworks/Java/quarkus/resteasy-hibernate/pom.xml
index be7cb2ae90c..d1dbf82f15b 100644
--- a/frameworks/Java/quarkus/hibernate/pom.xml
+++ b/frameworks/Java/quarkus/resteasy-hibernate/pom.xml
@@ -10,16 +10,28 @@
io.quarkus.benchmark
- hibernate
+ resteasy-hibernate
- io.quarkus.benchmark
- base
+ io.quarkus
+ quarkus-hibernate-orm
io.quarkus
- quarkus-hibernate-orm
+ quarkus-scheduler
+
+
+ io.quarkus
+ quarkus-resteasy
+
+
+ io.quarkus
+ quarkus-resteasy-jackson
+
+
+ io.quarkus
+ quarkus-jdbc-postgresql
com.github.spullara.mustache.java
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java
similarity index 85%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java
index c8e4d643e2d..322517a3d40 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java
@@ -1,6 +1,7 @@
package io.quarkus.benchmark.cdi;
import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Typed;
import javax.inject.Singleton;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
@@ -13,6 +14,8 @@ public class HibernateOrmNativeComponents {
@PersistenceUnit
EntityManagerFactory entityManagerFactory;
+ @Singleton
+ @Typed(SessionFactory.class)
@Produces
SessionFactory extractSessionFactory() {
return entityManagerFactory.unwrap( SessionFactory.class );
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
similarity index 100%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
diff --git a/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/model/Fortune.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/model/Fortune.java
new file mode 100644
index 00000000000..5228080b02b
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/model/Fortune.java
@@ -0,0 +1,56 @@
+package io.quarkus.benchmark.model;
+
+import org.hibernate.annotations.Immutable;
+
+import java.util.Objects;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Immutable
+public class Fortune {
+
+ @Id
+ private int id;
+ private String message;
+
+ public Fortune() {}
+
+ public Fortune(int id, String message) {
+ this.id = id;
+ this.message = message;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ Fortune fortune = (Fortune) o;
+ return id == fortune.id &&
+ Objects.equals(message, fortune.message);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, message);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/model/World.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/model/World.java
new file mode 100644
index 00000000000..a9a2acc4a82
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/model/World.java
@@ -0,0 +1,29 @@
+package io.quarkus.benchmark.model;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class World {
+
+ @Id
+ private int id;
+ private int randomNumber;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getRandomNumber() {
+ return randomNumber;
+ }
+
+ public void setRandomNumber(int randomNumber) {
+ this.randomNumber = randomNumber;
+ }
+
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/FortuneRepository.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
similarity index 82%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/FortuneRepository.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
index eb0b02151f9..9b845ee39e9 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/FortuneRepository.java
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
@@ -1,17 +1,19 @@
-package io.quarkus.benchmark.repository.hibernate;
+package io.quarkus.benchmark.repository;
-import io.quarkus.benchmark.model.hibernate.Fortune;
-import org.hibernate.SessionFactory;
-import org.hibernate.StatelessSession;
+import java.util.List;
-import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
+import javax.inject.Singleton;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
-import java.util.List;
-@ApplicationScoped
+import org.hibernate.SessionFactory;
+import org.hibernate.StatelessSession;
+
+import io.quarkus.benchmark.model.Fortune;
+
+@Singleton
public class FortuneRepository {
@Inject
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/WorldRepository.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
similarity index 94%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/WorldRepository.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
index 271517cbb93..ee05796d892 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/repository/hibernate/WorldRepository.java
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
@@ -1,20 +1,21 @@
-package io.quarkus.benchmark.repository.hibernate;
+package io.quarkus.benchmark.repository;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
-import java.util.stream.Collectors;
+
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.transaction.Transactional;
-import io.quarkus.benchmark.model.hibernate.World;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
+import io.quarkus.benchmark.model.World;
+
@Singleton
public class WorldRepository {
@@ -46,6 +47,7 @@ public World findSingleAndStateless(int id) {
}
}
+ @Transactional
public void updateAll(Collection worlds) {
try (Session s = sf.openSession()) {
s.setJdbcBatchSize(worlds.size());
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/hibernate/DbResource.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/DbResource.java
similarity index 96%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/hibernate/DbResource.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/DbResource.java
index e4b78337582..08ec68484cb 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/hibernate/DbResource.java
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/DbResource.java
@@ -1,12 +1,10 @@
-package io.quarkus.benchmark.resource.hibernate;
-
-import io.quarkus.benchmark.model.hibernate.World;
-import io.quarkus.benchmark.repository.hibernate.WorldRepository;
+package io.quarkus.benchmark.resource;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
+
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
@@ -16,6 +14,9 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+import io.quarkus.benchmark.model.World;
+import io.quarkus.benchmark.repository.WorldRepository;
+
@Singleton
@Path("/")
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/hibernate/FortuneResource.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
similarity index 83%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/hibernate/FortuneResource.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
index c09de8b075e..fe71803f631 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/hibernate/FortuneResource.java
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
@@ -1,4 +1,4 @@
-package io.quarkus.benchmark.resource.hibernate;
+package io.quarkus.benchmark.resource;
import java.io.StringWriter;
import java.util.ArrayList;
@@ -6,8 +6,8 @@
import java.util.Comparator;
import java.util.List;
-import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
+import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -17,12 +17,13 @@
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheFactory;
-import io.quarkus.benchmark.model.hibernate.Fortune;
-import io.quarkus.benchmark.repository.hibernate.FortuneRepository;
-@ApplicationScoped
+import io.quarkus.benchmark.model.Fortune;
+import io.quarkus.benchmark.repository.FortuneRepository;
+
+@Singleton
@Path("/")
-@Produces(MediaType.TEXT_HTML)
+@Produces(MediaType.TEXT_HTML+"; charset=UTF-8")
@Consumes(MediaType.APPLICATION_JSON)
public class FortuneResource {
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
similarity index 60%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
index 130a9e49451..c8bbb155545 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
@@ -4,18 +4,15 @@
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
-import java.util.Collections;
-import java.util.Map;
@Path("/json")
public class JsonResource {
- private static final String MESSAGE = "message";
private static final String HELLO = "Hello, World!";
@GET
@Produces(MediaType.APPLICATION_JSON)
- public Map json() {
- return Collections.singletonMap( MESSAGE, HELLO );
+ public Message json() {
+ return new Message(HELLO);
}
}
diff --git a/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/Message.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/Message.java
new file mode 100644
index 00000000000..73f0ffefb8a
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/Message.java
@@ -0,0 +1,13 @@
+package io.quarkus.benchmark.resource;
+
+public class Message {
+ private final String message;
+
+ public Message(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java b/frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
similarity index 100%
rename from frameworks/Java/quarkus/hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
diff --git a/frameworks/Java/quarkus/hibernate/src/main/resources/application.properties b/frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/application.properties
similarity index 53%
rename from frameworks/Java/quarkus/hibernate/src/main/resources/application.properties
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/application.properties
index bd41981e1c5..756e8f174d3 100644
--- a/frameworks/Java/quarkus/hibernate/src/main/resources/application.properties
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/application.properties
@@ -1,15 +1,16 @@
#Test preferQueryMode ? sendBufferSize ? receiveBufferSize ?
#disableColumnSanitiser requires lower case column names
-quarkus.datasource.url=jdbc:postgresql://tfb-database:5432/hello_world?loggerLevel=OFF&disableColumnSanitiser=true&assumeMinServerVersion=12&sslmode=disable
-%dev.quarkus.datasource.url=jdbc:postgresql://localhost:5432/hello_world?loggerLevel=OFF&disableColumnSanitiser=true&assumeMinServerVersion=12&sslmode=disable
-quarkus.datasource.driver=org.postgresql.Driver
+quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=benchmarkdbuser
quarkus.datasource.password=benchmarkdbpass
-quarkus.datasource.transactions=disabled
-quarkus.datasource.detect-statement-leaks=false
-quarkus.datasource.max-size=64
-quarkus.datasource.min-size=16
-quarkus.datasource.initial-size=64
+quarkus.datasource.jdbc.url=jdbc:postgresql://tfb-database:5432/hello_world?loggerLevel=OFF&disableColumnSanitiser=true&assumeMinServerVersion=12&sslmode=disable
+%dev.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/hello_world?loggerLevel=OFF&disableColumnSanitiser=true&assumeMinServerVersion=12&sslmode=disable
+quarkus.datasource.jdbc.driver=org.postgresql.Driver
+quarkus.datasource.jdbc.transactions=disabled
+quarkus.datasource.jdbc.detect-statement-leaks=false
+quarkus.datasource.jdbc.max-size=64
+quarkus.datasource.jdbc.min-size=16
+quarkus.datasource.jdbc.initial-size=64
quarkus.log.console.enable=true
quarkus.log.console.level=INFO
diff --git a/frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/fortunes.mustache b/frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/fortunes.mustache
new file mode 100644
index 00000000000..f9664a72eee
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/fortunes.mustache
@@ -0,0 +1,20 @@
+
+
+
+ Fortunes
+
+
+
+
+ id |
+ message |
+
+ {{#fortunes}}
+
+ {{id}} |
+ {{message}} |
+
+ {{/fortunes}}
+
+
+
diff --git a/frameworks/Java/quarkus/hibernate/src/main/resources/import.sql b/frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/import.sql
similarity index 100%
rename from frameworks/Java/quarkus/hibernate/src/main/resources/import.sql
rename to frameworks/Java/quarkus/resteasy-hibernate/src/main/resources/import.sql
diff --git a/frameworks/Java/quarkus/hibernate/start-app.sh b/frameworks/Java/quarkus/resteasy-hibernate/start-app.sh
similarity index 100%
rename from frameworks/Java/quarkus/hibernate/start-app.sh
rename to frameworks/Java/quarkus/resteasy-hibernate/start-app.sh
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/pom.xml b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/pom.xml
new file mode 100644
index 00000000000..77a1e4ba881
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+
+
+ io.quarkus
+ benchmark
+ 1.0-SNAPSHOT
+ ../
+
+
+ io.quarkus.benchmark
+ resteasy-reactive-hibernate-reactive
+
+
+
+ io.quarkus
+ quarkus-scheduler
+
+
+ io.quarkus
+ quarkus-reactive-pg-client
+
+
+ io.quarkus
+ quarkus-hibernate-reactive
+
+
+ io.quarkus
+ quarkus-resteasy-reactive
+
+
+ io.quarkus
+ quarkus-resteasy-reactive-jackson
+
+
+ io.vertx
+ vertx-web-templ-rocker
+
+
+ io.netty
+ netty-transport-native-epoll
+ linux-x86_64
+
+
+ com.github.spullara.mustache.java
+ compiler
+ 0.9.6
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
new file mode 100644
index 00000000000..d19fe291e53
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
@@ -0,0 +1,33 @@
+package io.quarkus.benchmark.filter;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import javax.inject.Singleton;
+
+import org.jboss.resteasy.reactive.server.ServerResponseFilter;
+
+import io.quarkus.scheduler.Scheduled;
+import io.vertx.core.http.HttpHeaders;
+import io.vertx.core.http.HttpServerResponse;
+
+@Singleton
+public class ServerHeaderFilter {
+
+ private static final CharSequence SERVER_HEADER_NAME = HttpHeaders.createOptimized("Server");
+ private static final CharSequence SERVER_HEADER_VALUE = HttpHeaders.createOptimized("Quarkus");
+ private static final CharSequence DATE_HEADER_NAME = HttpHeaders.createOptimized("Date");
+
+ private CharSequence date;
+
+ @Scheduled(every="1s")
+ void increment() {
+ date = HttpHeaders.createOptimized(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
+ }
+
+ @ServerResponseFilter
+ public void filter(HttpServerResponse response) {
+ response.putHeader(SERVER_HEADER_NAME, SERVER_HEADER_VALUE);
+ response.putHeader(DATE_HEADER_NAME, date);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/Fortune.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/Fortune.java
new file mode 100644
index 00000000000..5228080b02b
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/Fortune.java
@@ -0,0 +1,56 @@
+package io.quarkus.benchmark.model;
+
+import org.hibernate.annotations.Immutable;
+
+import java.util.Objects;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Immutable
+public class Fortune {
+
+ @Id
+ private int id;
+ private String message;
+
+ public Fortune() {}
+
+ public Fortune(int id, String message) {
+ this.id = id;
+ this.message = message;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ Fortune fortune = (Fortune) o;
+ return id == fortune.id &&
+ Objects.equals(message, fortune.message);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, message);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/World.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/World.java
new file mode 100644
index 00000000000..a9a2acc4a82
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/model/World.java
@@ -0,0 +1,29 @@
+package io.quarkus.benchmark.model;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class World {
+
+ @Id
+ private int id;
+ private int randomNumber;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getRandomNumber() {
+ return randomNumber;
+ }
+
+ public void setRandomNumber(int randomNumber) {
+ this.randomNumber = randomNumber;
+ }
+
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/BaseRepository.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/BaseRepository.java
new file mode 100644
index 00000000000..8cc1e2e9a01
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/BaseRepository.java
@@ -0,0 +1,19 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.function.Function;
+
+import javax.inject.Inject;
+
+import org.hibernate.reactive.mutiny.Mutiny;
+
+import io.smallrye.mutiny.Uni;
+
+public class BaseRepository {
+ @Inject
+ protected Mutiny.SessionFactory sf;
+
+ public Uni inSession(Function> work){
+ return sf.withSession(session -> work.apply(session));
+ }
+
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
new file mode 100644
index 00000000000..a34254a0825
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
@@ -0,0 +1,25 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.smallrye.mutiny.Uni;
+
+@ApplicationScoped
+public class FortuneRepository extends BaseRepository {
+
+ public Uni> findAll() {
+ return inSession(s -> {
+ CriteriaBuilder criteriaBuilder = sf.getCriteriaBuilder();
+ CriteriaQuery fortuneQuery = criteriaBuilder.createQuery(Fortune.class);
+ Root from = fortuneQuery.from(Fortune.class);
+ fortuneQuery.select(from);
+ return s.createQuery(fortuneQuery).getResultList();
+ });
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
new file mode 100644
index 00000000000..bc236b0e4ca
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
@@ -0,0 +1,65 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Singleton;
+
+import org.hibernate.reactive.mutiny.Mutiny;
+import org.hibernate.reactive.mutiny.Mutiny.Session;
+
+import io.quarkus.benchmark.model.World;
+import io.smallrye.mutiny.Uni;
+
+
+@Singleton
+public class WorldRepository extends BaseRepository {
+
+ /**
+ * This method is not required (nor specified) by the benchmark rules,
+ * but is quite handy to seed a local database and be able to experiment
+ * with the app locally.
+ */
+ public Uni createData() {
+ return inSession(s -> {
+ final ThreadLocalRandom random = ThreadLocalRandom.current();
+ int MAX = 10000;
+ Uni[] unis = new Uni[MAX];
+ for (int i=0; i null);
+ }
+ return Uni.combine().all().unis(unis).combinedWith(l -> null)
+ .flatMap(v -> s.flush())
+ .map(v -> null);
+ });
+ }
+
+ public Uni find(int id) {
+ return inSession(session -> singleFind(session, id));
+ }
+
+ public Uni> update(Mutiny.Session s, Collection worlds) {
+ return s.flush()
+ .map(v -> worlds);
+ }
+
+ public Uni> find(Session s, Set ids) {
+ //The rules require individual load: we can't use the Hibernate feature which allows load by multiple IDs as one single operation
+ ArrayList> l = new ArrayList<>(ids.size());
+ for (Integer id : ids) {
+ l.add(singleFind(s, id));
+ }
+ return Uni.combine().all().unis(l).combinedWith(list -> (List)list);
+ }
+
+ private static Uni singleFind(final Mutiny.Session ss, final Integer id) {
+ return ss.find(World.class, id);
+ }
+
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java
new file mode 100644
index 00000000000..4f5316fd95f
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java
@@ -0,0 +1,117 @@
+package io.quarkus.benchmark.resource;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.hibernate.FlushMode;
+import org.hibernate.reactive.mutiny.Mutiny;
+
+import io.quarkus.benchmark.model.World;
+import io.quarkus.benchmark.repository.WorldRepository;
+import io.smallrye.mutiny.Uni;
+
+@Produces(MediaType.APPLICATION_JSON)
+@Path("/")
+public class DbResource {
+
+ @Inject
+ WorldRepository worldRepository;
+
+ @GET
+ @Path("db")
+ public Uni db() {
+ return randomWorld();
+ }
+
+ @GET
+ @Path("queries")
+ public Uni> queries(@QueryParam("queries") String queries) {
+ return worldRepository.inSession(session -> randomWorldForRead(session, parseQueryCount(queries)));
+ }
+
+ private Uni> randomWorldForRead(Mutiny.Session session, int count) {
+ Set ids = new HashSet<>(count);
+ int counter = 0;
+ while (counter < count) {
+ counter += ids.add(Integer.valueOf(randomWorldNumber())) ? 1 : 0;
+ }
+ return worldRepository.find(session, ids);
+ }
+
+ @GET
+ @Path("updates")
+ public Uni> updates(@QueryParam("queries") String queries) {
+ return worldRepository.inSession(session -> {
+ // FIXME: not supported
+ // session.setJdbcBatchSize(worlds.size());
+ session.setFlushMode(FlushMode.MANUAL);
+
+ var worlds = randomWorldForRead(session, parseQueryCount(queries));
+ return worlds.flatMap(worldsCollection -> {
+ worldsCollection.forEach( w -> {
+ //Read the one field, as required by the following rule:
+ // # vi. At least the randomNumber field must be read from the database result set.
+ final int previousRead = w.getRandomNumber();
+ //Update it, but make sure to exclude the current number as Hibernate optimisations would have us "fail"
+ //the verification:
+ w.setRandomNumber(randomWorldNumber(previousRead));
+ } );
+
+ return worldRepository.update(session, worldsCollection);
+ });
+ });
+ }
+
+ private Uni randomWorld() {
+ return worldRepository.find(randomWorldNumber());
+ }
+
+ private int randomWorldNumber() {
+ return 1 + ThreadLocalRandom.current().nextInt(10000);
+ }
+
+ /**
+ * Also according to benchmark requirements, except that in this special case
+ * of the update test we need to ensure we'll actually generate an update operation:
+ * for this we need to generate a random number between 1 to 10000, but different
+ * from the current field value.
+ * @param previousRead
+ * @return
+ */
+ private int randomWorldNumber(final int previousRead) {
+ //conceptually split the random space in those before previousRead,
+ //and those after: this approach makes sure to not affect the random characteristics.
+ final int trueRandom = ThreadLocalRandom.current().nextInt(9999) + 2;
+ if (trueRandom<=previousRead) {
+ //all figures equal or before the current field read need to be shifted back by one
+ //so to avoid hitting the same number while not affecting the distribution.
+ return trueRandom - 1;
+ }
+ else {
+ //Those after are generated by taking the generated value 2...10000 as is.
+ return trueRandom;
+ }
+ }
+
+ private int parseQueryCount(String textValue) {
+ if (textValue == null) {
+ return 1;
+ }
+ int parsedValue;
+ try {
+ parsedValue = Integer.parseInt(textValue);
+ } catch (NumberFormatException e) {
+ return 1;
+ }
+ return Math.min(500, Math.max(1, parsedValue));
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
new file mode 100644
index 00000000000..4b23849cb2e
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
@@ -0,0 +1,47 @@
+package io.quarkus.benchmark.resource;
+
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Comparator;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.quarkus.benchmark.repository.FortuneRepository;
+import io.smallrye.mutiny.Uni;
+
+@Path("/fortunes")
+public class FortuneResource {
+
+ @Inject
+ FortuneRepository repository;
+ private Mustache template;
+ private Comparator fortuneComparator;
+
+
+ public FortuneResource() {
+ MustacheFactory mf = new DefaultMustacheFactory();
+ template = mf.compile("fortunes.mustache");
+ fortuneComparator = Comparator.comparing(fortune -> fortune.getMessage());
+ }
+
+ @Produces("text/html; charset=UTF-8")
+ @GET
+ public Uni fortunes() {
+ return repository.findAll()
+ .map(fortunes -> {
+ fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+ fortunes.sort(fortuneComparator);
+ StringWriter writer = new StringWriter();
+ template.execute(writer, Collections.singletonMap("fortunes", fortunes));
+ return writer.toString();
+ });
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/JsonResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
new file mode 100644
index 00000000000..c1cd3a3eb14
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
@@ -0,0 +1,19 @@
+package io.quarkus.benchmark.resource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/json")
+public class JsonResource {
+
+ private static final String HELLO = "Hello, World!";
+
+ @Produces(MediaType.APPLICATION_JSON)
+ @GET
+ public Message json() {
+ return new Message(HELLO);
+ }
+}
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/Message.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/Message.java
new file mode 100644
index 00000000000..73f0ffefb8a
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/Message.java
@@ -0,0 +1,13 @@
+package io.quarkus.benchmark.resource;
+
+public class Message {
+ private final String message;
+
+ public Message(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
new file mode 100644
index 00000000000..58094ad21ef
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
@@ -0,0 +1,20 @@
+package io.quarkus.benchmark.resource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import io.vertx.core.buffer.Buffer;
+
+@Path("/plaintext")
+public class PlaintextResource {
+ private static final String HELLO_WORLD = "Hello, world!";
+ private static final Buffer HELLO_WORLD_BUFFER = Buffer.factory.directBuffer(HELLO_WORLD, "UTF-8");
+
+ @Produces(MediaType.TEXT_PLAIN)
+ @GET
+ public Buffer plaintext() {
+ return HELLO_WORLD_BUFFER;
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/application.properties b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/application.properties
new file mode 100644
index 00000000000..18e5ae2367b
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/application.properties
@@ -0,0 +1,20 @@
+quarkus.datasource.db-kind=postgresql
+quarkus.datasource.username=benchmarkdbuser
+quarkus.datasource.password=benchmarkdbpass
+#quarkus.datasource.max-size=64
+
+# Reactive config
+quarkus.datasource.reactive=true
+quarkus.datasource.reactive.url=postgresql://tfb-database:5432/hello_world
+%dev.quarkus.datasource.reactive.url=postgresql://localhost:5432/hello_world
+
+quarkus.datasource.reactive.thread-local=true
+quarkus.datasource.reactive.cache-prepared-statements=true
+quarkus.datasource.reactive.max-size=4
+
+#quarkus.vertx.storage=false
+
+quarkus.log.console.enable=true
+quarkus.log.console.level=INFO
+quarkus.log.file.enable=false
+quarkus.log.level=INFO
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/fortunes.mustache b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/fortunes.mustache
new file mode 100644
index 00000000000..f9664a72eee
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/fortunes.mustache
@@ -0,0 +1,20 @@
+
+
+
+ Fortunes
+
+
+
+
+ id |
+ message |
+
+ {{#fortunes}}
+
+ {{id}} |
+ {{message}} |
+
+ {{/fortunes}}
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/start-app.sh b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/start-app.sh
new file mode 100755
index 00000000000..01b3e22ea2c
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/start-app.sh
@@ -0,0 +1,2 @@
+java -XX:+FlightRecorder -XX:+UseParallelGC -Dquarkus.datasource.url=vertx-reactive:postgresql://localhost:5432/hello_world -Dquarkus.http.host=127.0.0.1 -Djava.lang.Integer.IntegerCache.high=10000 -Dvertx.disableHttpHeadersValidation=true -Dvertx.disableMetrics=true -Dvertx.disableH2c=true -Dvertx.disableWebsockets=true -Dvertx.flashPolicyHandler=false -Dvertx.threadChecks=false -Dvertx.disableContextTimings=true -Dvertx.disableTCCL=true -Dhibernate.allow_update_outside_transaction=true -Djboss.threads.eqe.statistics=false -jar target/pgclient-1.0-SNAPSHOT-runner.jar
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/README.md b/frameworks/Java/quarkus/resteasy-reactive-hibernate/README.md
new file mode 100644
index 00000000000..7cbe9419a38
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/README.md
@@ -0,0 +1,69 @@
+# Local development
+
+During development it might be easier to start a PostgreSQL instance directly:
+
+ sudo podman run --ulimit memlock=-1:-1 -it --rm=true --network host --memory-swappiness=0 --name HibernateTestingPGSQL -e POSTGRES_USER=benchmarkdbuser -e POSTGRES_PASSWORD=benchmarkdbpass -e POSTGRES_DB=hello_world -p 5432:5432 postgres:12
+
+Then edit the `application.properties` resource, so to point to the database on localhost.
+
+On first run make sure you set Hibernate to create the schema:
+
+ quarkus.hibernate-orm.database.generation=drop-and-create
+
+Build the application (might need to have installed the parent and dependencies first):
+
+ mvn clean package
+
+Run the application
+
+ ./start-app.sh
+
+If you just created the DB schema, you will need to create the test data. Hit this endpoint once:
+
+ http://127.0.0.1:8080/createdata
+
+Generate load on the application to test / profile it. I suggest to use `https://github.com/giltene/wrk2`.
+
+Example run, assuming you have built wrk2 in `~/sources/wrk2` :
+
+ ~/sources/wrk2/wrk -c 100 -d 60 -R 400 http://localhost:8080/db
+
+The URL `http://localhost:8080/db` represents one specific benchmark; there are several more to try
+but you will likely want to focus on them one at a time.
+
+
+## Test URLs
+
+### Plaintext Test
+
+ http://localhost:8080/plaintext
+
+### JSON Encoding Test
+
+ http://localhost:8080/json
+
+### Database Query Test
+
+ http://localhost:8080/db
+
+### Database Queries Test
+
+ http://localhost:8080/queries?queries=5
+
+### Database Update Test
+
+ http://localhost:8080/updates?queries=5
+
+### Template rendering Test
+
+ http://localhost:8080/fortunes
+
+## Full verification
+
+Use the main Techempower script in the root to run all official verifications:
+
+./tfb --type all --mode verify --test quarkus-hibernate
+
+## Run the benchmark
+
+./tfb --type all --mode benchmark --test quarkus-hibernate
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/pom.xml b/frameworks/Java/quarkus/resteasy-reactive-hibernate/pom.xml
new file mode 100644
index 00000000000..2336a8ee4c5
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/pom.xml
@@ -0,0 +1,44 @@
+
+
+ 4.0.0
+
+
+ io.quarkus
+ benchmark
+ 1.0-SNAPSHOT
+ ../
+
+
+ io.quarkus.benchmark
+ resteasy-reactive-hibernate
+
+
+
+ io.quarkus
+ quarkus-hibernate-orm
+
+
+ io.quarkus
+ quarkus-scheduler
+
+
+ io.quarkus
+ quarkus-resteasy-reactive
+
+
+ io.quarkus
+ quarkus-resteasy-reactive-jackson
+
+
+ io.quarkus
+ quarkus-jdbc-postgresql
+
+
+ com.github.spullara.mustache.java
+ compiler
+ 0.9.6
+
+
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java
new file mode 100644
index 00000000000..322517a3d40
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/cdi/HibernateOrmNativeComponents.java
@@ -0,0 +1,24 @@
+package io.quarkus.benchmark.cdi;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Typed;
+import javax.inject.Singleton;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnit;
+
+import org.hibernate.SessionFactory;
+
+@Singleton
+public class HibernateOrmNativeComponents {
+
+ @PersistenceUnit
+ EntityManagerFactory entityManagerFactory;
+
+ @Singleton
+ @Typed(SessionFactory.class)
+ @Produces
+ SessionFactory extractSessionFactory() {
+ return entityManagerFactory.unwrap( SessionFactory.class );
+ }
+
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
new file mode 100644
index 00000000000..7043dd284e2
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
@@ -0,0 +1,32 @@
+package io.quarkus.benchmark.filter;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import javax.inject.Singleton;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Provider;
+
+import io.quarkus.scheduler.Scheduled;
+
+@Singleton
+@Provider
+public class ServerHeaderFilter implements ContainerResponseFilter {
+
+ private String date;
+
+ @Scheduled(every="1s")
+ void increment() {
+ date = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now());
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
+ final MultivaluedMap headers = responseContext.getHeaders();
+ headers.add( "Server", "Quarkus");
+ headers.add( "Date", date);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/model/Fortune.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/model/Fortune.java
new file mode 100644
index 00000000000..5228080b02b
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/model/Fortune.java
@@ -0,0 +1,56 @@
+package io.quarkus.benchmark.model;
+
+import org.hibernate.annotations.Immutable;
+
+import java.util.Objects;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Immutable
+public class Fortune {
+
+ @Id
+ private int id;
+ private String message;
+
+ public Fortune() {}
+
+ public Fortune(int id, String message) {
+ this.id = id;
+ this.message = message;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ Fortune fortune = (Fortune) o;
+ return id == fortune.id &&
+ Objects.equals(message, fortune.message);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, message);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/model/World.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/model/World.java
new file mode 100644
index 00000000000..a9a2acc4a82
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/model/World.java
@@ -0,0 +1,29 @@
+package io.quarkus.benchmark.model;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class World {
+
+ @Id
+ private int id;
+ private int randomNumber;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getRandomNumber() {
+ return randomNumber;
+ }
+
+ public void setRandomNumber(int randomNumber) {
+ this.randomNumber = randomNumber;
+ }
+
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
new file mode 100644
index 00000000000..9b845ee39e9
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
@@ -0,0 +1,31 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.StatelessSession;
+
+import io.quarkus.benchmark.model.Fortune;
+
+@Singleton
+public class FortuneRepository {
+
+ @Inject
+ SessionFactory sf;
+
+ public List findAllStateless() {
+ try (StatelessSession s = sf.openStatelessSession()) {
+ CriteriaBuilder criteriaBuilder = sf.getCriteriaBuilder();
+ CriteriaQuery fortuneQuery = criteriaBuilder.createQuery(Fortune.class);
+ Root from = fortuneQuery.from(Fortune.class);
+ fortuneQuery.select(from);
+ return s.createQuery(fortuneQuery).getResultList();
+ }
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
new file mode 100644
index 00000000000..ee05796d892
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
@@ -0,0 +1,77 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.transaction.Transactional;
+
+import org.hibernate.FlushMode;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.StatelessSession;
+
+import io.quarkus.benchmark.model.World;
+
+
+@Singleton
+public class WorldRepository {
+
+ @Inject
+ SessionFactory sf;
+
+ /**
+ * This method is not required (nor specified) by the benchmark rules,
+ * but is quite handy to seed a local database and be able to experiment
+ * with the app locally.
+ */
+ @Transactional
+ public void createData() {
+ try (StatelessSession statelessSession = sf.openStatelessSession()) {
+ final ThreadLocalRandom random = ThreadLocalRandom.current();
+ for (int i=1; i<=10000; i++) {
+ final World world = new World();
+ world.setId(i);
+ world.setRandomNumber(1 + random.nextInt(10000));
+ statelessSession.insert(world);
+ }
+ }
+ }
+
+ public World findSingleAndStateless(int id) {
+ try (StatelessSession ss = sf.openStatelessSession()) {
+ return singleStatelessWorldLoad(ss,id);
+ }
+ }
+
+ @Transactional
+ public void updateAll(Collection worlds) {
+ try (Session s = sf.openSession()) {
+ s.setJdbcBatchSize(worlds.size());
+ s.setHibernateFlushMode(FlushMode.MANUAL);
+ for (World w : worlds) {
+ s.update(w);
+ }
+ s.flush();
+ }
+ }
+
+ public Collection findReadonly(Set ids) {
+ try (StatelessSession s = sf.openStatelessSession()) {
+ //The rules require individual load: we can't use the Hibernate feature which allows load by multiple IDs as one single operation
+ ArrayList l = new ArrayList<>(ids.size());
+ for (Integer id : ids) {
+ l.add(singleStatelessWorldLoad(s,id));
+ }
+ return l;
+ }
+ }
+
+ private static World singleStatelessWorldLoad(final StatelessSession ss, final Integer id) {
+ return (World) ss.get(World.class, id);
+ }
+
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/DbResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/DbResource.java
new file mode 100644
index 00000000000..0354cc3aadd
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/DbResource.java
@@ -0,0 +1,137 @@
+package io.quarkus.benchmark.resource;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import io.quarkus.benchmark.model.World;
+import io.quarkus.benchmark.repository.WorldRepository;
+import io.smallrye.common.annotation.Blocking;
+
+
+@Singleton
+@Path("/")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class DbResource {
+
+ @Inject
+ WorldRepository worldRepository;
+
+ @Blocking
+ @GET
+ @Path("/db")
+ public World db() {
+ World world = randomWorldForRead();
+ if (world==null) throw new IllegalStateException( "No data found in DB. Did you seed the database? Make sure to invoke /createdata once." );
+ return world;
+ }
+
+ @Blocking
+ @GET
+ @Path("/queries")
+ public World[] queries(@QueryParam("queries") String queries) {
+ final int count = parseQueryCount(queries);
+ World[] worlds = randomWorldForRead(count).toArray(new World[0]);
+ return worlds;
+ }
+
+ @Blocking
+ @GET
+ @Path("/updates")
+ //Rules: https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#database-updates
+ //N.B. the benchmark seems to be designed to get in deadlocks when using a "safe pattern" of updating
+ // the entity within the same transaction as the one which read it.
+ // We therefore need to do a "read then write" while relinquishing the transaction between the two operations, as
+ // all other tested frameworks seem to do.
+ public World[] updates(@QueryParam("queries") String queries) {
+ final int count = parseQueryCount(queries);
+ final Collection worlds = randomWorldForRead(count);
+ worlds.forEach( w -> {
+ //Read the one field, as required by the following rule:
+ // # vi. At least the randomNumber field must be read from the database result set.
+ final int previousRead = w.getRandomNumber();
+ //Update it, but make sure to exclude the current number as Hibernate optimisations would have us "fail"
+ //the verification:
+ w.setRandomNumber(randomWorldNumber(previousRead));
+ } );
+ worldRepository.updateAll(worlds);
+ return worlds.toArray(new World[0]);
+ }
+
+ @Blocking
+ @GET
+ @Path( "/createdata" )
+ public String createData() {
+ worldRepository.createData();
+ return "OK";
+ }
+
+ private World randomWorldForRead() {
+ return worldRepository.findSingleAndStateless(randomWorldNumber());
+ }
+
+ private Collection randomWorldForRead(int count) {
+ Set ids = new HashSet<>(count);
+ int counter = 0;
+ while (counter < count) {
+ counter += ids.add(Integer.valueOf(randomWorldNumber())) ? 1 : 0;
+ }
+ return worldRepository.findReadonly(ids);
+ }
+
+ /**
+ * According to benchmark requirements
+ * @return returns a number from 1 to 10000
+ */
+ private int randomWorldNumber() {
+ return 1 + ThreadLocalRandom.current().nextInt(10000);
+ }
+
+
+ /**
+ * Also according to benchmark requirements, except that in this special case
+ * of the update test we need to ensure we'll actually generate an update operation:
+ * for this we need to generate a random number between 1 to 10000, but different
+ * from the current field value.
+ * @param previousRead
+ * @return
+ */
+ private int randomWorldNumber(final int previousRead) {
+ //conceptually split the random space in those before previousRead,
+ //and those after: this approach makes sure to not affect the random characteristics.
+ final int trueRandom = ThreadLocalRandom.current().nextInt(9999) + 2;
+ if (trueRandom<=previousRead) {
+ //all figures equal or before the current field read need to be shifted back by one
+ //so to avoid hitting the same number while not affecting the distribution.
+ return trueRandom - 1;
+ }
+ else {
+ //Those after are generated by taking the generated value 2...10000 as is.
+ return trueRandom;
+ }
+ }
+
+ private int parseQueryCount(String textValue) {
+ if (textValue == null) {
+ return 1;
+ }
+ int parsedValue;
+ try {
+ parsedValue = Integer.parseInt(textValue);
+ } catch (NumberFormatException e) {
+ return 1;
+ }
+ return Math.min(500, Math.max(1, parsedValue));
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
new file mode 100644
index 00000000000..2724a301a9d
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
@@ -0,0 +1,56 @@
+package io.quarkus.benchmark.resource;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.quarkus.benchmark.repository.FortuneRepository;
+import io.smallrye.common.annotation.Blocking;
+
+@Singleton
+@Path("/")
+@Produces(MediaType.TEXT_HTML+"; charset=UTF-8")
+@Consumes(MediaType.APPLICATION_JSON)
+public class FortuneResource {
+
+ @Inject
+ FortuneRepository repository;
+
+ private final Mustache template;
+ private final Comparator fortuneComparator;
+
+ public FortuneResource() {
+ MustacheFactory mf = new DefaultMustacheFactory();
+ template = mf.compile("fortunes.mustache");
+ fortuneComparator = Comparator.comparing(fortune -> fortune.getMessage());
+ }
+
+ @Blocking
+ @GET
+ @Path("/fortunes")
+ public String fortunes() {
+ List fortunes = new ArrayList<>(repository.findAllStateless());
+ fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+ fortunes.sort(fortuneComparator);
+
+ StringWriter writer = new StringWriter();
+ template.execute(writer, Collections.singletonMap("fortunes", fortunes));
+
+ return writer.toString();
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
new file mode 100644
index 00000000000..c8bbb155545
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
@@ -0,0 +1,18 @@
+package io.quarkus.benchmark.resource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/json")
+public class JsonResource {
+ private static final String HELLO = "Hello, World!";
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Message json() {
+ return new Message(HELLO);
+ }
+}
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/Message.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/Message.java
new file mode 100644
index 00000000000..73f0ffefb8a
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/Message.java
@@ -0,0 +1,13 @@
+package io.quarkus.benchmark.resource;
+
+public class Message {
+ private final String message;
+
+ public Message(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
new file mode 100644
index 00000000000..8acadbfeb7e
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
@@ -0,0 +1,17 @@
+package io.quarkus.benchmark.resource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/plaintext")
+public class PlaintextResource {
+ private static final String HELLO = "Hello, World!";
+
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String plaintext() {
+ return HELLO;
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/application.properties b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/application.properties
new file mode 100644
index 00000000000..756e8f174d3
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/application.properties
@@ -0,0 +1,30 @@
+#Test preferQueryMode ? sendBufferSize ? receiveBufferSize ?
+#disableColumnSanitiser requires lower case column names
+quarkus.datasource.db-kind=postgresql
+quarkus.datasource.username=benchmarkdbuser
+quarkus.datasource.password=benchmarkdbpass
+quarkus.datasource.jdbc.url=jdbc:postgresql://tfb-database:5432/hello_world?loggerLevel=OFF&disableColumnSanitiser=true&assumeMinServerVersion=12&sslmode=disable
+%dev.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/hello_world?loggerLevel=OFF&disableColumnSanitiser=true&assumeMinServerVersion=12&sslmode=disable
+quarkus.datasource.jdbc.driver=org.postgresql.Driver
+quarkus.datasource.jdbc.transactions=disabled
+quarkus.datasource.jdbc.detect-statement-leaks=false
+quarkus.datasource.jdbc.max-size=64
+quarkus.datasource.jdbc.min-size=16
+quarkus.datasource.jdbc.initial-size=64
+
+quarkus.log.console.enable=true
+quarkus.log.console.level=INFO
+quarkus.log.file.enable=false
+quarkus.log.level=INFO
+
+# Fully disable Hibernate ORM statistics gathering::
+quarkus.log.category."org.hibernate.engine.internal.StatisticalLoggingSessionEventListener".level=WARN
+
+# To create the schema:
+%dev.quarkus.hibernate-orm.database.generation=drop-and-create
+%dev.quarkus.hibernate-orm.sql-load-script=import.sql
+quarkus.hibernate-orm.database.generation=validate
+quarkus.hibernate-orm.log.sql=false
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/fortunes.mustache b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/fortunes.mustache
new file mode 100644
index 00000000000..f9664a72eee
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/fortunes.mustache
@@ -0,0 +1,20 @@
+
+
+
+ Fortunes
+
+
+
+
+ id |
+ message |
+
+ {{#fortunes}}
+
+ {{id}} |
+ {{message}} |
+
+ {{/fortunes}}
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/import.sql b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/import.sql
new file mode 100644
index 00000000000..f76881b4287
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/resources/import.sql
@@ -0,0 +1 @@
+INSERT INTO Fortune(id, message) VALUES (1, 'Test value One');
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/start-app.sh b/frameworks/Java/quarkus/resteasy-reactive-hibernate/start-app.sh
new file mode 100755
index 00000000000..f224e71fb26
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/start-app.sh
@@ -0,0 +1 @@
+java -XX:+FlightRecorder -XX:+UseParallelGC -Dquarkus.datasource.url=jdbc:postgresql://localhost:5432/hello_world?loggerLevel=OFF\&disableColumnSanitiser=true\&assumeMinServerVersion=12\&sslmode=disable -Dquarkus.http.host=127.0.0.1 -Djava.lang.Integer.IntegerCache.high=10000 -Dvertx.disableHttpHeadersValidation=true -Dvertx.disableMetrics=true -Dvertx.disableH2c=true -Dvertx.disableWebsockets=true -Dvertx.flashPolicyHandler=false -Dvertx.threadChecks=false -Dvertx.disableContextTimings=true -Dvertx.disableTCCL=true -Dhibernate.allow_update_outside_transaction=true -Djboss.threads.eqe.statistics=false -jar target/hibernate-1.0-SNAPSHOT-runner.jar
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/.factorypath b/frameworks/Java/quarkus/resteasy-reactive-pgclient/.factorypath
new file mode 100644
index 00000000000..268ec46be2b
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/.factorypath
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/pom.xml b/frameworks/Java/quarkus/resteasy-reactive-pgclient/pom.xml
new file mode 100644
index 00000000000..eca074a80a1
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+
+ io.quarkus
+ benchmark
+ 1.0-SNAPSHOT
+ ../
+
+
+ io.quarkus.benchmark
+ resteasy-reactive-pgclient
+
+
+
+ io.quarkus
+ quarkus-scheduler
+
+
+ io.quarkus
+ quarkus-reactive-pg-client
+
+
+ io.quarkus
+ quarkus-resteasy-reactive
+
+
+ io.quarkus
+ quarkus-resteasy-reactive-jackson
+
+
+ io.vertx
+ vertx-web-templ-rocker
+
+
+ io.netty
+ netty-transport-native-epoll
+ linux-x86_64
+
+
+ com.github.spullara.mustache.java
+ compiler
+ 0.9.6
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
new file mode 100644
index 00000000000..d19fe291e53
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/filter/ServerHeaderFilter.java
@@ -0,0 +1,33 @@
+package io.quarkus.benchmark.filter;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import javax.inject.Singleton;
+
+import org.jboss.resteasy.reactive.server.ServerResponseFilter;
+
+import io.quarkus.scheduler.Scheduled;
+import io.vertx.core.http.HttpHeaders;
+import io.vertx.core.http.HttpServerResponse;
+
+@Singleton
+public class ServerHeaderFilter {
+
+ private static final CharSequence SERVER_HEADER_NAME = HttpHeaders.createOptimized("Server");
+ private static final CharSequence SERVER_HEADER_VALUE = HttpHeaders.createOptimized("Quarkus");
+ private static final CharSequence DATE_HEADER_NAME = HttpHeaders.createOptimized("Date");
+
+ private CharSequence date;
+
+ @Scheduled(every="1s")
+ void increment() {
+ date = HttpHeaders.createOptimized(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
+ }
+
+ @ServerResponseFilter
+ public void filter(HttpServerResponse response) {
+ response.putHeader(SERVER_HEADER_NAME, SERVER_HEADER_VALUE);
+ response.putHeader(DATE_HEADER_NAME, date);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/model/Fortune.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/model/Fortune.java
new file mode 100644
index 00000000000..0e32970c9db
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/model/Fortune.java
@@ -0,0 +1,48 @@
+package io.quarkus.benchmark.model;
+
+import java.util.Objects;
+
+public class Fortune {
+
+ private int id;
+ private String message;
+
+ public Fortune() {}
+
+ public Fortune(int id, String message) {
+ this.id = id;
+ this.message = message;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ Fortune fortune = (Fortune) o;
+ return id == fortune.id &&
+ Objects.equals(message, fortune.message);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, message);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/model/World.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/model/World.java
new file mode 100644
index 00000000000..0d5205ae361
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/model/World.java
@@ -0,0 +1,35 @@
+package io.quarkus.benchmark.model;
+
+public class World implements Comparable{
+
+ private int id;
+ private int randomNumber;
+
+ public World() {}
+
+ public World(int id, int randomNumber) {
+ this.id = id;
+ this.randomNumber = randomNumber;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getRandomNumber() {
+ return randomNumber;
+ }
+
+ public void setRandomNumber(int randomNumber) {
+ this.randomNumber = randomNumber;
+ }
+
+ @Override
+ public int compareTo(World o) {
+ return Integer.compare(id, o.id);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
new file mode 100644
index 00000000000..4415583fa1d
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/FortuneRepository.java
@@ -0,0 +1,30 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.smallrye.mutiny.Uni;
+import io.vertx.mutiny.sqlclient.Row;
+
+@ApplicationScoped
+public class FortuneRepository {
+
+ @Inject
+ PgClients clients;
+
+ public Uni> findAll() {
+ return clients.getClient().preparedQuery("SELECT * FROM Fortune" )
+ .execute()
+ .map(rowset -> {
+ List ret = new ArrayList<>(rowset.size()+1);
+ for(Row r : rowset) {
+ ret.add(new Fortune(r.getInteger("id"), r.getString("message")));
+ }
+ return ret;
+ });
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClientFactory.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClientFactory.java
new file mode 100644
index 00000000000..ef99489cb26
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClientFactory.java
@@ -0,0 +1,56 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+import io.vertx.mutiny.core.Vertx;
+import io.vertx.mutiny.pgclient.PgPool;
+import io.vertx.pgclient.PgConnectOptions;
+import io.vertx.sqlclient.PoolOptions;
+
+@ApplicationScoped
+public class PgClientFactory {
+
+ // vertx-reactive:postgresql://tfb-database:5432/hello_world
+ private static final String PG_URI_MATCHER = "vertx-reactive:postgresql://([-a-zA-Z]+):([0-9]+)/(.*)";
+
+ @ConfigProperty(name = "quarkus.datasource.url")
+ String url;
+
+ @ConfigProperty(name = "quarkus.datasource.username")
+ String user;
+
+ @ConfigProperty(name = "quarkus.datasource.password")
+ String pass;
+
+ @Inject
+ Vertx vertx;
+
+ @Produces
+ @ApplicationScoped
+ public PgClients pgClients() {
+ return new PgClients(this);
+ }
+
+
+ PgPool sqlClient(int size) {
+ PoolOptions options = new PoolOptions();
+ PgConnectOptions connectOptions = new PgConnectOptions();
+ Matcher matcher = Pattern.compile(PG_URI_MATCHER).matcher(url);
+ matcher.matches();
+ connectOptions.setDatabase(matcher.group(3));
+ connectOptions.setHost(matcher.group(1));
+ connectOptions.setPort(Integer.parseInt(matcher.group(2)));
+ connectOptions.setUser(user);
+ connectOptions.setPassword(pass);
+ connectOptions.setCachePreparedStatements(true);
+ options.setMaxSize(size);
+ return PgPool.pool(vertx, connectOptions, options);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClients.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClients.java
new file mode 100644
index 00000000000..871e9b75a6e
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/PgClients.java
@@ -0,0 +1,38 @@
+package io.quarkus.benchmark.repository;
+
+import io.vertx.mutiny.pgclient.PgPool;
+import io.vertx.mutiny.sqlclient.SqlClient;
+
+class PgClients {
+ private static final int POOL_SIZE = 4;
+
+ private ThreadLocal sqlClient = new ThreadLocal<>();
+ private ThreadLocal pool = new ThreadLocal<>();
+ private PgClientFactory pgClientFactory;
+
+ // for ArC
+ public PgClients() {
+ }
+
+ public PgClients(PgClientFactory pgClientFactory) {
+ this.pgClientFactory = pgClientFactory;
+ }
+
+ SqlClient getClient() {
+ SqlClient ret = sqlClient.get();
+ if(ret == null) {
+ ret = pgClientFactory.sqlClient(1);
+ sqlClient.set(ret);
+ }
+ return ret;
+ }
+
+ synchronized PgPool getPool() {
+ PgPool ret = pool.get();
+ if(ret == null) {
+ ret = pgClientFactory.sqlClient(POOL_SIZE);
+ pool.set(ret);
+ }
+ return ret;
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
new file mode 100644
index 00000000000..2d9c71d1259
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java
@@ -0,0 +1,40 @@
+package io.quarkus.benchmark.repository;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import io.quarkus.benchmark.model.World;
+import io.smallrye.mutiny.Uni;
+import io.vertx.mutiny.sqlclient.Row;
+import io.vertx.mutiny.sqlclient.Tuple;
+
+@ApplicationScoped
+public class WorldRepository {
+
+ @Inject
+ PgClients clients;
+
+ public Uni find(int id) {
+ return clients.getClient().preparedQuery("SELECT id, randomNumber FROM World WHERE id = $1")
+ .execute(Tuple.of(id))
+ .map(rowset -> {
+ Row row = rowset.iterator().next();
+ return new World(row.getInteger(0), row.getInteger(1));
+ });
+ }
+
+ public Uni update(World[] worlds) {
+ Arrays.sort(worlds);
+ List args = new ArrayList<>(worlds.length);
+ for (World world : worlds) {
+ args.add(Tuple.of(world.getId(), world.getRandomNumber()));
+ }
+ return clients.getPool().preparedQuery("UPDATE World SET randomNumber = $2 WHERE id = $1")
+ .executeBatch(args)
+ .map(v -> null);
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/DbResource.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/DbResource.java
new file mode 100644
index 00000000000..fe87893d095
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/DbResource.java
@@ -0,0 +1,83 @@
+package io.quarkus.benchmark.resource;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import io.quarkus.benchmark.model.World;
+import io.quarkus.benchmark.repository.WorldRepository;
+import io.smallrye.mutiny.Uni;
+
+@Produces(MediaType.APPLICATION_JSON)
+@Path("/")
+public class DbResource {
+
+ @Inject
+ WorldRepository worldRepository;
+
+ @GET
+ @Path("db")
+ public Uni db() {
+ return randomWorld();
+ }
+
+ @GET
+ @Path("queries")
+ public Uni> queries(@QueryParam("queries") String queries) {
+ var worlds = new Uni[parseQueryCount(queries)];
+ var ret = new World[worlds.length];
+ Arrays.setAll(worlds, i -> {
+ return randomWorld().map(w -> ret[i] = w);
+ });
+
+ return Uni.combine().all().unis(worlds)
+ .combinedWith(v -> Arrays.asList(ret));
+ }
+
+ @GET
+ @Path("updates")
+ public Uni> updates(@QueryParam("queries") String queries) {
+ var worlds = new Uni[parseQueryCount(queries)];
+ var ret = new World[worlds.length];
+ Arrays.setAll(worlds, i -> {
+ return randomWorld().map(w -> {
+ w.setRandomNumber(randomWorldNumber());
+ ret[i] = w;
+ return w;
+ });
+ });
+
+ return Uni.combine().all().unis(worlds)
+ .combinedWith(v -> null)
+ .flatMap(v -> worldRepository.update(ret))
+ .map(v -> Arrays.asList(ret));
+ }
+
+ private Uni randomWorld() {
+ return worldRepository.find(randomWorldNumber());
+ }
+
+ private int randomWorldNumber() {
+ return 1 + ThreadLocalRandom.current().nextInt(10000);
+ }
+
+ private int parseQueryCount(String textValue) {
+ if (textValue == null) {
+ return 1;
+ }
+ int parsedValue;
+ try {
+ parsedValue = Integer.parseInt(textValue);
+ } catch (NumberFormatException e) {
+ return 1;
+ }
+ return Math.min(500, Math.max(1, parsedValue));
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
new file mode 100644
index 00000000000..4b23849cb2e
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/FortuneResource.java
@@ -0,0 +1,47 @@
+package io.quarkus.benchmark.resource;
+
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Comparator;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
+
+import io.quarkus.benchmark.model.Fortune;
+import io.quarkus.benchmark.repository.FortuneRepository;
+import io.smallrye.mutiny.Uni;
+
+@Path("/fortunes")
+public class FortuneResource {
+
+ @Inject
+ FortuneRepository repository;
+ private Mustache template;
+ private Comparator fortuneComparator;
+
+
+ public FortuneResource() {
+ MustacheFactory mf = new DefaultMustacheFactory();
+ template = mf.compile("fortunes.mustache");
+ fortuneComparator = Comparator.comparing(fortune -> fortune.getMessage());
+ }
+
+ @Produces("text/html; charset=UTF-8")
+ @GET
+ public Uni fortunes() {
+ return repository.findAll()
+ .map(fortunes -> {
+ fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+ fortunes.sort(fortuneComparator);
+ StringWriter writer = new StringWriter();
+ template.execute(writer, Collections.singletonMap("fortunes", fortunes));
+ return writer.toString();
+ });
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/JsonResource.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
new file mode 100644
index 00000000000..c1cd3a3eb14
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/JsonResource.java
@@ -0,0 +1,19 @@
+package io.quarkus.benchmark.resource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/json")
+public class JsonResource {
+
+ private static final String HELLO = "Hello, World!";
+
+ @Produces(MediaType.APPLICATION_JSON)
+ @GET
+ public Message json() {
+ return new Message(HELLO);
+ }
+}
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/Message.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/Message.java
new file mode 100644
index 00000000000..73f0ffefb8a
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/Message.java
@@ -0,0 +1,13 @@
+package io.quarkus.benchmark.resource;
+
+public class Message {
+ private final String message;
+
+ public Message(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
new file mode 100644
index 00000000000..58094ad21ef
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/java/io/quarkus/benchmark/resource/PlaintextResource.java
@@ -0,0 +1,20 @@
+package io.quarkus.benchmark.resource;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import io.vertx.core.buffer.Buffer;
+
+@Path("/plaintext")
+public class PlaintextResource {
+ private static final String HELLO_WORLD = "Hello, world!";
+ private static final Buffer HELLO_WORLD_BUFFER = Buffer.factory.directBuffer(HELLO_WORLD, "UTF-8");
+
+ @Produces(MediaType.TEXT_PLAIN)
+ @GET
+ public Buffer plaintext() {
+ return HELLO_WORLD_BUFFER;
+ }
+}
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/resources/application.properties b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/resources/application.properties
new file mode 100644
index 00000000000..0a1d6083f99
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/resources/application.properties
@@ -0,0 +1,10 @@
+quarkus.datasource.url=vertx-reactive:postgresql://tfb-database:5432/hello_world
+%dev.quarkus.datasource.url=vertx-reactive:postgresql://localhost:5432/hello_world
+quarkus.datasource.username=benchmarkdbuser
+quarkus.datasource.password=benchmarkdbpass
+quarkus.datasource.reactive.max-size=64
+quarkus.log.console.enable=true
+quarkus.log.console.level=INFO
+quarkus.log.file.enable=false
+quarkus.log.level=INFO
+quarkus.vertx.prefer-native-transport=true
\ No newline at end of file
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/resources/fortunes.mustache b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/resources/fortunes.mustache
new file mode 100644
index 00000000000..f9664a72eee
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/src/main/resources/fortunes.mustache
@@ -0,0 +1,20 @@
+
+
+
+ Fortunes
+
+
+
+
+ id |
+ message |
+
+ {{#fortunes}}
+
+ {{id}} |
+ {{message}} |
+
+ {{/fortunes}}
+
+
+
diff --git a/frameworks/Java/quarkus/resteasy-reactive-pgclient/start-app.sh b/frameworks/Java/quarkus/resteasy-reactive-pgclient/start-app.sh
new file mode 100755
index 00000000000..01b3e22ea2c
--- /dev/null
+++ b/frameworks/Java/quarkus/resteasy-reactive-pgclient/start-app.sh
@@ -0,0 +1,2 @@
+java -XX:+FlightRecorder -XX:+UseParallelGC -Dquarkus.datasource.url=vertx-reactive:postgresql://localhost:5432/hello_world -Dquarkus.http.host=127.0.0.1 -Djava.lang.Integer.IntegerCache.high=10000 -Dvertx.disableHttpHeadersValidation=true -Dvertx.disableMetrics=true -Dvertx.disableH2c=true -Dvertx.disableWebsockets=true -Dvertx.flashPolicyHandler=false -Dvertx.threadChecks=false -Dvertx.disableContextTimings=true -Dvertx.disableTCCL=true -Dhibernate.allow_update_outside_transaction=true -Djboss.threads.eqe.statistics=false -jar target/pgclient-1.0-SNAPSHOT-runner.jar
+