Bladeren bron

jooby: raw-jdbc, postgresql, updates/queries tests and latest release (#2883)

Edgar Espina 8 jaren geleden
bovenliggende
commit
afb49a954d

+ 20 - 7
frameworks/Java/jooby/README.md

@@ -1,12 +1,12 @@
 # Jooby Benchmarking Test
 
-[Jooby](http://jooby.org) is a micro-web framework for Java.
+[Jooby](http://jooby.org) Scalable, fast and modular micro web framework for Java and Kotlin.
 
 ```java
 public class App extends Jooby {
 
   {
-    get("/plaintext", () -> "Hello, World!");
+    get("/", () -> "Hello, World!");
   }
 
 }
@@ -14,7 +14,6 @@ public class App extends Jooby {
 
 This is the [Jooby](http://jooby.org) portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
 
-
 ### Plain Text Test
 * [Plain test source](src/main/java/com/techempower/App.java)
 
@@ -24,11 +23,14 @@ This is the [Jooby](http://jooby.org) portion of a [benchmarking test suite](../
 ### Single Query Test
 * [Single query test source](src/main/java/com/techempower/App.java)
 
-## Versions
+### Multiple Queries Test
+* [Multiple queries test source](src/main/java/com/techempower/App.java)
+
+### Database Update Test
+* [Database update test source](src/main/java/com/techempower/App.java)
 
-* [Jooby 1.1.0](http://jooby.org)
-* [Undertow 1.4.x](http://undertow.io)
-* [Jackson 2.8.x](http://wiki.fasterxml.com/JacksonHome)
+### Fortunes Test
+* [Fortunes test source](src/main/java/com/techempower/App.java)
 
 ## Test URLs
 
@@ -44,3 +46,14 @@ This is the [Jooby](http://jooby.org) portion of a [benchmarking test suite](../
 
     http://localhost:8080/db
 
+### Multiple Queries Test
+
+    http://localhost:8080/queries
+
+### Database updates Test
+
+    http://localhost:8080/updates
+
+### Fortunes Test
+
+    http://localhost:8080/fortunes

+ 7 - 6
frameworks/Java/jooby/benchmark_config.json

@@ -3,24 +3,25 @@
   "tests": [{
     "default": {
       "setup_file": "setup",
-      "db_url": "/db",
       "json_url": "/json",
       "plaintext_url": "/plaintext",
+      "db_url": "/db",
+      "query_url": "/queries?queries=",
       "fortune_url": "/fortunes",
+      "update_url": "/updates?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Fullstack",
-      "database": "MySQL",
       "framework": "jooby",
       "language": "Java",
       "flavor": "None",
-      "orm": "Raw",
       "platform": "Netty",
+      "database": "Postgres",
+      "database_os": "Linux",
+      "orm": "Raw",
       "webserver": "None",
       "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "Jooby",
-      "notes": "",
+      "display_name": "jooby",
       "versus": "netty"
     }
   }]

+ 2 - 4
frameworks/Java/jooby/conf/application.conf

@@ -6,11 +6,9 @@ application.env = prod
 ## server threads
 server.threads.Min = ${runtime.processors}
 server.threads.Max = ${runtime.processors-x2}
-
-# default DBHOST
-DBHOST = localhost
+netty.threads.Worker = 4
 
 ## database
-db.url = "jdbc:mysql://"${DBHOST}":3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts=true&cacheRSMetadata=true"
+db.url = "jdbc:postgresql://TFB-database:5432/hello_world"
 db.user = benchmarkdbuser
 db.password = benchmarkdbpass

+ 12 - 4
frameworks/Java/jooby/pom.xml

@@ -7,7 +7,7 @@
   <parent>
     <groupId>org.jooby</groupId>
     <artifactId>jooby-project</artifactId>
-    <version>1.1.0</version>
+    <version>1.1.3</version>
   </parent>
 
   <artifactId>jooby</artifactId>
@@ -17,7 +17,8 @@
   <name>jooby</name>
 
   <properties>
-    <jooby.version>1.1.0</jooby.version>
+    <jooby.version>1.1.3</jooby.version>
+    <postgresql.version>42.1.1</postgresql.version>
     <rocker.touchFile>/dev/null</rocker.touchFile>
 
     <!-- Startup class -->
@@ -31,10 +32,10 @@
       <artifactId>jooby-jackson</artifactId>
     </dependency>
 
-    <!-- requery -->
+    <!-- jdbc -->
     <dependency>
       <groupId>org.jooby</groupId>
-      <artifactId>jooby-requery</artifactId>
+      <artifactId>jooby-jdbc</artifactId>
     </dependency>
 
     <!-- mySQL -->
@@ -43,6 +44,13 @@
       <artifactId>mysql-connector-java</artifactId>
     </dependency>
 
+    <!-- postgresql -->
+    <dependency>
+      <groupId>org.postgresql</groupId>
+      <artifactId>postgresql</artifactId>
+      <version>${postgresql.version}</version>
+    </dependency>
+
     <!-- rocker -->
     <dependency>
       <groupId>org.jooby</groupId>

+ 1 - 1
frameworks/Java/jooby/public/views/fortunes.rocker.html

@@ -10,7 +10,7 @@
 <table>
     <tr><th>id</th><th>message</th></tr>
     @for (it: fortunes) {
-    <tr><td>@it.getId()</td><td>@it.getMessage()</td></tr>
+    <tr><td>@it.id</td><td>@it.message</td></tr>
     }
 </table>
 </body>

+ 2 - 4
frameworks/Java/jooby/setup.sh

@@ -1,10 +1,8 @@
 #!/bin/bash
 
-fw_depends mysql java maven
-
-sed -i 's|localhost|'"${DBHOST}"'|g' conf/application.conf
+fw_depends postgresql java maven
 
 mvn clean package
 
 cd target
-java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -jar jooby-1.0.jar &
+java -server -Xms512m -Xmx2g -jar jooby-1.0.jar &

+ 0 - 0
frameworks/Java/jooby/src/etc/requery.activator


+ 0 - 20
frameworks/Java/jooby/src/main/java/com/techempower/AbstractFortune.java

@@ -1,20 +0,0 @@
-package com.techempower;
-
-import io.requery.Entity;
-import io.requery.Key;
-
-/**
- * The model for the "fortune" database table.
- */
-@Entity
-public abstract class AbstractFortune implements Comparable<AbstractFortune> {
-  @Key
-  int id;
-
-  String message;
-
-  @Override
-  public int compareTo(AbstractFortune other) {
-    return message.compareTo(other.message);
-  }
-}

+ 0 - 15
frameworks/Java/jooby/src/main/java/com/techempower/AbstractWorld.java

@@ -1,15 +0,0 @@
-package com.techempower;
-
-import io.requery.Entity;
-import io.requery.Generated;
-import io.requery.Key;
-
-@Entity
-public abstract class AbstractWorld {
-
-  @Key
-  @Generated
-  int id;
-
-  int randomNumber;
-}

+ 143 - 41
frameworks/Java/jooby/src/main/java/com/techempower/App.java

@@ -2,35 +2,45 @@ package com.techempower;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 
-import io.requery.EntityStore;
-import io.requery.Persistable;
-
 import org.jooby.Jooby;
 import org.jooby.MediaType;
+import org.jooby.Request;
 
 import static org.jooby.MediaType.*;
 import org.jooby.Result;
-import org.jooby.Results;
+import org.jooby.Status;
 import org.jooby.jdbc.Jdbc;
 import org.jooby.json.Jackson;
-import org.jooby.requery.Requery;
 import org.jooby.rocker.Rockerby;
 
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.time.Instant;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Random;
 import java.util.concurrent.ThreadLocalRandom;
 
+import javax.inject.Inject;
+import javax.sql.DataSource;
+
 /**
  * @author jooby generator
  */
-@SuppressWarnings("unchecked")
 public class App extends Jooby {
-  
+
+  private static final String UPDATE_WORLD = "update world set randomNumber=? where id=?";
+
+  private static final String SELECT_WORLD = "select * from world where id=?";
+
   static final DateTimeFormatter fmt = DateTimeFormatter
       .ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
       .withZone(ZoneId.of("GMT"));
@@ -44,57 +54,149 @@ public class App extends Jooby {
 
   static final String HELLO_WORLD = "Hello, World!";
 
+  static final ByteBuffer HELLO_WORLD_BUFFER = ByteBuffer
+      .wrap(HELLO_WORLD.getBytes(StandardCharsets.UTF_8));
+
+  public static class Message {
+    public final String message = HELLO_WORLD;
+  }
+
+  @Inject
+  private DataSource ds;
+
   {
-    /** templates via rocker. */
+    /** Template engine: */
     use(new Rockerby());
 
-    /** json via jackson . */
+    /** JSON: */
     ObjectMapper mapper = new ObjectMapper();
     use(new Jackson(mapper));
 
-    /** database via requery. */
+    /** Database: */
     use(new Jdbc());
-    use(new Requery(Models.DEFAULT));
-
-    get("/plaintext", () -> result(HELLO_WORLD, text))
-        .renderer("text");
-
-    get("/json", () -> result(mapper.createObjectNode().put("message", HELLO_WORLD), json))
-        .renderer("json");
-
-    get("/db", req -> {
-      int id = ThreadLocalRandom.current().nextInt(DB_ROWS) + 1;
-      EntityStore<Persistable, World> store = require(EntityStore.class);
-      World world = store.select(World.class)
-          .where(World.ID.eq(id))
-          .get()
-          .first();
-      return result(world, json);
+
+    get("/plaintext", (req, rsp) -> {
+      rsp.send(result(HELLO_WORLD_BUFFER, plain));
+    }).renderer("byteBuffer");
+
+    get("/json", (req, rsp) -> {
+      rsp.send(result(new Message(), json));
+    }).renderer("json");
+
+    /** Single query: */
+    get("/db", (req, rsp) -> {
+      rsp.send(result(findOne(rndId()), json));
+    }).renderer("json");
+
+    /** Multiple queries: */
+    get("/queries", (req, rsp) -> {
+      // bound count
+      int count = queries(req);
+      List<World> result = new ArrayList<>();
+      Random rnd = ThreadLocalRandom.current();
+      try (Connection conn = ds.getConnection()) {
+        for (int i = 0; i < count; i++) {
+          int id = rndId(rnd);
+          try (final PreparedStatement query = conn.prepareStatement(SELECT_WORLD)) {
+            result.add(findOne(query, id));
+          }
+        }
+      }
+
+      rsp.send(result(result, json));
+    }).renderer("json");
+
+    /** Updates: */
+    get("/updates", (req, rsp) -> {
+      // bound count
+      int count = queries(req);
+      List<World> result = new ArrayList<>();
+      Random rnd = ThreadLocalRandom.current();
+      try (Connection conn = ds.getConnection()) {
+        for (int i = 0; i < count; i++) {
+          int id = rndId(rnd);
+          int newRandomNumber = rndId(rnd);
+          try (final PreparedStatement query = conn.prepareStatement(SELECT_WORLD);
+              final PreparedStatement update = conn.prepareStatement(UPDATE_WORLD)) {
+            // find
+            World world = findOne(query, id);
+
+            // update
+            update.setInt(1, newRandomNumber);
+            update.setInt(2, id);
+            update.execute();
+
+            result.add(new World(world.id, newRandomNumber));
+          }
+        }
+      }
+
+      rsp.send(result(result, json));
     }).renderer("json");
 
-    get("/fortunes", req -> {
-      EntityStore<Persistable, Fortune> store = require(EntityStore.class);
-      List<Fortune> fortunes = store.select(Fortune.class) 
-          .get()
-          .collect(new LinkedList<>());
-      Fortune fortune0 = new Fortune();
-      fortune0.setMessage("Additional fortune added at request time.");
-      fortune0.setId(0);
-      fortunes.add(fortune0);
+    /** Fortunes: */
+    get("/fortunes", (req, rsp) -> {
+      List<Fortune> fortunes = new ArrayList<>();
+      try (Connection connection = ds.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);
-      return views.fortunes.template(fortunes);
+      rsp.send(result(views.fortunes.template(fortunes), html));
     });
   }
 
+  public static void main(final String[] args) {
+    run(App::new, args);
+  }
+
+  private World findOne(int id) throws SQLException {
+    try (Connection conn = ds.getConnection()) {
+      try (PreparedStatement query = conn.prepareStatement(SELECT_WORLD)) {
+        return findOne(query, id);
+      }
+    }
+  }
+
+  private World findOne(PreparedStatement query, int id) throws SQLException {
+    query.setInt(1, id);
+    try (ResultSet resultSet = query.executeQuery()) {
+      resultSet.next();
+      return new World(resultSet.getInt("id"), resultSet.getInt("randomNumber"));
+    }
+  }
+
+  private final int rndId() {
+    return rndId(ThreadLocalRandom.current());
+  }
+
+  private final int rndId(Random rnd) {
+    return rnd.nextInt(DB_ROWS) + 1;
+  }
+
   private Result result(final Object value, final MediaType type) {
-    return Results.ok(value)
+    return new Result().set(value)
+        .status(Status.OK)
         .type(type)
         .header(H_SERVER, SERVER)
         .header(H_DATE, fmt.format(Instant.ofEpochMilli(System.currentTimeMillis())));
   }
 
-  public static void main(final String[] args) {
-    run(App::new, args);
+  private int queries(Request req) {
+    String value = req.param("queries").value("");
+    if (value.length() == 0) {
+      return 1;
+    }
+    try {
+      return Math.min(500, Math.max(1, Integer.parseInt(value)));
+    } catch (NumberFormatException x) {
+      return 1;
+    }
   }
-
 }

+ 17 - 0
frameworks/Java/jooby/src/main/java/com/techempower/Fortune.java

@@ -0,0 +1,17 @@
+package com.techempower;
+
+public final class Fortune implements Comparable<Fortune> {
+  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);
+  }
+}

+ 13 - 0
frameworks/Java/jooby/src/main/java/com/techempower/World.java

@@ -0,0 +1,13 @@
+package com.techempower;
+
+public class World {
+
+  public final int id;
+  public final int randomNumber;
+
+  public World(int id, int randomNumber) {
+    this.id = id;
+    this.randomNumber = randomNumber;
+  }
+
+}