WebServer.java 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import org.vertx.java.core.Handler;
  2. import org.vertx.java.core.buffer.Buffer;
  3. import org.vertx.java.core.eventbus.Message;
  4. import org.vertx.java.core.http.HttpServerRequest;
  5. import org.vertx.java.core.http.HttpServerResponse;
  6. import org.vertx.java.core.json.JsonArray;
  7. import org.vertx.java.core.json.JsonObject;
  8. import org.vertx.java.core.json.impl.Json;
  9. import org.vertx.java.platform.Verticle;
  10. import java.text.DateFormat;
  11. import java.text.SimpleDateFormat;
  12. import java.util.Collections;
  13. import java.util.Date;
  14. import java.util.Random;
  15. import java.util.concurrent.ThreadLocalRandom;
  16. public class WebServer extends Verticle implements Handler<HttpServerRequest> {
  17. private final Buffer helloWorldBuffer = new Buffer("Hello, World!");
  18. private final String helloWorldContentLength = String.valueOf(helloWorldBuffer.length());
  19. private final DateFormat DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z");
  20. private final Random random = ThreadLocalRandom.current();
  21. private String dateString;
  22. private static final String PATH_PLAINTEXT = "/plaintext";
  23. private static final String PATH_JSON = "/json";
  24. private static final String PATH_DB = "/db";
  25. private static final String PATH_QUERIES = "/queries";
  26. private static final String PATH_UPDATES = "/updates";
  27. private static final String RESPONSE_TYPE_PLAIN = "text/plain";
  28. private static final String RESPONSE_TYPE_JSON = "application/json";
  29. private static final String HEADER_CONTENT_TYPE = "Content-Type";
  30. private static final String HEADER_CONTENT_LENGTH = "Content-Length";
  31. private static final String HEADER_SERVER = "Server";
  32. private static final String HEADER_SERVER_VERTX = "vert.x";
  33. private static final String HEADER_DATE = "Date";
  34. private static final String MONGO_ADDRESS = "hello.persistor";
  35. private static final String UNDERSCORE_ID = "_id";
  36. private static final String TEXT_ID = "id";
  37. private static final String RANDOM_NUMBER = "randomNumber";
  38. private static final String TEXT_RESULT = "result";
  39. private static final String TEXT_QUERIES = "queries";
  40. private static final String TEXT_MESSAGE = "message";
  41. private static final String HELLO_WORLD = "Hello, world!";
  42. private static final String TEXT_ACTION = "action";
  43. private static final String TEXT_CRITERIA = "criteria";
  44. private static final String TEXT_UPDATE = "update";
  45. private static final String TEXT_OBJ_NEW = "objNew";
  46. private static final String TEXT_FINDONE = "findone";
  47. private static final String TEXT_COLLECTION = "collection";
  48. private static final String TEXT_WORLD = "World";
  49. private static final String TEXT_MATCHER = "matcher";
  50. @Override
  51. public void start() {
  52. vertx.createHttpServer().requestHandler(WebServer.this).listen(8080);
  53. vertx.setPeriodic(1000, new Handler<Long>() {
  54. @Override
  55. public void handle(Long timerID) {
  56. formatDate();
  57. }
  58. });
  59. formatDate();
  60. }
  61. @Override
  62. public void handle(HttpServerRequest req) {
  63. switch (req.path()) {
  64. case PATH_PLAINTEXT:
  65. handlePlainText(req);
  66. break;
  67. case PATH_JSON:
  68. handleJson(req);
  69. break;
  70. case PATH_DB:
  71. handleDbMongo(req);
  72. break;
  73. case PATH_QUERIES:
  74. handleDBMongo(req,false);
  75. break;
  76. case PATH_UPDATES:
  77. handleDBMongo(req,true);
  78. break;
  79. default:
  80. req.response().setStatusCode(404);
  81. req.response().end();
  82. }
  83. }
  84. private void formatDate() {
  85. dateString = DATE_FORMAT.format(new Date());
  86. }
  87. private void handlePlainText(HttpServerRequest req) {
  88. HttpServerResponse resp = req.response();
  89. setHeaders(resp, RESPONSE_TYPE_PLAIN, helloWorldContentLength);
  90. resp.end(helloWorldBuffer);
  91. }
  92. private void handleJson(HttpServerRequest req) {
  93. Buffer buff = new Buffer(Json.encode(Collections.singletonMap(TEXT_MESSAGE, HELLO_WORLD)));
  94. HttpServerResponse resp = req.response();
  95. setHeaders(resp, RESPONSE_TYPE_JSON, String.valueOf(buff.length()));
  96. resp.end(buff);
  97. }
  98. private void handleDbMongo(final HttpServerRequest req) {
  99. findRandom(new Handler<Message<JsonObject>>() {
  100. @Override
  101. public void handle(Message<JsonObject> reply) {
  102. JsonObject world = getResultFromReply(reply);
  103. String result = world.encode();
  104. sendResponse(req, result);
  105. }
  106. });
  107. }
  108. private JsonObject getResultFromReply(Message<JsonObject> reply) {
  109. JsonObject body = reply.body();
  110. JsonObject world = body.getObject(TEXT_RESULT);
  111. Object id = world.removeField(UNDERSCORE_ID);
  112. if (id instanceof Double) {
  113. world.putValue(TEXT_ID, Integer.valueOf(((Double)id).intValue()));
  114. } else {
  115. world.putValue(TEXT_ID, id);
  116. }
  117. return world;
  118. }
  119. private void handleDBMongo(final HttpServerRequest req, boolean randomUpdates) {
  120. int queriesParam = 1;
  121. try {
  122. queriesParam = Integer.parseInt(req.params().get(TEXT_QUERIES));
  123. } catch (NumberFormatException e) {
  124. queriesParam = 1;
  125. }
  126. if (queriesParam < 1) {
  127. queriesParam = 1;
  128. } else if (queriesParam > 500) {
  129. queriesParam = 500;
  130. }
  131. final MongoHandler dbh = new MongoHandler(req, queriesParam, randomUpdates);
  132. for (int i = 0; i < queriesParam; i++) {
  133. findRandom(dbh);
  134. }
  135. }
  136. private void findRandom(Handler<Message<JsonObject>> handler) {
  137. vertx.eventBus().send(
  138. MONGO_ADDRESS,
  139. new JsonObject()
  140. .putString(TEXT_ACTION, TEXT_FINDONE)
  141. .putString(TEXT_COLLECTION, TEXT_WORLD)
  142. .putObject(TEXT_MATCHER, new JsonObject().putNumber(UNDERSCORE_ID, (random.nextInt(10000) + 1))),
  143. handler);
  144. }
  145. private void updateRandom(JsonObject json) {
  146. vertx.eventBus().send(
  147. MONGO_ADDRESS,
  148. new JsonObject()
  149. .putString(TEXT_ACTION, TEXT_UPDATE)
  150. .putString(TEXT_COLLECTION, TEXT_WORLD)
  151. .putObject(TEXT_CRITERIA, new JsonObject().putValue(UNDERSCORE_ID, json.getValue(TEXT_ID)))
  152. .putObject(TEXT_OBJ_NEW, json)
  153. );
  154. }
  155. private void sendResponse(HttpServerRequest req, String result) {
  156. Buffer buff = new Buffer(result);
  157. HttpServerResponse resp = req.response();
  158. setHeaders(resp, RESPONSE_TYPE_JSON, String.valueOf(buff.length()));
  159. resp.end(buff);
  160. }
  161. private void setHeaders(HttpServerResponse resp, String contentType, String contentLength) {
  162. resp.putHeader(HEADER_CONTENT_TYPE, contentType);
  163. resp.putHeader(HEADER_CONTENT_LENGTH, contentLength);
  164. resp.putHeader(HEADER_SERVER, HEADER_SERVER_VERTX );
  165. resp.putHeader(HEADER_DATE, dateString);
  166. }
  167. private class MongoHandler implements Handler<Message<JsonObject>> {
  168. private final HttpServerRequest req;
  169. private final int queries;
  170. private final JsonArray worlds;
  171. private final Random random;
  172. private final boolean randomUpdates;
  173. public MongoHandler(HttpServerRequest request, int queriesParam, boolean performRandomUpdates) {
  174. req = request;
  175. queries = queriesParam;
  176. randomUpdates = performRandomUpdates;
  177. random = ThreadLocalRandom.current();
  178. worlds = new JsonArray();
  179. }
  180. @Override
  181. public void handle(Message<JsonObject> reply) {
  182. JsonObject world = getResultFromReply(reply);
  183. if (randomUpdates) {
  184. world.putValue(RANDOM_NUMBER, (random.nextInt(10000) + 1));
  185. updateRandom(world);
  186. }
  187. worlds.add(world);
  188. if (worlds.size() == this.queries) {
  189. // All queries have completed; send the response.
  190. String result = worlds.encode();
  191. sendResponse(req, result);
  192. }
  193. }
  194. }
  195. }