From 3a3a8800c30b50003eb4d5fe65df4c1b381ef5f8 Mon Sep 17 00:00:00 2001 From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com> Date: Thu, 5 Oct 2023 03:45:26 -0400 Subject: [PATCH 1/4] update javalin look into SpaRootConfig? Potential fix to 404 issues for SPA routing --- photon-server/build.gradle | 2 +- .../server/CameraSocketHandler.java | 13 ++-- .../server/DataSocketHandler.java | 16 +++-- .../photonvision/server/RequestHandler.java | 27 ++++--- .../java/org/photonvision/server/Server.java | 71 +++++++++---------- 5 files changed, 68 insertions(+), 61 deletions(-) diff --git a/photon-server/build.gradle b/photon-server/build.gradle index c51d290311..e1ac2aaf6e 100644 --- a/photon-server/build.gradle +++ b/photon-server/build.gradle @@ -34,7 +34,7 @@ dependencies { implementation project(':photon-core') implementation project(':photon-targeting') - implementation "io.javalin:javalin:4.2.0" + implementation "io.javalin:javalin:5.6.1" implementation wpilibTools.deps.wpilibJava("wpiutil") implementation wpilibTools.deps.wpilibJava("wpimath") diff --git a/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java b/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java index 940ea050c9..6240739eba 100644 --- a/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java @@ -25,6 +25,9 @@ import io.javalin.websocket.WsConnectContext; import io.javalin.websocket.WsContext; import io.javalin.websocket.WsMessageContext; + +import java.net.InetSocketAddress; +import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -56,16 +59,16 @@ private CameraSocketHandler() { } public void onConnect(WsConnectContext context) { - context.session.setIdleTimeout(Long.MAX_VALUE); // TODO: determine better value - var insa = context.session.getRemote().getInetSocketAddress(); - var host = insa.getAddress().toString() + ":" + insa.getPort(); + context.session.setIdleTimeout(Duration.ofMillis(Long.MAX_VALUE)); // TODO: determine better value + var remote = (InetSocketAddress) context.session.getRemoteAddress(); + var host = remote.getAddress().toString() + ":" + remote.getPort(); logger.info("New camera websocket connection from " + host); users.add(context); } protected void onClose(WsCloseContext context) { - var insa = context.session.getRemote().getInetSocketAddress(); - var host = insa.getAddress().toString() + ":" + insa.getPort(); + var remote = (InetSocketAddress) context.session.getRemoteAddress(); + var host = remote.getAddress().toString() + ":" + remote.getPort(); var reason = context.reason() != null ? context.reason() : "Connection closed by client"; logger.info("Closing camera websocket connection from " + host + " for reason: " + reason); svsManager.removeSubscription(context); diff --git a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java index 847deb9138..2a448ff089 100644 --- a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java @@ -25,7 +25,9 @@ import io.javalin.websocket.WsConnectContext; import io.javalin.websocket.WsContext; import java.io.IOException; +import java.net.InetSocketAddress; import java.nio.ByteBuffer; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -68,9 +70,9 @@ private DataSocketHandler() { } public void onConnect(WsConnectContext context) { - context.session.setIdleTimeout(Long.MAX_VALUE); // TODO: determine better value - var insa = context.session.getRemote().getInetSocketAddress(); - var host = insa.getAddress().toString() + ":" + insa.getPort(); + context.session.setIdleTimeout(Duration.ofMillis(Long.MAX_VALUE)); // TODO: determine better value + var remote = (InetSocketAddress) context.session.getRemoteAddress(); + var host = remote.getAddress().toString() + ":" + remote.getPort(); logger.info("New websocket connection from " + host); users.add(context); dcService.publishEvent( @@ -79,8 +81,8 @@ public void onConnect(WsConnectContext context) { } protected void onClose(WsCloseContext context) { - var insa = context.session.getRemote().getInetSocketAddress(); - var host = insa.getAddress().toString() + ":" + insa.getPort(); + var remote = (InetSocketAddress) context.session.getRemoteAddress(); + var host = remote.getAddress().toString() + ":" + remote.getPort(); var reason = context.reason() != null ? context.reason() : "Connection closed by client"; logger.info("Closing websocket connection from " + host + " for reason: " + reason); users.remove(context); @@ -332,9 +334,9 @@ public void broadcastMessage(Object message, WsContext userToSkip) sendMessage(message, user); } } else { - var skipUserPort = userToSkip.session.getRemote().getInetSocketAddress().getPort(); + var skipUserPort = ((InetSocketAddress) userToSkip.session.getRemoteAddress()).getPort(); for (WsContext user : users) { - var userPort = user.session.getRemote().getInetSocketAddress().getPort(); + var userPort = ((InetSocketAddress) user.session.getRemoteAddress()).getPort(); if (userPort != skipUserPort) { sendMessage(message, user); } diff --git a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java index 798fa2241d..c4d61221ab 100644 --- a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java @@ -69,7 +69,8 @@ public static void onSettingsImportRequest(Context ctx) { return; } - if (!file.getExtension().contains("zip")) { + + if (!file.extension().contains("zip")) { ctx.status(400); ctx.result( "The uploaded file was not of type 'zip'. The uploaded file should be a .zip file."); @@ -132,7 +133,7 @@ public static void onHardwareConfigRequest(Context ctx) { return; } - if (!file.getExtension().contains("json")) { + if (!file.extension().contains("json")) { ctx.status(400); ctx.result( "The uploaded file was not of type 'json'. The uploaded file should be a .json file."); @@ -174,7 +175,7 @@ public static void onHardwareSettingsRequest(Context ctx) { return; } - if (!file.getExtension().contains("json")) { + if (!file.extension().contains("json")) { ctx.status(400); ctx.result( "The uploaded file was not of type 'json'. The uploaded file should be a .json file."); @@ -216,7 +217,7 @@ public static void onNetworkConfigRequest(Context ctx) { return; } - if (!file.getExtension().contains("json")) { + if (!file.extension().contains("json")) { ctx.status(400); ctx.result( "The uploaded file was not of type 'json'. The uploaded file should be a .json file."); @@ -258,7 +259,7 @@ public static void onOfflineUpdateRequest(Context ctx) { return; } - if (!file.getExtension().contains("jar")) { + if (!file.extension().contains("jar")) { ctx.status(400); ctx.result( "The uploaded file was not of type 'jar'. The uploaded file should be a .jar file."); @@ -273,7 +274,7 @@ public static void onOfflineUpdateRequest(Context ctx) { File targetFile = new File(filePath.toString()); var stream = new FileOutputStream(targetFile); - file.getContent().transferTo(stream); + file.content().transferTo(stream); stream.close(); ctx.status(200); @@ -492,14 +493,20 @@ public static void onMetricsPublishRequest(Context ctx) { */ private static Optional handleTempFileCreation(UploadedFile file) { var tempFilePath = - new File(Path.of(System.getProperty("java.io.tmpdir"), file.getFilename()).toString()); - tempFilePath.getParentFile().mkdirs(); + new File(Path.of(System.getProperty("java.io.tmpdir"), file.filename()).toString()); + boolean makeDirsRes = tempFilePath.getParentFile().mkdirs(); + + if(!makeDirsRes) { + logger.error( + "There was an error while uploading " + file.filename() + " to the temp folder!"); + return Optional.empty(); + } try { - FileUtils.copyInputStreamToFile(file.getContent(), tempFilePath); + FileUtils.copyInputStreamToFile(file.content(), tempFilePath); } catch (IOException e) { logger.error( - "There was an error while uploading " + file.getFilename() + " to the temp folder!"); + "There was an error while uploading " + file.filename() + " to the temp folder!"); return Optional.empty(); } diff --git a/photon-server/src/main/java/org/photonvision/server/Server.java b/photon-server/src/main/java/org/photonvision/server/Server.java index 7a025d2b6e..db0fa5c7b6 100644 --- a/photon-server/src/main/java/org/photonvision/server/Server.java +++ b/photon-server/src/main/java/org/photonvision/server/Server.java @@ -19,7 +19,11 @@ import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; + +import java.net.InetSocketAddress; import java.util.StringJoiner; + +import io.javalin.plugin.bundled.CorsPluginConfig; import org.photonvision.common.logging.LogGroup; import org.photonvision.common.logging.Logger; @@ -27,46 +31,37 @@ public class Server { private static final Logger logger = new Logger(Server.class, LogGroup.WebServer); public static void start(int port) { - Javalin app = - Javalin.create( - config -> { - config.showJavalinBanner = false; - config.addStaticFiles("web", Location.CLASSPATH); - config.enableCorsForAllOrigins(); - - config.requestLogger( - (ctx, ms) -> { - StringJoiner joiner = - new StringJoiner(" ") - .add("Handled HTTP request of type") - .add(ctx.req.getMethod()) - .add("from endpoint") - .add(ctx.path()) - .add("for host") - .add(ctx.req.getRemoteHost()) - .add("in") - .add(ms.toString()) - .add("ms"); - - logger.debug(joiner.toString()); - }); + var app = Javalin.create(javalinConfig -> { + javalinConfig.showJavalinBanner = false; + javalinConfig.staticFiles.add("web"); + javalinConfig.plugins.enableCors(corsContainer -> { + corsContainer.add(CorsPluginConfig::anyHost); + }); - config.wsLogger( - ws -> - ws.onMessage( - ctx -> logger.debug("Got WebSockets message: " + ctx.message()))); + javalinConfig.requestLogger.http((ctx, ms) -> { + StringJoiner joiner = + new StringJoiner(" ") + .add("Handled HTTP request of type") + .add(ctx.req().getMethod()) + .add("from endpoint") + .add(ctx.path()) + .add("for host") + .add(ctx.req().getRemoteHost()) + .add("in") + .add(ms.toString()) + .add("ms"); - config.wsLogger( - ws -> - ws.onBinaryMessage( - ctx -> - logger.trace( - () -> { - var insa = ctx.session.getRemote().getInetSocketAddress(); - var host = insa.getAddress().toString() + ":" + insa.getPort(); - return "Got WebSockets binary message from host " + host; - }))); - }); + logger.debug(joiner.toString()); + }); + javalinConfig.requestLogger.ws(ws -> { + ws.onMessage(ctx -> logger.debug("Got WebSockets message: " + ctx.message())); + ws.onBinaryMessage(ctx -> logger.trace(() -> { + var remote = (InetSocketAddress) ctx.session.getRemoteAddress(); + var host = remote.getAddress().toString() + ":" + remote.getPort(); + return "Got WebSockets binary message from host: " + host; + })); + }); + }); /*Web Socket Events for Data Exchange */ var dsHandler = DataSocketHandler.getInstance(); From a207ed582726fe69b6a0fbf6dded43dd0416141b Mon Sep 17 00:00:00 2001 From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com> Date: Thu, 5 Oct 2023 04:09:50 -0400 Subject: [PATCH 2/4] bump again --- photon-server/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/photon-server/build.gradle b/photon-server/build.gradle index e1ac2aaf6e..47505fd132 100644 --- a/photon-server/build.gradle +++ b/photon-server/build.gradle @@ -34,7 +34,7 @@ dependencies { implementation project(':photon-core') implementation project(':photon-targeting') - implementation "io.javalin:javalin:5.6.1" + implementation "io.javalin:javalin:5.6.2" implementation wpilibTools.deps.wpilibJava("wpiutil") implementation wpilibTools.deps.wpilibJava("wpimath") From d3024c25e453ae2cd3a2b51a35f0d898f828ce8b Mon Sep 17 00:00:00 2001 From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com> Date: Thu, 5 Oct 2023 04:16:22 -0400 Subject: [PATCH 3/4] Formatting fixes --- .../server/CameraSocketHandler.java | 4 +- .../server/DataSocketHandler.java | 3 +- .../photonvision/server/RequestHandler.java | 3 +- .../java/org/photonvision/server/Server.java | 72 ++++++++++--------- 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java b/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java index 6240739eba..d93f9a9e44 100644 --- a/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/CameraSocketHandler.java @@ -25,7 +25,6 @@ import io.javalin.websocket.WsConnectContext; import io.javalin.websocket.WsContext; import io.javalin.websocket.WsMessageContext; - import java.net.InetSocketAddress; import java.time.Duration; import java.util.HashMap; @@ -59,7 +58,8 @@ private CameraSocketHandler() { } public void onConnect(WsConnectContext context) { - context.session.setIdleTimeout(Duration.ofMillis(Long.MAX_VALUE)); // TODO: determine better value + context.session.setIdleTimeout( + Duration.ofMillis(Long.MAX_VALUE)); // TODO: determine better value var remote = (InetSocketAddress) context.session.getRemoteAddress(); var host = remote.getAddress().toString() + ":" + remote.getPort(); logger.info("New camera websocket connection from " + host); diff --git a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java index 2a448ff089..19fc18f937 100644 --- a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java @@ -70,7 +70,8 @@ private DataSocketHandler() { } public void onConnect(WsConnectContext context) { - context.session.setIdleTimeout(Duration.ofMillis(Long.MAX_VALUE)); // TODO: determine better value + context.session.setIdleTimeout( + Duration.ofMillis(Long.MAX_VALUE)); // TODO: determine better value var remote = (InetSocketAddress) context.session.getRemoteAddress(); var host = remote.getAddress().toString() + ":" + remote.getPort(); logger.info("New websocket connection from " + host); diff --git a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java index c4d61221ab..c255748195 100644 --- a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java @@ -69,7 +69,6 @@ public static void onSettingsImportRequest(Context ctx) { return; } - if (!file.extension().contains("zip")) { ctx.status(400); ctx.result( @@ -496,7 +495,7 @@ private static Optional handleTempFileCreation(UploadedFile file) { new File(Path.of(System.getProperty("java.io.tmpdir"), file.filename()).toString()); boolean makeDirsRes = tempFilePath.getParentFile().mkdirs(); - if(!makeDirsRes) { + if (!makeDirsRes) { logger.error( "There was an error while uploading " + file.filename() + " to the temp folder!"); return Optional.empty(); diff --git a/photon-server/src/main/java/org/photonvision/server/Server.java b/photon-server/src/main/java/org/photonvision/server/Server.java index db0fa5c7b6..724459e14f 100644 --- a/photon-server/src/main/java/org/photonvision/server/Server.java +++ b/photon-server/src/main/java/org/photonvision/server/Server.java @@ -18,12 +18,9 @@ package org.photonvision.server; import io.javalin.Javalin; -import io.javalin.http.staticfiles.Location; - +import io.javalin.plugin.bundled.CorsPluginConfig; import java.net.InetSocketAddress; import java.util.StringJoiner; - -import io.javalin.plugin.bundled.CorsPluginConfig; import org.photonvision.common.logging.LogGroup; import org.photonvision.common.logging.Logger; @@ -31,37 +28,46 @@ public class Server { private static final Logger logger = new Logger(Server.class, LogGroup.WebServer); public static void start(int port) { - var app = Javalin.create(javalinConfig -> { - javalinConfig.showJavalinBanner = false; - javalinConfig.staticFiles.add("web"); - javalinConfig.plugins.enableCors(corsContainer -> { - corsContainer.add(CorsPluginConfig::anyHost); - }); + var app = + Javalin.create( + javalinConfig -> { + javalinConfig.showJavalinBanner = false; + javalinConfig.staticFiles.add("web"); + javalinConfig.plugins.enableCors( + corsContainer -> { + corsContainer.add(CorsPluginConfig::anyHost); + }); - javalinConfig.requestLogger.http((ctx, ms) -> { - StringJoiner joiner = - new StringJoiner(" ") - .add("Handled HTTP request of type") - .add(ctx.req().getMethod()) - .add("from endpoint") - .add(ctx.path()) - .add("for host") - .add(ctx.req().getRemoteHost()) - .add("in") - .add(ms.toString()) - .add("ms"); + javalinConfig.requestLogger.http( + (ctx, ms) -> { + StringJoiner joiner = + new StringJoiner(" ") + .add("Handled HTTP request of type") + .add(ctx.req().getMethod()) + .add("from endpoint") + .add(ctx.path()) + .add("for host") + .add(ctx.req().getRemoteHost()) + .add("in") + .add(ms.toString()) + .add("ms"); - logger.debug(joiner.toString()); - }); - javalinConfig.requestLogger.ws(ws -> { - ws.onMessage(ctx -> logger.debug("Got WebSockets message: " + ctx.message())); - ws.onBinaryMessage(ctx -> logger.trace(() -> { - var remote = (InetSocketAddress) ctx.session.getRemoteAddress(); - var host = remote.getAddress().toString() + ":" + remote.getPort(); - return "Got WebSockets binary message from host: " + host; - })); - }); - }); + logger.debug(joiner.toString()); + }); + javalinConfig.requestLogger.ws( + ws -> { + ws.onMessage(ctx -> logger.debug("Got WebSockets message: " + ctx.message())); + ws.onBinaryMessage( + ctx -> + logger.trace( + () -> { + var remote = (InetSocketAddress) ctx.session.getRemoteAddress(); + var host = + remote.getAddress().toString() + ":" + remote.getPort(); + return "Got WebSockets binary message from host: " + host; + })); + }); + }); /*Web Socket Events for Data Exchange */ var dsHandler = DataSocketHandler.getInstance(); From e2e4d4752fdaded2cf1cd5e08ed54cca52e458cc Mon Sep 17 00:00:00 2001 From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com> Date: Thu, 5 Oct 2023 09:33:18 -0400 Subject: [PATCH 4/4] bump slf4j-simple to 2.0.7 --- photon-server/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/photon-server/build.gradle b/photon-server/build.gradle index 47505fd132..6b1a5bf5ec 100644 --- a/photon-server/build.gradle +++ b/photon-server/build.gradle @@ -46,7 +46,7 @@ dependencies { implementation "org.msgpack:msgpack-core:0.9.0" implementation "org.msgpack:jackson-dataformat-msgpack:0.9.0" - implementation "org.slf4j:slf4j-simple:1.8.0-beta4" + implementation "org.slf4j:slf4j-simple:2.0.7" } shadowJar {