diff --git a/frameworks/Java/helidon/nima/pom.xml b/frameworks/Java/helidon/nima/pom.xml
index c859b758cfc..0d312c8eed8 100644
--- a/frameworks/Java/helidon/nima/pom.xml
+++ b/frameworks/Java/helidon/nima/pom.xml
@@ -21,7 +21,7 @@
io.helidon.applications
helidon-se
- 4.1.2
+ 4.1.5
@@ -38,6 +38,7 @@
1.3.0
4.5.3
0.9.23
+ 3.1.15
@@ -78,9 +79,9 @@
42.6.1
- com.fizzed
- rocker-runtime
- ${rocker.version}
+ gg.jte
+ jte
+ ${jte.version}
io.helidon.common.testing
@@ -98,7 +99,6 @@
test
-
@@ -125,20 +125,21 @@
+
- com.fizzed
- rocker-maven-plugin
- ${rocker.version}
+ gg.jte
+ jte-maven-plugin
+ ${jte.version}
+
+ ${project.basedir}/src/main/resources/views
+ Html
+
- generate-rocker-templates
generate-sources
generate
-
- src/main/resources
-
diff --git a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/JsonSerializer.java b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/JsonSerializer.java
index 322a7cf030c..0564fa8a911 100644
--- a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/JsonSerializer.java
+++ b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/JsonSerializer.java
@@ -2,8 +2,8 @@
import java.io.IOException;
import java.util.Arrays;
-import java.util.Map;
import java.util.List;
+import java.util.Map;
import com.jsoniter.output.JsonStream;
import com.jsoniter.output.JsonStreamPool;
@@ -15,7 +15,7 @@ private JsonSerializer() {
}
/**
- * Serialize an instance into a JSON object and return it as a byte array.
+ * Serialize an instance into a byte array.
*
* @param obj the instance
* @return the byte array
@@ -28,19 +28,31 @@ public static byte[] serialize(Object obj) {
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
} catch (IOException e) {
throw new JsonException(e);
- } finally {
- JsonStreamPool.returnJsonStream(stream);
}
}
/**
- * Serialize a map of strings into a JSON object and return it as a byte array.
+ * Serialize an instance into a JSON stream.
+ *
+ * @param obj the instance
+ * @param stream the JSON stream
+ */
+ public static void serialize(Object obj, JsonStream stream) {
+ try {
+ stream.reset(null);
+ stream.writeVal(obj.getClass(), obj);
+ } catch (IOException e) {
+ throw new JsonException(e);
+ }
+ }
+
+ /**
+ * Serialize a map of strings into a JSON stream.
*
* @param map the map
- * @return the byte array
+ * @param stream the JSON stream
*/
- public static byte[] serialize(Map map) {
- JsonStream stream = JsonStreamPool.borrowJsonStream();
+ public static void serialize(Map map, JsonStream stream) {
try {
stream.reset(null);
stream.writeObjectStart();
@@ -53,22 +65,18 @@ public static byte[] serialize(Map map) {
}
});
stream.writeObjectEnd();
- return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
} catch (IOException e) {
throw new JsonException(e);
- } finally {
- JsonStreamPool.returnJsonStream(stream);
}
}
/**
- * Serialize a list of objects into a JSON array and return it as a byte array.
+ * Serialize a list of objects into a JSON stream.
*
* @param objs the list of objects
- * @return the byte array
+ * @param stream the JSON stream
*/
- public static byte[] serialize(List> objs) {
- JsonStream stream = JsonStreamPool.borrowJsonStream();
+ public static void serialize(List> objs, JsonStream stream) {
try {
stream.reset(null);
stream.writeArrayStart();
@@ -82,11 +90,8 @@ public static byte[] serialize(List> objs) {
}
stream.writeArrayEnd();
- return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
} catch (IOException e) {
throw new JsonException(e);
- } finally {
- JsonStreamPool.returnJsonStream(stream);
}
}
}
diff --git a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/Main.java b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/Main.java
index df669d8a7a7..800ce927537 100644
--- a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/Main.java
+++ b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022 Oracle and/or its affiliates.
+ * Copyright (c) 2022, 2025 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,16 +19,18 @@
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;
+import com.jsoniter.output.JsonStream;
+import com.jsoniter.output.JsonStreamPool;
import io.helidon.benchmark.nima.models.DbRepository;
import io.helidon.benchmark.nima.models.HikariJdbcRepository;
import io.helidon.benchmark.nima.models.PgClientRepository;
import io.helidon.benchmark.nima.services.DbService;
import io.helidon.benchmark.nima.services.FortuneHandler;
+import io.helidon.config.Config;
+import io.helidon.config.ConfigException;
import io.helidon.http.Header;
import io.helidon.http.HeaderNames;
import io.helidon.http.HeaderValues;
-import io.helidon.config.Config;
-import io.helidon.config.ConfigException;
import io.helidon.logging.common.LogConfig;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.http.Handler;
@@ -93,7 +95,7 @@ static void routing(HttpRules rules) {
static class PlaintextHandler implements Handler {
static final Header CONTENT_TYPE = HeaderValues.createCached(HeaderNames.CONTENT_TYPE,
- "text/plain; charset=UTF-8");
+ "text/plain; charset=UTF-8");
static final Header CONTENT_LENGTH = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH, "13");
private static final byte[] RESPONSE_BYTES = "Hello, World!".getBytes(StandardCharsets.UTF_8);
@@ -110,14 +112,20 @@ static class JsonHandler implements Handler {
private static final String MESSAGE = "Hello, World!";
private static final int JSON_LENGTH = serialize(new Message(MESSAGE)).length;
static final Header CONTENT_LENGTH = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH,
- String.valueOf(JSON_LENGTH));
+ String.valueOf(JSON_LENGTH));
@Override
public void handle(ServerRequest req, ServerResponse res) {
- res.header(CONTENT_LENGTH);
- res.header(HeaderValues.CONTENT_TYPE_JSON);
- res.header(Main.SERVER);
- res.send(serialize(new Message(MESSAGE)));
+ JsonStream stream = JsonStreamPool.borrowJsonStream();
+ try {
+ res.header(CONTENT_LENGTH);
+ res.header(HeaderValues.CONTENT_TYPE_JSON);
+ res.header(Main.SERVER);
+ serialize(new Message(MESSAGE), stream);
+ res.send(stream.buffer().data(), 0, stream.buffer().tail());
+ } finally {
+ JsonStreamPool.returnJsonStream(stream);
+ }
}
}
@@ -147,4 +155,4 @@ public String getMessage() {
return message;
}
}
-}
+}
\ No newline at end of file
diff --git a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/Fortune.java b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/Fortune.java
index 96a5e2070be..190c792d345 100644
--- a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/Fortune.java
+++ b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/Fortune.java
@@ -1,7 +1,7 @@
package io.helidon.benchmark.nima.models;
-public final class Fortune {
+public final class Fortune implements Comparable {
public int id;
public String message;
@@ -17,4 +17,8 @@ public int getId() {
public String getMessage() {
return message;
}
+ @Override
+ public int compareTo(Fortune other) {
+ return message.compareTo(other.message);
+ }
}
diff --git a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnectionPool.java b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnectionPool.java
new file mode 100644
index 00000000000..478847702cb
--- /dev/null
+++ b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnectionPool.java
@@ -0,0 +1,143 @@
+
+package io.helidon.benchmark.nima.models;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+
+import io.vertx.core.Vertx;
+import io.vertx.pgclient.PgConnectOptions;
+import io.vertx.pgclient.PgConnection;
+import io.vertx.sqlclient.PreparedQuery;
+import io.vertx.sqlclient.Row;
+import io.vertx.sqlclient.RowSet;
+
+class PgClientConnectionPool implements AutoCloseable {
+
+ private final Vertx vertx;
+ private final PgConnectOptions options;
+ private final ReentrantLock lock = new ReentrantLock();
+ private final Map connectionMap = new HashMap<>();
+
+ public PgClientConnectionPool(Vertx vertx, PgConnectOptions options) {
+ this.vertx = vertx;
+ this.options = options;
+ }
+
+ public PgClientConnection clientConnection() {
+ String carrierThread = carrierThread();
+ PgClientConnection connection = connectionMap.get(carrierThread);
+ if (connection == null) {
+ try {
+ lock.lock();
+ connection = connectionMap.get(carrierThread);
+ if (connection == null) {
+ connection = newConnection();
+ connectionMap.put(carrierThread, connection);
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ return connection;
+ }
+
+ @Override
+ public void close() {
+ try {
+ for (PgClientConnection connection : connectionMap.values()) {
+ connection.close();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private PgClientConnection newConnection() {
+ try {
+ PgConnection conn = PgConnection.connect(vertx, options)
+ .toCompletionStage().toCompletableFuture().get();
+ PgClientConnection clientConn = new PgClientConnection(conn);
+ clientConn.prepare();
+ return clientConn;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static String carrierThread() {
+ String threadName = Thread.currentThread().toString();
+ return threadName.substring(threadName.indexOf('@') + 1);
+ }
+
+ public static class PgClientConnection implements AutoCloseable {
+ static final int UPDATE_QUERIES = 500;
+ private static String SELECT_WORLD = "SELECT id, randomnumber from WORLD where id=$1";
+ private static String SELECT_FORTUNE = "SELECT * from FORTUNE";
+
+ private PreparedQuery> worldQuery;
+ private PreparedQuery> fortuneQuery;
+ private PreparedQuery>[] updateQuery;
+
+ private final PgConnection conn;
+
+ PgClientConnection(PgConnection conn) {
+ this.conn = conn;
+ }
+
+ public PgConnection pgConnection() {
+ return conn;
+ }
+
+ @Override
+ public void close() {
+ conn.close();
+ }
+
+ public PreparedQuery> worldQuery() {
+ return worldQuery;
+ }
+
+ public PreparedQuery> fortuneQuery() {
+ return fortuneQuery;
+ }
+
+ public PreparedQuery> updateQuery(int queryCount) {
+ return updateQuery[queryCount - 1];
+ }
+
+ @SuppressWarnings("unchecked")
+ void prepare() {
+ try {
+ worldQuery = conn.prepare(SELECT_WORLD)
+ .toCompletionStage().toCompletableFuture().get().query();
+ fortuneQuery = conn.prepare(SELECT_FORTUNE)
+ .toCompletionStage().toCompletableFuture().get().query();
+ updateQuery = (PreparedQuery>[]) new PreparedQuery>[UPDATE_QUERIES];
+ for (int i = 0; i < UPDATE_QUERIES; i++) {
+ updateQuery[i] = conn.prepare(singleUpdate(i + 1))
+ .toCompletionStage().toCompletableFuture().get().query();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static String singleUpdate(int count) {
+ StringBuilder sql = new StringBuilder();
+ sql.append("UPDATE WORLD SET RANDOMNUMBER = CASE ID");
+ for (int i = 0; i < count; i++) {
+ int k = i * 2 + 1;
+ sql.append(" WHEN $").append(k).append(" THEN $").append(k + 1);
+ }
+ sql.append(" ELSE RANDOMNUMBER");
+ sql.append(" END WHERE ID IN ($1");
+ for (int i = 1; i < count; i++) {
+ int k = i * 2 + 1;
+ sql.append(",$").append(k);
+ }
+ sql.append(")");
+ return sql.toString();
+ }
+ }
+}
diff --git a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientRepository.java b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientRepository.java
index 291131eca17..3f3bd2624eb 100644
--- a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientRepository.java
+++ b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientRepository.java
@@ -2,7 +2,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import io.helidon.config.Config;
@@ -10,58 +9,46 @@
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.pgclient.PgConnectOptions;
-import io.vertx.pgclient.PgPool;
-import io.vertx.sqlclient.PoolOptions;
import io.vertx.sqlclient.PreparedQuery;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowSet;
-import io.vertx.sqlclient.SqlClient;
import io.vertx.sqlclient.Tuple;
import static io.helidon.benchmark.nima.models.DbRepository.randomWorldNumber;
+import static io.helidon.benchmark.nima.models.PgClientConnectionPool.PgClientConnection.UPDATE_QUERIES;
public class PgClientRepository implements DbRepository {
private static final Logger LOGGER = Logger.getLogger(PgClientRepository.class.getName());
- private static final int UPDATE_QUERIES = 500;
- private final SqlClient updatePool;
-
- private final PreparedQuery> getFortuneQuery;
- private final PreparedQuery> getWorldQuery;
- private final PreparedQuery>[] updateWorldSingleQuery;
+ private final PgClientConnectionPool connectionPool;
@SuppressWarnings("unchecked")
public PgClientRepository(Config config) {
- Vertx vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true));
+ VertxOptions vertxOptions = new VertxOptions()
+ .setPreferNativeTransport(true)
+ .setBlockedThreadCheckInterval(100000);
+ Vertx vertx = Vertx.vertx(vertxOptions);
PgConnectOptions connectOptions = new PgConnectOptions()
.setPort(config.get("port").asInt().orElse(5432))
- .setCachePreparedStatements(config.get("cache-prepared-statements").asBoolean().orElse(true))
.setHost(config.get("host").asString().orElse("tfb-database"))
.setDatabase(config.get("db").asString().orElse("hello_world"))
.setUser(config.get("username").asString().orElse("benchmarkdbuser"))
.setPassword(config.get("password").asString().orElse("benchmarkdbpass"))
+ .setCachePreparedStatements(true)
+ .setPreparedStatementCacheMaxSize(UPDATE_QUERIES + 2)
+ .setPreparedStatementCacheSqlFilter(s -> true) // cache all
+ .setTcpNoDelay(true)
+ .setTcpQuickAck(true)
+ .setTcpKeepAlive(true)
.setPipeliningLimit(100000);
-
- int sqlPoolSize = config.get("sql-pool-size").asInt().orElse(64);
- PoolOptions clientOptions = new PoolOptions().setMaxSize(sqlPoolSize);
- LOGGER.info("sql-pool-size is " + sqlPoolSize);
-
- SqlClient queryPool = PgPool.client(vertx, connectOptions, clientOptions);
- updatePool = PgPool.client(vertx, connectOptions, clientOptions);
-
- getWorldQuery = queryPool.preparedQuery("SELECT id, randomnumber FROM world WHERE id = $1");
- getFortuneQuery = queryPool.preparedQuery("SELECT id, message FROM fortune");
-
- updateWorldSingleQuery = new PreparedQuery[UPDATE_QUERIES];
- for (int i = 0; i < UPDATE_QUERIES; i++) {
- updateWorldSingleQuery[i] = queryPool.preparedQuery(singleUpdate(i + 1));
- }
+ connectionPool = new PgClientConnectionPool(vertx, connectOptions);
}
@Override
public World getWorld(int id) {
try {
- return getWorldQuery.execute(Tuple.of(id))
+ PreparedQuery> worldQuery = connectionPool.clientConnection().worldQuery();
+ return worldQuery.execute(Tuple.of(id))
.map(rows -> {
Row r = rows.iterator().next();
return new World(r.getInteger(0), r.getInteger(1));
@@ -74,13 +61,14 @@ public World getWorld(int id) {
@Override
public List getWorlds(int count) {
try {
+ PreparedQuery> worldQuery = connectionPool.clientConnection().worldQuery();
List> futures = new ArrayList<>();
for (int i = 0; i < count; i++) {
- futures.add(getWorldQuery.execute(Tuple.of(randomWorldNumber()))
- .map(rows -> {
- Row r = rows.iterator().next();
- return new World(r.getInteger(0), r.getInteger(1));
- }));
+ futures.add(worldQuery.execute(Tuple.of(randomWorldNumber()))
+ .map(rows -> {
+ Row r = rows.iterator().next();
+ return new World(r.getInteger(0), r.getInteger(1));
+ }));
}
return Future.all(futures).toCompletionStage().toCompletableFuture().get().list();
} catch (Exception e) {
@@ -92,7 +80,18 @@ public List getWorlds(int count) {
public List updateWorlds(int count) {
List worlds = getWorlds(count);
try {
- return updateWorlds(worlds, count, updatePool);
+ PreparedQuery> updateQuery = connectionPool.clientConnection().updateQuery(count);
+ List updateParams = new ArrayList<>(count * 2);
+ for (World world : worlds) {
+ updateParams.add(world.id);
+ world.randomNumber = randomWorldNumber();
+ updateParams.add(world.randomNumber);
+ }
+ return updateQuery.execute(Tuple.wrap(updateParams))
+ .toCompletionStage()
+ .thenApply(rows -> worlds)
+ .toCompletableFuture()
+ .get();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -101,7 +100,8 @@ public List updateWorlds(int count) {
@Override
public List getFortunes() {
try {
- return getFortuneQuery.execute()
+ PreparedQuery> fortuneQuery = connectionPool.clientConnection().fortuneQuery();
+ return fortuneQuery.execute()
.map(rows -> {
List fortunes = new ArrayList<>(rows.size() + 1);
for (Row r : rows) {
@@ -113,37 +113,4 @@ public List getFortunes() {
throw new RuntimeException(e);
}
}
-
- private List updateWorlds(List worlds, int count, SqlClient pool)
- throws ExecutionException, InterruptedException {
- int size = worlds.size();
- List updateParams = new ArrayList<>(size * 2);
- for (World world : worlds) {
- updateParams.add(world.id);
- world.randomNumber = randomWorldNumber();
- updateParams.add(world.randomNumber);
- }
- return updateWorldSingleQuery[count - 1].execute(Tuple.wrap(updateParams))
- .toCompletionStage()
- .thenApply(rows -> worlds)
- .toCompletableFuture()
- .get();
- }
-
- private static String singleUpdate(int count) {
- StringBuilder sql = new StringBuilder();
- sql.append("UPDATE WORLD SET RANDOMNUMBER = CASE ID");
- for (int i = 0; i < count; i++) {
- int k = i * 2 + 1;
- sql.append(" WHEN $").append(k).append(" THEN $").append(k + 1);
- }
- sql.append(" ELSE RANDOMNUMBER");
- sql.append(" END WHERE ID IN ($1");
- for (int i = 1; i < count; i++) {
- int k = i * 2 + 1;
- sql.append(",$").append(k);
- }
- sql.append(")");
- return sql.toString();
- }
}
\ No newline at end of file
diff --git a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/DbService.java b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/DbService.java
index e3bd1fe39fc..a1e97de44b5 100644
--- a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/DbService.java
+++ b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/DbService.java
@@ -1,21 +1,19 @@
-
package io.helidon.benchmark.nima.services;
-import java.util.List;
-
+import com.jsoniter.output.JsonStream;
+import com.jsoniter.output.JsonStreamPool;
import io.helidon.benchmark.nima.models.DbRepository;
-import io.helidon.benchmark.nima.models.World;
+import io.helidon.common.mapper.OptionalValue;
import io.helidon.common.parameters.Parameters;
import io.helidon.http.HeaderValues;
import io.helidon.webserver.http.HttpRules;
import io.helidon.webserver.http.HttpService;
import io.helidon.webserver.http.ServerRequest;
import io.helidon.webserver.http.ServerResponse;
-import io.helidon.common.mapper.OptionalValue;
+import static io.helidon.benchmark.nima.JsonSerializer.serialize;
import static io.helidon.benchmark.nima.Main.SERVER;
import static io.helidon.benchmark.nima.models.DbRepository.randomWorldNumber;
-import static io.helidon.benchmark.nima.JsonSerializer.serialize;
public class DbService implements HttpService {
@@ -33,24 +31,41 @@ public void routing(HttpRules httpRules) {
}
private void db(ServerRequest req, ServerResponse res) {
- res.header(SERVER);
- res.header(HeaderValues.CONTENT_TYPE_JSON);
- res.send(serialize(repository.getWorld(randomWorldNumber())));
+ JsonStream stream = JsonStreamPool.borrowJsonStream();
+ try {
+ res.header(SERVER);
+ res.header(HeaderValues.CONTENT_TYPE_JSON);
+ serialize(repository.getWorld(randomWorldNumber()), stream);
+ res.send(stream.buffer().data(), 0, stream.buffer().tail());
+ } finally {
+ JsonStreamPool.returnJsonStream(stream);
+ }
}
private void queries(ServerRequest req, ServerResponse res) {
- res.header(SERVER);
- res.header(HeaderValues.CONTENT_TYPE_JSON);
- int count = parseQueryCount(req.query());
- res.send(serialize(repository.getWorlds(count)));
+ JsonStream stream = JsonStreamPool.borrowJsonStream();
+ try {
+ res.header(SERVER);
+ res.header(HeaderValues.CONTENT_TYPE_JSON);
+ int count = parseQueryCount(req.query());
+ serialize(repository.getWorlds(count), stream);
+ res.send(stream.buffer().data(), 0, stream.buffer().tail());
+ } finally {
+ JsonStreamPool.returnJsonStream(stream);
+ }
}
private void updates(ServerRequest req, ServerResponse res) {
- res.header(SERVER);
- res.header(HeaderValues.CONTENT_TYPE_JSON);
- int count = parseQueryCount(req.query());
- List worlds = repository.updateWorlds(count);
- res.send(serialize(worlds));
+ JsonStream stream = JsonStreamPool.borrowJsonStream();
+ try {
+ res.header(SERVER);
+ res.header(HeaderValues.CONTENT_TYPE_JSON);
+ int count = parseQueryCount(req.query());
+ serialize(repository.updateWorlds(count), stream);
+ res.send(stream.buffer().data(), 0, stream.buffer().tail());
+ } finally {
+ JsonStreamPool.returnJsonStream(stream);
+ }
}
private int parseQueryCount(Parameters parameters) {
@@ -66,4 +81,4 @@ private int parseQueryCount(Parameters parameters) {
}
return Math.min(500, Math.max(1, parsedValue));
}
-}
\ No newline at end of file
+}
diff --git a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/FortuneHandler.java b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/FortuneHandler.java
index 8847b7d0bc1..b821f8f9261 100644
--- a/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/FortuneHandler.java
+++ b/frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/services/FortuneHandler.java
@@ -1,16 +1,21 @@
package io.helidon.benchmark.nima.services;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.List;
-import com.fizzed.rocker.runtime.ArrayOfByteArraysOutput;
+import gg.jte.TemplateOutput;
import io.helidon.benchmark.nima.models.DbRepository;
import io.helidon.benchmark.nima.models.Fortune;
import io.helidon.webserver.http.Handler;
import io.helidon.webserver.http.ServerRequest;
import io.helidon.webserver.http.ServerResponse;
-import views.fortunes;
+
+import gg.jte.html.OwaspHtmlTemplateOutput;
+import gg.jte.generated.precompiled.JtefortunesGenerated;
import static io.helidon.benchmark.nima.Main.CONTENT_TYPE_HTML;
import static io.helidon.benchmark.nima.Main.SERVER;
@@ -33,8 +38,38 @@ public void handle(ServerRequest req, ServerResponse res) {
List fortuneList = repository.getFortunes();
fortuneList.add(ADDITIONAL_FORTUNE);
fortuneList.sort(Comparator.comparing(Fortune::getMessage));
- res.send(fortunes.template(fortuneList)
- .render(ArrayOfByteArraysOutput.FACTORY)
- .toByteArray());
+ try (OutputStream os = res.outputStream()) {
+ JtefortunesGenerated.render(new OwaspHtmlTemplateOutput(new HelidonTemplateOutput(os)),
+ null, fortuneList);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
+
+ static class HelidonTemplateOutput implements TemplateOutput{
+ private final OutputStream os;
+
+ HelidonTemplateOutput(OutputStream os) {
+ this.os = os;
+ }
+
+ @Override
+ public void writeContent(String value) {
+ writeBinaryContent(value.getBytes(StandardCharsets.UTF_8));
+ }
+
+ @Override
+ public void writeContent(String value, int beginIndex, int endIndex) {
+ writeBinaryContent(value.substring(beginIndex, endIndex).getBytes(StandardCharsets.UTF_8));
+ }
+
+ @Override
+ public void writeBinaryContent(byte[] value) {
+ try {
+ os.write(value);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
}
\ No newline at end of file
diff --git a/frameworks/Java/helidon/nima/src/main/resources/application.yaml b/frameworks/Java/helidon/nima/src/main/resources/application.yaml
index d2d8e8943b4..4a26ea0d0e0 100644
--- a/frameworks/Java/helidon/nima/src/main/resources/application.yaml
+++ b/frameworks/Java/helidon/nima/src/main/resources/application.yaml
@@ -36,6 +36,5 @@ host: "tfb-database"
db: "hello_world"
username: benchmarkdbuser
password: benchmarkdbpass
-sql-pool-size: 300
db-repository: "pgclient" # "pgclient" (default) or "hikari"
diff --git a/frameworks/Java/helidon/nima/src/main/resources/views/fortunes.jte b/frameworks/Java/helidon/nima/src/main/resources/views/fortunes.jte
new file mode 100644
index 00000000000..52dc350b25f
--- /dev/null
+++ b/frameworks/Java/helidon/nima/src/main/resources/views/fortunes.jte
@@ -0,0 +1,2 @@
+@param java.util.List fortunes
+Fortunesid | message |
@for(io.helidon.benchmark.nima.models.Fortune fortune : fortunes)${fortune.getId()} | ${fortune.getMessage()} |
@endfor
\ No newline at end of file
diff --git a/frameworks/Java/helidon/nima/src/main/resources/views/fortunes.rocker.html b/frameworks/Java/helidon/nima/src/main/resources/views/fortunes.rocker.html
deleted file mode 100644
index 3ebcae44729..00000000000
--- a/frameworks/Java/helidon/nima/src/main/resources/views/fortunes.rocker.html
+++ /dev/null
@@ -1,24 +0,0 @@
-@import io.helidon.benchmark.nima.models.Fortune
-@import java.util.List
-@args (List fortunes)
-
-
-
-
-Fortunes
-
-
-
-
- id |
- message |
-
- @for (f : fortunes) {
-
- @f.getId() |
- @f.getMessage() |
-
- }
-
-
-
\ No newline at end of file