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

org.zalando.riptide.Route Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show newest version
package org.zalando.riptide;

import com.google.common.reflect.TypeToken;
import org.apiguardian.api.API;
import org.springframework.http.client.ClientHttpResponse;
import org.zalando.fauxpas.ThrowingConsumer;
import org.zalando.fauxpas.ThrowingRunnable;

import static org.apiguardian.api.API.Status.STABLE;
import static org.zalando.fauxpas.TryWith.tryWith;

/**
 *
 * @see RoutingTree
 */
@API(status = STABLE)
@FunctionalInterface
public interface Route {

    /**
     * Executes this route against the specific response. It's within the responsibility of a {@link Route route}
     * implementation to ensure the stream is consumed (optional) and properly closed. A fully consumed response stream
     * allows for connection reuse and is therefore highly encouraged. Making sure that every response is properly
     * closed ensures that stale connections are not exhausting the connection pool.
     *
     * Most {@link Route routes} will do both operations internally, but the responsibility can be handed over to the
     * caller of the {@link Route route} by unmarshalling the stream into a {@link java.io.Closeable} or
     * {@link AutoCloseable} bean.
     *
     * @param response the client response
     * @param reader a utility to unmarshall the response into Java beans
     * @throws Exception if anything goes wrong during route execution, primarily used for {@link java.io.IOException}
     */
    void execute(final ClientHttpResponse response, final MessageReader reader) throws Exception;

    default Route merge(final Route other) {
        return other;
    }

    static Route call(final ThrowingRunnable runnable) {
        return (response, reader) ->
                tryWith(response, (ClientHttpResponse ignored) -> runnable.tryRun());
    }

    static Route call(final ThrowingConsumer consumer) {
        return (response, reader) ->
                tryWith(response, consumer);
    }

    static  Route call(final Class type, final ThrowingConsumer consumer) {
        return call(TypeToken.of(type), consumer);
    }

    static  Route call(final TypeToken type, final ThrowingConsumer consumer) {
        return (response, reader) -> {

            final I body = reader.read(type, response);
            consumer.tryAccept(body);
        };
    }

}