summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2021-07-14 14:34:36 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2021-07-14 15:11:17 +0200
commitd5a7b61b15c4a480a8ae049d907b149c872ac5cd (patch)
tree10e783ce1915961e92606cd6217e0ee7df910635 /container-core
parent19ef310d5795cff7c131ba432af8aee1cf0f7a9e (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.java43
-rw-r--r--container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java131
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());
}
}