summaryrefslogtreecommitdiffstats
path: root/jdisc_http_service/src/main/java/com/yahoo/jdisc/http
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2020-11-13 10:07:52 +0100
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2020-11-13 10:07:52 +0100
commit588545859beeae0b94d3311db80751cbe508f66c (patch)
treedddb3e63f0cd95f6b02bf218b64d0df270bee54b /jdisc_http_service/src/main/java/com/yahoo/jdisc/http
parent152d8f57d0d62506c83894907ca3c2e1fc56dfd6 (diff)
Prepare FilterBindings to allow default filter chains and metrics
Track and expose filter ids from FilterBindings. Add builder to simplify construction for FilterBindings in provider and unit tests. Move FilterBindings to com.yahoo.jdisc.http.server.jetty package. Encapsulate binding matching in FilterBindings.
Diffstat (limited to 'jdisc_http_service/src/main/java/com/yahoo/jdisc/http')
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/FilterBindings.java30
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterBindings.java110
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java18
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java2
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscContext.java12
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java10
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java4
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/package-info.java4
8 files changed, 129 insertions, 61 deletions
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/FilterBindings.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/FilterBindings.java
deleted file mode 100644
index 4dabed41bc6..00000000000
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/FilterBindings.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.jdisc.http.server;
-
-import com.yahoo.jdisc.application.BindingRepository;
-import com.yahoo.jdisc.http.filter.RequestFilter;
-import com.yahoo.jdisc.http.filter.ResponseFilter;
-
-/**
- * @author bakksjo
- */
-public class FilterBindings {
-
- private final BindingRepository<RequestFilter> requestFilters;
- private final BindingRepository<ResponseFilter> responseFilters;
-
- public FilterBindings(BindingRepository<RequestFilter> requestFilters,
- BindingRepository<ResponseFilter> responseFilters) {
- this.requestFilters = requestFilters;
- this.responseFilters = responseFilters;
- }
-
- public BindingRepository<RequestFilter> getRequestFilters() {
- return requestFilters;
- }
-
- public BindingRepository<ResponseFilter> getResponseFilters() {
- return responseFilters;
- }
-
-}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterBindings.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterBindings.java
new file mode 100644
index 00000000000..301c92a4583
--- /dev/null
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterBindings.java
@@ -0,0 +1,110 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.http.server.jetty;
+
+import com.yahoo.jdisc.application.BindingRepository;
+import com.yahoo.jdisc.application.BindingSet;
+import com.yahoo.jdisc.application.UriPattern;
+import com.yahoo.jdisc.http.filter.RequestFilter;
+import com.yahoo.jdisc.http.filter.ResponseFilter;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import static java.util.stream.Collectors.toSet;
+
+/**
+ * Resolves request/response filter (chain) from a {@link URI} instance.
+ *
+ * @author Oyvind Bakksjo
+ * @author bjorncs
+ */
+public class FilterBindings {
+
+ private final BindingSet<FilterHolder<RequestFilter>> requestFilters;
+ private final BindingSet<FilterHolder<ResponseFilter>> responseFilters;
+
+ private FilterBindings(
+ BindingSet<FilterHolder<RequestFilter>> requestFilters,
+ BindingSet<FilterHolder<ResponseFilter>> responseFilters) {
+ this.requestFilters = requestFilters;
+ this.responseFilters = responseFilters;
+ }
+
+ public Optional<String> resolveRequestFilter(URI uri) { return resolveFilterId(requestFilters, uri); }
+
+ public Optional<String> resolveResponseFilter(URI uri) { return resolveFilterId(responseFilters, uri); }
+
+ public RequestFilter getRequestFilter(String filterId) { return getFilterInstance(requestFilters, filterId); }
+
+ public ResponseFilter getResponseFilter(String filterId) { return getFilterInstance(responseFilters, filterId); }
+
+ public Collection<String> requestFilterIds() { return filterIds(requestFilters); }
+
+ public Collection<String> responseFilterIds() { return filterIds(responseFilters); }
+
+ public Collection<RequestFilter> requestFilters() { return filters(requestFilters); }
+
+ public Collection<ResponseFilter> responseFilters() { return filters(responseFilters); }
+
+ private static <T> Optional<String> resolveFilterId(BindingSet<FilterHolder<T>> filters, URI uri) {
+ return Optional.ofNullable(filters.resolve(uri))
+ .map(holder -> holder.filterId);
+ }
+
+ private static <T> T getFilterInstance(BindingSet<FilterHolder<T>> filters, String filterId) {
+ return stream(filters)
+ .filter(filterEntry -> filterId.equals(filterEntry.getValue().filterId))
+ .map(filterEntry -> filterEntry.getValue().filterInstance)
+ .findAny()
+ .orElseThrow(() -> new IllegalArgumentException("No filter with id " + filterId));
+ }
+
+ private static <T> Collection<String> filterIds(BindingSet<FilterHolder<T>> filters) {
+ return stream(filters)
+ .map(filterEntry -> filterEntry.getValue().filterId)
+ .collect(toSet());
+ }
+
+ private static <T> Collection<T> filters(BindingSet<FilterHolder<T>> filters) {
+ return stream(filters)
+ .map(filterEntry -> filterEntry.getValue().filterInstance)
+ .collect(toSet());
+ }
+
+ private static <T> Stream<Map.Entry<UriPattern, FilterHolder<T>>> stream(BindingSet<FilterHolder<T>> filters) {
+ return StreamSupport.stream(filters.spliterator(), false);
+ }
+
+ public static class Builder {
+ private final BindingRepository<FilterHolder<RequestFilter>> requestFilters = new BindingRepository<>();
+ private final BindingRepository<FilterHolder<ResponseFilter>> responseFilters = new BindingRepository<>();
+
+ public Builder() {}
+
+ public Builder addRequestFilter(String id, String binding, RequestFilter filter) {
+ requestFilters.bind(binding, new FilterHolder<>(id, filter));
+ return this;
+ }
+
+ public Builder addResponseFilter(String id, String binding, ResponseFilter filter) {
+ responseFilters.bind(binding, new FilterHolder<>(id, filter));
+ return this;
+ }
+
+ public FilterBindings build() { return new FilterBindings(requestFilters.activate(), responseFilters.activate()); }
+ }
+
+ private static class FilterHolder<T> {
+ final String filterId;
+ final T filterInstance;
+
+ FilterHolder(String filterId, T filterInstance) {
+ this.filterId = filterId;
+ this.filterInstance = filterInstance;
+ }
+ }
+}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java
index 1734dc3716f..7f761d6ab4a 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilteringRequestHandler.java
@@ -4,7 +4,6 @@ package com.yahoo.jdisc.http.server.jetty;
import com.google.common.base.Preconditions;
import com.yahoo.jdisc.Request;
import com.yahoo.jdisc.Response;
-import com.yahoo.jdisc.application.BindingSet;
import com.yahoo.jdisc.handler.AbstractRequestHandler;
import com.yahoo.jdisc.handler.BindingNotFoundException;
import com.yahoo.jdisc.handler.CompletionHandler;
@@ -42,13 +41,10 @@ class FilteringRequestHandler extends AbstractRequestHandler {
};
- private final BindingSet<RequestFilter> requestFilters;
- private final BindingSet<ResponseFilter> responseFilters;
+ private final FilterBindings filterBindings;
- public FilteringRequestHandler(BindingSet<RequestFilter> requestFilters,
- BindingSet<ResponseFilter> responseFilters) {
- this.requestFilters = requestFilters;
- this.responseFilters = responseFilters;
+ public FilteringRequestHandler(FilterBindings filterBindings) {
+ this.filterBindings = filterBindings;
}
@Override
@@ -56,8 +52,12 @@ class FilteringRequestHandler extends AbstractRequestHandler {
Preconditions.checkArgument(request instanceof HttpRequest, "Expected HttpRequest, got " + request);
Objects.requireNonNull(originalResponseHandler, "responseHandler");
- RequestFilter requestFilter = requestFilters.resolve(request.getUri());
- ResponseFilter responseFilter = responseFilters.resolve(request.getUri());
+ RequestFilter requestFilter = filterBindings.resolveRequestFilter(request.getUri())
+ .map(filterBindings::getRequestFilter)
+ .orElse(null);
+ ResponseFilter responseFilter = filterBindings.resolveResponseFilter(request.getUri())
+ .map(filterBindings::getResponseFilter)
+ .orElse(null);
// Not using request.connect() here - it adds logic for error handling that we'd rather leave to the framework.
RequestHandler resolvedRequestHandler = request.container().resolveHandler(request);
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java
index 2cab06e9e23..ed5095fb06f 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java
@@ -212,7 +212,7 @@ class HttpRequestDispatch {
AccessLogEntry accessLogEntry,
HttpServletRequest servletRequest) {
RequestHandler requestHandler = wrapHandlerIfFormPost(
- new FilteringRequestHandler(context.requestFilters, context.responseFilters),
+ new FilteringRequestHandler(context.filterBindings),
servletRequest, context.serverConfig.removeRawPostBodyForWwwUrlEncodedPost());
return new AccessLoggingRequestHandler(requestHandler, accessLogEntry);
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscContext.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscContext.java
index 4172ec16b00..4667ff3975b 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscContext.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscContext.java
@@ -2,31 +2,25 @@
package com.yahoo.jdisc.http.server.jetty;
import com.yahoo.jdisc.Metric;
-import com.yahoo.jdisc.application.BindingSet;
import com.yahoo.jdisc.http.ServerConfig;
-import com.yahoo.jdisc.http.filter.RequestFilter;
-import com.yahoo.jdisc.http.filter.ResponseFilter;
import com.yahoo.jdisc.service.CurrentContainer;
import java.util.concurrent.Executor;
public class JDiscContext {
- final BindingSet<RequestFilter> requestFilters;
- final BindingSet<ResponseFilter> responseFilters;
+ final FilterBindings filterBindings;
final CurrentContainer container;
final Executor janitor;
final Metric metric;
final ServerConfig serverConfig;
- public JDiscContext(BindingSet<RequestFilter> requestFilters,
- BindingSet<ResponseFilter> responseFilters,
+ public JDiscContext(FilterBindings filterBindings,
CurrentContainer container,
Executor janitor,
Metric metric,
ServerConfig serverConfig) {
- this.requestFilters = requestFilters;
- this.responseFilters = responseFilters;
+ this.filterBindings = filterBindings;
this.container = container;
this.janitor = janitor;
this.metric = metric;
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java
index e3bcec765cd..5a904299e44 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscFilterInvokerFilter.java
@@ -3,7 +3,6 @@ package com.yahoo.jdisc.http.server.jetty;
import com.yahoo.container.logging.AccessLogEntry;
import com.yahoo.jdisc.handler.ResponseHandler;
-import com.yahoo.jdisc.http.filter.RequestFilter;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncListener;
@@ -76,7 +75,8 @@ class JDiscFilterInvokerFilter implements Filter {
private void runChainAndResponseFilters(URI uri, HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
Optional<OneTimeRunnable> responseFilterInvoker =
- Optional.ofNullable(jDiscContext.responseFilters.resolve(uri))
+ jDiscContext.filterBindings.resolveResponseFilter(uri)
+ .map(jDiscContext.filterBindings::getResponseFilter)
.map(responseFilter ->
new OneTimeRunnable(() ->
filterInvoker.invokeResponseFilterChain(responseFilter, uri, request, response)));
@@ -106,12 +106,12 @@ class JDiscFilterInvokerFilter implements Filter {
private HttpServletRequest runRequestFilterWithMatchingBinding(AtomicReference<Boolean> responseReturned, URI uri, HttpServletRequest request, HttpServletResponse response) throws IOException {
try {
- RequestFilter requestFilter = jDiscContext.requestFilters.resolve(uri);
- if (requestFilter == null)
+ String requestFilterId = jDiscContext.filterBindings.resolveRequestFilter(uri).orElse(null);
+ if (requestFilterId == null)
return request;
ResponseHandler responseHandler = createResponseHandler(responseReturned, request, response);
- return filterInvoker.invokeRequestFilterChain(requestFilter, uri, request, responseHandler);
+ return filterInvoker.invokeRequestFilterChain(jDiscContext.filterBindings.getRequestFilter(requestFilterId), uri, request, responseHandler);
} catch (Exception e) {
throw new RuntimeException("Failed running request filter chain for uri " + uri, e);
}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
index 2f96cb76ae0..490b379bc98 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
@@ -10,7 +10,6 @@ import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.http.ConnectorConfig;
import com.yahoo.jdisc.http.ServerConfig;
import com.yahoo.jdisc.http.ServletPathsConfig;
-import com.yahoo.jdisc.http.server.FilterBindings;
import com.yahoo.jdisc.service.AbstractServerProvider;
import com.yahoo.jdisc.service.CurrentContainer;
import org.eclipse.jetty.http.HttpField;
@@ -94,8 +93,7 @@ public class JettyHttpServer extends AbstractServerProvider {
janitor = newJanitor();
- JDiscContext jDiscContext = new JDiscContext(filterBindings.getRequestFilters().activate(),
- filterBindings.getResponseFilters().activate(),
+ JDiscContext jDiscContext = new JDiscContext(filterBindings,
container,
janitor,
metric,
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/package-info.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/package-info.java
deleted file mode 100644
index f6afffbaff0..00000000000
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-@ExportPackage
-package com.yahoo.jdisc.http.server;
-import com.yahoo.osgi.annotation.ExportPackage;