feature/undertow #4
4 changed files with 125 additions and 109 deletions
|
@ -1,22 +1,17 @@
|
|||
package ch.fritteli.labyrinth.server;
|
||||
|
||||
import ch.fritteli.labyrinth.generator.model.Labyrinth;
|
||||
import ch.fritteli.labyrinth.generator.renderer.html.HTMLRenderer;
|
||||
import ch.fritteli.labyrinth.generator.renderer.pdf.PDFRenderer;
|
||||
import ch.fritteli.labyrinth.generator.renderer.text.TextRenderer;
|
||||
import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer;
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import io.vavr.collection.HashMap;
|
||||
import io.vavr.collection.HashSet;
|
||||
import io.vavr.collection.List;
|
||||
import io.vavr.collection.Map;
|
||||
import io.vavr.collection.Set;
|
||||
import io.vavr.collection.Stream;
|
||||
import io.vavr.control.Option;
|
||||
import io.vavr.control.Try;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -251,71 +246,4 @@ public class LabyrinthServer {
|
|||
return Stream.of(values()).find(param -> param.names.exists(name::equalsIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
||||
public enum OutputType {
|
||||
TEXT_PLAIN("text/plain; charset=UTF-8",
|
||||
labyrinth -> TextRenderer.newInstance().render(labyrinth).getBytes(StandardCharsets.UTF_8),
|
||||
"txt",
|
||||
false,
|
||||
"t",
|
||||
"text"
|
||||
),
|
||||
HTML("text/html",
|
||||
labyrinth -> HTMLRenderer.newInstance().render(labyrinth).getBytes(StandardCharsets.UTF_8),
|
||||
"html",
|
||||
false,
|
||||
"h",
|
||||
"html"
|
||||
),
|
||||
PDF("application/pdf", labyrinth -> PDFRenderer.newInstance().render(labyrinth), "pdf", false, "p", "pdf"),
|
||||
PDFFILE("application/pdf",
|
||||
labyrinth -> PDFRenderer.newInstance().render(labyrinth),
|
||||
"pdf",
|
||||
true,
|
||||
"f",
|
||||
"pdffile"
|
||||
),
|
||||
BINARY("application/octet-stream", SerializerDeserializer::serialize, "laby", true, "b", "binary");
|
||||
@Getter
|
||||
@NonNull
|
||||
private final String contentType;
|
||||
@NonNull
|
||||
private final List<String> names;
|
||||
@NonNull
|
||||
private final Function<Labyrinth, byte[]> render;
|
||||
@Getter
|
||||
private final boolean attachment;
|
||||
@Getter
|
||||
@NonNull
|
||||
private final String fileExtension;
|
||||
|
||||
OutputType(@NonNull final String contentType,
|
||||
@NonNull final Function<Labyrinth, byte[]> render,
|
||||
@NonNull final String fileExtension,
|
||||
final boolean attachment,
|
||||
@NonNull final String... names) {
|
||||
this.contentType = contentType;
|
||||
this.render = render;
|
||||
this.fileExtension = fileExtension;
|
||||
this.attachment = attachment;
|
||||
this.names = List.of(names);
|
||||
}
|
||||
|
||||
public static Option<OutputType> ofString(@Nullable final String name) {
|
||||
if (name == null) {
|
||||
return Option.none();
|
||||
}
|
||||
final String nameLC = name.toLowerCase();
|
||||
return Stream.of(values()).find(param -> param.names.contains(nameLC));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.names.last();
|
||||
}
|
||||
|
||||
public byte[] render(@NonNull final Labyrinth labyrinth) {
|
||||
return this.render.apply(labyrinth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
77
src/main/java/ch/fritteli/labyrinth/server/OutputType.java
Normal file
77
src/main/java/ch/fritteli/labyrinth/server/OutputType.java
Normal file
|
@ -0,0 +1,77 @@
|
|||
package ch.fritteli.labyrinth.server;
|
||||
|
||||
import ch.fritteli.labyrinth.generator.model.Labyrinth;
|
||||
import ch.fritteli.labyrinth.generator.renderer.html.HTMLRenderer;
|
||||
import ch.fritteli.labyrinth.generator.renderer.pdf.PDFRenderer;
|
||||
import ch.fritteli.labyrinth.generator.renderer.text.TextRenderer;
|
||||
import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer;
|
||||
import io.vavr.collection.List;
|
||||
import io.vavr.collection.Stream;
|
||||
import io.vavr.control.Option;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Function;
|
||||
|
||||
public enum OutputType {
|
||||
TEXT_PLAIN("text/plain; charset=UTF-8",
|
||||
labyrinth -> TextRenderer.newInstance().render(labyrinth).getBytes(StandardCharsets.UTF_8),
|
||||
"txt",
|
||||
false,
|
||||
"t",
|
||||
"text"
|
||||
),
|
||||
HTML("text/html",
|
||||
labyrinth -> HTMLRenderer.newInstance().render(labyrinth).getBytes(StandardCharsets.UTF_8),
|
||||
"html",
|
||||
false,
|
||||
"h",
|
||||
"html"
|
||||
),
|
||||
PDF("application/pdf", labyrinth -> PDFRenderer.newInstance().render(labyrinth), "pdf", false, "p", "pdf"),
|
||||
PDFFILE("application/pdf", labyrinth -> PDFRenderer.newInstance().render(labyrinth), "pdf", true, "f", "pdffile"),
|
||||
BINARY("application/octet-stream", SerializerDeserializer::serialize, "laby", true, "b", "binary");
|
||||
@Getter
|
||||
@NonNull
|
||||
private final String contentType;
|
||||
@NonNull
|
||||
private final List<String> names;
|
||||
@NonNull
|
||||
private final Function<Labyrinth, byte[]> render;
|
||||
@Getter
|
||||
private final boolean attachment;
|
||||
@Getter
|
||||
@NonNull
|
||||
private final String fileExtension;
|
||||
|
||||
OutputType(@NonNull final String contentType,
|
||||
@NonNull final Function<Labyrinth, byte[]> render,
|
||||
@NonNull final String fileExtension,
|
||||
final boolean attachment,
|
||||
@NonNull final String... names) {
|
||||
this.contentType = contentType;
|
||||
this.render = render;
|
||||
this.fileExtension = fileExtension;
|
||||
this.attachment = attachment;
|
||||
this.names = List.of(names);
|
||||
}
|
||||
|
||||
public static Option<OutputType> ofString(@Nullable final String name) {
|
||||
if (name == null) {
|
||||
return Option.none();
|
||||
}
|
||||
final String nameLC = name.toLowerCase();
|
||||
return Stream.of(values()).find(param -> param.names.contains(nameLC));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.names.last();
|
||||
}
|
||||
|
||||
public byte[] render(@NonNull final Labyrinth labyrinth) {
|
||||
return this.render.apply(labyrinth);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package ch.fritteli.labyrinth.server.undertow_playground;
|
||||
|
||||
import ch.fritteli.labyrinth.generator.model.Labyrinth;
|
||||
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.HttpString;
|
||||
import io.vavr.control.Option;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Deque;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@Slf4j
|
||||
class LabyrinthHttpHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
||||
if (exchange.isInIoThread()) {
|
||||
exchange.dispatch(this);
|
||||
return;
|
||||
}
|
||||
final Map<String, Deque<String>> queryParameters = exchange.getQueryParameters();
|
||||
final Option<String> output = UndertowPlayground.getFirstOption(queryParameters, "output");
|
||||
final Option<Integer> width = UndertowPlayground.getIntOption(queryParameters, "width");
|
||||
final Option<Integer> height = UndertowPlayground.getIntOption(queryParameters, "height");
|
||||
final Option<Integer> id = UndertowPlayground.getIntOption(queryParameters, "id");
|
||||
|
||||
log.info("Output: {}", output);
|
||||
log.info("Width: {}", width);
|
||||
log.info("Height: {}", height);
|
||||
log.info("Id: {}", id);
|
||||
final Integer theId = id.getOrElse(() -> new Random().nextInt());
|
||||
final Labyrinth labyrinth = new Labyrinth(width.get(), height.get(), theId);
|
||||
final OutputType outputType = output.flatMap(OutputType::ofString).get();
|
||||
final byte[] result = outputType.render(labyrinth);
|
||||
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, outputType.getContentType());
|
||||
exchange.getResponseHeaders().put(HttpString.tryFromString("X-Labyrinth-ID"), String.valueOf(theId));
|
||||
exchange.getResponseHeaders().put(HttpString.tryFromString("X-Labyrinth-Width"), String.valueOf(width.get()));
|
||||
exchange.getResponseHeaders().put(HttpString.tryFromString("X-Labyrinth-Height"), String.valueOf(height.get()));
|
||||
exchange.getResponseSender().send(ByteBuffer.wrap(result));
|
||||
}
|
||||
}
|
|
@ -1,54 +1,20 @@
|
|||
package ch.fritteli.labyrinth.server.undertow_playground;
|
||||
|
||||
import ch.fritteli.labyrinth.generator.model.Labyrinth;
|
||||
import ch.fritteli.labyrinth.server.LabyrinthServer;
|
||||
import io.undertow.server.HttpHandler;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.server.RoutingHandler;
|
||||
import io.undertow.util.HeaderValues;
|
||||
import io.undertow.util.Headers;
|
||||
import io.undertow.util.HttpString;
|
||||
import io.vavr.control.Option;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Deque;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@Slf4j
|
||||
public class UndertowPlayground {
|
||||
public static final RoutingHandler r = new RoutingHandler().get("/create/{output}", new HttpHandler() {
|
||||
@Override
|
||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
||||
if (exchange.isInIoThread()) {
|
||||
exchange.dispatch(this);
|
||||
return;
|
||||
}
|
||||
final Map<String, Deque<String>> queryParameters = exchange.getQueryParameters();
|
||||
final Option<String> output = getFirstOption(queryParameters, "output");
|
||||
final Option<Integer> width = getIntOption(queryParameters, "width");
|
||||
final Option<Integer> height = getIntOption(queryParameters, "height");
|
||||
final Option<Integer> id = getIntOption(queryParameters, "id");
|
||||
|
||||
log.info("Output: {}", output);
|
||||
log.info("Width: {}", width);
|
||||
log.info("Height: {}", height);
|
||||
log.info("Id: {}", id);
|
||||
final Integer theId = id.getOrElse(() -> new Random().nextInt());
|
||||
final Labyrinth labyrinth = new Labyrinth(width.get(), height.get(), theId);
|
||||
final LabyrinthServer.OutputType outputType = output.flatMap(LabyrinthServer.OutputType::ofString).get();
|
||||
final byte[] result = outputType.render(labyrinth);
|
||||
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, outputType.getContentType());
|
||||
exchange.getResponseHeaders().put(HttpString.tryFromString("X-Labyrinth-ID"), String.valueOf(theId));
|
||||
exchange.getResponseHeaders()
|
||||
.put(HttpString.tryFromString("X-Labyrinth-Width"), String.valueOf(width.get()));
|
||||
exchange.getResponseHeaders()
|
||||
.put(HttpString.tryFromString("X-Labyrinth-Height"), String.valueOf(height.get()));
|
||||
exchange.getResponseSender().send(ByteBuffer.wrap(result));
|
||||
}
|
||||
}).post("/render", new HttpHandler() {
|
||||
public static final RoutingHandler r = new RoutingHandler().get("/create/{output}", new LabyrinthHttpHandler()).post("/render", new HttpHandler() {
|
||||
@Override
|
||||
public void handleRequest(final HttpServerExchange exchange) {
|
||||
if (exchange.isInIoThread()) {
|
||||
|
@ -67,13 +33,13 @@ public class UndertowPlayground {
|
|||
});
|
||||
|
||||
@NonNull
|
||||
private static Option<Integer> getIntOption(@NonNull final Map<String, Deque<String>> queryParams,
|
||||
public static Option<Integer> getIntOption(@NonNull final Map<String, Deque<String>> queryParams,
|
||||
@NonNull final String paramName) {
|
||||
return getFirstOption(queryParams, paramName).toTry().map(Integer::parseInt).toOption();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static Option<String> getFirstOption(@NonNull final Map<String, Deque<String>> queryParams,
|
||||
public static Option<String> getFirstOption(@NonNull final Map<String, Deque<String>> queryParams,
|
||||
@NonNull final String paramName) {
|
||||
return Option.of(queryParams.get(paramName)).map(Deque::peek).flatMap(Option::of);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue