|
@@ -1,29 +1,25 @@
|
|
package hello.services;
|
|
package hello.services;
|
|
|
|
|
|
-import hello.helpers.HttpHeadersHelper;
|
|
|
|
-import hello.helpers.PostgresDbHelper;
|
|
|
|
-import hello.models.World;
|
|
|
|
-
|
|
|
|
import java.sql.Connection;
|
|
import java.sql.Connection;
|
|
import java.sql.PreparedStatement;
|
|
import java.sql.PreparedStatement;
|
|
import java.sql.ResultSet;
|
|
import java.sql.ResultSet;
|
|
import java.sql.SQLException;
|
|
import java.sql.SQLException;
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
|
|
import javax.sql.DataSource;
|
|
import javax.sql.DataSource;
|
|
|
|
|
|
-import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
-import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
-import com.linecorp.armeria.common.HttpData;
|
|
|
|
-import com.linecorp.armeria.common.HttpResponse;
|
|
|
|
-import com.linecorp.armeria.common.MediaType;
|
|
|
|
-import com.linecorp.armeria.server.annotation.Default;
|
|
|
|
|
|
+import com.zaxxer.hikari.HikariDataSource;
|
|
|
|
+
|
|
|
|
+import com.linecorp.armeria.server.ServiceRequestContext;
|
|
import com.linecorp.armeria.server.annotation.Get;
|
|
import com.linecorp.armeria.server.annotation.Get;
|
|
import com.linecorp.armeria.server.annotation.Param;
|
|
import com.linecorp.armeria.server.annotation.Param;
|
|
-import com.zaxxer.hikari.HikariDataSource;
|
|
|
|
|
|
+import com.linecorp.armeria.server.annotation.ProducesJson;
|
|
|
|
+
|
|
|
|
+import hello.helpers.PostgresDbHelper;
|
|
|
|
+import hello.models.World;
|
|
|
|
|
|
public class PostgresDbService {
|
|
public class PostgresDbService {
|
|
- private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
|
|
|
|
|
|
private static final String SELECT_QUERY = "SELECT * FROM world WHERE id = ?";
|
|
private static final String SELECT_QUERY = "SELECT * FROM world WHERE id = ?";
|
|
private static final String UPDATE_QUERY =
|
|
private static final String UPDATE_QUERY =
|
|
@@ -36,37 +32,49 @@ public class PostgresDbService {
|
|
}
|
|
}
|
|
|
|
|
|
@Get("/db")
|
|
@Get("/db")
|
|
- public HttpResponse db() throws Exception {
|
|
|
|
- return HttpResponse.of(
|
|
|
|
- HttpHeadersHelper.getHttpHeader(MediaType.JSON),
|
|
|
|
- HttpData.of(MAPPER.writeValueAsBytes(getWorld(getRandomNumber())))
|
|
|
|
- );
|
|
|
|
|
|
+ @ProducesJson
|
|
|
|
+ public CompletableFuture<World> db(ServiceRequestContext ctx) throws Exception {
|
|
|
|
+ return getWorld(getRandomNumber(), ctx);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Get("/queries/{count}")
|
|
|
|
+ @ProducesJson
|
|
|
|
+ public CompletableFuture<World[]> queries(
|
|
|
|
+ @Param("count") String count,
|
|
|
|
+ ServiceRequestContext ctx) {
|
|
|
|
+ return doQueries(count, ctx);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Get("/queries/")
|
|
|
|
+ @ProducesJson
|
|
|
|
+ public CompletableFuture<World[]> queries(ServiceRequestContext ctx) {
|
|
|
|
+ return doQueries("", ctx);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private CompletableFuture<World[]> doQueries(
|
|
|
|
+ @Param("count") String count,
|
|
|
|
+ ServiceRequestContext ctx) {
|
|
|
|
+ return getWorlds(getSanitizedCount(count), ctx);
|
|
}
|
|
}
|
|
|
|
|
|
- // need to use regex as /queries/{count} doesn't work when count is null
|
|
|
|
- @Get("regex:^/queries/(?<count>.*)$")
|
|
|
|
- public HttpResponse queries(
|
|
|
|
- @Param("count")
|
|
|
|
- @Default("")
|
|
|
|
- String count) throws JsonProcessingException, SQLException {
|
|
|
|
- return HttpResponse.of(
|
|
|
|
- HttpHeadersHelper.getHttpHeader(MediaType.JSON),
|
|
|
|
- HttpData.of(
|
|
|
|
- MAPPER.writeValueAsBytes(getWorlds(getSanitizedCount(count))))
|
|
|
|
- );
|
|
|
|
|
|
+ @Get("/updates/{count}")
|
|
|
|
+ @ProducesJson
|
|
|
|
+ public CompletableFuture<World[]> update(
|
|
|
|
+ @Param("count") String count,
|
|
|
|
+ ServiceRequestContext ctx) {
|
|
|
|
+ return doUpdate(count, ctx);
|
|
}
|
|
}
|
|
|
|
|
|
- @Get("regex:^/updates/(?<count>.*)$")
|
|
|
|
- public HttpResponse update(
|
|
|
|
- @Param("count")
|
|
|
|
- @Default("")
|
|
|
|
- String count) throws JsonProcessingException, SQLException {
|
|
|
|
- return HttpResponse.of(
|
|
|
|
- HttpHeadersHelper.getHttpHeader(MediaType.JSON),
|
|
|
|
- HttpData.of(
|
|
|
|
- MAPPER.writeValueAsBytes(
|
|
|
|
- getUpdatedWorlds(getSanitizedCount(count))))
|
|
|
|
- );
|
|
|
|
|
|
+ @Get("/updates/")
|
|
|
|
+ @ProducesJson
|
|
|
|
+ public CompletableFuture<World[]> update(ServiceRequestContext ctx) {
|
|
|
|
+ return doUpdate("", ctx);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private CompletableFuture<World[]> doUpdate(
|
|
|
|
+ String count,
|
|
|
|
+ ServiceRequestContext ctx) {
|
|
|
|
+ return getUpdatedWorlds(getSanitizedCount(count), ctx);
|
|
}
|
|
}
|
|
|
|
|
|
private static int getRandomNumber() {
|
|
private static int getRandomNumber() {
|
|
@@ -88,71 +96,87 @@ public class PostgresDbService {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private World getWorld(int number) throws SQLException {
|
|
|
|
- try (final Connection connection = dataSource.getConnection();
|
|
|
|
- final PreparedStatement statement =
|
|
|
|
- connection.prepareStatement(SELECT_QUERY)) {
|
|
|
|
-
|
|
|
|
- statement.setInt(1, number);
|
|
|
|
-
|
|
|
|
- try (final ResultSet resultSet = statement.executeQuery()) {
|
|
|
|
- resultSet.next();
|
|
|
|
- return new World(resultSet.getInt(1), resultSet.getInt(2));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ private CompletableFuture<World> getWorld(int number, ServiceRequestContext ctx) {
|
|
|
|
+ return CompletableFuture.supplyAsync(
|
|
|
|
+ () -> {
|
|
|
|
+ try (final Connection connection = dataSource.getConnection();
|
|
|
|
+ final PreparedStatement statement =
|
|
|
|
+ connection.prepareStatement(SELECT_QUERY)) {
|
|
|
|
+
|
|
|
|
+ statement.setInt(1, number);
|
|
|
|
+
|
|
|
|
+ try (final ResultSet resultSet = statement.executeQuery()) {
|
|
|
|
+ resultSet.next();
|
|
|
|
+ return new World(resultSet.getInt(1), resultSet.getInt(2));
|
|
|
|
+ }
|
|
|
|
+ } catch (SQLException e) {
|
|
|
|
+ throw new IllegalStateException("Database error", e);
|
|
|
|
+ }
|
|
|
|
+ }, ctx.blockingTaskExecutor());
|
|
}
|
|
}
|
|
|
|
|
|
- private World[] getWorlds(int count) throws SQLException {
|
|
|
|
- World[] worlds = new World[count];
|
|
|
|
-
|
|
|
|
- try (final Connection connection = dataSource.getConnection()) {
|
|
|
|
- for (int i = 0; i < count; i++) {
|
|
|
|
- final int id = getRandomNumber();
|
|
|
|
-
|
|
|
|
- try (final PreparedStatement statement =
|
|
|
|
- connection.prepareStatement(SELECT_QUERY)) {
|
|
|
|
- statement.setInt(1, id);
|
|
|
|
-
|
|
|
|
- try (final ResultSet resultSet = statement.executeQuery()) {
|
|
|
|
- resultSet.next();
|
|
|
|
- worlds[i] = new World(id, resultSet.getInt(2));
|
|
|
|
|
|
+ private CompletableFuture<World[]> getWorlds(int count, ServiceRequestContext ctx) {
|
|
|
|
+ return CompletableFuture.supplyAsync(
|
|
|
|
+ () -> {
|
|
|
|
+ World[] worlds = new World[count];
|
|
|
|
+
|
|
|
|
+ try (final Connection connection = dataSource.getConnection()) {
|
|
|
|
+ for (int i = 0; i < count; i++) {
|
|
|
|
+ final int id = getRandomNumber();
|
|
|
|
+
|
|
|
|
+ try (final PreparedStatement statement =
|
|
|
|
+ connection.prepareStatement(SELECT_QUERY)) {
|
|
|
|
+ statement.setInt(1, id);
|
|
|
|
+
|
|
|
|
+ try (final ResultSet resultSet = statement.executeQuery()) {
|
|
|
|
+ resultSet.next();
|
|
|
|
+ worlds[i] = new World(id, resultSet.getInt(2));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (SQLException e) {
|
|
|
|
+ throw new IllegalStateException("Database error", e);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return worlds;
|
|
|
|
|
|
+ return worlds;
|
|
|
|
+ }, ctx.blockingTaskExecutor());
|
|
}
|
|
}
|
|
|
|
|
|
- private World[] getUpdatedWorlds(int count) throws SQLException {
|
|
|
|
- World[] worlds = new World[count];
|
|
|
|
|
|
+ private CompletableFuture<World[]> getUpdatedWorlds(int count, ServiceRequestContext ctx) {
|
|
|
|
+ return CompletableFuture.supplyAsync(
|
|
|
|
+ () -> {
|
|
|
|
|
|
- try (final Connection connection = dataSource.getConnection()) {
|
|
|
|
- for (int i = 0; i < count; i++) {
|
|
|
|
- final int id = getRandomNumber();
|
|
|
|
- final int randomNumber = getRandomNumber();
|
|
|
|
|
|
+ World[] worlds = new World[count];
|
|
|
|
|
|
- try (final PreparedStatement select =
|
|
|
|
- connection.prepareStatement(SELECT_QUERY);
|
|
|
|
- final PreparedStatement update =
|
|
|
|
- connection.prepareStatement(UPDATE_QUERY)) {
|
|
|
|
|
|
+ try (final Connection connection = dataSource.getConnection()) {
|
|
|
|
+ for (int i = 0; i < count; i++) {
|
|
|
|
+ final int id = getRandomNumber();
|
|
|
|
+ final int randomNumber = getRandomNumber();
|
|
|
|
|
|
- // get
|
|
|
|
- select.setInt(1, id);
|
|
|
|
|
|
+ try (final PreparedStatement select =
|
|
|
|
+ connection.prepareStatement(SELECT_QUERY);
|
|
|
|
+ final PreparedStatement update =
|
|
|
|
+ connection.prepareStatement(UPDATE_QUERY)) {
|
|
|
|
|
|
- try (final ResultSet set = select.executeQuery()) {
|
|
|
|
- set.next();
|
|
|
|
|
|
+ // get
|
|
|
|
+ select.setInt(1, id);
|
|
|
|
|
|
- // update
|
|
|
|
- update.setInt(1, randomNumber);
|
|
|
|
- update.setInt(2, id);
|
|
|
|
- update.execute();
|
|
|
|
|
|
+ try (final ResultSet set = select.executeQuery()) {
|
|
|
|
+ set.next();
|
|
|
|
|
|
- worlds[i] = new World(id, set.getInt(2));
|
|
|
|
- worlds[i].randomNumber = randomNumber;
|
|
|
|
|
|
+ // update
|
|
|
|
+ update.setInt(1, randomNumber);
|
|
|
|
+ update.setInt(2, id);
|
|
|
|
+ update.execute();
|
|
|
|
+
|
|
|
|
+ worlds[i] = new World(id, set.getInt(2));
|
|
|
|
+ worlds[i].randomNumber = randomNumber;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (SQLException e) {
|
|
|
|
+ throw new IllegalStateException("Database error", e);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return worlds;
|
|
|
|
|
|
+ return worlds;
|
|
|
|
+ }, ctx.blockingTaskExecutor());
|
|
}
|
|
}
|
|
}
|
|
}
|