diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-07-14 14:34:36 +0200 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-07-14 15:11:17 +0200 |
commit | d5a7b61b15c4a480a8ae049d907b149c872ac5cd (patch) | |
tree | 10e783ce1915961e92606cd6217e0ee7df910635 /container-core | |
parent | 19ef310d5795cff7c131ba432af8aee1cf0f7a9e (diff) |
Add extra parameter for specifying additional handler method config
Extend RouteBuilder with new method overloads taking HandlerConfig as
extra parameter.
Diffstat (limited to 'container-core')
-rw-r--r-- | container-core/src/main/java/com/yahoo/restapi/RestApi.java | 43 | ||||
-rw-r--r-- | container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java | 131 |
2 files changed, 136 insertions, 38 deletions
diff --git a/container-core/src/main/java/com/yahoo/restapi/RestApi.java b/container-core/src/main/java/com/yahoo/restapi/RestApi.java index 6f5bf298de3..6ca7135c628 100644 --- a/container-core/src/main/java/com/yahoo/restapi/RestApi.java +++ b/container-core/src/main/java/com/yahoo/restapi/RestApi.java @@ -20,6 +20,7 @@ public interface RestApi { static Builder builder() { return new RestApiImpl.BuilderImpl(); } static RouteBuilder route(String pathPattern) { return new RestApiImpl.RouteBuilderImpl(pathPattern); } + static HandlerConfigBuilder handlerConfig() { return new RestApiImpl.HandlerConfigBuilderImpl(); } HttpResponse handleRequest(HttpRequest request); ObjectMapper jacksonJsonMapper(); @@ -41,17 +42,47 @@ public interface RestApi { interface RouteBuilder { RouteBuilder name(String name); + RouteBuilder addFilter(Filter filter); + + // GET RouteBuilder get(Handler<?> handler); + RouteBuilder get(Handler<?> handler, HandlerConfigBuilder config); + + // POST RouteBuilder post(Handler<?> handler); - <REQUEST_ENTITY> RouteBuilder post(Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); + <REQUEST_ENTITY> RouteBuilder post( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); + RouteBuilder post(Handler<?> handler, HandlerConfigBuilder config); + <REQUEST_ENTITY> RouteBuilder post( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config); + + // PUT RouteBuilder put(Handler<?> handler); - <REQUEST_ENTITY> RouteBuilder put(Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); + <REQUEST_ENTITY> RouteBuilder put( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); + RouteBuilder put(Handler<?> handler, HandlerConfigBuilder config); + <REQUEST_ENTITY> RouteBuilder put( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config); + + // DELETE RouteBuilder delete(Handler<?> handler); + RouteBuilder delete(Handler<?> handler, HandlerConfigBuilder config); + + // PATCH RouteBuilder patch(Handler<?> handler); - <REQUEST_ENTITY> RouteBuilder patch(Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); + <REQUEST_ENTITY> RouteBuilder patch( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); + RouteBuilder patch(Handler<?> handler, HandlerConfigBuilder config); + <REQUEST_ENTITY> RouteBuilder patch( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config); + + // Default RouteBuilder defaultHandler(Handler<?> handler); - <REQUEST_ENTITY> RouteBuilder defaultHandler(Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); - RouteBuilder addFilter(Filter filter); + RouteBuilder defaultHandler(Handler<?> handler, HandlerConfigBuilder config); + <REQUEST_ENTITY> RouteBuilder defaultHandler( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler); + <REQUEST_ENTITY> RouteBuilder defaultHandler( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config); } @FunctionalInterface interface Handler<RESPONSE_ENTITY> { @@ -70,6 +101,8 @@ public interface RestApi { @FunctionalInterface interface Filter { HttpResponse filterRequest(FilterContext context); } + interface HandlerConfigBuilder {} + interface RequestContext { HttpRequest request(); PathParameters pathParameters(); diff --git a/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java b/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java index d63add5ed1d..5b18ac428cd 100644 --- a/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java +++ b/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java @@ -14,7 +14,6 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.ListIterator; @@ -269,7 +268,7 @@ class RestApiImpl implements RestApi { @Override public RestApi build() { return new RestApiImpl(this); } } - public static class RouteBuilderImpl implements RestApi.RouteBuilder { + static class RouteBuilderImpl implements RestApi.RouteBuilder { private final String pathPattern; private String name; private final Map<Method, HandlerHolder<?>> handlerPerMethod = new HashMap<>(); @@ -279,50 +278,106 @@ class RestApiImpl implements RestApi { RouteBuilderImpl(String pathPattern) { this.pathPattern = pathPattern; } @Override public RestApi.RouteBuilder name(String name) { this.name = name; return this; } - @Override public RestApi.RouteBuilder get(Handler<?> handler) { - return addHandler(Method.GET, handler); + @Override public RestApi.RouteBuilder addFilter(RestApi.Filter filter) { filters.add(filter); return this; } + + // GET + @Override public RouteBuilder get(Handler<?> handler) { return get(handler, null); } + @Override public RouteBuilder get(Handler<?> handler, HandlerConfigBuilder config) { + return addHandler(Method.GET, handler, config); } - @Override public RestApi.RouteBuilder post(Handler<?> handler) { - return addHandler(Method.POST, handler); + + // POST + @Override public RouteBuilder post(Handler<?> handler) { return post(handler, null); } + @Override public <REQUEST_ENTITY> RouteBuilder post( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler) { + return post(type, handler, null); } - @Override public <ENTITY> RouteBuilder post(Class<ENTITY> type, HandlerWithRequestEntity<ENTITY, ?> handler) { - return addHandler(Method.POST, type, handler); + @Override public RouteBuilder post(Handler<?> handler, HandlerConfigBuilder config) { + return addHandler(Method.POST, handler, config); } - @Override public RestApi.RouteBuilder put(Handler<?> handler) { - return addHandler(Method.PUT, handler); + @Override public <REQUEST_ENTITY> RouteBuilder post( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config) { + return addHandler(Method.POST, type, handler, config); } - @Override public <ENTITY> RouteBuilder put(Class<ENTITY> type, HandlerWithRequestEntity<ENTITY, ?> handler) { - return addHandler(Method.PUT, type, handler); + + // PUT + @Override public RouteBuilder put(Handler<?> handler) { return put(handler, null); } + @Override public <REQUEST_ENTITY> RouteBuilder put( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler) { + return put(type, handler, null); } - @Override public RestApi.RouteBuilder delete(Handler<?> handler) { - return addHandler(Method.DELETE, handler); + @Override public RouteBuilder put(Handler<?> handler, HandlerConfigBuilder config) { + return addHandler(Method.PUT, handler, null); } - @Override public RestApi.RouteBuilder patch(Handler<?> handler) { - return addHandler(Method.PATCH, handler); + @Override public <REQUEST_ENTITY> RouteBuilder put( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config) { + return addHandler(Method.PUT, type, handler, config); } - @Override public <ENTITY> RouteBuilder patch(Class<ENTITY> type, HandlerWithRequestEntity<ENTITY, ?> handler) { - return addHandler(Method.PATCH, type, handler); + + // DELETE + @Override public RouteBuilder delete(Handler<?> handler) { return delete(handler, null); } + @Override public RouteBuilder delete(Handler<?> handler, HandlerConfigBuilder config) { + return addHandler(Method.DELETE, handler, config); } - @Override public RestApi.RouteBuilder defaultHandler(Handler<?> handler) { - defaultHandler = HandlerHolder.of(handler); return this; + + // PATCH + @Override public RouteBuilder patch(Handler<?> handler) { return patch(handler, null); } + @Override public <REQUEST_ENTITY> RouteBuilder patch( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler) { + return patch(type, handler, null); } - @Override public <ENTITY> RouteBuilder defaultHandler(Class<ENTITY> type, HandlerWithRequestEntity<ENTITY, ?> handler) { - defaultHandler = HandlerHolder.of(type, handler); return this; + @Override public RouteBuilder patch(Handler<?> handler, HandlerConfigBuilder config) { + return addHandler(Method.PATCH, handler, config); + } + @Override public <REQUEST_ENTITY> RouteBuilder patch( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config) { + return addHandler(Method.PATCH, type, handler, config); } - @Override public RestApi.RouteBuilder addFilter(RestApi.Filter filter) { filters.add(filter); return this; } - private RestApi.RouteBuilder addHandler(Method method, Handler<?> handler) { - handlerPerMethod.put(method, HandlerHolder.of(handler)); return this; + // Default + @Override public RouteBuilder defaultHandler(Handler<?> handler) { + return defaultHandler(handler, null); + } + @Override public RouteBuilder defaultHandler(Handler<?> handler, HandlerConfigBuilder config) { + defaultHandler = HandlerHolder.of(handler, build(config)); return this; + } + @Override public <REQUEST_ENTITY> RouteBuilder defaultHandler( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler) { + return defaultHandler(type, handler, null); + } + @Override + public <REQUEST_ENTITY> RouteBuilder defaultHandler( + Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, HandlerConfigBuilder config) { + defaultHandler = HandlerHolder.of(type, handler, build(config)); return this; + } + + private RestApi.RouteBuilder addHandler(Method method, Handler<?> handler, HandlerConfigBuilder config) { + handlerPerMethod.put(method, HandlerHolder.of(handler, build(config))); return this; } private <ENTITY> RestApi.RouteBuilder addHandler( - Method method, Class<ENTITY> type, HandlerWithRequestEntity<ENTITY, ?> handler) { - handlerPerMethod.put(method, HandlerHolder.of(type, handler)); return this; + Method method, Class<ENTITY> type, HandlerWithRequestEntity<ENTITY, ?> handler, HandlerConfigBuilder config) { + handlerPerMethod.put(method, HandlerHolder.of(type, handler, build(config))); return this; + } + + private static HandlerConfig build(HandlerConfigBuilder builder) { + if (builder == null) return HandlerConfig.empty(); + return ((HandlerConfigBuilderImpl)builder).build(); } private Route build() { return new Route(this); } } + static class HandlerConfigBuilderImpl implements HandlerConfigBuilder { + HandlerConfig build() { return new HandlerConfig(this); } + } + + private static class HandlerConfig { + HandlerConfig(HandlerConfigBuilderImpl builder) {} + + static HandlerConfig empty() { return new HandlerConfigBuilderImpl().build(); } + } + private static class RequestContextImpl implements RestApi.RequestContext { final HttpRequest request; final Path pathMatcher; @@ -460,21 +515,29 @@ class RestApiImpl implements RestApi { private static class HandlerHolder<REQUEST_ENTITY> { final Class<REQUEST_ENTITY> type; final HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler; + final HandlerConfig config; - HandlerHolder(Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler) { + private HandlerHolder( + Class<REQUEST_ENTITY> type, + HandlerWithRequestEntity<REQUEST_ENTITY, ?> handler, + HandlerConfig config) { this.type = type; this.handler = handler; + this.config = config; } static <RESPONSE_ENTITY, REQUEST_ENTITY> HandlerHolder<REQUEST_ENTITY> of( - Class<REQUEST_ENTITY> type, HandlerWithRequestEntity<REQUEST_ENTITY, RESPONSE_ENTITY> handler) { - return new HandlerHolder<>(type, handler); + Class<REQUEST_ENTITY> type, + HandlerWithRequestEntity<REQUEST_ENTITY, RESPONSE_ENTITY> handler, + HandlerConfig config) { + return new HandlerHolder<>(type, handler, config); } - static <RESPONSE_ENTITY> HandlerHolder<Void> of(Handler<RESPONSE_ENTITY> handler) { + static <RESPONSE_ENTITY> HandlerHolder<Void> of(Handler<RESPONSE_ENTITY> handler, HandlerConfig config) { return new HandlerHolder<>( Void.class, - (HandlerWithRequestEntity<Void, RESPONSE_ENTITY>) (context, nullEntity) -> handler.handleRequest(context)); + (HandlerWithRequestEntity<Void, RESPONSE_ENTITY>) (context, nullEntity) -> handler.handleRequest(context), + config); } Object executeHandler(RestApi.RequestContext context, Object entity) { return handler.handleRequest(context, type.cast(entity)); } @@ -507,7 +570,9 @@ class RestApiImpl implements RestApi { } private HandlerHolder<?> createDefaultMethodHandler() { - return HandlerHolder.of(context -> { throw new RestApiException.MethodNotAllowed(context.request()); }); + return HandlerHolder.of( + context -> { throw new RestApiException.MethodNotAllowed(context.request()); }, + HandlerConfig.empty()); } } |