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

com.plaid.client.http.ApacheHttpClientHttpDelegate Maven / Gradle / Ivy

There is a newer version: 30.1.0
Show newest version
package com.plaid.client.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpMessage;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.plaid.client.exception.PlaidClientsideException;
import com.plaid.client.exception.PlaidCommunicationsException;
import com.plaid.client.exception.PlaidMfaException;
import com.plaid.client.exception.PlaidServersideException;
import com.plaid.client.exception.PlaidServersideUnknownResponseException;
import com.plaid.client.response.ErrorResponse;
import com.plaid.client.response.MfaResponse;
import com.plaid.client.response.UnknownResponse;

public class ApacheHttpClientHttpDelegate implements HttpDelegate {

    private String baseUri;
    private CloseableHttpClient httpClient;
    private ObjectMapper jsonMapper;
    private WireLogger wireLogger;
    private static String LIBRARY_VERSION = ApacheHttpClientHttpDelegate.class.getPackage().getImplementationVersion();

    public ApacheHttpClientHttpDelegate(String baseUri, CloseableHttpClient httpClient) {
        this.baseUri = baseUri;
        this.httpClient = httpClient;
        this.jsonMapper = new ObjectMapper();
        if (LIBRARY_VERSION == null) {
        	LIBRARY_VERSION = "development version";
        }
    }

    public static ApacheHttpClientHttpDelegate createDefault(String baseUri) {
        CloseableHttpClient httpClient = System.getProperty("https.protocols") == null ?
                HttpClients.createDefault() : HttpClients.createSystem();
        return new ApacheHttpClientHttpDelegate(baseUri, httpClient);
    }

    public void setWireLogger(WireLogger wireLogger) {
		this.wireLogger = wireLogger;
	}

    public WireLogger getWireLogger() {
		return wireLogger;
	}

    @Override
    public  HttpResponseWrapper doPost(PlaidHttpRequest request, Class clazz) {

        List parameters = mapToNvps(request.getParameters());

        try {
            HttpPost post = new HttpPost(baseUri + request.getPath());

            HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8");
            post.setEntity(entity);

            if (request.hasTimeout()) {
                int timeout = request.getTimeout();

                RequestConfig config = RequestConfig.custom()
                        .setConnectTimeout(timeout)
                        .setSocketTimeout(timeout)
                        .setConnectionRequestTimeout(timeout)
                        .build();
                post.setConfig(config);
            }

            addUserAgent(post);

            CloseableHttpResponse response = httpClient.execute(post);

            return handleResponse(post, response, clazz);

        } catch (UnsupportedEncodingException e) {
            throw new PlaidClientsideException(e);
        } catch (IOException e) {
            throw new PlaidCommunicationsException(e);
        }
    }

    @Override
    public  HttpResponseWrapper doGet(PlaidHttpRequest request, Class clazz) {
        try {

            List parameters = mapToNvps(request.getParameters());

            URI uri = new URIBuilder(baseUri)
                .setPath(request.getPath())
                .addParameters(parameters)
                .build();

            HttpGet get = new HttpGet(uri);

            addUserAgent(get);

            CloseableHttpResponse response = httpClient.execute(get);

            return handleResponse(get, response, clazz);

        } catch (UnsupportedEncodingException e) {
            throw new PlaidClientsideException(e);
        } catch (IOException e) {
            throw new PlaidCommunicationsException(e);
        } catch (URISyntaxException e) {
            throw new PlaidClientsideException(e);
        }
    }

    @Override
    public  HttpResponseWrapper doDelete(PlaidHttpRequest request, Class clazz) {
        try {

            List parameters = mapToNvps(request.getParameters());

            URI uri = new URIBuilder(baseUri)
                .setPath(request.getPath())
                .addParameters(parameters)
                .build();

            HttpDelete delete = new HttpDelete(uri);

            addUserAgent(delete);

            CloseableHttpResponse response = httpClient.execute(delete);

            return handleResponse(delete, response, clazz);

        } catch (UnsupportedEncodingException e) {
            throw new PlaidClientsideException(e);
        } catch (IOException e) {
            throw new PlaidCommunicationsException(e);
        } catch (URISyntaxException e) {
            throw new PlaidClientsideException(e);
        }
    }

    @Override
    public  HttpResponseWrapper doPatch(PlaidHttpRequest request, Class clazz) {

        List parameters = mapToNvps(request.getParameters());

        try {
            HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8");
            HttpPatch patch = new HttpPatch(baseUri + request.getPath());
            patch.setEntity(entity);

            addUserAgent(patch);

            CloseableHttpResponse response = httpClient.execute(patch);

            return handleResponse(patch, response, clazz);

        } catch (UnsupportedEncodingException e) {
            throw new PlaidClientsideException(e);
        } catch (IOException e) {
            throw new PlaidCommunicationsException(e);
        }
    }

    private void wireLog(HttpRequestBase request, CloseableHttpResponse response, JsonNode responseBody) {
		if (wireLogger != null) {
			wireLogger.logRequestResponsePair(request, response, responseBody);
		}
	}

	private  HttpResponseWrapper handleResponse(HttpRequestBase request, CloseableHttpResponse response,
            Class clazz) {

    	HttpEntity responseEntity = response.getEntity();

        try {

        	int statusCode = response.getStatusLine().getStatusCode();
        	JsonNode jsonBody = jsonMapper.readTree(responseEntity.getContent());
            EntityUtils.consume(responseEntity);

            wireLog(request, response, jsonBody);

            if (HttpStatus.SC_OK == statusCode) {

                T responseBody = jsonMapper.convertValue(jsonBody, clazz);
                return HttpResponseWrapper.create(statusCode, responseBody);

            } else if (HttpStatus.SC_CREATED == statusCode) {

                MfaResponse mfaResponse = jsonMapper.convertValue(jsonBody, MfaResponse.class);
                throw new PlaidMfaException(mfaResponse, statusCode);

            } else if (statusCode >= HttpStatus.SC_BAD_REQUEST) {

                ErrorResponse errorResponse = jsonMapper.convertValue(jsonBody, ErrorResponse.class);
                throw new PlaidServersideException(errorResponse, statusCode);

            } else {
                UnknownResponse unknownResponse = jsonMapper.convertValue(jsonBody, UnknownResponse.class);
                throw new PlaidServersideUnknownResponseException(unknownResponse, statusCode);
            }

        } catch (IllegalStateException | IOException e) {

            throw new PlaidCommunicationsException("Unable to interpret Plaid response", e);
        } finally {

            try {
                response.close();
            } catch (IOException e) {

            }

        }

    }

    private static List mapToNvps(Map params) {
        List nvps = new ArrayList();
        for (Entry entry : params.entrySet()) {
            nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return nvps;
    }

    private static void addUserAgent(HttpMessage httpMessage) {
        httpMessage.addHeader("User-Agent", "plaid-java " + LIBRARY_VERSION);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy