From 720928f80ed7d0c48095cf339fa2efd3dedc6160 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 2 Dec 2024 21:50:09 +1300 Subject: [PATCH] Fix path ordering route building issue - RouteIndexBuild.Entry.pathMap as LinkedHashMap The RouteIndexBuild.Entry.pathMap needs to preserve ordering of the routes. The order that they are added/registered must be preserved. This is the precedence of route matching where the first match wins (literal paths should match first etc). --- .../java/io/avaje/jex/core/BootstrapServer.java | 2 ++ .../main/java/io/avaje/jex/routes/RouteEntry.java | 5 +++++ .../main/java/io/avaje/jex/routes/RouteIndex.java | 13 +++++++++++++ .../java/io/avaje/jex/routes/RouteIndexBuild.java | 7 ++----- .../src/main/java/io/avaje/jex/routes/Routes.java | 6 +++++- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/avaje-jex/src/main/java/io/avaje/jex/core/BootstrapServer.java b/avaje-jex/src/main/java/io/avaje/jex/core/BootstrapServer.java index 7ba28e8c..dafba879 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/core/BootstrapServer.java +++ b/avaje-jex/src/main/java/io/avaje/jex/core/BootstrapServer.java @@ -15,6 +15,7 @@ import java.net.InetSocketAddress; import java.net.UnknownHostException; +import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.INFO; public final class BootstrapServer { @@ -67,6 +68,7 @@ static Jex.Server start(Jex jex, SpiRoutes routes) { "started com.sun.net.httpserver.HttpServer on port {0}://{1}", scheme, socketAddress); + log.log(DEBUG, routes); return new JdkJexServer(server, jex.lifecycle(), handler); } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/avaje-jex/src/main/java/io/avaje/jex/routes/RouteEntry.java b/avaje-jex/src/main/java/io/avaje/jex/routes/RouteEntry.java index cd1a9e40..d7e60350 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/routes/RouteEntry.java +++ b/avaje-jex/src/main/java/io/avaje/jex/routes/RouteEntry.java @@ -80,4 +80,9 @@ public boolean literal() { public Set roles() { return roles; } + + @Override + public String toString() { + return path.raw(); + } } diff --git a/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndex.java b/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndex.java index c7df775a..71b62acb 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndex.java +++ b/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndex.java @@ -1,5 +1,6 @@ package io.avaje.jex.routes; +import java.util.Arrays; import java.util.List; final class RouteIndex { @@ -22,6 +23,13 @@ final class RouteIndex { .toArray(new IndexEntry[0]); } + @Override + public String toString() { + return "RouteIndex{" + Arrays.toString(entries) + + ", wildcards=" + Arrays.toString(wildcardEntries) + + '}'; + } + private static IndexEntry toEntry(List routeEntries) { return new IndexEntry(routeEntries.toArray(new SpiRoutes.Entry[0])); } @@ -77,6 +85,11 @@ private static final class IndexEntry { this.pathEntries = pathEntries; } + @Override + public String toString() { + return Arrays.toString(pathEntries); + } + SpiRoutes.Entry match(String pathInfo) { for (SpiRoutes.Entry entry : pathEntries) { if (entry.matches(pathInfo)) { diff --git a/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndexBuild.java b/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndexBuild.java index bb7b7674..e13259cf 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndexBuild.java +++ b/avaje-jex/src/main/java/io/avaje/jex/routes/RouteIndexBuild.java @@ -2,10 +2,7 @@ import io.avaje.jex.ExchangeHandler; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Build the RouteIndex. @@ -54,7 +51,7 @@ RouteIndex build() { private static class Entry { private final List list = new ArrayList<>(); - private final Map> pathMap = new HashMap<>(); + private final Map> pathMap = new LinkedHashMap<>(); void add(SpiRoutes.Entry entry) { if (entry.literal()) { diff --git a/avaje-jex/src/main/java/io/avaje/jex/routes/Routes.java b/avaje-jex/src/main/java/io/avaje/jex/routes/Routes.java index 505b8666..f8a4a0d4 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/routes/Routes.java +++ b/avaje-jex/src/main/java/io/avaje/jex/routes/Routes.java @@ -25,12 +25,16 @@ final class Routes implements SpiRoutes { private final AtomicLong noRouteCounter = new AtomicLong(); - Routes(EnumMap typeMap, List filters) { this.typeMap = typeMap; this.filters = filters; } + @Override + public String toString() { + return "Routes{" + typeMap + ", filters=" + filters + '}'; + } + @Override public void inc() { noRouteCounter.incrementAndGet();