Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions frameworks/Java/loveqq/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Loveqq MVC Benchmarking Test

This is the Loveqq MVC portion of a [benchmarking test suite](../) comparing a variety of web development platforms.

An embedded reactor-netty is used for the web server.

### Plaintext Test

* [Plaintext test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)

### JSON Serialization Test

* [JSON test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)

### Database Query Test

* [Database Query test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)

### Database Queries Test

* [Database Queries test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)

### Database Update Test

* [Database Update test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)

### Template rendering Test

* [Template rendering test source](src/main/java/com/kfyty/benchmark/example/controller/WebMvcController.java)

## Versions

* [Java OpenJDK 21](http://openjdk.java.net/)
* [loveqq-framework 1.1.6-M5](http://github.com/kfyty/loveqq-framework)

## 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
30 changes: 30 additions & 0 deletions frameworks/Java/loveqq/benchmark_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"framework": "loveqq",
"tests": [
{
"default": {
"plaintext_url": "/plaintext",
"json_url": "/json",
"db_url": "/db",
"query_url": "/queries?queries=",
"update_url": "/updates?queries=",
"fortune_url": "/fortunes",
"port": 8080,
"approach": "Realistic",
"classification": "Fullstack",
"database": "Postgres",
"framework": "loveqq",
"language": "Java",
"flavor": "None",
"orm": "Micro",
"platform": "Netty",
"webserver": "reactor-netty",
"os": "Linux",
"database_os": "Linux",
"display_name": "loveqq",
"notes": "",
"versus": "None"
}
}
]
}
19 changes: 19 additions & 0 deletions frameworks/Java/loveqq/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[framework]
name = "loveqq"

[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"
database = "Postgres"
database_os = "Linux"
os = "Linux"
orm = "Micro"
platform = "Netty"
webserver = "reactor-netty"
versus = ""
14 changes: 14 additions & 0 deletions frameworks/Java/loveqq/loveqq.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM maven:3.9.7-amazoncorretto-21 as maven
WORKDIR /loveqq
COPY src src
COPY pom.xml pom.xml
RUN mvn package -q -P !default,!dev,!gpg

FROM openjdk:21-jdk-slim
WORKDIR /loveqq
COPY --from=maven /loveqq/target/boot-lib boot-lib
COPY --from=maven /loveqq/target/loveqq-benchmark-1.0-SNAPSHOT.jar app.jar

EXPOSE 8080

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"]
78 changes: 78 additions & 0 deletions frameworks/Java/loveqq/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.kfyty</groupId>
<artifactId>loveqq-framework</artifactId>
<version>1.1.6-M5</version>
</parent>

<artifactId>loveqq-benchmark</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<java.version>21</java.version>
<postgresql.version>42.7.7</postgresql.version>
<jstachio.version>1.3.6</jstachio.version>
<boot-start-class>com.kfyty.benchmark.example.Main</boot-start-class>
</properties>

<dependencies>
<dependency>
<groupId>com.kfyty</groupId>
<artifactId>loveqq-boot</artifactId>
<version>${loveqq.framework.version}</version>
</dependency>

<dependency>
<groupId>com.kfyty</groupId>
<artifactId>loveqq-boot-starter-datasource</artifactId>
<version>${loveqq.framework.version}</version>
</dependency>

<dependency>
<groupId>com.kfyty</groupId>
<artifactId>loveqq-boot-starter-netty</artifactId>
<version>${loveqq.framework.version}</version>
</dependency>

<dependency>
<groupId>com.kfyty</groupId>
<artifactId>loveqq-boot-starter-logback</artifactId>
<version>${loveqq.framework.version}</version>
</dependency>

<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>

<dependency>
<groupId>io.jstach</groupId>
<artifactId>jstachio</artifactId>
<version>${jstachio.version}</version>
</dependency>

<dependency>
<groupId>io.jstach</groupId>
<artifactId>jstachio-apt</artifactId>
<version>${jstachio.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.kfyty</groupId>
<artifactId>loveqq-boot-starter-test</artifactId>
<version>${loveqq.framework.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.kfyty.benchmark.example;

import com.kfyty.loveqq.framework.boot.K;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.BootApplication;
import com.kfyty.loveqq.framework.web.core.autoconfig.annotation.EnableWebMvc;

@EnableWebMvc
@BootApplication
public class Main {

public static void main(String[] args) {
K.start(Main.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.kfyty.benchmark.example.controller;

import com.kfyty.benchmark.example.model.Fortune;
import com.kfyty.benchmark.example.model.Fortunes;
import com.kfyty.benchmark.example.model.World;
import com.kfyty.benchmark.example.repository.DbRepository;
import com.kfyty.benchmark.example.utils.Utils;
import com.kfyty.loveqq.framework.web.core.annotation.GetMapping;
import com.kfyty.loveqq.framework.web.core.annotation.RestController;
import com.kfyty.loveqq.framework.web.core.annotation.bind.RequestParam;
import com.kfyty.loveqq.framework.web.core.http.ServerResponse;
import io.jstach.jstachio.JStachio;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

@RestController
public class WebMvcController {
private static final byte[] TEXT_BODY = "Hello, World!".getBytes(StandardCharsets.UTF_8);

private final DbRepository dbRepository;

public WebMvcController(DbRepository dbRepository) {
this.dbRepository = dbRepository;
}

/**
* GET /plaintext HTTP/1.1
*/
@GetMapping(value = "/plaintext", produces = "text/plain; charset=UTF-8")
public byte[] plaintext(ServerResponse response) {
response.setHeader("Content-Length", "13");
return TEXT_BODY;
}

/**
* GET /json HTTP/1.1
*/
@GetMapping(value = "/json")
public Map<String, String> json(ServerResponse response) {
response.setHeader("Content-Length", "27");
return Map.of("message", "Hello, world!");
}

/**
* GET /db HTTP/1.1
*/
@GetMapping("/db")
public World db() {
return dbRepository.getWorld(Utils.randomWorldNumber());
}

/**
* GET /queries?queries=10 HTTP/1.1
*/
@GetMapping("/queries")
public World[] queries(@RequestParam(defaultValue = "1") Integer queries) {
return Utils.randomWorldNumbers().mapToObj(dbRepository::getWorld).limit(queries).toArray(World[]::new);
}

/**
* GET /updates?queries=10 HTTP/1.1
*/
@GetMapping("/updates")
public List<World> updates(@RequestParam(defaultValue = "1") Integer queries) {
List<World> worlds = Utils.randomWorldNumbers()
.mapToObj(id -> {
World world = dbRepository.getWorld(id);
int randomNumber;
do {
randomNumber = Utils.randomWorldNumber();
} while (randomNumber == world.randomNumber);
world.randomNumber = randomNumber;
return world;
})
.limit(queries)
.sorted(Comparator.comparingInt(w -> w.id))
.toList();
dbRepository.updateWorlds(worlds);
return worlds;
}

/**
* GET /fortunes HTTP/1.1
*/
@GetMapping(value = "/fortunes", produces = "text/html; charset=UTF-8")
public String fortunes() {
List<Fortune> fortunes = dbRepository.fortunes();
fortunes.add(new Fortune(0, "Additional fortune added at request time."));

Collections.sort(fortunes);

return JStachio.render(new Fortunes(fortunes));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.kfyty.benchmark.example.filter;

import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
import com.kfyty.loveqq.framework.web.core.filter.Filter;
import com.kfyty.loveqq.framework.web.core.filter.FilterChain;
import com.kfyty.loveqq.framework.web.core.http.ServerRequest;
import com.kfyty.loveqq.framework.web.core.http.ServerResponse;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;

import java.time.Clock;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

@Component
public class ResponseHeaderFilter implements Filter {
private static final Clock clock = Clock.systemDefaultZone();

@Override
public Publisher<Void> doFilter(ServerRequest request, ServerResponse response, FilterChain chain) {
response.setHeader("Server", "loveqq");
response.setHeader("Date", DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(clock)));
return Mono.from(chain.doFilter(request, response));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.kfyty.benchmark.example.model;

public final class Fortune implements Comparable<Fortune>{
public int id;
public String message;

public Fortune() {
}

public Fortune(int id, String message) {
this.id = id;
this.message = message;
}

@Override
public int compareTo(final Fortune other) {
return message.compareTo(other.message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.kfyty.benchmark.example.model;

import io.jstach.jstache.JStache;

import java.util.List;

@JStache(path = "fortunes.mustache")
public record Fortunes(List<Fortune> fortunes) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.kfyty.benchmark.example.model;

public final class World {
public int id;
public int randomNumber;

public World() {
}

public World(int id, int randomNumber) {
this.id = id;
this.randomNumber = randomNumber;
}
}
Loading