diff --git a/pom.xml b/pom.xml index f66355e..a4e0c8e 100644 --- a/pom.xml +++ b/pom.xml @@ -162,7 +162,7 @@ io.javalin javalin - 6.7.0 + 7.2.3 @@ -202,7 +202,7 @@ gitlab4j-api 6.2.0 - + jakarta.servlet jakarta.servlet-api diff --git a/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java b/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java index 48a6f1a..f1d42da 100644 --- a/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java +++ b/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java @@ -6,7 +6,7 @@ package me.bobert.netneutrality.http.server; * https://discord.gg/qUa6zNFZsd */ -import io.javalin.Javalin; +import io.javalin.config.RoutesConfig; import io.javalin.http.Handler; import me.bobert.netneutrality.db.service.GuildServiceProvider; import net.dv8tion.jda.api.JDA; @@ -18,7 +18,7 @@ import java.util.Map; import java.util.function.Supplier; /** - * Registers the {@code /actions/*} endpoints on a {@link Javalin} instance. + * Registers the {@code /actions/*} endpoints on a {@link RoutesConfig} instance. */ public final class ActionRoutes { @@ -29,12 +29,12 @@ public final class ActionRoutes { } public static void register( - Javalin app, + RoutesConfig routes, Supplier jdaSupplier, GuildServiceProvider guildServices, Runnable shutdownHook ) { - app.get("/actions/status", ctx -> { + routes.get("/actions/status", ctx -> { JDA jda = GuildRoutes.jda(jdaSupplier); ctx.json(Map.of( "health", String.valueOf(jda.getStatus()), @@ -47,17 +47,17 @@ public final class ActionRoutes { ctx.result("Shutting down.."); scheduleShutdown(shutdownHook); }; - app.post("/actions/shutdown", shutdown); - app.get("/actions/shutdown", shutdown); + routes.post("/actions/shutdown", shutdown); + routes.get("/actions/shutdown", shutdown); - app.get("/actions/settings/current/{guildId}", ctx -> { + routes.get("/actions/settings/current/{guildId}", ctx -> { Guild guild = GuildRoutes.guild(jdaSupplier, ctx); Map settings = guildServices.get(guild).getGuildSettingService().getSettings(); ctx.json(Map.of("status", "ok", "settings", settings)); }); - app.post("/actions/settings/reload/{guildId}", ctx -> { + routes.post("/actions/settings/reload/{guildId}", ctx -> { Guild guild = GuildRoutes.guild(jdaSupplier, ctx); guildServices.get(guild).getGuildSettingService().reloadSettingsCache(); diff --git a/src/main/java/me/bobert/netneutrality/http/server/GuildRoutes.java b/src/main/java/me/bobert/netneutrality/http/server/GuildRoutes.java index 1b392b8..5ebf818 100644 --- a/src/main/java/me/bobert/netneutrality/http/server/GuildRoutes.java +++ b/src/main/java/me/bobert/netneutrality/http/server/GuildRoutes.java @@ -6,7 +6,7 @@ package me.bobert.netneutrality.http.server; * https://discord.gg/qUa6zNFZsd */ -import io.javalin.Javalin; +import io.javalin.config.RoutesConfig; import io.javalin.http.Context; import io.javalin.http.NotFoundResponse; import io.javalin.http.ServiceUnavailableResponse; @@ -18,27 +18,27 @@ import java.util.Map; import java.util.function.Supplier; /** - * Registers the read-only {@code /guilds/*} endpoints on a {@link Javalin} instance. + * Registers the read-only {@code /guilds/*} endpoints on a {@link RoutesConfig} instance. */ public final class GuildRoutes { private GuildRoutes() { } - public static void register(Javalin app, Supplier jdaSupplier) { - app.get("/guilds/owner", ctx -> ctx.json( + public static void register(RoutesConfig routes, Supplier jdaSupplier) { + routes.get("/guilds/owner", ctx -> ctx.json( jda(jdaSupplier).getGuilds().stream() .map(guild -> ordered("guild_id", guild.getId(), "owner_id", guild.getOwnerId())) .toList() )); - app.get("/guilds/channels/{guildId}", ctx -> ctx.json( + routes.get("/guilds/channels/{guildId}", ctx -> ctx.json( guild(jdaSupplier, ctx).getTextChannels().stream() .map(channel -> ordered("channel_id", channel.getId(), "channel_name", channel.getName())) .toList() )); - app.get("/guilds/roles/{guildId}", ctx -> ctx.json( + routes.get("/guilds/roles/{guildId}", ctx -> ctx.json( guild(jdaSupplier, ctx).getRoles().stream() .map(role -> ordered("channel_id", role.getId(), "channel_name", role.getName())) .toList() diff --git a/src/main/java/me/bobert/netneutrality/http/server/WebApi.java b/src/main/java/me/bobert/netneutrality/http/server/WebApi.java index 88d0f74..0a3fbf1 100644 --- a/src/main/java/me/bobert/netneutrality/http/server/WebApi.java +++ b/src/main/java/me/bobert/netneutrality/http/server/WebApi.java @@ -55,26 +55,27 @@ public class WebApi implements Lifecycle { int port = Integer.parseInt(settings.get("NETNEUTRALITY_API_PORT", "9000")); logger.info("Starting web server..."); + // Javalin 7 requires routes, exception and error handlers to be registered upfront. app = Javalin.create(config -> { config.jsonMapper(new GsonJsonMapper()); - config.showJavalinBanner = false; + config.startup.showJavalinBanner = false; + + config.routes.get("/", ctx -> ctx.html(LIVENESS_HTML)); + GuildRoutes.register(config.routes, jdaSupplier); + ActionRoutes.register(config.routes, jdaSupplier, guildServices, shutdownHook); + + config.routes.exception(HttpResponseException.class, (e, ctx) -> + ctx.status(e.getStatus()).json(Map.of("status", "error", "message", e.getMessage())) + ); + + config.routes.exception(Exception.class, (e, ctx) -> { + logger.error("Unhandled error while serving [{}]", ctx.path(), e); + ctx.status(500).json(Map.of("status", "error")); + }); + + config.routes.error(404, ctx -> ctx.json(Map.of("status", "error", "message", "Not found"))); }); - app.get("/", ctx -> ctx.html(LIVENESS_HTML)); - GuildRoutes.register(app, jdaSupplier); - ActionRoutes.register(app, jdaSupplier, guildServices, shutdownHook); - - app.exception(HttpResponseException.class, (e, ctx) -> - ctx.status(e.getStatus()).json(Map.of("status", "error", "message", e.getMessage())) - ); - - app.exception(Exception.class, (e, ctx) -> { - logger.error("Unhandled error while serving [{}]", ctx.path(), e); - ctx.status(500).json(Map.of("status", "error")); - }); - - app.error(404, ctx -> ctx.json(Map.of("status", "error", "message", "Not found"))); - app.start(port); logger.info("Web server started on port [{}]", port); } diff --git a/src/test/java/me/bobert/netneutrality/http/WebModuleTest.java b/src/test/java/me/bobert/netneutrality/http/WebModuleTest.java index 0b0685f..221eb39 100644 --- a/src/test/java/me/bobert/netneutrality/http/WebModuleTest.java +++ b/src/test/java/me/bobert/netneutrality/http/WebModuleTest.java @@ -26,9 +26,11 @@ class WebModuleTest { @BeforeEach void setUp() { - server = Javalin.create(config -> config.showJavalinBanner = false); - server.get("/counter", ctx -> ctx.result("{\"hits\":" + hits.incrementAndGet() + "}")); - server.post("/counter", ctx -> ctx.result("{\"hits\":" + hits.incrementAndGet() + "}")); + server = Javalin.create(config -> { + config.startup.showJavalinBanner = false; + config.routes.get("/counter", ctx -> ctx.result("{\"hits\":" + hits.incrementAndGet() + "}")); + config.routes.post("/counter", ctx -> ctx.result("{\"hits\":" + hits.incrementAndGet() + "}")); + }); server.start(0); port = server.port(); }