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

com.turbospaces.http.CommonHttpClient Maven / Gradle / Ivy

package com.turbospaces.http;

import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.Objects;

import org.apache.commons.lang3.tuple.Pair;
import org.apache.http.HttpEntity;
import org.apache.http.HttpRequest;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.MDC;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.net.HttpHeaders;
import com.turbospaces.mdc.MdcTags;
import com.turbospaces.ups.PlainServiceInfo;

import lombok.experimental.Delegate;

public class CommonHttpClient implements AdvancedHttpClient {
    @Delegate
    private final CloseableHttpClient http;

    private final ObjectMapper mapper;

    @Delegate
    private final PlainServiceInfo si;

    public CommonHttpClient(CloseableHttpClient http, ObjectMapper mapper, PlainServiceInfo si) {
        this.http = Objects.requireNonNull(http);
        this.mapper = Objects.requireNonNull(mapper);
        this.si = Objects.requireNonNull(si);
    }

    @Override
    public HttpPost preparePost(String path, HttpEntity httpEntity) throws URISyntaxException {
        HttpPost post = prepareRequest(new HttpPost(), path);
        post.setEntity(httpEntity);
        return post;
    }

    @Override
    public HttpPut preparePut(String path, HttpEntity httpEntity) throws URISyntaxException {
        HttpPut post = prepareRequest(new HttpPut(), path);
        post.setEntity(httpEntity);
        return post;
    }

    @Override
    public HttpPost preparePost(String path, Object payload) throws URISyntaxException, JsonProcessingException {
        HttpPost post = prepareRequest(new HttpPost(), path);
        post.setEntity(new StringEntity(mapper.writeValueAsString(payload), ContentType.APPLICATION_JSON));
        return post;
    }

    @Override
    public HttpRequest addBasicAuth(HttpRequest httpRequest) {
        StringBuffer buf = new StringBuffer(si.getUserName());
        buf.append(':').append(si.getPassword());
        httpRequest.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString(buf.toString().getBytes(StandardCharsets.UTF_8)));
        return httpRequest;
    }

    @Override
    public HttpGet prepareGet(String path, NameValuePair... params) throws URISyntaxException {
        return prepareRequest(new HttpGet(), path, params);
    }

    private  T prepareRequest(T req, String path, NameValuePair... params) throws URISyntaxException {
        URIBuilder uriBuilder = toUriBuilder(path);
        if (params != null) {
            for (NameValuePair p : params) {
                uriBuilder.addParameter(p.getName(), p.getValue());
            }
        }

        req.setURI(uriBuilder.build());
        req.setHeader(
                HttpHeaders.ACCEPT,
                Arrays.stream(req.getHeaders(HttpHeaders.ACCEPT)).findFirst().map(NameValuePair::getValue).orElse("application/json"));
        req.setHeader(
                HttpHeaders.CONTENT_TYPE,
                Arrays.stream(req.getHeaders(HttpHeaders.CONTENT_TYPE)).findFirst().map(NameValuePair::getValue).orElse("application/json"));
        return req;
    }

    public URIBuilder toUriBuilder(String path) {
        URIBuilder uri = new URIBuilder();
        uri.setScheme(si.getScheme());
        uri.setHost(si.getHost());
        if (si.getPort() > 0) {
            uri.setPort(si.getPort());
        }
        uri.setPath(path);
        return uri;
    }

    @Override
    @SuppressWarnings("unchecked")
    public  R send(HttpRequestBase req, Class respClass) throws Exception {
        MDC.put(MdcTags.MDC_PATH, req.getURI().getPath());

        try (CloseableHttpResponse httpResp = execute(req)) {
            int status = httpResp.getStatusLine().getStatusCode();
            String text = EntityUtils.toString(httpResp.getEntity());

            if (HttpStatus.SC_OK == status || HttpStatus.SC_CREATED == status) {
                R resp;
                if (respClass == String.class) {
                    resp = (R) text;
                } else {
                    resp = mapper.readValue(text, respClass);
                }
                return resp;
            }

            throw new UnexpectedHttpClientException(httpResp.getStatusLine(), text, httpResp.getAllHeaders());
        } finally {
            MDC.remove(MdcTags.MDC_PATH);
        }
    }

    @Override
    public  Pair sendNoStatusCheck(HttpRequestBase req, Class respClass) throws Exception {
        MDC.put(MdcTags.MDC_PATH, req.getURI().getPath());

        try (CloseableHttpResponse httpResp = execute(req)) {
            StatusLine status = httpResp.getStatusLine();
            String text = EntityUtils.toString(httpResp.getEntity());
            R resp;
            if (respClass == String.class) {
                resp = respClass.cast(text);
            } else {
                resp = mapper.readValue(text, respClass);
            }
            return Pair.of(status, resp);
        } finally {
            MDC.remove(MdcTags.MDC_PATH);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy