|
@@ -2,35 +2,45 @@ package com.techempower;
|
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
|
-import io.requery.EntityStore;
|
|
|
|
-import io.requery.Persistable;
|
|
|
|
-
|
|
|
|
import org.jooby.Jooby;
|
|
import org.jooby.Jooby;
|
|
import org.jooby.MediaType;
|
|
import org.jooby.MediaType;
|
|
|
|
+import org.jooby.Request;
|
|
|
|
|
|
import static org.jooby.MediaType.*;
|
|
import static org.jooby.MediaType.*;
|
|
import org.jooby.Result;
|
|
import org.jooby.Result;
|
|
-import org.jooby.Results;
|
|
|
|
|
|
+import org.jooby.Status;
|
|
import org.jooby.jdbc.Jdbc;
|
|
import org.jooby.jdbc.Jdbc;
|
|
import org.jooby.json.Jackson;
|
|
import org.jooby.json.Jackson;
|
|
-import org.jooby.requery.Requery;
|
|
|
|
import org.jooby.rocker.Rockerby;
|
|
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.Instant;
|
|
import java.time.ZoneId;
|
|
import java.time.ZoneId;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
+import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
-import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Locale;
|
|
|
|
+import java.util.Random;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
|
|
|
|
+import javax.inject.Inject;
|
|
|
|
+import javax.sql.DataSource;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* @author jooby generator
|
|
* @author jooby generator
|
|
*/
|
|
*/
|
|
-@SuppressWarnings("unchecked")
|
|
|
|
public class App extends Jooby {
|
|
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
|
|
static final DateTimeFormatter fmt = DateTimeFormatter
|
|
.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
|
|
.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
|
|
.withZone(ZoneId.of("GMT"));
|
|
.withZone(ZoneId.of("GMT"));
|
|
@@ -44,57 +54,149 @@ public class App extends Jooby {
|
|
|
|
|
|
static final String HELLO_WORLD = "Hello, World!";
|
|
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());
|
|
use(new Rockerby());
|
|
|
|
|
|
- /** json via jackson . */
|
|
|
|
|
|
+ /** JSON: */
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
use(new Jackson(mapper));
|
|
use(new Jackson(mapper));
|
|
|
|
|
|
- /** database via requery. */
|
|
|
|
|
|
+ /** Database: */
|
|
use(new Jdbc());
|
|
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");
|
|
}).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);
|
|
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) {
|
|
private Result result(final Object value, final MediaType type) {
|
|
- return Results.ok(value)
|
|
|
|
|
|
+ return new Result().set(value)
|
|
|
|
+ .status(Status.OK)
|
|
.type(type)
|
|
.type(type)
|
|
.header(H_SERVER, SERVER)
|
|
.header(H_SERVER, SERVER)
|
|
.header(H_DATE, fmt.format(Instant.ofEpochMilli(System.currentTimeMillis())));
|
|
.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;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|