From 741894163bc8a9fe4a29936376a2e0daacd3c6e9 Mon Sep 17 00:00:00 2001 From: Manuel Friedli Date: Thu, 6 Apr 2023 08:19:44 +0200 Subject: [PATCH] Implement rendering of binary data. --- .../labyrinth/server/LabyrinthServer.java | 46 +------------------ .../server/handler/AbstractHttpHandler.java | 7 ++- .../server/handler/RenderHandler.java | 36 ++++++++++++++- src/main/resources/logback.xml | 2 + 4 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java b/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java index 09ed5fc..f0f0321 100644 --- a/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java +++ b/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java @@ -45,7 +45,7 @@ public class LabyrinthServer { private void start() { Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "listener-stopper")); this.undertow.start(); - log.info("Listeing on http://{}:{}", this.config.getAddress().getHostAddress(), this.config.getPort()); + log.info("Listening on http://{}:{}", this.config.getAddress().getHostAddress(), this.config.getPort()); } private void stop() { @@ -53,48 +53,4 @@ public class LabyrinthServer { this.undertow.stop(); log.info("Server stopped."); } - -// private void handleRender(final HttpExchange exchange) { -// this.executorService.submit(() -> { -// try { -// log.debug("Handling request to {}", exchange.getRequestURI()); -// final String requestMethod = exchange.getRequestMethod(); -// if (!requestMethod.equals("POST")) { -// exchange.getResponseBody().close(); -// exchange.sendResponseHeaders(405, -1); -// return; -// } -// final byte[] bytes = exchange.getRequestBody().readAllBytes(); -// -// final Labyrinth labyrinth = SerializerDeserializer.deserialize(bytes); -// -// final OutputType output = exchange.getRequestHeaders() -// .get("Accept") -// .contains(OutputType.HTML.getContentType()) ? -// OutputType.HTML : -// OutputType.TEXT_PLAIN; -// final byte[] render; -// final Headers responseHeaders = exchange.getResponseHeaders(); -// try { -// render = output.render(labyrinth); -// } catch (Exception e) { -// responseHeaders.add("Content-type", "text/plain; charset=UTF-8"); -// exchange.sendResponseHeaders(500, 0); -// final OutputStream responseBody = exchange.getResponseBody(); -// responseBody.write(("Error: " + e).getBytes(StandardCharsets.UTF_8)); -// responseBody.flush(); -// return; -// } -// responseHeaders.add("Content-type", output.getContentType()); -// exchange.sendResponseHeaders(200, 0); -// final OutputStream responseBody = exchange.getResponseBody(); -// responseBody.write(render); -// responseBody.flush(); -// } catch (Exception e) { -// log.error("FSCK!", e); -// } finally { -// exchange.close(); -// } -// }); -// } } diff --git a/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java b/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java index 384ecc2..198c7a4 100644 --- a/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java +++ b/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java @@ -7,13 +7,17 @@ import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.UUID; @Slf4j public abstract class AbstractHttpHandler implements HttpHandler { @Override public final void handleRequest(@NonNull final HttpServerExchange exchange) { - try (final MDC.MDCCloseable mdc = MDC.putCloseable("correlationId", UUID.randomUUID().toString())) { + final Instant start = Instant.now(); + try (final MDC.MDCCloseable closeable = MDC.putCloseable("correlationId", UUID.randomUUID().toString())) { + if (exchange.isInIoThread()) { log.debug("Dispatching request"); exchange.dispatch(this); @@ -27,6 +31,7 @@ public abstract class AbstractHttpHandler implements HttpHandler { .getResponseSender() .send(StatusCodes.INTERNAL_SERVER_ERROR_STRING); } + log.debug("Completed request in {}ms.", start.until(Instant.now(), ChronoUnit.MILLIS)); } } diff --git a/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java b/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java index a440b90..c5e47d9 100644 --- a/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java +++ b/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java @@ -1,17 +1,49 @@ package ch.fritteli.labyrinth.server.handler; +import ch.fritteli.labyrinth.generator.model.Labyrinth; +import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer; +import ch.fritteli.labyrinth.server.OutputType; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; +import io.undertow.util.Headers; import io.undertow.util.StatusCodes; +import io.vavr.control.Option; +import lombok.extern.slf4j.Slf4j; +import java.nio.ByteBuffer; + +@Slf4j public class RenderHandler implements HttpHandler { @Override public void handleRequest(final HttpServerExchange exchange) { + log.debug("Handling render request"); + if (exchange.isInIoThread()) { exchange.dispatch(this); return; } - exchange.setStatusCode(StatusCodes.NOT_IMPLEMENTED); - exchange.getResponseSender().send("Rendering binary data is not implemented yet."); + exchange.getRequestReceiver().receiveFullBytes((httpServerExchange, bytes) -> { + final Labyrinth labyrinth = SerializerDeserializer.deserialize(bytes); + final OutputType output = Option.of(httpServerExchange.getRequestHeaders().get(Headers.ACCEPT)) + .exists(values -> values.contains(OutputType.HTML.getContentType())) ? + OutputType.HTML : + OutputType.TEXT_PLAIN; + final byte[] render; + try { + render = output.render(labyrinth); + } catch (final Exception e) { + log.error("Error rendering binary labyrinth data", e); + httpServerExchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR) + .getResponseSender() + .send("Error rendering labyrinth: %s".formatted(e.getMessage())); + return; + } + httpServerExchange + .setStatusCode(StatusCodes.OK) + .getResponseHeaders() + .put(Headers.CONTENT_TYPE, output.getContentType()); + httpServerExchange.getResponseSender() + .send(ByteBuffer.wrap(render)); + }); } } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 6cec730..69dd770 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -13,5 +13,7 @@ + +