001
002package io.vrap.rmf.base.client;
003
004import static io.vrap.rmf.base.client.utils.ClientUtils.blockingWait;
005
006import java.net.URI;
007import java.time.Duration;
008import java.util.concurrent.CompletableFuture;
009import java.util.function.Function;
010
011import com.fasterxml.jackson.core.type.TypeReference;
012import com.fasterxml.jackson.databind.JavaType;
013
014import io.vrap.rmf.base.client.http.HandlerStack;
015
016/**
017 * Interface for an HTTP client accessing the API and mapping to a known output type
018 */
019public interface ApiHttpClient extends AutoCloseable, VrapHttpClient {
020    public String CLOSED_MESSAGE = "Client is already closed.";
021
022    static Duration DEFAULT_TIMEOUT = Duration.ofSeconds(120);
023
024    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final ApiHttpRequest request,
025            final Class<O> outputType) {
026        return execute(request, apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType));
027    }
028
029    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final ApiHttpRequest request,
030            final TypeReference<O> outputType) {
031        return execute(request, apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType));
032    }
033
034    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final ApiHttpRequest request,
035            final JavaType outputType) {
036        return execute(request, apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType));
037    }
038
039    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final ApiHttpRequest request,
040            final Function<ApiHttpResponse<byte[]>, ApiHttpResponse<O>> mapper) {
041        return execute(request).thenApply(mapper);
042    }
043
044    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final ClientRequestCommand<O> method) {
045        return method.execute(this);
046    }
047
048    default public <T, O> CompletableFuture<ApiHttpResponse<O>> execute(final CreateHttpRequestCommand method,
049            final Class<O> outputType) {
050        return execute(method, apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType));
051    }
052
053    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final CreateHttpRequestCommand method,
054            final JavaType outputType) {
055        return execute(method, apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType));
056    }
057
058    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final CreateHttpRequestCommand method,
059            final TypeReference<O> outputType) {
060        return execute(method, apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType));
061    }
062
063    default public <O> CompletableFuture<ApiHttpResponse<O>> execute(final CreateHttpRequestCommand method,
064            final Function<ApiHttpResponse<byte[]>, ApiHttpResponse<O>> mapper) {
065        return execute(method.createHttpRequest()).thenApply(mapper);
066    }
067
068    default public <O> ApiHttpResponse<O> executeBlocking(final CreateHttpRequestCommand method,
069            final Function<ApiHttpResponse<byte[]>, ApiHttpResponse<O>> mapper, Duration timeout) {
070        ApiHttpRequest request = method.createHttpRequest();
071        return blockingWait(execute(request).thenApply(mapper), request, timeout);
072    }
073
074    default public <O> ApiHttpResponse<O> executeBlocking(final CreateHttpRequestCommand method,
075            final Class<O> outputType, Duration timeout) {
076        return executeBlocking(method,
077            apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType), timeout);
078    }
079
080    default public <O> ApiHttpResponse<O> executeBlocking(final CreateHttpRequestCommand method,
081            final JavaType outputType, Duration timeout) {
082        return executeBlocking(method,
083            apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType), timeout);
084    }
085
086    default public <O> ApiHttpResponse<O> executeBlocking(final CreateHttpRequestCommand method,
087            final TypeReference<O> outputType, Duration timeout) {
088        return executeBlocking(method,
089            apiHttpResponse -> getSerializerService().convertResponse(apiHttpResponse, outputType), timeout);
090    }
091
092    default public CompletableFuture<ApiHttpResponse<byte[]>> send(final CreateHttpRequestCommand method) {
093        return execute(method.createHttpRequest());
094    }
095
096    default public <T> ApiHttpResponse<byte[]> sendBlocking(final CreateHttpRequestCommand method,
097            final Duration timeout) {
098        ApiHttpRequest request = method.createHttpRequest();
099        return blockingWait(execute(request), request, timeout);
100    }
101
102    public ResponseSerializer getSerializerService();
103
104    public URI getBaseUri();
105
106    public static ApiHttpClient of(final String baseUri, final HandlerStack stack) {
107        return of(URI.create(baseUri), stack, ResponseSerializer.of());
108    }
109
110    public static ApiHttpClient of(final URI baseUri, final HandlerStack stack) {
111        return of(baseUri, stack, ResponseSerializer.of());
112    }
113
114    public static ApiHttpClient of(final String baseUri, final HandlerStack stack,
115            final ResponseSerializer serializer) {
116        return of(URI.create(baseUri), stack, serializer);
117    }
118
119    public static ApiHttpClient of(final URI baseUri, final HandlerStack stack, final ResponseSerializer serializer) {
120        return new ApiHttpClientImpl(baseUri, stack, serializer);
121    }
122}