All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.inverno.mod.http.server.ExchangeInterceptor Maven / Gradle / Ivy

There is a newer version: 1.11.0
Show newest version
/*
 * Copyright 2021 Jeremy KUHN
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.inverno.mod.http.server;

import io.inverno.mod.http.base.ExchangeContext;
import reactor.core.publisher.Mono;

/**
 * 

* An exchange interceptor is used to intercept a server exchange before it is handled by a {@link ExchangeHandler}. *

* *

* Multiple exchange interceptors can be chained on an exchange handler invoking {@link ReactiveExchangeHandler#intercept(io.inverno.mod.http.server.ExchangeInterceptor)} method multiple times in * order to form an exchange handling chain. *

* *

* An exchange interceptor is meant to perform extra processing or instrumentation on the exchange prior to the actual exchange processing by the exchange handler. But it can also fully process the * exchange and stop the exchange handling chain by returning an empty Mono in which case the exchange handler will not be invoked. *

* * @author Jeremy Kuhn * @since 1.3 * * @see ReactiveExchangeHandler * * @param the type of the exchange context * @param the type of exchange handled by the handler */ @FunctionalInterface public interface ExchangeInterceptor> { /** *

* Intercepts the exchange before the exchange handler is invoked. *

* * @param exchange the server exchange to handle * * @return a Mono emitting the exchange or an instrumented exchange to continue the exchange handling chain or an empty Mono to stop the exchange handling chain */ Mono intercept(B exchange); /** *

* Returns a composed interceptor that invokes this interceptor first and then invokes the specified interceptor. *

* * @param after the interceptor to invoke after this interceptor * * @return a composed interceptor that invokes in sequence this interceptor followed by the specified interceptor */ default ExchangeInterceptor andThen(ExchangeInterceptor after) { return exchange -> this.intercept(exchange).flatMap(after::intercept); } /** *

* Returns a composed interceptor that invokes the specified interceptor first and then invokes this interceptor. *

* * @param before the interceptor to invoke before this interceptor * * @return a composed interceptor that invokes in sequence this interceptor followed by the specified interceptor */ default ExchangeInterceptor compose(ExchangeInterceptor before) { return exchange -> before.intercept(exchange).flatMap(this::intercept); } /** *

* Returns an interceptor resulting from chaining the specified interceptors in sequence. *

* * @param
the type of the exchange context * @param the type of exchange handled by the handler * @param interceptors the interceptors to chain * * @return a composed interceptor */ @SafeVarargs @SuppressWarnings("varargs") static > ExchangeInterceptor of(ExchangeInterceptor... interceptors) { return exchange -> { Mono interceptorChain = null; for(ExchangeInterceptor interceptor : interceptors) { if(interceptorChain == null) { interceptorChain = interceptor.intercept(exchange); } else { interceptorChain = interceptorChain.flatMap(interceptor::intercept); } } return interceptorChain; }; } }