-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds a path prefix routing object. #412
Conversation
Add routingObjectDef utility method in favour of configBlock.
26ab88f
to
845bd0e
Compare
public Optional<HttpHandler> route(LiveHttpRequest request) { | ||
String path = request.path(); | ||
|
||
return routes.entrySet().stream() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we use floorEntry() with the default ordering ? That should return a correct path route.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is mimics the routing logic from BackendServicesRouter
. It is important to keep both components identical until we deprecate BackendServicesRouter
.
It is better to minimise the number of variables while migrating backend services router to the new routing object model.
Once the migration is successfully concluded and tested, we shall then optimise this part as a separate increment. Therefore we should leave this as it is. For now.
/** | ||
* Resolves a routing object reference from route database. | ||
*/ | ||
public class RouteRefLookup implements Function<RoutingObjectReference, HttpHandler> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would consider creating an interface for this instead of implementing Function directly. This is not as much to have a slightly easier to read code but basically a solution to overcome the problem that the IDEs 'Find usages' will find any Function instead of only Function<RoutingObjectReference, HttpHandler>
@@ -44,28 +47,37 @@ | |||
*/ | |||
public class RoutingObjectFactory { | |||
public static final ImmutableMap<String, Schema.FieldType> BUILTIN_HANDLER_SCHEMAS; | |||
private static final ImmutableMap<String, HttpHandlerFactory> BUILTIN_HANDLER_FACTORIES; | |||
public static final ImmutableMap<String, HttpHandlerFactory> BUILTIN_HANDLER_FACTORIES; | |||
public static final Function<RoutingObjectReference, HttpHandler> DEFAULT_REFERENCE_LOOKUP = reference -> (request, ctx) -> Eventual.of(response(NOT_FOUND) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should move the Eventual.of(response(NOT_FOUND)
down to a new line.
.map(Map.Entry::getValue); | ||
} | ||
|
||
public static class Factory implements HttpHandlerFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've generally been using the convention that X.Factory
builds instances of X
, but here PathPrefixRouter
seems to be just an internal component of the HttpHandler
except that it is public, with the handler just being a lambda.
What is the reason for this divergence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is to simplify unit testing.
Otherwise PathPrefixRouter
would have to be a HttpHandler
with a return type of Eventual<LiveHttpResponse>
. This would complicate unit testing.
The Factory
for every class in routing.handlers.*
returns a routing object as a HttpHandler
instance. From the consumer's point of view it doesn't matter if PathPrefixRouter
is the underlying implementation, or merely just a part of it. But it being merely an internal component of an HttpHandler
simplifies unit tests and the divergence is preferred.
|
||
handler.handle(HttpRequest.get("/x").build()) | ||
.toMono() | ||
?.block() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?.block() | |
.block() |
toMono
is a kotlin method with a non-nullable return type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay. Good catch. I'll change them.
|
||
handler.handle(HttpRequest.get("/foo/").build()) | ||
.toMono() | ||
?.block() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?.block() | |
.block() |
toMono
is a kotlin method with a non-nullable return type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
||
handler.handle(HttpRequest.get("/foo").build()) | ||
.toMono() | ||
?.block() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?.block() | |
.block() |
val response = RouteRefLookup(routeDb).apply(RoutingObjectReference("handler1")) | ||
.handle(get("/").build()) | ||
.toMono() | ||
?.block() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?.block() | |
.block() |
public HttpHandler apply(RoutingObjectReference route) { | ||
return this.routeDatabase.get(route.name()) | ||
.map(RoutingObjectRecord::getHandler) | ||
.orElse((x, y) -> Eventual.of(response(NOT_FOUND) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During discussion we noticed that there may be a bug here and in many similar circumstances in which a LiveHttpRequest
is not having its body consumed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed this handler. However I will review the usage of other handlers separately.
@@ -36,21 +36,25 @@ | |||
* A StyxObjectStore based route reference lookup function. | |||
*/ | |||
class RouteDbRefLookup implements RouteRefLookup { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation below here is incorrect on several lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been fixed.
Adds a new routing object called "PathPrefixRouter". It performs a routing decision based on longest path prefix.
Example usage:
The destination can be also inlined. Like so: