
com.harrys.hyppo.client.v1.HyppoHttpClient Maven / Gradle / Ivy
The newest version!
package com.harrys.hyppo.client.v1;
import com.harrys.hyppo.client.v1.error.HyppoAuthException;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.time.Clock;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by jpetty on 12/18/15.
*/
public final class HyppoHttpClient {
private static final Logger log = LoggerFactory.getLogger(HyppoHttpClient.class);
private final HyppoClientConfig config;
public HyppoHttpClient(final HyppoClientConfig config) {
this.config = config;
}
public T executeDelete(final String path, final ResponseHandler handler) throws IOException {
return executeDelete(path, Collections.emptyList(), handler);
}
public T executeDelete(final String path, final List queryParams, final ResponseHandler handler) throws IOException {
final HttpDelete request = new HttpDelete(requestURI(path, queryParams));
attachSignature(request, queryParams, new byte[0]);
return executeRequest(request, handler);
}
public T executeGet(final String path, final ResponseHandler handler) throws IOException {
return executeGet(path, Collections.emptyList(), handler);
}
public T executeGet(final String path, final List queryParams, final ResponseHandler handler) throws IOException {
final HttpGet request = new HttpGet(requestURI(path, queryParams));
attachSignature(request, queryParams, new byte[0]);
return executeRequest(request, handler);
}
public T executePost(final String path, final String body, final ResponseHandler handler) throws IOException {
return executePost(path, Collections.emptyList(), body, handler);
}
public T executePost(final String path, final List params, final String body, final ResponseHandler handler) throws IOException {
final HttpPost request = new HttpPost(requestURI(path, params));
request.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON));
attachSignature(request, params, body.getBytes(StandardCharsets.UTF_8));
return executeRequest(request, handler);
}
private T executeRequest(final HttpUriRequest request, final ResponseHandler handler) throws IOException {
final CloseableHttpClient client = createClientInstance();
try {
final CloseableHttpResponse response = client.execute(request);
// Wrap the response in a buffer to facilitate error handlers re-playing the content if the response
// size is smaller than the max allowable buffer
if (response.getEntity().getContentLength() >= 0 && response.getEntity().getContentLength() < config.getMaxBufferSize()) {
EntityUtils.updateEntity(response, new BufferedHttpEntity(response.getEntity()));
}
// Explicit check for the authorization status of the API key
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED){
throw new HyppoAuthException(config);
}
try {
log.debug("{} - {} : {}", request.getMethod(), request.getURI().getPath(), response.getStatusLine().getStatusCode());
return handler.handleResponse(response);
} finally {
IOUtils.closeQuietly(response);
}
} catch (Exception e) {
log.error("{} - {} : FAILED - {}", request.getMethod(), request.getURI().getPath(), e.toString());
throw e;
} finally {
IOUtils.closeQuietly(client);
}
}
private void attachSignature(final HttpUriRequest request, final List params, final byte[] content) {
final RequestDigestBuffer digest =
RequestDigestBuffer.newBuilder(config)
.withMethod(request.getMethod())
.withPath(request.getURI().getPath())
.withQueryParams(params)
.withTimestamp(Instant.now(Clock.systemUTC()).toEpochMilli())
.build();
final byte[] signature = digest.doFinal(content);
for (final Header h : digest.requestHeaders(signature)){
request.addHeader(h);
}
}
private CloseableHttpClient createClientInstance(){
final RequestConfig requestConfig = RequestConfig.copy(RequestConfig.DEFAULT)
.setConnectionRequestTimeout((int)config.getConnectTimeout().toMillis())
.setSocketTimeout((int)config.getConnectTimeout().toMillis())
.build();
final List headers = new ArrayList<>(1);
headers.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType()));
return HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setDefaultHeaders(headers)
.build();
}
private URI requestURI(final String path, final List queryParams) {
try {
return new URIBuilder(config.getBaseURI())
.setPath(path)
.setParameters(queryParams)
.build();
} catch (URISyntaxException use) {
String paramString = "";
for (final NameValuePair nvp : queryParams) {
paramString += "'" + nvp.getName() + "' -> '" + nvp.getValue() + "'";
}
throw new IllegalArgumentException("Invalid URI for path='" + path + "' params=" + paramString, use);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy