use of io.micronaut.http.filter.HttpClientFilter in project micronaut-core by micronaut-projects.
the class DefaultHttpClient method applyFilterToResponsePublisher.
/**
* @param parentRequest The parent request
* @param request The request
* @param requestURI The URI of the request
* @param requestWrapper The request wrapper
* @param responsePublisher The response publisher
* @param <I> The input type
* @param <O> The output type
* @return The {@link Publisher} for the response
*/
protected <I, O> Publisher<io.micronaut.http.HttpResponse<O>> applyFilterToResponsePublisher(io.micronaut.http.HttpRequest<?> parentRequest, io.micronaut.http.HttpRequest<I> request, URI requestURI, AtomicReference<io.micronaut.http.HttpRequest> requestWrapper, Publisher<io.micronaut.http.HttpResponse<O>> responsePublisher) {
if (request instanceof MutableHttpRequest) {
((MutableHttpRequest<I>) request).uri(requestURI);
List<HttpClientFilter> filters = filterResolver.resolveFilters(request, clientFilterEntries);
if (parentRequest != null) {
filters.add(new ClientServerContextFilter(parentRequest));
}
OrderUtil.reverseSort(filters);
Publisher<io.micronaut.http.HttpResponse<O>> finalResponsePublisher = responsePublisher;
filters.add((req, chain) -> finalResponsePublisher);
ClientFilterChain filterChain = buildChain(requestWrapper, filters);
if (parentRequest != null) {
responsePublisher = ServerRequestContext.with(parentRequest, (Supplier<Publisher<io.micronaut.http.HttpResponse<O>>>) () -> {
try {
return Flux.from((Publisher<io.micronaut.http.HttpResponse<O>>) filters.get(0).doFilter(request, filterChain)).contextWrite(ctx -> ctx.put(ServerRequestContext.KEY, parentRequest));
} catch (Throwable t) {
return Flux.error(t);
}
});
} else {
try {
responsePublisher = (Publisher<io.micronaut.http.HttpResponse<O>>) filters.get(0).doFilter(request, filterChain);
} catch (Throwable t) {
responsePublisher = Flux.error(t);
}
}
}
return responsePublisher;
}
use of io.micronaut.http.filter.HttpClientFilter in project micronaut-core by micronaut-projects.
the class DefaultHttpClientFilterResolver method resolveFilterEntries.
@Override
public List<FilterEntry<HttpClientFilter>> resolveFilterEntries(ClientFilterResolutionContext context) {
return clientFilters.stream().map(httpClientFilter -> {
AnnotationMetadata annotationMetadata = annotationMetadataResolver.resolveMetadata(httpClientFilter);
HttpMethod[] methods = annotationMetadata.enumValues(Filter.class, "methods", HttpMethod.class);
FilterPatternStyle patternStyle = annotationMetadata.enumValue(Filter.class, "patternStyle", FilterPatternStyle.class).orElse(FilterPatternStyle.ANT);
final Set<HttpMethod> httpMethods = new HashSet<>(Arrays.asList(methods));
if (annotationMetadata.hasStereotype(FilterMatcher.class)) {
httpMethods.addAll(Arrays.asList(annotationMetadata.enumValues(FilterMatcher.class, "methods", HttpMethod.class)));
}
return FilterEntry.of(httpClientFilter, annotationMetadata, httpMethods, patternStyle, annotationMetadata.stringValues(Filter.class));
}).filter(entry -> {
AnnotationMetadata annotationMetadata = entry.getAnnotationMetadata();
boolean matches = !annotationMetadata.hasStereotype(FilterMatcher.class);
String filterAnnotation = annotationMetadata.getAnnotationNameByStereotype(FilterMatcher.class).orElse(null);
if (filterAnnotation != null && !matches) {
matches = context.getAnnotationMetadata().hasStereotype(filterAnnotation);
}
if (matches) {
String[] clients = annotationMetadata.stringValues(Filter.class, "serviceId");
boolean hasClients = ArrayUtils.isNotEmpty(clients);
if (hasClients) {
matches = containsIdentifier(context.getClientIds(), clients);
}
}
return matches;
}).collect(Collectors.toList());
}
use of io.micronaut.http.filter.HttpClientFilter in project micronaut-core by micronaut-projects.
the class DefaultHttpClientFilterResolver method resolveFilters.
@Override
public List<HttpClientFilter> resolveFilters(HttpRequest<?> request, List<FilterEntry<HttpClientFilter>> filterEntries) {
String requestPath = StringUtils.prependUri("/", request.getUri().getPath());
io.micronaut.http.HttpMethod method = request.getMethod();
List<HttpClientFilter> filterList = new ArrayList<>(filterEntries.size());
for (FilterEntry<HttpClientFilter> filterEntry : filterEntries) {
final HttpClientFilter filter = filterEntry.getFilter();
if (filter instanceof Toggleable && !((Toggleable) filter).isEnabled()) {
continue;
}
boolean matches = true;
if (filterEntry.hasMethods()) {
matches = anyMethodMatches(method, filterEntry.getFilterMethods());
}
if (filterEntry.hasPatterns()) {
matches = matches && anyPatternMatches(requestPath, filterEntry.getPatterns(), filterEntry.getPatternStyle());
}
if (matches) {
filterList.add(filter);
}
}
return filterList;
}
use of io.micronaut.http.filter.HttpClientFilter in project micronaut-core by micronaut-projects.
the class DefaultHttpClient method buildChain.
private ClientFilterChain buildChain(AtomicReference<io.micronaut.http.HttpRequest> requestWrapper, List<HttpClientFilter> filters) {
AtomicInteger integer = new AtomicInteger();
int len = filters.size();
return new ClientFilterChain() {
@Override
public Publisher<? extends io.micronaut.http.HttpResponse<?>> proceed(MutableHttpRequest<?> request) {
int pos = integer.incrementAndGet();
if (pos > len) {
throw new IllegalStateException("The FilterChain.proceed(..) method should be invoked exactly once per filter execution. The method has instead been invoked multiple times by an erroneous filter definition.");
}
HttpClientFilter httpFilter = filters.get(pos);
try {
return httpFilter.doFilter(requestWrapper.getAndSet(request), this);
} catch (Throwable t) {
return Flux.error(t);
}
}
};
}
Aggregations