diff options
Diffstat (limited to 'jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server')
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; |