diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2020-11-13 10:07:52 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2020-11-13 10:07:52 +0100 |
commit | 588545859beeae0b94d3311db80751cbe508f66c (patch) | |
tree | dddb3e63f0cd95f6b02bf218b64d0df270bee54b /jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterBindings.java | |
parent | 152d8f57d0d62506c83894907ca3c2e1fc56dfd6 (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/server/jetty/FilterBindings.java')
-rw-r--r-- | jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/FilterBindings.java | 110 |
1 files changed, 110 insertions, 0 deletions
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; + } + } +} |