Implement rendering of binary data.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Manuel Friedli 2023-04-06 08:19:44 +02:00
parent 87fba97672
commit 741894163b
Signed by: manuel
GPG key ID: 41D08ABA75634DA1
4 changed files with 43 additions and 48 deletions

View file

@ -45,7 +45,7 @@ public class LabyrinthServer {
private void start() { private void start() {
Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "listener-stopper")); Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "listener-stopper"));
this.undertow.start(); 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() { private void stop() {
@ -53,48 +53,4 @@ public class LabyrinthServer {
this.undertow.stop(); this.undertow.stop();
log.info("Server stopped."); 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();
// }
// });
// }
} }

View file

@ -7,13 +7,17 @@ import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC; import org.slf4j.MDC;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.UUID; import java.util.UUID;
@Slf4j @Slf4j
public abstract class AbstractHttpHandler implements HttpHandler { public abstract class AbstractHttpHandler implements HttpHandler {
@Override @Override
public final void handleRequest(@NonNull final HttpServerExchange exchange) { 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()) { if (exchange.isInIoThread()) {
log.debug("Dispatching request"); log.debug("Dispatching request");
exchange.dispatch(this); exchange.dispatch(this);
@ -27,6 +31,7 @@ public abstract class AbstractHttpHandler implements HttpHandler {
.getResponseSender() .getResponseSender()
.send(StatusCodes.INTERNAL_SERVER_ERROR_STRING); .send(StatusCodes.INTERNAL_SERVER_ERROR_STRING);
} }
log.debug("Completed request in {}ms.", start.until(Instant.now(), ChronoUnit.MILLIS));
} }
} }

View file

@ -1,17 +1,49 @@
package ch.fritteli.labyrinth.server.handler; 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.HttpHandler;
import io.undertow.server.HttpServerExchange; import io.undertow.server.HttpServerExchange;
import io.undertow.util.Headers;
import io.undertow.util.StatusCodes; 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 { public class RenderHandler implements HttpHandler {
@Override @Override
public void handleRequest(final HttpServerExchange exchange) { public void handleRequest(final HttpServerExchange exchange) {
log.debug("Handling render request");
if (exchange.isInIoThread()) { if (exchange.isInIoThread()) {
exchange.dispatch(this); exchange.dispatch(this);
return; return;
} }
exchange.setStatusCode(StatusCodes.NOT_IMPLEMENTED); exchange.getRequestReceiver().receiveFullBytes((httpServerExchange, bytes) -> {
exchange.getResponseSender().send("Rendering binary data is not implemented yet."); 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));
});
} }
} }

View file

@ -13,5 +13,7 @@
<root level="info"> <root level="info">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
<logger name="ch.fritteli.labyrinth.server.handler.AbstractHttpHandler" level="debug"/>
<logger name="ch.fritteli.labyrinth.server.handler.CreateHandler" level="debug"/> <logger name="ch.fritteli.labyrinth.server.handler.CreateHandler" level="debug"/>
<logger name="ch.fritteli.labyrinth.server.handler.RenderHandler" level="debug"/>
</configuration> </configuration>