Reformat everything.
First prototype of runnign with untertow.
This commit is contained in:
		
							parent
							
								
									682e0d0f25
								
							
						
					
					
						commit
						0bc1114aec
					
				
					 8 changed files with 281 additions and 270 deletions
				
			
		|  | @ -119,15 +119,13 @@ public class LabyrinthServer { | |||
|                 } | ||||
|                 responseHeaders.add("Content-type", output.getContentType()); | ||||
|                 if (output.isAttachment()) { | ||||
|                     responseHeaders.add( | ||||
|                             "Content-disposition", | ||||
|                             String.format("attachment; filename=\"labyrinth-%dx%d-%d.%s\"", | ||||
|                                           width, | ||||
|                                           height, | ||||
|                                           id, | ||||
|                                           output.getFileExtension() | ||||
|                             ) | ||||
|                     ); | ||||
|                     responseHeaders.add("Content-disposition", String.format( | ||||
|                             "attachment; filename=\"labyrinth-%dx%d-%d.%s\"", | ||||
|                             width, | ||||
|                             height, | ||||
|                             id, | ||||
|                             output.getFileExtension() | ||||
|                     )); | ||||
|                 } | ||||
|                 exchange.sendResponseHeaders(200, 0); | ||||
|                 final OutputStream responseBody = exchange.getResponseBody(); | ||||
|  | @ -254,7 +252,7 @@ public class LabyrinthServer { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private enum OutputType { | ||||
|     public enum OutputType { | ||||
|         TEXT_PLAIN("text/plain; charset=UTF-8", | ||||
|                    labyrinth -> TextRenderer.newInstance().render(labyrinth).getBytes(StandardCharsets.UTF_8), | ||||
|                    "txt", | ||||
|  | @ -303,7 +301,7 @@ public class LabyrinthServer { | |||
|             this.names = List.of(names); | ||||
|         } | ||||
| 
 | ||||
|         static Option<OutputType> ofString(@Nullable final String name) { | ||||
|         public static Option<OutputType> ofString(@Nullable final String name) { | ||||
|             if (name == null) { | ||||
|                 return Option.none(); | ||||
|             } | ||||
|  | @ -316,7 +314,7 @@ public class LabyrinthServer { | |||
|             return this.names.last(); | ||||
|         } | ||||
| 
 | ||||
|         byte[] render(@NonNull final Labyrinth labyrinth) { | ||||
|         public byte[] render(@NonNull final Labyrinth labyrinth) { | ||||
|             return this.render.apply(labyrinth); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -10,7 +10,6 @@ import org.jetbrains.annotations.Nullable; | |||
| 
 | ||||
| import java.net.InetAddress; | ||||
| 
 | ||||
| 
 | ||||
| @AllArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| @Slf4j | ||||
| @Value | ||||
|  | @ -18,8 +17,7 @@ public class ServerConfig { | |||
|     public static final String SYSPROP_HOST = "fritteli.labyrinth.server.host"; | ||||
|     public static final String SYSPROP_PORT = "fritteli.labyrinth.server.port"; | ||||
| 
 | ||||
|     @NonNull | ||||
|     InetAddress address; | ||||
|     @NonNull InetAddress address; | ||||
|     int port; | ||||
| 
 | ||||
|     public ServerConfig(@Nullable final String address, final int port) throws ConfigurationException { | ||||
|  | @ -28,6 +26,19 @@ public class ServerConfig { | |||
|         log.debug("host={}, port={}", this.address, this.port); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private static InetAddress validateAddress(@Nullable final String address) { | ||||
|         return Try.of(() -> InetAddress.getByName(address)) | ||||
|                   .getOrElseThrow(cause -> new ConfigurationException("Invalid hostname/address: " + address, cause)); | ||||
|     } | ||||
| 
 | ||||
|     private static int validatePort(final int port) { | ||||
|         if (port < 0 || port > 0xFFFF) { | ||||
|             throw new ConfigurationException("Port out of range (0..65535): " + port); | ||||
|         } | ||||
|         return port; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static ServerConfig init() throws ConfigurationException { | ||||
|         final String host = System.getProperty(SYSPROP_HOST); | ||||
|  | @ -36,26 +47,16 @@ public class ServerConfig { | |||
|         return new ServerConfig(host, port); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private static InetAddress validateAddress(@Nullable final String address) { | ||||
|         return Try.of(() -> InetAddress.getByName(address)) | ||||
|                 .getOrElseThrow(cause -> new ConfigurationException("Invalid hostname/address: " + address, cause)); | ||||
|     } | ||||
| 
 | ||||
|     private static int validatePort(@Nullable final String portString) { | ||||
|         if (portString == null) { | ||||
|             log.info("No port configured; using default."); | ||||
|             return 0; | ||||
|         } | ||||
|         return Try.of(() -> Integer.valueOf(portString)) | ||||
|                 .map(ServerConfig::validatePort) | ||||
|                 .getOrElseThrow(cause -> new ConfigurationException("Failed to parse port specified in system property '" + SYSPROP_PORT + "': " + portString, cause)); | ||||
|     } | ||||
| 
 | ||||
|     private static int validatePort(final int port) { | ||||
|         if (port < 0 || port > 0xFFFF) { | ||||
|             throw new ConfigurationException("Port out of range (0..65535): " + port); | ||||
|         } | ||||
|         return port; | ||||
|                   .map(ServerConfig::validatePort) | ||||
|                   .getOrElseThrow(cause -> new ConfigurationException( | ||||
|                           "Failed to parse port specified in system property '" + SYSPROP_PORT + "': " + portString, | ||||
|                           cause | ||||
|                   )); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -24,43 +24,6 @@ public class StaticResourcesFileHandler implements HttpHandler { | |||
|         log.debug("Created {}", this.getClass().getSimpleName()); | ||||
|     } | ||||
| 
 | ||||
|     private static void redirect(@NonNull final HttpExchange exchange, @NonNull final String target) throws IOException { | ||||
|         log.debug("Sending redirect to {}", target); | ||||
|         exchange.getResponseHeaders().add("Location", target); | ||||
|         exchange.sendResponseHeaders(302, -1); | ||||
|     } | ||||
| 
 | ||||
|     private static void notFound(@NonNull final HttpExchange exchange, @NonNull final String path) throws IOException { | ||||
|         log.debug("Resource '{}' not found, replying with HTTP 404", path); | ||||
|         exchange.getResponseHeaders().add("Content-type", "text/plain; charset=utf-8"); | ||||
|         exchange.sendResponseHeaders(404, 0); | ||||
|         exchange.getResponseBody().write("404 - Not found".getBytes(StandardCharsets.UTF_8)); | ||||
|         exchange.getResponseBody().flush(); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private static byte[] getBytes(@NonNull final String path) throws IOException { | ||||
|         final InputStream stream = StaticResourcesFileHandler.class.getClassLoader().getResourceAsStream(WEBASSETS_DIRECTORY + path); | ||||
|         if (stream == null) { | ||||
|             log.debug("Resource '{}' not found in classpath.", path); | ||||
|             return new byte[0]; | ||||
|         } | ||||
|         final byte[] response = IOUtils.toByteArray(stream); | ||||
|         log.debug("Sending reply; {} bytes", response.length); | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     private static String getMimeType(@NonNull final String path) { | ||||
|         if (path.endsWith(".html")) { | ||||
|             return "text/html"; | ||||
|         } | ||||
|         if (path.endsWith(".css")) { | ||||
|             return "text/css"; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle(@NonNull final HttpExchange exchange) throws IOException { | ||||
|         this.executorService.submit(() -> { | ||||
|  | @ -86,7 +49,13 @@ public class StaticResourcesFileHandler implements HttpHandler { | |||
|                     notFound(exchange, path); | ||||
|                     return; | ||||
|                 } | ||||
|                 log.debug("Serving {}{} with mimetype {}: {} bytes", WEBASSETS_DIRECTORY, path, mimeType, responseBytes.length); | ||||
|                 log.debug( | ||||
|                         "Serving {}{} with mimetype {}: {} bytes", | ||||
|                         WEBASSETS_DIRECTORY, | ||||
|                         path, | ||||
|                         mimeType, | ||||
|                         responseBytes.length | ||||
|                 ); | ||||
|                 exchange.getResponseHeaders().add("Content-type", mimeType); | ||||
|                 exchange.sendResponseHeaders(200, 0); | ||||
|                 exchange.getResponseBody().write(responseBytes); | ||||
|  | @ -98,4 +67,43 @@ public class StaticResourcesFileHandler implements HttpHandler { | |||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private static void redirect(@NonNull final HttpExchange exchange, @NonNull final String target) throws | ||||
|                                                                                                      IOException { | ||||
|         log.debug("Sending redirect to {}", target); | ||||
|         exchange.getResponseHeaders().add("Location", target); | ||||
|         exchange.sendResponseHeaders(302, -1); | ||||
|     } | ||||
| 
 | ||||
|     private static void notFound(@NonNull final HttpExchange exchange, @NonNull final String path) throws IOException { | ||||
|         log.debug("Resource '{}' not found, replying with HTTP 404", path); | ||||
|         exchange.getResponseHeaders().add("Content-type", "text/plain; charset=utf-8"); | ||||
|         exchange.sendResponseHeaders(404, 0); | ||||
|         exchange.getResponseBody().write("404 - Not found".getBytes(StandardCharsets.UTF_8)); | ||||
|         exchange.getResponseBody().flush(); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     private static String getMimeType(@NonNull final String path) { | ||||
|         if (path.endsWith(".html")) { | ||||
|             return "text/html"; | ||||
|         } | ||||
|         if (path.endsWith(".css")) { | ||||
|             return "text/css"; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private static byte[] getBytes(@NonNull final String path) throws IOException { | ||||
|         final InputStream stream = StaticResourcesFileHandler.class.getClassLoader() | ||||
|                                                                    .getResourceAsStream(WEBASSETS_DIRECTORY + path); | ||||
|         if (stream == null) { | ||||
|             log.debug("Resource '{}' not found in classpath.", path); | ||||
|             return new byte[0]; | ||||
|         } | ||||
|         final byte[] response = IOUtils.toByteArray(stream); | ||||
|         log.debug("Sending reply; {} bytes", response.length); | ||||
|         return response; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| 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; | ||||
|  | @ -10,69 +12,69 @@ 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"); | ||||
|     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); | ||||
|                     exchange.getResponseSender().send( | ||||
|                             "Output: " + output + | ||||
|                                     ", Width: " + width + | ||||
|                                     ", Height: " + height + | ||||
|                                     ", Id: " + id | ||||
|                     ); | ||||
|                 } | ||||
|             }) | ||||
|             .post("/render", new HttpHandler() { | ||||
|                 @Override | ||||
|                 public void handleRequest(final HttpServerExchange exchange) { | ||||
|                     if (exchange.isInIoThread()) { | ||||
|                         exchange.dispatch(this); | ||||
|                         return; | ||||
|                     } | ||||
|                     exchange.getResponseSender().send("TODO: read body, render stuff"); | ||||
|                 } | ||||
|             }) | ||||
|             .setFallbackHandler(new HttpHandler() { | ||||
|                                     @Override | ||||
|                                     public void handleRequest(HttpServerExchange exchange) throws Exception { | ||||
|                                         exchange.getResponseSender().send("Request: " + exchange.getRequestURI()); | ||||
|                                         final HeaderValues strings = exchange.getRequestHeaders().get(Headers.ACCEPT); | ||||
|                                         strings.peekFirst(); | ||||
|                                     } | ||||
|                                 } | ||||
|             ); | ||||
|             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() { | ||||
|         @Override | ||||
|         public void handleRequest(final HttpServerExchange exchange) { | ||||
|             if (exchange.isInIoThread()) { | ||||
|                 exchange.dispatch(this); | ||||
|                 return; | ||||
|             } | ||||
|             exchange.getResponseSender().send("TODO: read body, render stuff"); | ||||
|         } | ||||
|     }).setFallbackHandler(new HttpHandler() { | ||||
|         @Override | ||||
|         public void handleRequest(HttpServerExchange exchange) throws Exception { | ||||
|             exchange.getResponseSender().send("Request: " + exchange.getRequestURI()); | ||||
|             final HeaderValues strings = exchange.getRequestHeaders().get(Headers.ACCEPT); | ||||
|             strings.peekFirst(); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     @NonNull | ||||
|     private 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); | ||||
|     private 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<Integer> getIntOption(@NonNull final Map<String, Deque<String>> queryParams, @NonNull final String paramName) { | ||||
|         return getFirstOption(queryParams, paramName) | ||||
|                 .toTry() | ||||
|                 .map(Integer::parseInt) | ||||
|                 .toOption(); | ||||
|     private 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); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,17 +1,17 @@ | |||
| <?xml version="1.0" encoding="utf-8" ?> | ||||
| <configuration> | ||||
| 	<shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/> | ||||
|     <shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/> | ||||
| 
 | ||||
| 	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||
| 		<!-- encoders are by default assigned the type | ||||
| 		ch.qos.logback.classic.encoder.PatternLayoutEncoder --> | ||||
| 		<encoder> | ||||
| 			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||||
| 		</encoder> | ||||
| 	</appender> | ||||
|     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||
|         <!-- encoders are by default assigned the type | ||||
|         ch.qos.logback.classic.encoder.PatternLayoutEncoder --> | ||||
|         <encoder> | ||||
|             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||||
|         </encoder> | ||||
|     </appender> | ||||
| 
 | ||||
| 	<root level="info"> | ||||
| 		<appender-ref ref="STDOUT"/> | ||||
| 	</root> | ||||
| 	<logger name="ch.fritteli.labyrinth.server.StaticResourcesFileHandler" level="debug"/> | ||||
|     <root level="info"> | ||||
|         <appender-ref ref="STDOUT"/> | ||||
|     </root> | ||||
|     <logger name="ch.fritteli.labyrinth.server.StaticResourcesFileHandler" level="debug"/> | ||||
| </configuration> | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <title>Labyrinth Generator</title> | ||||
|     <link rel="stylesheet" href="style.css"> | ||||
|     <link href="style.css" rel="stylesheet"> | ||||
| </head> | ||||
| <body> | ||||
| <div class="content"> | ||||
|  | @ -11,8 +11,8 @@ | |||
|     <p>Enter some values, click the "Create!" button and see what happens!</p> | ||||
|     <form action="/create" method="get"> | ||||
|         <div class="inputs-wrapper"> | ||||
|             <label for="width">Width:</label><input id="width" name="width" type="number" min="1" required> | ||||
|             <label for="height">Height:</label><input id="height" name="height" type="number" min="1" required> | ||||
|             <label for="width">Width:</label><input id="width" min="1" name="width" required type="number"> | ||||
|             <label for="height">Height:</label><input id="height" min="1" name="height" required type="number"> | ||||
|             <label for="output">Output format:</label> | ||||
|             <select id="output" name="output" required> | ||||
|                 <option label="HTML Document" value="html"></option> | ||||
|  | @ -24,7 +24,7 @@ | |||
|             <label for="id">Seed (optional):</label><input id="id" name="id" type="number"> | ||||
|         </div> | ||||
|         <div class="controls-wrapper"> | ||||
|             <button type="submit" class="primary">Create!</button> | ||||
|             <button class="primary" type="submit">Create!</button> | ||||
|             <button type="reset">Reset form</button> | ||||
|         </div> | ||||
|     </form> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue