From e1d941c66d5ff1e25577f6313470e7f65c067dbb Mon Sep 17 00:00:00 2001 From: Romain Grecourt Date: Thu, 28 Sep 2023 15:49:45 -0700 Subject: [PATCH] Update HttpRules API to not have method with vararg with generics - Update HttpService interface to not be a Supplier to remove ambiguity - Replace `register(Supplier... service)` with register(HttpService... service)` - Overload it with 5 variants to accept up to 5 suppliers of services (@SafeVarags is not usable on interfaces) - Add `register(List services)` for more than 5 services - Replace `register(String pathPattern, Supplier... service)` with register(String pathPattern, HttpService... service)` - Overload it with 5 variants to accept up to 5 suppliers of services (@SafeVarags is not usable on interfaces) - Add `register(String pathPattern, List services)` for more than 5 services Fixes #7656 --- .../helidon/webserver/http/HttpRouting.java | 107 ++++++++++- .../webserver/http/HttpRoutingFeature.java | 11 +- .../io/helidon/webserver/http/HttpRules.java | 175 +++++++++++++++++- .../helidon/webserver/http/HttpService.java | 11 +- .../helidon/webserver/http/ServiceRules.java | 21 +-- .../webserver/http/HttpRoutingTest.java | 4 +- .../helidon/webserver/http/HttpRulesTest.java | 5 +- 7 files changed, 293 insertions(+), 41 deletions(-) diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRouting.java b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRouting.java index 083316f01e3..39fabed79fa 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRouting.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRouting.java @@ -143,10 +143,105 @@ private enum RoutingResult { */ public interface Builder extends HttpRules, io.helidon.common.Builder { @Override - Builder register(Supplier... service); + Builder register(HttpService... service); @Override - Builder register(String path, Supplier... service); + default Builder register(Supplier service) { + HttpRules.super.register(service); + return this; + } + + @Override + default Builder register(Supplier service1, Supplier service2) { + HttpRules.super.register(service1, service2); + return this; + } + + @Override + default Builder register(Supplier service1, + Supplier service2, + Supplier service3) { + HttpRules.super.register(service1, service2, service3); + return this; + } + + @Override + default Builder register(Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4) { + HttpRules.super.register(service1, service2, service3, service4); + return this; + } + + @Override + default Builder register(Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4, + Supplier service5) { + HttpRules.super.register(service1, service2, service3, service4, service5); + return this; + } + + @Override + default Builder register(List> services) { + HttpRules.super.register(services); + return this; + } + + @Override + Builder register(String path, HttpService... service); + + @Override + default Builder register(String pathPattern, Supplier service) { + HttpRules.super.register(pathPattern, service); + return this; + } + + @Override + default Builder register(String pathPattern, + Supplier service1, + Supplier service2) { + HttpRules.super.register(pathPattern, service1, service2); + return this; + } + + @Override + default Builder register(String pathPattern, + Supplier service1, + Supplier service2, + Supplier service3) { + HttpRules.super.register(pathPattern, service1, service2, service3); + return this; + } + + @Override + default Builder register(String pathPattern, + Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4) { + HttpRules.super.register(pathPattern, service1, service2, service3, service4); + return this; + } + + @Override + default Builder register(String pathPattern, + Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4, + Supplier service5) { + HttpRules.super.register(pathPattern, service1, service2, service3, service4, service5); + return this; + } + + @Override + default Builder register(String pathPattern, List> services) { + HttpRules.super.register(pathPattern, services); + return this; + } @Override Builder route(HttpRoute route); @@ -438,13 +533,13 @@ public HttpRouting build() { } @Override - public Builder register(Supplier... service) { + public Builder register(HttpService... service) { mainRouting.service(service); return this; } @Override - public Builder register(String path, Supplier... service) { + public Builder register(String path, HttpService... service) { mainRouting.service(path, service); return this; } @@ -620,13 +715,13 @@ public HttpRouting build() { } @Override - public Builder register(Supplier... service) { + public Builder register(HttpService... service) { rootRules.register(service); return this; } @Override - public Builder register(String pathPattern, Supplier... service) { + public Builder register(String pathPattern, HttpService... service) { rootRules.register(pathPattern, service); return this; } diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRoutingFeature.java b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRoutingFeature.java index a0c6d9a6728..0424aea859d 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRoutingFeature.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRoutingFeature.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; import io.helidon.common.Weighted; @@ -42,14 +41,14 @@ void filter(Filter filter) { } void error(Class exceptionClass, ErrorHandler handler) { - this.registrations.add(new ErrorReg(exceptionClass, handler)); + this.registrations.add(new ErrorReg<>(exceptionClass, handler)); } - void service(Supplier... services) { + void service(HttpService... services) { this.registrations.add(new ServiceReg(services)); } - void service(String path, Supplier... services) { + void service(String path, HttpService... services) { this.registrations.add(new ServicePathReg(path, services)); } @@ -78,14 +77,14 @@ public void register(HttpRouting.Builder routing) { } } - private record ServiceReg(Supplier[] services) implements Registration { + private record ServiceReg(HttpService[] services) implements Registration { @Override public void register(HttpRouting.Builder routing) { routing.register(services); } } - private record ServicePathReg(String path, Supplier[] services) implements Registration { + private record ServicePathReg(String path, HttpService[] services) implements Registration { @Override public void register(HttpRouting.Builder routing) { routing.register(path, services); diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRules.java b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRules.java index 60ecb2e8727..2175fffd185 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRules.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpRules.java @@ -16,6 +16,7 @@ package io.helidon.webserver.http; +import java.util.List; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -36,7 +37,96 @@ public interface HttpRules { * @param service service to register * @return updated rules */ - HttpRules register(Supplier... service); + HttpRules register(HttpService... service); + + /** + * Register a service on the current path. + * + * @param service service to register + * @return updated rules + */ + default HttpRules register(Supplier service) { + return register(service.get()); + } + + /** + * Register two services on the current path. + * + * @param service1 first service to register + * @param service2 second service to register + * @return updated rules + */ + default HttpRules register(Supplier service1, + Supplier service2) { + return register(service1.get(), service2.get()); + } + + /** + * Register three services on the current path. + * + * @param service1 first service to register + * @param service2 second service to register + * @param service3 third service to register + * @return updated rules + */ + default HttpRules register(Supplier service1, + Supplier service2, + Supplier service3) { + return register(service1.get(), service2.get(), service3.get()); + } + + /** + * Register four services on the current path. + * + * @param service1 first service to register + * @param service2 second service to register + * @param service3 third service to register + * @param service4 fourth service to register + * @return updated rules + */ + default HttpRules register(Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4) { + return register(service1.get(), service2.get(), service3.get(), service4.get()); + } + + /** + * Register five services on the current path. + * + * @param service1 first service to register + * @param service2 second service to register + * @param service3 third service to register + * @param service4 fourth service to register + * @param service5 fifth service to register + * @return updated rules + */ + default HttpRules register(Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4, + Supplier service5) { + return register(service1.get(), service2.get(), service3.get(), service4.get(), service5.get()); + } + + /** + * Register services on the current path. + * + * @param services services to register + * @return updated rules + */ + default HttpRules register(List> services) { + return register(services.stream().map(Supplier::get).toArray(HttpService[]::new)); + } + + /** + * Register a service on sub-path of the current path. + * + * @param pathPattern URI path pattern + * @param service service to register + * @return updated rules + */ + HttpRules register(String pathPattern, HttpService... service); /** * Register a service on sub-path of the current path. @@ -45,7 +135,88 @@ public interface HttpRules { * @param service service to register * @return updated rules */ - HttpRules register(String pathPattern, Supplier... service); + default HttpRules register(String pathPattern, Supplier service) { + return register(pathPattern, service.get()); + } + + /** + * Register two services on sub-path of the current path. + * + * @param pathPattern URI path pattern + * @param service1 first service to register + * @param service2 second service to register + * @return updated rules + */ + default HttpRules register(String pathPattern, + Supplier service1, + Supplier service2) { + return register(pathPattern, service1.get(), service2.get()); + } + + /** + * Register three services on sub-path of the current path. + * + * @param pathPattern URI path pattern + * @param service1 first service to register + * @param service2 second service to register + * @param service3 third service to register + * @return updated rules + */ + default HttpRules register(String pathPattern, + Supplier service1, + Supplier service2, + Supplier service3) { + return register(pathPattern, service1.get(), service2.get(), service3.get()); + } + + /** + * Register four services on sub-path of the current path. + * + * @param pathPattern URI path pattern + * @param service1 first service to register + * @param service2 second service to register + * @param service3 third service to register + * @param service4 fourth service to register + * @return updated rules + */ + default HttpRules register(String pathPattern, + Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4) { + return register(pathPattern, service1.get(), service2.get(), service3.get(), service4.get()); + } + + /** + * Register five services on sub-path of the current path. + * + * @param pathPattern URI path pattern + * @param service1 first service to register + * @param service2 second service to register + * @param service3 third service to register + * @param service4 fourth service to register + * @param service5 fifth service to register + * @return updated rules + */ + default HttpRules register(String pathPattern, + Supplier service1, + Supplier service2, + Supplier service3, + Supplier service4, + Supplier service5) { + return register(pathPattern, service1.get(), service2.get(), service3.get(), service4.get(), service5.get()); + } + + /** + * Register services on sub-path of the current path. + * + * @param pathPattern URI path pattern + * @param services services to register + * @return updated rules + */ + default HttpRules register(String pathPattern, List> services) { + return register(pathPattern, services.stream().map(Supplier::get).toArray(HttpService[]::new)); + } /** * Add a route. This allows also protocol version specific routing. diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpService.java b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpService.java index 312894f7223..83644d22694 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpService.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/http/HttpService.java @@ -16,22 +16,16 @@ package io.helidon.webserver.http; -import java.util.function.Supplier; - import io.helidon.webserver.ServerLifecycle; /** * Encapsulates a set of {@link HttpRouting routing} rules and related logic. *

* Instance can be assigned to the {@link HttpRouting routing} using - * {@link HttpRouting.Builder#register(java.util.function.Supplier[])} methods. + * {@link HttpRouting.Builder#register(java.util.function.Supplier)} methods. */ @FunctionalInterface -public interface HttpService extends Supplier, ServerLifecycle { - @Override - default HttpService get() { - return this; - } +public interface HttpService extends ServerLifecycle { /** * Updates the routing to add handlers of this service. @@ -40,4 +34,3 @@ default HttpService get() { */ void routing(HttpRules rules); } - diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/http/ServiceRules.java b/webserver/webserver/src/main/java/io/helidon/webserver/http/ServiceRules.java index ba6749e4cbf..ff2913a5700 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/http/ServiceRules.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/http/ServiceRules.java @@ -19,7 +19,6 @@ import java.util.LinkedList; import java.util.List; import java.util.function.Predicate; -import java.util.function.Supplier; import io.helidon.http.Method; import io.helidon.http.PathMatcher; @@ -46,26 +45,22 @@ class ServiceRules implements HttpRules { } @Override - public HttpRules register(Supplier... services) { - for (Supplier service : services) { - HttpService theService = service.get(); - ServiceRules subRules = new ServiceRules(theService, PathMatchers.any(), ALWAYS_PREDICATE); - theService.routing(subRules); + public HttpRules register(HttpService... services) { + for (HttpService service : services) { + ServiceRules subRules = new ServiceRules(service, PathMatchers.any(), ALWAYS_PREDICATE); + service.routing(subRules); routes.add(subRules.build()); } - return this; } @Override - public HttpRules register(String pathPattern, Supplier... services) { - for (Supplier service : services) { - HttpService theService = service.get(); - ServiceRules subRules = new ServiceRules(theService, PathMatchers.create(pathPattern), ALWAYS_PREDICATE); - theService.routing(subRules); + public HttpRules register(String pathPattern, HttpService... services) { + for (HttpService service : services) { + ServiceRules subRules = new ServiceRules(service, PathMatchers.create(pathPattern), ALWAYS_PREDICATE); + service.routing(subRules); routes.add(subRules.build()); } - return this; } diff --git a/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRoutingTest.java b/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRoutingTest.java index ffc1949f431..86fe2b95a87 100644 --- a/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRoutingTest.java +++ b/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRoutingTest.java @@ -118,12 +118,12 @@ public Handler getHandler() { } @Override - public HttpRouting.Builder register(Supplier... service) { + public HttpRouting.Builder register(HttpService... service) { return null; } @Override - public HttpRouting.Builder register(String path, Supplier... service) { + public HttpRouting.Builder register(String path, HttpService... service) { return null; } diff --git a/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRulesTest.java b/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRulesTest.java index dc20c2fb181..27c57e8448d 100644 --- a/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRulesTest.java +++ b/webserver/webserver/src/test/java/io/helidon/webserver/http/HttpRulesTest.java @@ -17,7 +17,6 @@ package io.helidon.webserver.http; import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Stream; import io.helidon.http.Method; @@ -119,12 +118,12 @@ public Handler getHandler() { } @Override - public HttpRules register(Supplier... service) { + public HttpRules register(HttpService... service) { return null; } @Override - public HttpRules register(String pathPattern, Supplier... service) { + public HttpRules register(String pathPattern, HttpService... service) { return null; }