|
@@ -3,41 +3,46 @@ package sabina.benchmark;
|
|
import static java.lang.Integer.parseInt;
|
|
import static java.lang.Integer.parseInt;
|
|
import static sabina.Sabina.*;
|
|
import static sabina.Sabina.*;
|
|
import static sabina.content.JsonContent.toJson;
|
|
import static sabina.content.JsonContent.toJson;
|
|
|
|
+import static sabina.view.MustacheView.renderMustache;
|
|
|
|
|
|
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
|
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
|
-import sabina.Exchange;
|
|
|
|
import sabina.Request;
|
|
import sabina.Request;
|
|
|
|
|
|
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.Date;
|
|
|
|
-import java.util.Properties;
|
|
|
|
-import java.util.Random;
|
|
|
|
|
|
+import java.util.*;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
|
|
import javax.sql.DataSource;
|
|
import javax.sql.DataSource;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * When it is implemented, add this to benchmark_config
|
|
|
|
- * "fortune_url": "/fortune",
|
|
|
|
- * "update_url": "/update",
|
|
|
|
|
|
+ * .
|
|
*/
|
|
*/
|
|
final class Application {
|
|
final class Application {
|
|
- private static final Properties CONFIG = loadConfig ();
|
|
|
|
- private static final DataSource DS = createSessionFactory ();
|
|
|
|
- private static final String QUERY = "select * from world where id = ?";
|
|
|
|
|
|
+ private static final String SETTINGS_RESOURCE = "/server.properties";
|
|
|
|
+ private static final Properties SETTINGS = loadConfiguration ();
|
|
|
|
|
|
|
|
+ private static final String JDBC_URL = SETTINGS.getProperty ("mysql.uri")
|
|
|
|
+ .replace ("${db.host}", "localhost"); // TODO Move this to Gradle build
|
|
|
|
+ private static final DataSource DATA_SOURCE = createSessionFactory ();
|
|
private static final int DB_ROWS = 10000;
|
|
private static final int DB_ROWS = 10000;
|
|
|
|
+
|
|
|
|
+ private static final String SELECT_WORLD = "select * from world where id = ?";
|
|
|
|
+ private static final String UPDATE_WORLD = "update world set randomNumber = ? where id = ?";
|
|
|
|
+ private static final String SELECT_FORTUNES = "select * from fortune";
|
|
|
|
+
|
|
private static final String MESSAGE = "Hello, World!";
|
|
private static final String MESSAGE = "Hello, World!";
|
|
private static final String CONTENT_TYPE_TEXT = "text/plain";
|
|
private static final String CONTENT_TYPE_TEXT = "text/plain";
|
|
|
|
+ private static final String CONTENT_TYPE_JSON = "application/json";
|
|
|
|
+ private static final String QUERIES_PARAM = "queries";
|
|
|
|
|
|
- private static Properties loadConfig () {
|
|
|
|
|
|
+ private static Properties loadConfiguration () {
|
|
try {
|
|
try {
|
|
- Properties config = new Properties ();
|
|
|
|
- config.load (Class.class.getResourceAsStream ("/server.properties"));
|
|
|
|
- return config;
|
|
|
|
|
|
+ Properties settings = new Properties ();
|
|
|
|
+ settings.load (Class.class.getResourceAsStream (SETTINGS_RESOURCE));
|
|
|
|
+ return settings;
|
|
}
|
|
}
|
|
catch (Exception ex) {
|
|
catch (Exception ex) {
|
|
throw new RuntimeException (ex);
|
|
throw new RuntimeException (ex);
|
|
@@ -46,13 +51,13 @@ final class Application {
|
|
|
|
|
|
private static DataSource createSessionFactory () {
|
|
private static DataSource createSessionFactory () {
|
|
try {
|
|
try {
|
|
- ComboPooledDataSource cpds = new ComboPooledDataSource ();
|
|
|
|
- cpds.setJdbcUrl (CONFIG.getProperty ("mysql.uri"));
|
|
|
|
- cpds.setMinPoolSize (32);
|
|
|
|
- cpds.setMaxPoolSize (256);
|
|
|
|
- cpds.setCheckoutTimeout (1800);
|
|
|
|
- cpds.setMaxStatements (50);
|
|
|
|
- return cpds;
|
|
|
|
|
|
+ ComboPooledDataSource dataSource = new ComboPooledDataSource ();
|
|
|
|
+ dataSource.setMinPoolSize (32);
|
|
|
|
+ dataSource.setMaxPoolSize (256);
|
|
|
|
+ dataSource.setCheckoutTimeout (1800);
|
|
|
|
+ dataSource.setMaxStatements (50);
|
|
|
|
+ dataSource.setJdbcUrl (JDBC_URL);
|
|
|
|
+ return dataSource;
|
|
}
|
|
}
|
|
catch (Exception ex) {
|
|
catch (Exception ex) {
|
|
throw new RuntimeException (ex);
|
|
throw new RuntimeException (ex);
|
|
@@ -61,11 +66,11 @@ final class Application {
|
|
|
|
|
|
private static int getQueries (final Request request) {
|
|
private static int getQueries (final Request request) {
|
|
try {
|
|
try {
|
|
- String param = request.queryParams ("queries");
|
|
|
|
- if (param == null)
|
|
|
|
|
|
+ String parameter = request.queryParams (QUERIES_PARAM);
|
|
|
|
+ if (parameter == null)
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
- int queries = parseInt (param);
|
|
|
|
|
|
+ int queries = parseInt (parameter);
|
|
if (queries < 1)
|
|
if (queries < 1)
|
|
return 1;
|
|
return 1;
|
|
if (queries > 500)
|
|
if (queries > 500)
|
|
@@ -78,51 +83,90 @@ final class Application {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private static Object getJson (Exchange it) {
|
|
|
|
- it.response.type ("application/json");
|
|
|
|
|
|
+ private static Object getJson (Request it) {
|
|
|
|
+ it.response.type (CONTENT_TYPE_JSON);
|
|
return toJson (new Message ());
|
|
return toJson (new Message ());
|
|
}
|
|
}
|
|
|
|
|
|
- private static Object getDb (Exchange it) {
|
|
|
|
- final int queries = getQueries (it.request);
|
|
|
|
|
|
+ private static Object getDb (Request it) {
|
|
|
|
+ final int queries = getQueries (it);
|
|
final World[] worlds = new World[queries];
|
|
final World[] worlds = new World[queries];
|
|
|
|
|
|
- try (final Connection con = DS.getConnection ()) {
|
|
|
|
|
|
+ try (final Connection con = DATA_SOURCE.getConnection ()) {
|
|
final Random random = ThreadLocalRandom.current ();
|
|
final Random random = ThreadLocalRandom.current ();
|
|
- PreparedStatement stmt = con.prepareStatement (QUERY);
|
|
|
|
|
|
+ final PreparedStatement stmt = con.prepareStatement (SELECT_WORLD);
|
|
|
|
|
|
- for (int i = 0; i < queries; i++) {
|
|
|
|
|
|
+ for (int ii = 0; ii < queries; ii++) {
|
|
stmt.setInt (1, random.nextInt (DB_ROWS) + 1);
|
|
stmt.setInt (1, random.nextInt (DB_ROWS) + 1);
|
|
- ResultSet rs = stmt.executeQuery ();
|
|
|
|
- while (rs.next ()) {
|
|
|
|
- worlds[i] = new World ();
|
|
|
|
- worlds[i].id = rs.getInt (1);
|
|
|
|
- worlds[i].randomNumber = rs.getInt (2);
|
|
|
|
- }
|
|
|
|
|
|
+ final ResultSet rs = stmt.executeQuery ();
|
|
|
|
+ while (rs.next ())
|
|
|
|
+ worlds[ii] = new World (rs.getInt (1), rs.getInt (2));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (SQLException e) {
|
|
catch (SQLException e) {
|
|
e.printStackTrace ();
|
|
e.printStackTrace ();
|
|
}
|
|
}
|
|
|
|
|
|
- it.response.type ("application/json");
|
|
|
|
- return toJson (it.request.queryParams ("queries") == null? worlds[0] : worlds);
|
|
|
|
|
|
+ it.response.type (CONTENT_TYPE_JSON);
|
|
|
|
+ return toJson (it.queryParams (QUERIES_PARAM) == null? worlds[0] : worlds);
|
|
}
|
|
}
|
|
|
|
|
|
- private static Object getFortune (Exchange aExchange) {
|
|
|
|
- throw new UnsupportedOperationException ();
|
|
|
|
|
|
+ private static Object getFortunes (Request it) {
|
|
|
|
+ final List<Fortune> fortunes = new ArrayList<> ();
|
|
|
|
+
|
|
|
|
+ try (final Connection con = DATA_SOURCE.getConnection ()) {
|
|
|
|
+ final ResultSet rs = con.prepareStatement (SELECT_FORTUNES).executeQuery ();
|
|
|
|
+ while (rs.next ())
|
|
|
|
+ fortunes.add (new Fortune (rs.getInt (1), rs.getString (2)));
|
|
|
|
+ }
|
|
|
|
+ catch (SQLException e) {
|
|
|
|
+ e.printStackTrace ();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fortunes.add (new Fortune (42, "Additional fortune added at request time."));
|
|
|
|
+ fortunes.sort ((a, b) -> a.message.compareTo (b.message));
|
|
|
|
+
|
|
|
|
+ it.response.type ("text/html; charset=utf-8");
|
|
|
|
+ return renderMustache ("/fortunes.mustache", fortunes);
|
|
}
|
|
}
|
|
|
|
|
|
- private static Object getUpdate (Exchange aExchange) {
|
|
|
|
- throw new UnsupportedOperationException ();
|
|
|
|
|
|
+ private static Object getUpdates (Request it) {
|
|
|
|
+ final int queries = getQueries (it);
|
|
|
|
+ final World[] worlds = new World[queries];
|
|
|
|
+
|
|
|
|
+ try (final Connection con = DATA_SOURCE.getConnection ()) {
|
|
|
|
+ con.setAutoCommit (false);
|
|
|
|
+ final Random random = ThreadLocalRandom.current ();
|
|
|
|
+ final PreparedStatement stmtSelect = con.prepareStatement (SELECT_WORLD);
|
|
|
|
+ final PreparedStatement stmtUpdate = con.prepareStatement (UPDATE_WORLD);
|
|
|
|
+
|
|
|
|
+ for (int ii = 0; ii < queries; ii++) {
|
|
|
|
+ stmtSelect.setInt (1, random.nextInt (DB_ROWS) + 1);
|
|
|
|
+ final ResultSet rs = stmtSelect.executeQuery ();
|
|
|
|
+ while (rs.next ()) {
|
|
|
|
+ worlds[ii] = new World (rs.getInt (1), rs.getInt (2));
|
|
|
|
+ stmtUpdate.setInt (1, random.nextInt (DB_ROWS) + 1);
|
|
|
|
+ stmtUpdate.setInt (2, worlds[ii].id);
|
|
|
|
+ stmtUpdate.addBatch ();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ stmtUpdate.executeBatch ();
|
|
|
|
+ con.commit ();
|
|
|
|
+ }
|
|
|
|
+ catch (SQLException e) {
|
|
|
|
+ e.printStackTrace ();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ it.response.type (CONTENT_TYPE_JSON);
|
|
|
|
+ return toJson (it.queryParams (QUERIES_PARAM) == null? worlds[0] : worlds);
|
|
}
|
|
}
|
|
|
|
|
|
- private static Object getPlaintext (Exchange it) {
|
|
|
|
|
|
+ private static Object getPlaintext (Request it) {
|
|
it.response.type (CONTENT_TYPE_TEXT);
|
|
it.response.type (CONTENT_TYPE_TEXT);
|
|
return MESSAGE;
|
|
return MESSAGE;
|
|
}
|
|
}
|
|
|
|
|
|
- private static void addCommonHeaders (Exchange it) {
|
|
|
|
|
|
+ private static void addCommonHeaders (Request it) {
|
|
it.header ("Server", "Undertow/1.1.2");
|
|
it.header ("Server", "Undertow/1.1.2");
|
|
it.response.raw ().addDateHeader ("Date", new Date ().getTime ());
|
|
it.response.raw ().addDateHeader ("Date", new Date ().getTime ());
|
|
}
|
|
}
|
|
@@ -130,12 +174,13 @@ final class Application {
|
|
public static void main (String[] args) {
|
|
public static void main (String[] args) {
|
|
get ("/json", Application::getJson);
|
|
get ("/json", Application::getJson);
|
|
get ("/db", Application::getDb);
|
|
get ("/db", Application::getDb);
|
|
- get ("/fortune", Application::getFortune);
|
|
|
|
- get ("/update", Application::getUpdate);
|
|
|
|
|
|
+ get ("/query", Application::getDb);
|
|
|
|
+ get ("/fortune", Application::getFortunes);
|
|
|
|
+ get ("/update", Application::getUpdates);
|
|
get ("/plaintext", Application::getPlaintext);
|
|
get ("/plaintext", Application::getPlaintext);
|
|
after (Application::addCommonHeaders);
|
|
after (Application::addCommonHeaders);
|
|
|
|
|
|
- setIpAddress (CONFIG.getProperty ("web.host"));
|
|
|
|
- start (parseInt (CONFIG.getProperty ("web.port")));
|
|
|
|
|
|
+ host (SETTINGS.getProperty ("web.host"));
|
|
|
|
+ start (parseInt (SETTINGS.getProperty ("web.port")));
|
|
}
|
|
}
|
|
}
|
|
}
|