diff --git a/frameworks/Java/hserver-business/README.md b/frameworks/Java/hserver-business/README.md new file mode 100644 index 00000000000..e7b3ed7ff3f --- /dev/null +++ b/frameworks/Java/hserver-business/README.md @@ -0,0 +1,39 @@ +# HServer Benchmarking Test +This is the HServer portion of a [benchmarking test suite](../) comparing a variety of web development platforms. + +### Tests +* [JSON test source](src/main/java/com/test/hserver/controller/TestController.java) +* [Plaintext test source](src/main/java/com/test/hserver/controller/TestController.java) +* [Data-Store test source](src/main/java/com/test/hserver/controller/TestController.java) +* [Data-Update test source](src/main/java/com/test/hserver/controller/TestController.java) +* [Fortunes test source](src/main/java/com/test/hserver/controller/TestController.java) + +## Infrastructure Software Versions + +* [HServer](https://gitee.com/HServer/HServer) +* [Java OpenJDK 1.8](http://openjdk.java.net/) + +## Test URLs + +### JSON Encoding Test + +http://localhost:8888/json + +### Plain Text Test + +http://localhost:8888/plaintext + +### Data-Store/Database Mapping Test + +http://localhost:8888/db?queries=2 + +### Update Test + +http://localhost:8888/updates?queries=2 + +### Fortunes Test + +http://localhost:8888/fortunes + +### Query Test +http://localhost:8888/queries?queries=2 diff --git a/frameworks/Java/hserver-business/benchmark_config.json b/frameworks/Java/hserver-business/benchmark_config.json new file mode 100644 index 00000000000..3ddb2633a15 --- /dev/null +++ b/frameworks/Java/hserver-business/benchmark_config.json @@ -0,0 +1,31 @@ + +{ + "framework": "hserver", + "tests": [ + { + "default": { + "db_url": "/db", + "fortune_url": "/fortunes", + "plaintext_url": "/plaintext", + "json_url": "/json", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8888, + "approach": "Realistic", + "classification": "Fullstack", + "database": "Postgres", + "framework": "hserver", + "language": "Java", + "flavor": "None", + "orm": "Full", + "platform": "hserver", + "webserver": "hserver", + "os": "Linux", + "database_os": "Linux", + "display_name": "hserver-business", + "notes": "", + "versus": "hserver" + } + } + ] +} diff --git a/frameworks/Java/hserver-business/config.toml b/frameworks/Java/hserver-business/config.toml new file mode 100644 index 00000000000..73c489afa9e --- /dev/null +++ b/frameworks/Java/hserver-business/config.toml @@ -0,0 +1,17 @@ +[framework] +name = "hserver-business" + +[main] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Fullstack" +os = "Linux" +orm = "Full" +platform = "hserver" +webserver = "hserver" +versus = "hserver" diff --git a/frameworks/Java/hserver-business/hserver.dockerfile b/frameworks/Java/hserver-business/hserver.dockerfile new file mode 100644 index 00000000000..372cd10a98d --- /dev/null +++ b/frameworks/Java/hserver-business/hserver.dockerfile @@ -0,0 +1,13 @@ +FROM maven:3.8.4-openjdk-17-slim as maven +WORKDIR /hserver +COPY pom.xml pom.xml +COPY src src +RUN mvn package + +FROM openjdk:17.0.2 +WORKDIR /hserver +COPY --from=maven /hserver/target/hserver-1.0.jar app.jar + +EXPOSE 8888 + +CMD ["java", "-jar", "app.jar"] diff --git a/frameworks/Java/hserver-business/pom.xml b/frameworks/Java/hserver-business/pom.xml new file mode 100644 index 00000000000..70d6e1b0c12 --- /dev/null +++ b/frameworks/Java/hserver-business/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + com.test.hserver + hserver + 1.0 + + + hserver-parent + cn.hserver + 3.6.0 + + + UTF-8 + 3.3.1 + 42.7.2 + + + + + + hserver + cn.hserver + + + + hserver-plugin-web + cn.hserver + + + com.zaxxer + HikariCP + ${version.hikaricp} + + + org.postgresql + postgresql + ${version.postgres} + + + + + + hserver-plugin-maven + cn.hserver + + + + diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/StartApp.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/StartApp.java new file mode 100644 index 00000000000..b4e215081da --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/StartApp.java @@ -0,0 +1,18 @@ +package com.test.hserver; + + +import cn.hserver.HServerApplication; +import cn.hserver.core.ioc.annotation.HServerBoot; +import cn.hserver.core.server.context.ConstConfig; + + +/** + * @author hxm + */ +@HServerBoot +public class StartApp { + + public static void main(String[] args) { + HServerApplication.run(StartApp.class, 8888, args); + } +} diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/Fortune.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/Fortune.java new file mode 100644 index 00000000000..ce67c19ea45 --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/Fortune.java @@ -0,0 +1,24 @@ +package com.test.hserver.bean; + +public final class Fortune implements Comparable { + public final int id; + + public final String message; + + public Fortune(int id, String message) { + this.id = id; + this.message = message; + } + @Override + public int compareTo(Fortune other) { + return message.compareTo(other.message); + } + + public int getId() { + return id; + } + + public String getMessage() { + return message; + } +} \ No newline at end of file diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/Message.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/Message.java new file mode 100644 index 00000000000..ec823bfb974 --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/Message.java @@ -0,0 +1,13 @@ +package com.test.hserver.bean; + +public class Message { + private String message = "Hello, World!"; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} \ No newline at end of file diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/World.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/World.java new file mode 100644 index 00000000000..206846abcc3 --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/bean/World.java @@ -0,0 +1,24 @@ +package com.test.hserver.bean; + +public class World implements Comparable { + private final int id; + + private final int randomNumber; + + public World(int id, int randomNumber) { + this.id = id; + this.randomNumber = randomNumber; + } + + public int getId() { + return id; + } + + public int getRandomNumber() { + return randomNumber; + } + + @Override public int compareTo(World o) { + return id - o.id; + } +} \ No newline at end of file diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/controller/TestController.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/controller/TestController.java new file mode 100644 index 00000000000..c4bc3b4b0fb --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/controller/TestController.java @@ -0,0 +1,136 @@ +package com.test.hserver.controller; + +import cn.hserver.core.ioc.annotation.Autowired; +import cn.hserver.plugin.web.annotation.Controller; +import cn.hserver.plugin.web.annotation.GET; +import cn.hserver.plugin.web.interfaces.HttpRequest; +import cn.hserver.plugin.web.interfaces.HttpResponse; +import com.test.hserver.bean.Fortune; +import com.test.hserver.bean.Message; +import com.test.hserver.bean.World; +import com.test.hserver.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +import static com.test.hserver.util.Util.getQueries; +import static com.test.hserver.util.Util.randomWorld; + +/** + * @author hxm + */ +@Controller +public class TestController { + private static final String HELLO = "Hello, World!"; + private static final String SELECT_WORLD = "select * from world where id=?"; + + @Autowired + private DataSource dataSource; + + @GET("/json") + public Message json(HttpResponse response) { + response.setHeader("Date", DateUtil.getTime()); + return new Message(); + } + + @GET("/plaintext") + public String plaintext(HttpResponse response) { + response.setHeader("Date", DateUtil.getTime()); + return HELLO; + } + + @GET("/db") + public void db(HttpResponse response) throws SQLException { + World result; + try (Connection conn = dataSource.getConnection()) { + try (final PreparedStatement statement = conn.prepareStatement(SELECT_WORLD)) { + statement.setInt(1, randomWorld()); + try (ResultSet rs = statement.executeQuery()) { + rs.next(); + result = new World(rs.getInt("id"), rs.getInt("randomNumber")); + } + } + } + response.setHeader("Date", DateUtil.getTime()); + response.sendJson(result); + } + + @GET("/queries") + public void queries(HttpRequest request,HttpResponse response) throws Exception { + World[] result = new World[getQueries(request.query("queries"))]; + try (Connection conn = dataSource.getConnection()) { + for (int i = 0; i < result.length; i++) { + try (final PreparedStatement statement = conn.prepareStatement(SELECT_WORLD)) { + statement.setInt(1, randomWorld()); + try (ResultSet rs = statement.executeQuery()) { + rs.next(); + result[i] = new World(rs.getInt("id"), rs.getInt("randomNumber")); + } + } + } + } + response.setHeader("Date", DateUtil.getTime()); + response.sendJson(result); + } + + + @GET("/updates") + public void updates(HttpRequest request,HttpResponse response) throws Exception { + World[] result = new World[getQueries(request.query("queries"))]; + StringJoiner updateSql = new StringJoiner( + ", ", + "UPDATE world SET randomNumber = temp.randomNumber FROM (VALUES ", + " ORDER BY 1) AS temp(id, randomNumber) WHERE temp.id = world.id"); + + try (Connection connection = dataSource.getConnection()) { + try (PreparedStatement statement = connection.prepareStatement(SELECT_WORLD)) { + for (int i = 0; i < result.length; i++) { + statement.setInt(1, randomWorld()); + try (ResultSet rs = statement.executeQuery()) { + rs.next(); + result[i] = new World(rs.getInt("id"), randomWorld()); + } + // prepare update query + updateSql.add("(?, ?)"); + } + } + + try (PreparedStatement statement = connection.prepareStatement(updateSql.toString())) { + int i = 0; + for (World world : result) { + statement.setInt(++i, world.getRandomNumber()); + statement.setInt(++i, world.getRandomNumber()); + } + statement.executeUpdate(); + } + } + response.setHeader("Date", DateUtil.getTime()); + response.sendJson(result); + } + + @GET("/fortunes") + public void fortunes(HttpResponse response) throws Exception { + List fortunes = new ArrayList<>(); + try (Connection connection = dataSource.getConnection()) { + try (PreparedStatement stt = connection.prepareStatement("select * from fortune")) { + try (ResultSet rs = stt.executeQuery()) { + while (rs.next()) { + fortunes.add(new Fortune(rs.getInt("id"), rs.getString("message"))); + } + } + } + } + fortunes.add(new Fortune(0, "Additional fortune added at request time.")); + Collections.sort(fortunes); + response.setHeader("Date", DateUtil.getTime()); + Map data=new HashMap<>(); + data.put("data",fortunes); + response.sendTemplate("fortunes.ftl",data); + } +} diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/db/DataSourceConfig.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/db/DataSourceConfig.java new file mode 100644 index 00000000000..0fee7b56b1c --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/db/DataSourceConfig.java @@ -0,0 +1,25 @@ +package com.test.hserver.db; + +import cn.hserver.core.ioc.annotation.Autowired; +import cn.hserver.core.ioc.annotation.Bean; +import cn.hserver.core.ioc.annotation.Configuration; +import com.zaxxer.hikari.HikariDataSource; + +import javax.sql.DataSource; + +@Configuration +public class DataSourceConfig { + + @Autowired + private PostgresConfig postgresConfig; + + @Bean + public DataSource initDataSource() { + HikariDataSource ds = new HikariDataSource(); + ds.setJdbcUrl(postgresConfig.getJdbcUrl()); + ds.setUsername(postgresConfig.getUsername()); + ds.setPassword(postgresConfig.getPassword()); + ds.setMaximumPoolSize(postgresConfig.getMaximumPoolSize()); + return ds; + } +} diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/db/PostgresConfig.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/db/PostgresConfig.java new file mode 100644 index 00000000000..57c08ea4b25 --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/db/PostgresConfig.java @@ -0,0 +1,57 @@ +package com.test.hserver.db; + + +import cn.hserver.core.ioc.annotation.ConfigurationProperties; + +@ConfigurationProperties +public class PostgresConfig { + private String jdbcUrl; + private String username; + private String password; + private int maximumPoolSize; + + public PostgresConfig() { + } + + public String getJdbcUrl() { + return jdbcUrl; + } + + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getMaximumPoolSize() { + return maximumPoolSize; + } + + public void setMaximumPoolSize(int maximumPoolSize) { + this.maximumPoolSize = maximumPoolSize; + } + + @Override + public String toString() { + return "PostgresConfig{" + + "jdbcUrl='" + jdbcUrl + '\'' + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", maximumPoolSize=" + maximumPoolSize + + '}'; + } +} \ No newline at end of file diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/task/TimeAdd.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/task/TimeAdd.java new file mode 100644 index 00000000000..a1f866b2d89 --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/task/TimeAdd.java @@ -0,0 +1,15 @@ +package com.test.hserver.task; + +import cn.hserver.core.ioc.annotation.Bean; +import cn.hserver.core.ioc.annotation.Task; +import com.test.hserver.util.DateUtil; + +@Bean +public class TimeAdd { + + @Task(name = "时间计算", time = "1000") + public void add() { + DateUtil.time = DateUtil.getNow(); + } + +} diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/util/DateUtil.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/util/DateUtil.java new file mode 100644 index 00000000000..0874b9bd9eb --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/util/DateUtil.java @@ -0,0 +1,25 @@ +package com.test.hserver.util; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + +/** + * @author hxm + */ +public class DateUtil { + private static final DateTimeFormatter GMT_FMT = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); + private static final ZoneId zoneId = ZoneId.of("GMT"); + public static String getNow() { + return GMT_FMT.format(LocalDateTime.now().atZone(zoneId)); + } + public static String time; + public static String getTime(){ + if (time==null){ + time=getNow(); + return time; + } + return time; + } +} diff --git a/frameworks/Java/hserver-business/src/main/java/com/test/hserver/util/Util.java b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/util/Util.java new file mode 100644 index 00000000000..775f4f8f0f6 --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/java/com/test/hserver/util/Util.java @@ -0,0 +1,18 @@ +package com.test.hserver.util; + +import java.util.concurrent.ThreadLocalRandom; + +public class Util { + public static int randomWorld() { + return 1 + ThreadLocalRandom.current().nextInt(10000); + } + + public static int getQueries(String queries) { + try { + int count = Integer.parseInt(queries); + return Math.min(500, Math.max(1, count)); + } catch (Exception e) { + return 1; + } + } +} \ No newline at end of file diff --git a/frameworks/Java/hserver-business/src/main/resources/app.properties b/frameworks/Java/hserver-business/src/main/resources/app.properties new file mode 100644 index 00000000000..11b8d560772 --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/resources/app.properties @@ -0,0 +1,6 @@ +jdbcUrl= jdbc:postgresql://tfb-database:5432/hello_world +username= benchmarkdbuser +password= benchmarkdbpass +maximumPoolSize= 256 + +log=info diff --git a/frameworks/Java/hserver-business/src/main/resources/template/fortunes.ftl b/frameworks/Java/hserver-business/src/main/resources/template/fortunes.ftl new file mode 100644 index 00000000000..233927248fa --- /dev/null +++ b/frameworks/Java/hserver-business/src/main/resources/template/fortunes.ftl @@ -0,0 +1,20 @@ + + + + Fortunes + + + + + + + + <#list data as fortune> + + + + + +
idmessage
${fortune.id?html}${fortune.message?html}
+ + \ No newline at end of file diff --git a/frameworks/Java/hserver/benchmark_config.json b/frameworks/Java/hserver/benchmark_config.json index 87397f30d93..035eae68c9c 100644 --- a/frameworks/Java/hserver/benchmark_config.json +++ b/frameworks/Java/hserver/benchmark_config.json @@ -5,11 +5,11 @@ { "default": { "db_url": "/db", - "query_url": "/queries?queries=", "fortune_url": "/fortunes", "plaintext_url": "/plaintext", - "update_url": "/updates?queries=", "json_url": "/json", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", "port": 8888, "approach": "Realistic", "classification": "Fullstack", @@ -18,8 +18,8 @@ "language": "Java", "flavor": "None", "orm": "Full", - "platform": "None", - "webserver": "None", + "platform": "hserver", + "webserver": "hserver", "os": "Linux", "database_os": "Linux", "display_name": "hserver", @@ -28,4 +28,4 @@ } } ] -} \ No newline at end of file +} diff --git a/frameworks/Java/hserver/config.toml b/frameworks/Java/hserver/config.toml index db5b6ff47a1..6979faa03a0 100644 --- a/frameworks/Java/hserver/config.toml +++ b/frameworks/Java/hserver/config.toml @@ -12,6 +12,6 @@ approach = "Realistic" classification = "Fullstack" os = "Linux" orm = "Full" -platform = "None" -webserver = "None" -versus = "hserver" \ No newline at end of file +platform = "hserver" +webserver = "hserver" +versus = "hserver" diff --git a/frameworks/Java/hserver/hserver.dockerfile b/frameworks/Java/hserver/hserver.dockerfile index 483485da30f..372cd10a98d 100644 --- a/frameworks/Java/hserver/hserver.dockerfile +++ b/frameworks/Java/hserver/hserver.dockerfile @@ -1,13 +1,13 @@ -FROM maven:3.6.3-openjdk-8-slim as maven +FROM maven:3.8.4-openjdk-17-slim as maven WORKDIR /hserver COPY pom.xml pom.xml COPY src src RUN mvn package -FROM openjdk:8u275-jdk-slim +FROM openjdk:17.0.2 WORKDIR /hserver COPY --from=maven /hserver/target/hserver-1.0.jar app.jar EXPOSE 8888 -CMD ["java", "-jar", "app.jar"] \ No newline at end of file +CMD ["java", "-jar", "app.jar"] diff --git a/frameworks/Java/hserver/pom.xml b/frameworks/Java/hserver/pom.xml index b841cbd60ab..70d6e1b0c12 100644 --- a/frameworks/Java/hserver/pom.xml +++ b/frameworks/Java/hserver/pom.xml @@ -11,7 +11,7 @@ hserver-parent cn.hserver - 3.5.M2 + 3.6.0 UTF-8 diff --git a/frameworks/Java/hserver/src/main/java/com/test/hserver/controller/TestController.java b/frameworks/Java/hserver/src/main/java/com/test/hserver/controller/TestController.java index 9ab5d958039..c4bc3b4b0fb 100644 --- a/frameworks/Java/hserver/src/main/java/com/test/hserver/controller/TestController.java +++ b/frameworks/Java/hserver/src/main/java/com/test/hserver/controller/TestController.java @@ -3,11 +3,14 @@ import cn.hserver.core.ioc.annotation.Autowired; import cn.hserver.plugin.web.annotation.Controller; import cn.hserver.plugin.web.annotation.GET; +import cn.hserver.plugin.web.interfaces.HttpRequest; import cn.hserver.plugin.web.interfaces.HttpResponse; import com.test.hserver.bean.Fortune; import com.test.hserver.bean.Message; import com.test.hserver.bean.World; import com.test.hserver.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.sql.DataSource; import java.sql.Connection; @@ -59,8 +62,8 @@ public void db(HttpResponse response) throws SQLException { } @GET("/queries") - public void queries(String queries,HttpResponse response) throws Exception { - World[] result = new World[getQueries(queries)]; + public void queries(HttpRequest request,HttpResponse response) throws Exception { + World[] result = new World[getQueries(request.query("queries"))]; try (Connection conn = dataSource.getConnection()) { for (int i = 0; i < result.length; i++) { try (final PreparedStatement statement = conn.prepareStatement(SELECT_WORLD)) { @@ -78,8 +81,8 @@ public void queries(String queries,HttpResponse response) throws Exception { @GET("/updates") - public void updates(String queries,HttpResponse response) throws Exception { - World[] result = new World[getQueries(queries)]; + public void updates(HttpRequest request,HttpResponse response) throws Exception { + World[] result = new World[getQueries(request.query("queries"))]; StringJoiner updateSql = new StringJoiner( ", ", "UPDATE world SET randomNumber = temp.randomNumber FROM (VALUES ",