Skip to content

Commit 5b9a8b9

Browse files
committed
feat:loveqq framework benchmark
1 parent 5e14b91 commit 5b9a8b9

File tree

16 files changed

+499
-0
lines changed

16 files changed

+499
-0
lines changed

frameworks/Java/loveqq/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Loveqq MVC Benchmarking Test
2+
3+
This is the Loveqq MVC portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
4+
5+
An embedded reactor-netty is used for the web server.
6+
7+
### Plaintext Test
8+
9+
* [Plaintext test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)
10+
11+
### JSON Serialization Test
12+
13+
* [JSON test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)
14+
15+
### Database Query Test
16+
17+
* [Database Query test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)
18+
19+
### Database Queries Test
20+
21+
* [Database Queries test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)
22+
23+
### Database Update Test
24+
25+
* [Database Update test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)
26+
27+
### Template rendering Test
28+
29+
* [Template rendering test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)
30+
31+
## Versions
32+
33+
* [Java OpenJDK 21](http://openjdk.java.net/)
34+
* [loveqq-framework 1.1.6-M5](http://github.com/kfyty/loveqq-framework)
35+
36+
## Test URLs
37+
38+
### Plaintext Test
39+
40+
http://localhost:8080/plaintext
41+
42+
### JSON Encoding Test
43+
44+
http://localhost:8080/json
45+
46+
### Database Query Test
47+
48+
http://localhost:8080/db
49+
50+
### Database Queries Test
51+
52+
http://localhost:8080/queries?queries=5
53+
54+
### Database Update Test
55+
56+
http://localhost:8080/updates?queries=5
57+
58+
### Template rendering Test
59+
60+
http://localhost:8080/fortunes
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"framework": "loveqq",
3+
"tests": [
4+
{
5+
"default": {
6+
"plaintext_url": "/plaintext",
7+
"json_url": "/json",
8+
"db_url": "/db",
9+
"query_url": "/queries?queries=",
10+
"update_url": "/updates?queries=",
11+
"fortune_url": "/fortunes",
12+
"port": 8080,
13+
"approach": "Realistic",
14+
"classification": "Fullstack",
15+
"database": "Postgres",
16+
"framework": "loveqq",
17+
"language": "Java",
18+
"flavor": "None",
19+
"orm": "Micro",
20+
"platform": "Netty",
21+
"webserver": "reactor-netty",
22+
"os": "Linux",
23+
"database_os": "Linux",
24+
"display_name": "loveqq",
25+
"notes": "",
26+
"versus": "None"
27+
}
28+
}
29+
]
30+
}

frameworks/Java/loveqq/config.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[framework]
2+
name = "loveqq"
3+
4+
[main]
5+
urls.plaintext = "/plaintext"
6+
urls.json = "/json"
7+
urls.db = "/db"
8+
urls.query = "/queries?queries="
9+
urls.update = "/updates?queries="
10+
urls.fortune = "/fortunes"
11+
approach = "Realistic"
12+
classification = "Fullstack"
13+
database = "Postgres"
14+
database_os = "Linux"
15+
os = "Linux"
16+
orm = "Micro"
17+
platform = "Netty"
18+
webserver = "reactor-netty"
19+
versus = ""
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM maven:3.9.7-amazoncorretto-21 as maven
2+
WORKDIR /loveqq
3+
COPY src src
4+
COPY pom.xml pom.xml
5+
RUN mvn package -q -P !default,!dev,!gpg
6+
7+
FROM openjdk:21-jdk-slim
8+
WORKDIR /loveqq
9+
COPY --from=maven /loveqq/target/boot-lib boot-lib
10+
COPY --from=maven /loveqq/target/loveqq-benchmark-1.0-SNAPSHOT.jar app.jar
11+
12+
EXPOSE 8080
13+
14+
CMD ["java", "-server", "--add-opens=java.base/java.lang=ALL-UNNAMED", "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED", "--add-opens=java.base/sun.reflect.annotation=ALL-UNNAMED", "-jar", "app.jar"]

frameworks/Java/loveqq/pom.xml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>com.kfyty</groupId>
8+
<artifactId>loveqq-framework</artifactId>
9+
<version>1.1.6-M3</version>
10+
</parent>
11+
12+
<artifactId>loveqq-benchmark</artifactId>
13+
<version>1.0-SNAPSHOT</version>
14+
15+
<properties>
16+
<java.version>21</java.version>
17+
<postgresql.version>42.7.7</postgresql.version>
18+
<jstachio.version>1.3.6</jstachio.version>
19+
<boot-start-class>com.kfyty.benchmark.example.Main</boot-start-class>
20+
</properties>
21+
22+
<dependencies>
23+
<dependency>
24+
<groupId>com.kfyty</groupId>
25+
<artifactId>loveqq-boot</artifactId>
26+
<version>${loveqq.framework.version}</version>
27+
</dependency>
28+
29+
<dependency>
30+
<groupId>com.kfyty</groupId>
31+
<artifactId>loveqq-boot-starter-datasource</artifactId>
32+
<version>${loveqq.framework.version}</version>
33+
</dependency>
34+
35+
<dependency>
36+
<groupId>com.kfyty</groupId>
37+
<artifactId>loveqq-boot-starter-netty</artifactId>
38+
<version>${loveqq.framework.version}</version>
39+
</dependency>
40+
41+
<dependency>
42+
<groupId>com.kfyty</groupId>
43+
<artifactId>loveqq-boot-starter-logback</artifactId>
44+
<version>${loveqq.framework.version}</version>
45+
</dependency>
46+
47+
<dependency>
48+
<groupId>org.yaml</groupId>
49+
<artifactId>snakeyaml</artifactId>
50+
</dependency>
51+
52+
<dependency>
53+
<groupId>org.postgresql</groupId>
54+
<artifactId>postgresql</artifactId>
55+
<version>${postgresql.version}</version>
56+
</dependency>
57+
58+
<dependency>
59+
<groupId>io.jstach</groupId>
60+
<artifactId>jstachio</artifactId>
61+
<version>${jstachio.version}</version>
62+
</dependency>
63+
64+
<dependency>
65+
<groupId>io.jstach</groupId>
66+
<artifactId>jstachio-apt</artifactId>
67+
<version>${jstachio.version}</version>
68+
<scope>provided</scope>
69+
</dependency>
70+
71+
<dependency>
72+
<groupId>com.kfyty</groupId>
73+
<artifactId>loveqq-boot-starter-test</artifactId>
74+
<version>${loveqq.framework.version}</version>
75+
<scope>test</scope>
76+
</dependency>
77+
</dependencies>
78+
</project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.kfyty.benchmark.example;
2+
3+
import com.kfyty.loveqq.framework.boot.K;
4+
import com.kfyty.loveqq.framework.core.autoconfig.annotation.BootApplication;
5+
import com.kfyty.loveqq.framework.web.core.autoconfig.annotation.EnableWebMvc;
6+
7+
@EnableWebMvc
8+
@BootApplication
9+
public class Main {
10+
11+
public static void main(String[] args) {
12+
K.start(Main.class, args);
13+
}
14+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.kfyty.benchmark.example.controller;
2+
3+
import com.kfyty.benchmark.example.model.Fortune;
4+
import com.kfyty.benchmark.example.model.Fortunes;
5+
import com.kfyty.benchmark.example.model.World;
6+
import com.kfyty.benchmark.example.repository.DbRepository;
7+
import com.kfyty.benchmark.example.utils.Utils;
8+
import com.kfyty.loveqq.framework.web.core.annotation.GetMapping;
9+
import com.kfyty.loveqq.framework.web.core.annotation.RestController;
10+
import com.kfyty.loveqq.framework.web.core.annotation.bind.RequestParam;
11+
import com.kfyty.loveqq.framework.web.core.http.ServerResponse;
12+
import io.jstach.jstachio.JStachio;
13+
14+
import java.nio.charset.StandardCharsets;
15+
import java.util.Collections;
16+
import java.util.Comparator;
17+
import java.util.List;
18+
import java.util.Map;
19+
20+
@RestController
21+
public class WebMvcController {
22+
private static final byte[] TEXT_BODY = "Hello, World!".getBytes(StandardCharsets.UTF_8);
23+
24+
private final DbRepository dbRepository;
25+
26+
public WebMvcController(DbRepository dbRepository) {
27+
this.dbRepository = dbRepository;
28+
}
29+
30+
/**
31+
* GET /plaintext HTTP/1.1
32+
*/
33+
@GetMapping(value = "/plaintext", produces = "text/plain; charset=UTF-8")
34+
public byte[] plaintext(ServerResponse response) {
35+
response.setHeader("Content-Length", "13");
36+
return TEXT_BODY;
37+
}
38+
39+
/**
40+
* GET /json HTTP/1.1
41+
*/
42+
@GetMapping(value = "/json")
43+
public Map<String, String> json(ServerResponse response) {
44+
response.setHeader("Content-Length", "27");
45+
return Map.of("message", "Hello, world!");
46+
}
47+
48+
/**
49+
* GET /db HTTP/1.1
50+
*/
51+
@GetMapping("/db")
52+
public World db() {
53+
return dbRepository.getWorld(Utils.randomWorldNumber());
54+
}
55+
56+
/**
57+
* GET /queries?queries=10 HTTP/1.1
58+
*/
59+
@GetMapping("/queries")
60+
public World[] queries(@RequestParam(defaultValue = "1") Integer queries) {
61+
return Utils.randomWorldNumbers().mapToObj(dbRepository::getWorld).limit(queries).toArray(World[]::new);
62+
}
63+
64+
/**
65+
* GET /updates?queries=10 HTTP/1.1
66+
*/
67+
@GetMapping("/updates")
68+
public List<World> updates(@RequestParam(defaultValue = "1") Integer queries) {
69+
List<World> worlds = Utils.randomWorldNumbers()
70+
.mapToObj(id -> {
71+
World world = dbRepository.getWorld(id);
72+
int randomNumber;
73+
do {
74+
randomNumber = Utils.randomWorldNumber();
75+
} while (randomNumber == world.randomNumber);
76+
world.randomNumber = randomNumber;
77+
return world;
78+
})
79+
.limit(queries)
80+
.sorted(Comparator.comparingInt(w -> w.id))
81+
.toList();
82+
dbRepository.updateWorlds(worlds);
83+
return worlds;
84+
}
85+
86+
/**
87+
* GET /fortunes HTTP/1.1
88+
*/
89+
@GetMapping(value = "/fortunes", produces = "text/html; charset=UTF-8")
90+
public String fortunes() {
91+
List<Fortune> fortunes = dbRepository.fortunes();
92+
fortunes.add(new Fortune(0, "Additional fortune added at request time."));
93+
94+
Collections.sort(fortunes);
95+
96+
return JStachio.render(new Fortunes(fortunes));
97+
}
98+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.kfyty.benchmark.example.filter;
2+
3+
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
4+
import com.kfyty.loveqq.framework.web.core.filter.Filter;
5+
import com.kfyty.loveqq.framework.web.core.filter.FilterChain;
6+
import com.kfyty.loveqq.framework.web.core.http.ServerRequest;
7+
import com.kfyty.loveqq.framework.web.core.http.ServerResponse;
8+
import org.reactivestreams.Publisher;
9+
import reactor.core.publisher.Mono;
10+
11+
import java.time.Clock;
12+
import java.time.ZonedDateTime;
13+
import java.time.format.DateTimeFormatter;
14+
15+
@Component
16+
public class ResponseHeaderFilter implements Filter {
17+
private static final Clock clock = Clock.systemDefaultZone();
18+
19+
@Override
20+
public Publisher<Void> doFilter(ServerRequest request, ServerResponse response, FilterChain chain) {
21+
response.setHeader("Server", "loveqq");
22+
response.setHeader("Date", DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(clock)));
23+
return Mono.from(chain.doFilter(request, response));
24+
}
25+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.kfyty.benchmark.example.model;
2+
3+
public final class Fortune implements Comparable<Fortune>{
4+
public int id;
5+
public String message;
6+
7+
public Fortune() {
8+
}
9+
10+
public Fortune(int id, String message) {
11+
this.id = id;
12+
this.message = message;
13+
}
14+
15+
@Override
16+
public int compareTo(final Fortune other) {
17+
return message.compareTo(other.message);
18+
}
19+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.kfyty.benchmark.example.model;
2+
3+
import io.jstach.jstache.JStache;
4+
5+
import java.util.List;
6+
7+
@JStache(path = "fortunes.mustache")
8+
public record Fortunes(List<Fortune> fortunes) {
9+
}

0 commit comments

Comments
 (0)