package hello; import static hello.Helper.getQueries; import static hello.Helper.randomWorldNumber; import static hello.Helper.sendException; import static hello.Helper.sendJson; import com.mongodb.async.client.MongoCollection; import com.mongodb.async.client.MongoDatabase; import com.mongodb.client.model.Filters; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; import java.util.concurrent.CompletableFuture; import org.bson.Document; /** * Handles the multi-query database test using MongoDB with an asynchronous API. */ final class QueriesMongoAsyncHandler implements HttpHandler { private final MongoCollection worldCollection; QueriesMongoAsyncHandler(MongoDatabase db) { worldCollection = db.getCollection("world"); } @Override public void handleRequest(HttpServerExchange exchange) { int queries = getQueries(exchange); nWorlds(queries).whenComplete( (worlds, exception) -> { if (exception != null) { sendException(exchange, exception); } else { sendJson(exchange, worlds); } }); } private CompletableFuture nWorlds(int n) { @SuppressWarnings({ "unchecked", "rawtypes" }) CompletableFuture[] futures = new CompletableFuture[n]; for (int i = 0; i < futures.length; i++) { futures[i] = oneWorld(); } return CompletableFuture.allOf(futures).thenApply( nil -> { World[] worlds = new World[futures.length]; for (int i = 0; i < futures.length; i++) { worlds[i] = futures[i].join(); } return worlds; }); } private CompletableFuture oneWorld() { CompletableFuture future = new CompletableFuture<>(); worldCollection .find(Filters.eq(randomWorldNumber())) .map(Helper::mongoDocumentToWorld) .first( (world, exception) -> { if (exception != null) { future.completeExceptionally(exception); } else { future.complete(world); } }); return future; } }