diff options
author | Morten Tokle <mortent@verizonmedia.com> | 2020-11-16 13:48:24 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-16 13:48:24 +0100 |
commit | 24533200de429c8b54e5ad6384a318cd03642656 (patch) | |
tree | feb11c8e9376bf96b7ee75b66d41bd0e505ec53a | |
parent | 8a50df0fd94f25011cb3a6fe9dfce40b5ece2969 (diff) | |
parent | 588545859beeae0b94d3311db80751cbe508f66c (diff) |
Merge pull request #15330 from vespa-engine/bjorncs/jdisc-http-service-filtering
Prepare FilterBindings to allow default filter chains and metrics
16 files changed, 248 insertions, 266 deletions
diff --git a/container-disc/pom.xml b/container-disc/pom.xml index 1caf66e29dc..413af786f2c 100644 --- a/container-disc/pom.xml +++ b/container-disc/pom.xml @@ -32,6 +32,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>com.yahoo.vespa</groupId> <artifactId>config-lib</artifactId> <version>${project.version}</version> diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/FilterBindingsProvider.java b/container-disc/src/main/java/com/yahoo/container/jdisc/FilterBindingsProvider.java index 972f9dd8e18..195aee93246 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/FilterBindingsProvider.java +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/FilterBindingsProvider.java @@ -5,12 +5,9 @@ import com.yahoo.component.ComponentId; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.container.di.componentgraph.Provider; import com.yahoo.container.http.filter.FilterChainRepository; -import com.yahoo.jdisc.application.BindingRepository; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.filter.RequestFilter; -import com.yahoo.jdisc.http.filter.ResponseFilter; import com.yahoo.jdisc.http.filter.SecurityRequestFilter; -import com.yahoo.jdisc.http.server.FilterBindings; +import com.yahoo.jdisc.http.server.jetty.FilterBindings; import java.util.ArrayList; import java.util.List; @@ -18,28 +15,26 @@ import java.util.List; /** * Provides filter bindings based on vespa config. * - * @author bakksjo + * @author Oyvind Bakksjo + * @author bjorncs */ public class FilterBindingsProvider implements Provider<FilterBindings> { - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - final BindingRepository<ResponseFilter> responseFilters = new BindingRepository<>(); + private final FilterBindings filterBindings; public FilterBindingsProvider(ComponentId componentId, ServerConfig config, FilterChainRepository filterChainRepository, ComponentRegistry<SecurityRequestFilter> legacyRequestFilters) { - ComponentId serverId = componentId.getNamespace(); try { - FilterUtil.setupFilters( + this.filterBindings = FilterUtil.setupFilters( componentId, legacyRequestFilters, toFilterSpecs(config.filter()), - filterChainRepository, - requestFilters, - responseFilters); + filterChainRepository); } catch (Exception e) { - throw new RuntimeException("Invalid config for http server " + serverId, e); + throw new RuntimeException( + "Invalid config for http server '" + componentId.getNamespace() + "': " + e.getMessage(), e); } } @@ -51,10 +46,7 @@ public class FilterBindingsProvider implements Provider<FilterBindings> { return outFilters; } - @Override - public FilterBindings get() { - return new FilterBindings(requestFilters, responseFilters); - } + @Override public FilterBindings get() { return filterBindings; } @Override public void deconstruct() {} diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/FilterUtil.java b/container-disc/src/main/java/com/yahoo/container/jdisc/FilterUtil.java index 24af56788b9..52829d6710e 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/FilterUtil.java +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/FilterUtil.java @@ -5,12 +5,11 @@ import com.yahoo.component.ComponentId; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.container.http.filter.FilterChainRepository; -import com.yahoo.jdisc.application.BindingRepository; -import com.yahoo.jdisc.application.UriPattern; import com.yahoo.jdisc.http.filter.RequestFilter; import com.yahoo.jdisc.http.filter.ResponseFilter; import com.yahoo.jdisc.http.filter.SecurityRequestFilter; import com.yahoo.jdisc.http.filter.SecurityRequestFilterChain; +import com.yahoo.jdisc.http.server.jetty.FilterBindings; import java.util.List; @@ -18,18 +17,15 @@ import java.util.List; * Helper class to set up filter binding repositories based on config. * * @author Øyvind Bakksjø + * @author bjorncs */ class FilterUtil { private static final ComponentId SEARCH_SERVER_COMPONENT_ID = ComponentId.fromString("SearchServer"); - private final BindingRepository<RequestFilter> requestFilters; - private final BindingRepository<ResponseFilter> responseFilters; + private final FilterBindings.Builder builder = new FilterBindings.Builder(); - private FilterUtil(BindingRepository<RequestFilter> requestFilters, BindingRepository<ResponseFilter> responseFilters) { - this.requestFilters = requestFilters; - this.responseFilters = responseFilters; - } + private FilterUtil() {} private void configureFilters(List<FilterSpec> filtersConfig, FilterChainRepository filterChainRepository) { for (FilterSpec filterConfig : filtersConfig) { @@ -37,50 +33,48 @@ class FilterUtil { if (filter == null) { throw new RuntimeException("No http filter with id " + filterConfig.getId()); } - addFilter(filter, filterConfig.getBinding()); + addFilter(filter, filterConfig.getBinding(), filterConfig.getId()); } } - private void addFilter(Object filter, String binding) { + private void addFilter(Object filter, String binding, String filterId) { if (filter instanceof RequestFilter && filter instanceof ResponseFilter) { throw new RuntimeException("The filter " + filter.getClass().getName() + " is unsupported since it's both a RequestFilter and a ResponseFilter."); } else if (filter instanceof RequestFilter) { - requestFilters.put(new UriPattern(binding), (RequestFilter) filter); + builder.addRequestFilter(filterId, binding, (RequestFilter) filter); } else if (filter instanceof ResponseFilter) { - responseFilters.put(new UriPattern(binding), (ResponseFilter) filter); + builder.addResponseFilter(filterId, binding, (ResponseFilter) filter); } else { throw new RuntimeException("Unknown filter type " + filter.getClass().getName()); } } - //TVT: remove + // TODO(gjoranv): remove private void configureLegacyFilters(ComponentId id, ComponentRegistry<SecurityRequestFilter> legacyRequestFilters) { ComponentId serverName = id.getNamespace(); if (SEARCH_SERVER_COMPONENT_ID.equals(serverName) && !legacyRequestFilters.allComponents().isEmpty()) { - requestFilters.bind("http://*/*", - SecurityRequestFilterChain.newInstance(legacyRequestFilters.allComponents())); + builder.addRequestFilter( + "legacy-filters", "http://*/*", SecurityRequestFilterChain.newInstance(legacyRequestFilters.allComponents())); } } /** * Populates binding repositories with filters based on config. - * - * @param requestFilters output argument that will be mutated - * @param responseFilters output argument that will be mutated */ - public static void setupFilters(ComponentId componentId, - ComponentRegistry<SecurityRequestFilter> legacyRequestFilters, - List<FilterSpec> filtersConfig, - FilterChainRepository filterChainRepository, - BindingRepository<RequestFilter> requestFilters, - BindingRepository<ResponseFilter> responseFilters) { - FilterUtil filterUtil = new FilterUtil(requestFilters, responseFilters); - - // TODO: remove + public static FilterBindings setupFilters( + ComponentId componentId, + ComponentRegistry<SecurityRequestFilter> legacyRequestFilters, + List<FilterSpec> filtersConfig, + FilterChainRepository filterChainRepository) { + FilterUtil filterUtil = new FilterUtil(); + + // TODO(gjoranv): remove filterUtil.configureLegacyFilters(componentId, legacyRequestFilters); filterUtil.configureFilters(filtersConfig, filterChainRepository); + + return filterUtil.builder.build(); } public static class FilterSpec { diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java index e3039e88525..c233680590d 100644 --- a/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java +++ b/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java @@ -5,32 +5,19 @@ import com.yahoo.component.ComponentId; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.container.core.ChainsConfig; import com.yahoo.container.http.filter.FilterChainRepository; -import com.yahoo.jdisc.application.BindingRepository; -import com.yahoo.jdisc.application.UriPattern; import com.yahoo.jdisc.http.ServerConfig; import com.yahoo.jdisc.http.filter.RequestFilter; import com.yahoo.jdisc.http.filter.ResponseFilter; -import com.yahoo.jdisc.http.server.FilterBindings; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeMatcher; +import com.yahoo.jdisc.http.server.jetty.FilterBindings; import org.junit.Test; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; /** - * @author bakksjo + * @author Oyvind Bakksjo + * @author bjorncs */ public class FilterBindingsProviderTest { final ServerConfig.Builder configBuilder = new ServerConfig.Builder(); @@ -52,9 +39,9 @@ public class FilterBindingsProviderTest { final FilterBindings filterBindings = provider.get(); - assertNotNull(filterBindings); - assertFalse(filterBindings.getRequestFilters().iterator().hasNext()); - assertFalse(filterBindings.getResponseFilters().iterator().hasNext()); + assertThat(filterBindings).isNotNull(); + assertThat(filterBindings.requestFilterIds()).isEmpty(); + assertThat(filterBindings.responseFilterIds()).isEmpty(); } @Test @@ -105,19 +92,11 @@ public class FilterBindingsProviderTest { final FilterBindings filterBindings = provider.get(); // Verify. - assertNotNull(filterBindings); - assertThat( - filterBindings.getRequestFilters(), - containsFilters(requestFilter1Instance, requestFilter2Instance)); - assertThat( - filterBindings.getRequestFilters(), - not(containsFilters(requestFilter3Instance))); - assertThat( - filterBindings.getResponseFilters(), - containsFilters(responseFilter1Instance, responseFilter3Instance)); - assertThat( - filterBindings.getResponseFilters(), - not(containsFilters(responseFilter2Instance))); + assertThat(filterBindings).isNotNull(); + assertThat(filterBindings.requestFilters()) + .containsExactlyInAnyOrder(requestFilter1Instance, requestFilter2Instance); + assertThat(filterBindings.responseFilters()) + .containsExactlyInAnyOrder(responseFilter1Instance, responseFilter3Instance); } private interface DualRoleFilter extends RequestFilter, ResponseFilter {} @@ -148,7 +127,7 @@ public class FilterBindingsProviderTest { new ComponentRegistry<>()); fail("Dual-role filter should not be accepted"); } catch (RuntimeException e) { - assertTrue(e.getMessage().contains("Invalid config")); + assertThat(e.getMessage()).contains("Invalid config"); } } @@ -173,30 +152,8 @@ public class FilterBindingsProviderTest { new ComponentRegistry<>()); fail("Config with unknown filter reference should not be accepted"); } catch (RuntimeException e) { - assertTrue(e.getMessage().contains("Invalid config")); + assertThat(e.getMessage()).contains("Invalid config"); } } - @SafeVarargs - @SuppressWarnings("varargs") - private static <T> Matcher<? super BindingRepository<T>> containsFilters( - final T... requiredInstances) { - return new TypeSafeMatcher<>() { - private final Set<T> requiredFilterSet = new HashSet<>(Arrays.asList(requiredInstances)); - - @Override - protected boolean matchesSafely(final BindingRepository<T> actualInstances) { - final Set<T> notFoundFilterSet = new HashSet<>(requiredFilterSet); - for (final Map.Entry<UriPattern, T> actualEntry : actualInstances) { - notFoundFilterSet.remove(actualEntry.getValue()); - } - return notFoundFilterSet.isEmpty(); - } - - @Override - public void describeTo(final Description description) { - description.appendText("BindingRepository containing " + requiredFilterSet); - } - }; - } } 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; diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java index 0b94829f720..a978e42f7cb 100644 --- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java +++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java @@ -7,7 +7,6 @@ import com.yahoo.jdisc.AbstractResource; import com.yahoo.jdisc.Request; import com.yahoo.jdisc.ResourceReference; import com.yahoo.jdisc.Response; -import com.yahoo.jdisc.application.BindingRepository; import com.yahoo.jdisc.handler.AbstractRequestHandler; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; @@ -24,7 +23,6 @@ import com.yahoo.jdisc.http.filter.ResponseHeaderFilter; import com.yahoo.jdisc.http.filter.chain.RequestFilterChain; import com.yahoo.jdisc.http.filter.chain.ResponseFilterChain; import com.yahoo.jdisc.http.guiceModules.ConnectorFactoryRegistryModule; -import com.yahoo.jdisc.http.server.FilterBindings; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -53,12 +51,12 @@ import static org.mockito.Mockito.when; public class FilterTestCase { @Test public void requireThatRequestFilterIsNotRunOnUnboundPath() throws Exception { - final RequestFilter filter = mock(RequestFilterMockBase.class); - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - requestFilters.bind("http://*/filtered/*", filter); - final BindingRepository<ResponseFilter> responseFilters = null; + RequestFilterMockBase filter = mock(RequestFilterMockBase.class); + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/filtered/*", filter) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -71,11 +69,11 @@ public class FilterTestCase { @Test public void requireThatRequestFilterIsRunOnBoundPath() throws Exception { final RequestFilter filter = mock(RequestFilterMockBase.class); - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - requestFilters.bind("http://*/filtered/*", filter); - final BindingRepository<ResponseFilter> responseFilters = null; + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/filtered/*", filter) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/filtered/status.html"); @@ -88,11 +86,11 @@ public class FilterTestCase { @Test public void requireThatRequestFilterChangesAreSeenByRequestHandler() throws Exception { final RequestFilter filter = new HeaderRequestFilter("foo", "bar"); - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - requestFilters.bind("http://*/*", filter); - final BindingRepository<ResponseFilter> responseFilters = null; + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/*", filter) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("status.html"); @@ -104,11 +102,11 @@ public class FilterTestCase { @Test public void requireThatRequestFilterCanRespond() throws Exception { - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - requestFilters.bind("http://*/*", new RespondForbiddenFilter()); - final BindingRepository<ResponseFilter> responseFilters = null; + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/*", new RespondForbiddenFilter()) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html").expectStatusCode(is(Response.Status.FORBIDDEN)); @@ -121,11 +119,11 @@ public class FilterTestCase { public void requireThatFilterCanHaveNullCompletionHandler() throws Exception { final int responseStatus = Response.Status.OK; final String responseMessage = "Excellent"; - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - requestFilters.bind("http://*/*", new NullCompletionHandlerFilter(responseStatus, responseMessage)); - final BindingRepository<ResponseFilter> responseFilters = null; + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/*", new NullCompletionHandlerFilter(responseStatus, responseMessage)) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html") .expectStatusCode(is(responseStatus)) @@ -138,11 +136,11 @@ public class FilterTestCase { @Test public void requireThatRequestFilterExecutionIsExceptionSafe() throws Exception { - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - final BindingRepository<ResponseFilter> responseFilters = null; - requestFilters.bind("http://*/*", new ThrowingRequestFilter()); + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/*", new ThrowingRequestFilter()) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html").expectStatusCode(is(Response.Status.INTERNAL_SERVER_ERROR)); @@ -154,11 +152,11 @@ public class FilterTestCase { @Test public void requireThatResponseFilterIsNotRunOnUnboundPath() throws Exception { final ResponseFilter filter = mock(ResponseFilterMockBase.class); - final BindingRepository<RequestFilter> requestFilters = null; - final BindingRepository<ResponseFilter> responseFilters = new BindingRepository<>(); - responseFilters.bind("http://*/filtered/*", filter); + FilterBindings filterBindings = new FilterBindings.Builder() + .addResponseFilter("my-response-filter", "http://*/filtered/*", filter) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -171,11 +169,11 @@ public class FilterTestCase { @Test public void requireThatResponseFilterIsRunOnBoundPath() throws Exception { final ResponseFilter filter = mock(ResponseFilterMockBase.class); - final BindingRepository<RequestFilter> requestFilters = null; - final BindingRepository<ResponseFilter> responseFilters = new BindingRepository<>(); - responseFilters.bind("http://*/filtered/*", filter); + FilterBindings filterBindings = new FilterBindings.Builder() + .addResponseFilter("my-response-filter", "http://*/filtered/*", filter) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/filtered/status.html"); @@ -187,11 +185,11 @@ public class FilterTestCase { @Test public void requireThatResponseFilterChangesAreWrittenToResponse() throws Exception { - final BindingRepository<RequestFilter> requestFilters = null; - final BindingRepository<ResponseFilter> responseFilters = new BindingRepository<>(); - responseFilters.bind("http://*/*", new HeaderResponseFilter("foo", "bar")); + FilterBindings filterBindings = new FilterBindings.Builder() + .addResponseFilter("my-response-filter", "http://*/*", new HeaderResponseFilter("foo", "bar")) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html") .expectHeader("foo", is("bar")); @@ -203,11 +201,11 @@ public class FilterTestCase { @Test public void requireThatResponseFilterExecutionIsExceptionSafe() throws Exception { - final BindingRepository<RequestFilter> requestFilters = null; - final BindingRepository<ResponseFilter> responseFilters = new BindingRepository<>(); - responseFilters.bind("http://*/*", new ThrowingResponseFilter()); + FilterBindings filterBindings = new FilterBindings.Builder() + .addResponseFilter("my-response-filter", "http://*/*", new ThrowingResponseFilter()) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html").expectStatusCode(is(Response.Status.INTERNAL_SERVER_ERROR)); @@ -218,15 +216,15 @@ public class FilterTestCase { @Test public void requireThatRequestFilterAndResponseFilterCanBindToSamePath() throws Exception { - final String uriPattern = "http://*/*"; - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); final RequestFilter requestFilter = mock(RequestFilterMockBase.class); - requestFilters.bind(uriPattern, requestFilter); - final BindingRepository<ResponseFilter> responseFilters = new BindingRepository<>(); final ResponseFilter responseFilter = mock(ResponseFilterMockBase.class); - responseFilters.bind(uriPattern, responseFilter); + final String uriPattern = "http://*/*"; + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", uriPattern, requestFilter) + .addResponseFilter("my-response-filter", uriPattern, responseFilter) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -239,12 +237,12 @@ public class FilterTestCase { @Test public void requireThatResponseFromRequestFilterGoesThroughResponseFilter() throws Exception { - final BindingRepository<RequestFilter> requestFilters = new BindingRepository<>(); - requestFilters.bind("http://*/*", new RespondForbiddenFilter()); - final BindingRepository<ResponseFilter> responseFilters = new BindingRepository<>(); - responseFilters.bind("http://*/*", new HeaderResponseFilter("foo", "bar")); + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/*", new RespondForbiddenFilter()) + .addResponseFilter("my-response-filter", "http://*/*", new HeaderResponseFilter("foo", "bar")) + .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, requestFilters, responseFilters); + final TestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html") .expectStatusCode(is(Response.Status.FORBIDDEN)) @@ -384,26 +382,20 @@ public class FilterTestCase { private static TestDriver newDriver( final MyRequestHandler requestHandler, - final BindingRepository<RequestFilter> requestFilters, - final BindingRepository<ResponseFilter> responseFilters) + FilterBindings filterBindings) throws IOException { return TestDriver.newInstance( JettyHttpServer.class, requestHandler, - newFilterModule(requestFilters, responseFilters)); + newFilterModule(filterBindings)); } - private static com.google.inject.Module newFilterModule( - final BindingRepository<RequestFilter> requestFilters, - final BindingRepository<ResponseFilter> responseFilters) { + private static com.google.inject.Module newFilterModule(FilterBindings filterBindings) { return Modules.combine( new AbstractModule() { @Override protected void configure() { - bind(FilterBindings.class).toInstance( - new FilterBindings( - requestFilters != null ? requestFilters : EMPTY_REQUEST_FILTER_REPOSITORY, - responseFilters != null ? responseFilters : EMPTY_RESPONSE_FILTER_REPOSITORY)); + bind(FilterBindings.class).toInstance(filterBindings); bind(ServerConfig.class).toInstance(new ServerConfig(new ServerConfig.Builder())); bind(ConnectorConfig.class).toInstance(new ConnectorConfig(new ConnectorConfig.Builder())); bind(ServletPathsConfig.class).toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); @@ -412,9 +404,6 @@ public class FilterTestCase { new ConnectorFactoryRegistryModule()); } - private static final BindingRepository<RequestFilter> EMPTY_REQUEST_FILTER_REPOSITORY = new BindingRepository<>(); - private static final BindingRepository<ResponseFilter> EMPTY_RESPONSE_FILTER_REPOSITORY = new BindingRepository<>(); - private static abstract class RequestFilterMockBase extends AbstractResource implements RequestFilter {} private static abstract class ResponseFilterMockBase extends AbstractResource implements ResponseFilter {} diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java index a239dc1ae23..63307dab5ff 100644 --- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java +++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java @@ -4,11 +4,9 @@ package com.yahoo.jdisc.http.server.jetty; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.util.Modules; -import com.yahoo.jdisc.application.BindingRepository; import com.yahoo.jdisc.http.ServerConfig; import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.jdisc.http.guiceModules.ConnectorFactoryRegistryModule; -import com.yahoo.jdisc.http.server.FilterBindings; import com.yahoo.jdisc.test.ServerProviderConformanceTest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; @@ -770,9 +768,7 @@ public class HttpServerConformanceTest extends ServerProviderConformanceTest { @Override protected void configure() { bind(FilterBindings.class) - .toInstance(new FilterBindings( - new BindingRepository<>(), - new BindingRepository<>())); + .toInstance(new FilterBindings.Builder().build()); bind(ServerConfig.class) .toInstance(new ServerConfig(new ServerConfig.Builder())); bind(ServletPathsConfig.class) diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDrivers.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDrivers.java index 255e42fb886..2ff19794ea3 100644 --- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDrivers.java +++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDrivers.java @@ -4,16 +4,12 @@ package com.yahoo.jdisc.http.server.jetty; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.util.Modules; -import com.yahoo.jdisc.application.BindingRepository; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.http.ConnectorConfig; import com.yahoo.jdisc.http.ServerConfig; import com.yahoo.jdisc.http.ServletPathsConfig; -import com.yahoo.jdisc.http.filter.RequestFilter; -import com.yahoo.jdisc.http.filter.ResponseFilter; import com.yahoo.jdisc.http.guiceModules.ConnectorFactoryRegistryModule; import com.yahoo.jdisc.http.guiceModules.ServletModule; -import com.yahoo.jdisc.http.server.FilterBindings; import java.io.IOException; import java.nio.file.Path; @@ -83,10 +79,7 @@ public class TestDrivers { bind(ServletPathsConfig.class).toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); bind(ServerConfig.class).toInstance(new ServerConfig(serverConfig)); bind(ConnectorConfig.class).toInstance(new ConnectorConfig(connectorConfigBuilder)); - bind(FilterBindings.class).toInstance( - new FilterBindings( - new BindingRepository<>(), - new BindingRepository<>())); + bind(FilterBindings.class).toInstance(new FilterBindings.Builder().build()); } }, new ConnectorFactoryRegistryModule(connectorConfigBuilder), diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java index 5ad76c6348f..272d6fbb66c 100644 --- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java +++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java @@ -7,13 +7,12 @@ import com.google.inject.util.Modules; import com.yahoo.jdisc.AbstractResource; import com.yahoo.jdisc.Request; import com.yahoo.jdisc.Response; -import com.yahoo.jdisc.application.BindingRepository; import com.yahoo.jdisc.handler.ContentChannel; import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.jdisc.http.filter.RequestFilter; import com.yahoo.jdisc.http.filter.ResponseFilter; -import com.yahoo.jdisc.http.server.FilterBindings; +import com.yahoo.jdisc.http.server.jetty.FilterBindings; import com.yahoo.jdisc.http.server.jetty.FilterInvoker; import com.yahoo.jdisc.http.server.jetty.SimpleHttpClient.ResponseValidator; import com.yahoo.jdisc.http.server.jetty.TestDriver; @@ -79,21 +78,27 @@ public class JDiscFilterForServletTest extends ServletTestBase { } private TestDriver requestFilterTestDriver() throws IOException { - return TestDrivers.newInstance(dummyRequestHandler, bindings(requestFilters(), noBindings())); + FilterBindings filterBindings = new FilterBindings.Builder() + .addRequestFilter("my-request-filter", "http://*/*", new TestRequestFilter()) + .build(); + return TestDrivers.newInstance(dummyRequestHandler, bindings(filterBindings)); } private TestDriver responseFilterTestDriver() throws IOException { - return TestDrivers.newInstance(dummyRequestHandler, bindings(noBindings(), responseFilters())); + FilterBindings filterBindings = new FilterBindings.Builder() + .addResponseFilter("my-response-filter", "http://*/*", new TestResponseFilter()) + .build(); + return TestDrivers.newInstance(dummyRequestHandler, bindings(filterBindings)); } - private Module bindings(BindingRepository<RequestFilter> requestFilters, - BindingRepository<ResponseFilter> responseFilters) { + + private Module bindings(FilterBindings filterBindings) { return Modules.combine( new AbstractModule() { @Override protected void configure() { - bind(FilterBindings.class).toInstance(new FilterBindings(requestFilters, responseFilters)); + bind(FilterBindings.class).toInstance(filterBindings); bind(FilterInvoker.class).toInstance(new FilterInvoker() { @Override public HttpServletRequest invokeRequestFilterChain( @@ -122,23 +127,6 @@ public class JDiscFilterForServletTest extends ServletTestBase { guiceModule()); } - private BindingRepository<RequestFilter> requestFilters() { - BindingRepository<RequestFilter> repository = new BindingRepository<>(); - repository.bind("http://*/*" , new TestRequestFilter()); - return repository; - } - - private BindingRepository<ResponseFilter> responseFilters() { - BindingRepository<ResponseFilter> repository = new BindingRepository<>(); - repository.bind("http://*/*" , new TestResponseFilter()); - return repository; - } - - private <T> BindingRepository<T> noBindings() { - return new BindingRepository<>(); - } - - static class TestRequestFilter extends AbstractResource implements RequestFilter { static final String simpleName = TestRequestFilter.class.getSimpleName(); static final String responseContent = "Rejected by " + simpleName; |