Expose start and end tile; accept start and end input parameters when
creating labyrinths.
This commit is contained in:
		
							parent
							
								
									7ebff97d3e
								
							
						
					
					
						commit
						a08a999e82
					
				
					 7 changed files with 111 additions and 12 deletions
				
			
		|  | @ -1,7 +1,8 @@ | |||
| package ch.fritteli.labyrinth.server; | ||||
| 
 | ||||
| import ch.fritteli.labyrinth.server.handler.CreateHandler; | ||||
| import ch.fritteli.labyrinth.server.handler.RenderHandler; | ||||
| import ch.fritteli.labyrinth.server.handler.RenderV1Handler; | ||||
| import ch.fritteli.labyrinth.server.handler.RenderV2Handler; | ||||
| import io.undertow.Undertow; | ||||
| import io.undertow.server.RoutingHandler; | ||||
| import io.vavr.control.Try; | ||||
|  | @ -21,7 +22,8 @@ public class LabyrinthServer { | |||
|         log.info("Starting Server at http://{}:{}/", hostAddress, port); | ||||
|         final RoutingHandler routingHandler = new RoutingHandler() | ||||
|                 .get(CreateHandler.PATH_TEMPLATE, new CreateHandler()) | ||||
|                 .post(RenderHandler.PATH_TEMPLATE, new RenderHandler()); | ||||
|                 .post(RenderV1Handler.PATH_TEMPLATE, new RenderV1Handler()) | ||||
|                 .post(RenderV2Handler.PATH_TEMPLATE, new RenderV2Handler()); | ||||
| 
 | ||||
|         this.undertow = Undertow.builder() | ||||
|                 .addHttpListener(port, hostAddress) | ||||
|  |  | |||
|  | @ -5,7 +5,8 @@ import ch.fritteli.labyrinth.generator.renderer.html.HTMLRenderer; | |||
| import ch.fritteli.labyrinth.generator.renderer.json.JsonRenderer; | ||||
| import ch.fritteli.labyrinth.generator.renderer.pdf.PDFRenderer; | ||||
| import ch.fritteli.labyrinth.generator.renderer.text.TextRenderer; | ||||
| import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer; | ||||
| import ch.fritteli.labyrinth.generator.serialization.v1.SerializerDeserializerV1; | ||||
| import ch.fritteli.labyrinth.generator.serialization.v2.SerializerDeserializerV2; | ||||
| import io.vavr.collection.List; | ||||
| import io.vavr.collection.Stream; | ||||
| import io.vavr.control.Option; | ||||
|  | @ -55,10 +56,16 @@ public enum OutputType { | |||
|             "pdffile"), | ||||
|     BINARY("application/octet-stream", | ||||
|             "laby", | ||||
|             SerializerDeserializer::serialize, | ||||
|             SerializerDeserializerV1::serialize, | ||||
|             true, | ||||
|             "b", | ||||
|             "binary"); | ||||
|             "binary"), | ||||
|     BINARY_V2("application/octet-stream", | ||||
|             "lab2", | ||||
|             SerializerDeserializerV2::serialize, | ||||
|             true, | ||||
|             "v", | ||||
|             "binaryv2"); | ||||
|     @Getter | ||||
|     @NonNull | ||||
|     private final String contentType; | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| package ch.fritteli.labyrinth.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.labyrinth.generator.Generator; | ||||
| import ch.fritteli.labyrinth.generator.model.Labyrinth; | ||||
| import ch.fritteli.labyrinth.generator.model.Position; | ||||
| import ch.fritteli.labyrinth.server.OutputType; | ||||
| import io.vavr.Tuple; | ||||
| import io.vavr.Tuple2; | ||||
|  | @ -25,6 +27,8 @@ class ParametersToLabyrinthExtractor { | |||
|         final Option<Integer> width = getParameterValue(RequestParameter.WIDTH); | ||||
|         final Option<Integer> height = getParameterValue(RequestParameter.HEIGHT); | ||||
|         final Option<Long> id = getParameterValue(RequestParameter.ID); | ||||
|         final Option<Position> start = getParameterValue(RequestParameter.START); | ||||
|         final Option<Position> end = getParameterValue(RequestParameter.END); | ||||
| 
 | ||||
|         if (output.isEmpty()) { | ||||
|             return Try.failure(new IllegalArgumentException("Path parameter %s is required and must be one of: %s".formatted( | ||||
|  | @ -45,7 +49,16 @@ class ParametersToLabyrinthExtractor { | |||
|             ))); | ||||
|         } | ||||
| 
 | ||||
|         return Try.of(() -> Tuple.of(output.get(), new Labyrinth(width.get(), height.get(), id.getOrElse(() -> new Random().nextLong())))); | ||||
|         return Try.of(() -> { | ||||
|             final Labyrinth labyrinth; | ||||
|             if (start.isDefined() && end.isDefined()) { | ||||
|                 labyrinth = new Labyrinth(width.get(), height.get(), id.getOrElse(() -> new Random().nextLong()), start.get(), end.get()); | ||||
|             } else { | ||||
|                 labyrinth = new Labyrinth(width.get(), height.get(), id.getOrElse(() -> new Random().nextLong())); | ||||
|             } | ||||
|             new Generator(labyrinth).run(); | ||||
|             return Tuple.of(output.get(), labyrinth); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| package ch.fritteli.labyrinth.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.labyrinth.generator.model.Labyrinth; | ||||
| import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer; | ||||
| import ch.fritteli.labyrinth.generator.serialization.v1.SerializerDeserializerV1; | ||||
| import ch.fritteli.labyrinth.server.OutputType; | ||||
| import io.undertow.server.HttpServerExchange; | ||||
| import io.undertow.util.HeaderValues; | ||||
|  | @ -12,9 +12,9 @@ import lombok.NonNull; | |||
| import lombok.extern.slf4j.Slf4j; | ||||
| 
 | ||||
| @Slf4j | ||||
| public class RenderHandler extends AbstractHttpHandler { | ||||
| public class RenderV1Handler extends AbstractHttpHandler { | ||||
| 
 | ||||
|     public static final String PATH_TEMPLATE = "/render/{output}"; | ||||
|     public static final String PATH_TEMPLATE = "/render/v1/{output}"; | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle(final HttpServerExchange exchange) { | ||||
|  | @ -28,7 +28,7 @@ public class RenderHandler extends AbstractHttpHandler { | |||
|             final OutputType output = this.getOutputType(httpServerExchange); | ||||
|             final byte[] render; | ||||
|             try { | ||||
|                 final Labyrinth labyrinth = SerializerDeserializer.deserialize(bytes); | ||||
|                 final Labyrinth labyrinth = SerializerDeserializerV1.deserialize(bytes); | ||||
|                 render = output.render(labyrinth); | ||||
|             } catch (final Exception e) { | ||||
|                 log.error("Error rendering binary labyrinth data", e); | ||||
|  | @ -0,0 +1,60 @@ | |||
| package ch.fritteli.labyrinth.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.labyrinth.generator.model.Labyrinth; | ||||
| import ch.fritteli.labyrinth.generator.serialization.v2.SerializerDeserializerV2; | ||||
| import ch.fritteli.labyrinth.server.OutputType; | ||||
| import io.undertow.server.HttpServerExchange; | ||||
| import io.undertow.util.HeaderValues; | ||||
| import io.undertow.util.Headers; | ||||
| import io.undertow.util.StatusCodes; | ||||
| import java.nio.ByteBuffer; | ||||
| import lombok.NonNull; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| 
 | ||||
| @Slf4j | ||||
| public class RenderV2Handler extends AbstractHttpHandler { | ||||
| 
 | ||||
|     public static final String PATH_TEMPLATE = "/render/v2/{output}"; | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle(final HttpServerExchange exchange) { | ||||
|         log.debug("Handling render request"); | ||||
| 
 | ||||
|         if (exchange.isInIoThread()) { | ||||
|             exchange.dispatch(this); | ||||
|             return; | ||||
|         } | ||||
|         exchange.getRequestReceiver().receiveFullBytes((httpServerExchange, bytes) -> { | ||||
|             final OutputType output = this.getOutputType(httpServerExchange); | ||||
|             final byte[] render; | ||||
|             try { | ||||
|                 final Labyrinth labyrinth = SerializerDeserializerV2.deserialize(bytes); | ||||
|                 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)); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private OutputType getOutputType(@NonNull final HttpServerExchange httpServerExchange) { | ||||
|         return RequestParameter.OUTPUT.<OutputType>getParameterValue(httpServerExchange.getQueryParameters()) | ||||
|                 .getOrElse(() -> { | ||||
|                     final HeaderValues accept = httpServerExchange.getRequestHeaders().get(Headers.ACCEPT); | ||||
|                     if (accept.contains(OutputType.HTML.getContentType())) { | ||||
|                         return OutputType.HTML; | ||||
|                     } | ||||
|                     return OutputType.TEXT_PLAIN; | ||||
|                 }); | ||||
|     } | ||||
| } | ||||
|  | @ -1,5 +1,6 @@ | |||
| package ch.fritteli.labyrinth.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.labyrinth.generator.model.Position; | ||||
| import ch.fritteli.labyrinth.server.OutputType; | ||||
| import io.vavr.Tuple2; | ||||
| import io.vavr.collection.HashMap; | ||||
|  | @ -26,7 +27,23 @@ enum RequestParameter { | |||
|             .toOption() | ||||
|             .onEmpty(() -> log.debug("Unparseable value for parameter 'id': '{}'", p)), "i", "id"), | ||||
|     OUTPUT(p -> OutputType.ofString(p) | ||||
|             .onEmpty(() -> log.debug("Unparseable value for parameter 'output': '{}'", p)), "o", "output"); | ||||
|             .onEmpty(() -> log.debug("Unparseable value for parameter 'output': '{}'", p)), "o", "output"), | ||||
|     START(p -> Try.of(() -> { | ||||
|                 final String[] parts = p.split(","); | ||||
|                 final int x = Integer.parseInt(parts[0]); | ||||
|                 final int y = Integer.parseInt(parts[1]); | ||||
|                 return new Position(x, y); | ||||
|             }) | ||||
|             .toOption() | ||||
|             .onEmpty(() -> log.debug("Unparseable value for parameter 'start': '{}'", p)), "s", "start"), | ||||
|     END(p -> Try.of(() -> { | ||||
|                 final String[] parts = p.split(","); | ||||
|                 final int x = Integer.parseInt(parts[0]); | ||||
|                 final int y = Integer.parseInt(parts[1]); | ||||
|                 return new Position(x, y); | ||||
|             }) | ||||
|             .toOption() | ||||
|             .onEmpty(() -> log.debug("Unparseable value for parameter 'end': '{}'", p)), "e", "end"); | ||||
|     @NonNull | ||||
|     private final Function<String, Option<?>> extractor; | ||||
|     @Getter | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue