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

org.jboss.resteasy.reactive.client.impl.InvocationBuilderImpl Maven / Gradle / Ivy

There is a newer version: 3.17.5
Show newest version
package org.jboss.resteasy.reactive.client.impl;

import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.READ_TIMEOUT;

import java.net.URI;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.client.CompletionStageRxInvoker;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.Invocation;
import jakarta.ws.rs.client.RxInvoker;
import jakarta.ws.rs.client.RxInvokerProvider;
import jakarta.ws.rs.core.CacheControl;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.GenericType;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;

import org.jboss.resteasy.reactive.common.core.BlockingNotAllowedException;
import org.jboss.resteasy.reactive.common.jaxrs.ConfigurationImpl;
import org.jboss.resteasy.reactive.spi.ThreadSetupAction;

import io.vertx.core.Context;
import io.vertx.core.http.HttpClient;

public class InvocationBuilderImpl implements Invocation.Builder {

    private static final long DEFAULT_READ_TIMEOUT = 30_000L;

    final URI uri;
    final HttpClient httpClient;
    final WebTargetImpl target;
    final RequestSpec requestSpec;
    final Map properties = new HashMap<>();
    final ConfigurationImpl configuration;
    final ClientImpl restClient;
    final HandlerChain handlerChain;
    final ThreadSetupAction requestContext;
    final long readTimeoutMs;

    public InvocationBuilderImpl(URI uri, ClientImpl restClient, HttpClient httpClient,
            WebTargetImpl target,
            ConfigurationImpl configuration, HandlerChain handlerChain, ThreadSetupAction requestContext) {
        this.uri = uri;
        this.restClient = restClient;
        this.httpClient = httpClient;
        this.target = target;
        this.requestSpec = new RequestSpec(configuration);
        this.configuration = configuration;
        this.handlerChain = handlerChain;
        this.requestContext = requestContext;
        Object readTimeoutMs = configuration.getProperty(READ_TIMEOUT);
        if (readTimeoutMs == null) {
            this.readTimeoutMs = DEFAULT_READ_TIMEOUT;
        } else {
            this.readTimeoutMs = (long) readTimeoutMs;
        }
    }

    @Override
    public Invocation build(String method) {
        setUserAgentIfNotSet();
        return new InvocationImpl(method, async(), null);
    }

    @Override
    public Invocation build(String method, Entity entity) {
        setUserAgentIfNotSet();
        return new InvocationImpl(method, async(), entity);
    }

    @Override
    public Invocation buildGet() {
        return build("GET");
    }

    @Override
    public Invocation buildDelete() {
        return build("DELETE");
    }

    @Override
    public Invocation buildPost(Entity entity) {
        return build("POST", entity);
    }

    @Override
    public Invocation buildPut(Entity entity) {
        return build("PUT", entity);
    }

    @Override
    public AsyncInvokerImpl async() {
        setUserAgentIfNotSet();
        return new AsyncInvokerImpl(restClient, httpClient, uri, requestSpec, configuration,
                properties, handlerChain, requestContext);
    }

    @Override
    public Invocation.Builder accept(String... mediaTypes) {
        requestSpec.headers.accept(mediaTypes);
        return this;
    }

    @Override
    public Invocation.Builder accept(MediaType... mediaTypes) {
        requestSpec.headers.accept(mediaTypes);
        return this;
    }

    @Override
    public Invocation.Builder acceptLanguage(Locale... locales) {
        requestSpec.headers.acceptLanguage(locales);
        return this;
    }

    @Override
    public Invocation.Builder acceptLanguage(String... locales) {
        requestSpec.headers.acceptLanguage(locales);
        return this;
    }

    @Override
    public Invocation.Builder acceptEncoding(String... encodings) {
        requestSpec.headers.acceptEncoding(encodings);
        return this;
    }

    @Override
    public Invocation.Builder cookie(Cookie cookie) {
        requestSpec.headers.cookie(cookie);
        return this;
    }

    @Override
    public Invocation.Builder cookie(String name, String value) {
        requestSpec.headers.cookie(new Cookie(name, value));
        return this;
    }

    @Override
    public Invocation.Builder cacheControl(CacheControl cacheControl) {
        requestSpec.headers.cacheControl(cacheControl);
        return this;
    }

    @Override
    public Invocation.Builder header(String name, Object value) {
        requestSpec.headers.header(name, value);
        return this;
    }

    @Override
    public Invocation.Builder headers(MultivaluedMap headers) {
        requestSpec.headers.setHeaders(headers);
        return this;
    }

    @Override
    public Invocation.Builder property(String name, Object value) {
        properties.put(name, value);
        return this;
    }

    @Override
    public CompletionStageRxInvoker rx() {
        return new AsyncInvokerImpl(restClient, httpClient, uri, requestSpec, configuration,
                properties, handlerChain, requestContext);
    }

    @Override
    public  T rx(Class clazz) {
        setUserAgentIfNotSet();
        if (clazz == MultiInvoker.class) {
            return (T) new MultiInvoker(this);
        } else if (clazz == UniInvoker.class) {
            return (T) new UniInvoker(this);
        }
        RxInvokerProvider invokerProvider = requestSpec.configuration.getRxInvokerProvider(clazz);
        if (invokerProvider != null) {
            // FIXME: should pass the Quarkus executor here, but MP-CP or not?
            return (T) invokerProvider.getRxInvoker(this, null);
        }
        // TCK says we could throw IllegalStateException, or not, it doesn't discriminate, and the spec doesn't say
        return null;
    }

    private void setUserAgentIfNotSet() {
        if (!requestSpec.headers.getHeaders().containsKey(HttpHeaders.USER_AGENT)
                && restClient.getUserAgent() != null && !restClient.getUserAgent().isEmpty()) {
            this.requestSpec.headers.header(HttpHeaders.USER_AGENT, restClient.getUserAgent());
        }
    }

    @Override
    public Response get() {
        return unwrap(async().get());
    }

    private  T unwrap(CompletableFuture c) {
        if (Context.isOnEventLoopThread()) {
            throw new BlockingNotAllowedException();
        }
        try {
            return c.get();
        } catch (InterruptedException e) {
            throw new ProcessingException(e);
        } catch (ExecutionException e) {
            if (e.getCause() instanceof ProcessingException) {
                throw (ProcessingException) e.getCause();
            }
            if (e.getCause() instanceof WebApplicationException) {
                throw (WebApplicationException) e.getCause();
            }
            throw new ProcessingException(e.getCause().getMessage(), e.getCause());
        }
    }

    @Override
    public  T get(Class responseType) {
        return unwrap(async().get(responseType));
    }

    @Override
    public  T get(GenericType responseType) {
        return unwrap(async().get(responseType));
    }

    @Override
    public Response put(Entity entity) {
        return unwrap(async().put(entity));
    }

    @Override
    public  T put(Entity entity, Class responseType) {
        return unwrap(async().put(entity, responseType));
    }

    @Override
    public  T put(Entity entity, GenericType responseType) {
        return unwrap(async().put(entity, responseType));
    }

    @Override
    public Response post(Entity entity) {
        return unwrap(async().post(entity));
    }

    @Override
    public  T post(Entity entity, Class responseType) {
        return unwrap(async().post(entity, responseType));
    }

    @Override
    public  T post(Entity entity, GenericType responseType) {
        return unwrap(async().post(entity, responseType));
    }

    @Override
    public Response delete() {
        return unwrap(async().delete());
    }

    @Override
    public  T delete(Class responseType) {
        return unwrap(async().delete(responseType));
    }

    @Override
    public  T delete(GenericType responseType) {
        return unwrap(async().delete(responseType));
    }

    @Override
    public Response head() {
        return unwrap(async().head());
    }

    @Override
    public Response options() {
        return unwrap(async().options());
    }

    @Override
    public  T options(Class responseType) {
        return unwrap(async().options(responseType));
    }

    @Override
    public  T options(GenericType responseType) {
        return unwrap(async().options(responseType));
    }

    @Override
    public Response trace() {
        return unwrap(async().trace());
    }

    @Override
    public  T trace(Class responseType) {
        return unwrap(async().trace(responseType));
    }

    @Override
    public  T trace(GenericType responseType) {
        return unwrap(async().trace(responseType));
    }

    @Override
    public Response method(String name) {
        return unwrap(async().method(name));
    }

    @Override
    public  T method(String name, Class responseType) {
        return unwrap(async().method(name, responseType));
    }

    @Override
    public  T method(String name, GenericType responseType) {
        return unwrap(async().method(name, responseType));
    }

    @Override
    public Response method(String name, Entity entity) {
        return unwrap(async().method(name, entity));
    }

    @Override
    public  T method(String name, Entity entity, Class responseType) {
        return unwrap(async().method(name, entity, responseType));
    }

    @Override
    public  T method(String name, Entity entity, GenericType responseType) {
        return unwrap(async().method(name, entity, responseType));
    }

    public WebTargetImpl getTarget() {
        return target;
    }

    public void setChunked(boolean chunked) {
        this.requestSpec.chunked = chunked;
    }

    public boolean getChunked() {
        return requestSpec.chunked;
    }

    public ClientRequestHeaders getHeaders() {
        return requestSpec.headers;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy