001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.reactive.function.client; 018 019import java.util.function.Function; 020 021import reactor.core.publisher.Mono; 022 023import org.springframework.util.Assert; 024 025/** 026 * Represents a function that filters an {@linkplain ExchangeFunction exchange function}. 027 * <p>The filter is executed when a {@code Subscriber} subscribes to the 028 * {@code Publisher} returned by the {@code WebClient}. 029 * 030 * @author Arjen Poutsma 031 * @since 5.0 032 */ 033@FunctionalInterface 034public interface ExchangeFilterFunction { 035 036 /** 037 * Apply this filter to the given request and exchange function. 038 * <p>The given {@linkplain ExchangeFunction} represents the next entity 039 * in the chain, to be invoked via 040 * {@linkplain ExchangeFunction#exchange(ClientRequest) invoked} in order to 041 * proceed with the exchange, or not invoked to shortcut the chain. 042 * @param request the current request 043 * @param next the next exchange function in the chain 044 * @return the filtered response 045 */ 046 Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next); 047 048 /** 049 * Return a composed filter function that first applies this filter, and 050 * then applies the given {@code "after"} filter. 051 * @param afterFilter the filter to apply after this filter 052 * @return the composed filter 053 */ 054 default ExchangeFilterFunction andThen(ExchangeFilterFunction afterFilter) { 055 Assert.notNull(afterFilter, "ExchangeFilterFunction must not be null"); 056 return (request, next) -> 057 filter(request, afterRequest -> afterFilter.filter(afterRequest, next)); 058 } 059 060 /** 061 * Apply this filter to the given {@linkplain ExchangeFunction}, resulting 062 * in a filtered exchange function. 063 * @param exchange the exchange function to filter 064 * @return the filtered exchange function 065 */ 066 default ExchangeFunction apply(ExchangeFunction exchange) { 067 Assert.notNull(exchange, "ExchangeFunction must not be null"); 068 return request -> this.filter(request, exchange); 069 } 070 071 /** 072 * Adapt the given request processor function to a filter function that only 073 * operates on the {@code ClientRequest}. 074 * @param processor the request processor 075 * @return the resulting filter adapter 076 */ 077 static ExchangeFilterFunction ofRequestProcessor(Function<ClientRequest, Mono<ClientRequest>> processor) { 078 Assert.notNull(processor, "ClientRequest Function must not be null"); 079 return (request, next) -> processor.apply(request).flatMap(next::exchange); 080 } 081 082 /** 083 * Adapt the given response processor function to a filter function that 084 * only operates on the {@code ClientResponse}. 085 * @param processor the response processor 086 * @return the resulting filter adapter 087 */ 088 static ExchangeFilterFunction ofResponseProcessor(Function<ClientResponse, Mono<ClientResponse>> processor) { 089 Assert.notNull(processor, "ClientResponse Function must not be null"); 090 return (request, next) -> next.exchange(request).flatMap(processor); 091 } 092 093}