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

io.hypertrack.net.HyperTrackClient Maven / Gradle / Ivy

The newest version!
package io.hypertrack.net;

import com.google.gson.Gson;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

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

/**
 * Class for HyperTrack client that makes requests to the HyperTrack API server.
 */
public class HyperTrackClient {
    /**
     * API endpoint.
     */
    private String endpoint = "https://api.hypertrack.com/api/v1";

    /**
     * SDK version and user agent.
     */
    private String VERSION = "1.0.0";
    private String userAgent = "HyperTrack/v1 JavaBindings/" + VERSION;

    /**
     * Http client.
     */
    private HttpClient httpClient;

    /**
     * Account keys.
     */
    private String secretKey;

    /**
     * Instantiates the client object with account keys on app.hypertrack.io
     *
     * @param secretKey Account secret key
     */
    public HyperTrackClient(final String secretKey) {
        this(secretKey, null);
    }

    /**
     * Instantiates the client object with account keys and custom API url.
     *
     * @param secretKey Account secret key
     * @param endpoint  API url for client
     */
    public HyperTrackClient(final String secretKey, final String endpoint) {
        this.secretKey = secretKey;

        if (endpoint != null) {
            this.endpoint = endpoint;
        }

        httpClient = HttpClients.createDefault();
    }

    /**
     * Method to call requests on client and return response as String.
     *
     * @param path   Endpoint path of request
     * @param method Request method, supports GET, POST, PATCH and DELETE
     * @param data   Request data, for params in GET or body in POST/PATCH requests
     * @return Response as String object
     * @throws HyperTrackException
     */
    public String request(final String path, final String method,
                          final Map data) throws HyperTrackException {
        HttpUriRequest request = setupRequest(path, method, data);
        return executeRequest(request);
    }

    /**
     * Method to call PATCH requests on client for file uploads.
     *
     * @param path      API endpoint to be PATCHed
     * @param fileParam Files to be uploaded with key names
     * @return Response as String object
     * @throws HyperTrackException
     */
    public String request(final String path, Map fileParam) throws HyperTrackException {
        MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();

        for (String key : fileParam.keySet()) {
            multipartEntity.addBinaryBody(key, fileParam.get(key));
        }

        HttpPatch request = (HttpPatch) setupRequest(path, "PATCH", null);
        request.setEntity(multipartEntity.build());
        request.removeHeaders("Content-Type");
        return executeRequest(request);
    }

    /**
     * Method to execute requests.
     *
     * @param request Request to be executed
     * @return Response as String
     * @throws HyperTrackException
     */
    private String executeRequest(HttpUriRequest request) throws HyperTrackException {
        HttpResponse response;

        try {
            response = httpClient.execute(request);

            if (validateResponse(response)) {
                HttpEntity entity = response.getEntity();
                String responseBody = "";

                if (entity != null) {
                    responseBody = EntityUtils.toString(entity, "UTF-8");
                }

                return responseBody;
            } else {
                throw HyperTrackException.parseResponse(response);
            }
        } catch (final ClientProtocolException e) {
            e.printStackTrace();
            throw new HyperTrackException(e.getMessage(), e);
        } catch (final IOException e) {
            e.printStackTrace();
            throw new HyperTrackException(e.getMessage(), e);
        }
    }

    /**
     * Setup the request with headers, parameters and body.
     *
     * @param data   Request parameters
     * @param path   Request endpoint
     * @param method Request method
     * @param data
     * @return Request object with parameters and headers
     */
    private HttpUriRequest setupRequest(final String path, final String method, Map data) {
        String normalizedPath = path.toLowerCase();
        StringBuilder sb = new StringBuilder();

        // If we are given a fully qualified uri then skip building the endpoint
        if (normalizedPath.startsWith("http://") || normalizedPath.startsWith("https://")) {
            sb.append(path);
        } else {
            sb.append(this.endpoint);

            if (!normalizedPath.startsWith("/")) {
                sb.append("/");
            }
            sb.append(normalizedPath);
        }
        String url = sb.toString();
        HttpUriRequest request = buildMethod(url, method, data);

        request.addHeader(new BasicHeader("Authorization", "token " + this.secretKey));
        request.addHeader(new BasicHeader("User-Agent", this.userAgent));
        request.addHeader(new BasicHeader("Accept", "application/json"));
        request.addHeader(new BasicHeader("Content-Type", "application/json"));
        request.addHeader(new BasicHeader("Accept-Charset", "utf-8"));

        return request;
    }

    /**
     * Builds request object with parameters and method.
     *
     * @param path   Request endpoint
     * @param method Request method
     * @param params Request parameters
     * @return Request object with parameters
     */
    private HttpUriRequest buildMethod(final String path, final String method,
                                       final Map params) {
        if (method.equalsIgnoreCase("GET")) {
            URI uri = buildUri(path, params);
            return new HttpGet(uri);
        } else if (method.equalsIgnoreCase("POST")) {
            URI uri = buildUri(path, null);
            StringEntity entity = buildEntityBody(params);
            HttpPost post = new HttpPost(uri);
            post.setEntity(entity);
            return post;
        } else if (method.equalsIgnoreCase("DELETE")) {
            URI uri = buildUri(path, null);
            return new HttpDelete(uri);
        } else if (method.equalsIgnoreCase("PATCH")) {
            URI uri = buildUri(path, null);
            StringEntity entity = buildEntityBody(params);
            HttpPatch patch = new HttpPatch(uri);
            patch.setEntity(entity);
            return patch;
        } else {
            throw new IllegalArgumentException("Unknown HTTP method: " + method);
        }
    }

    /**
     * Build uri, with GET parameters if applicable.
     *
     * @param path   Request endpoint
     * @param params GET parameters
     * @return Uri object
     */
    private URI buildUri(final String path, final Map params) {
        StringBuilder sb = new StringBuilder();
        sb.append(path);

        if (params != null && params.size() > 0) {
            sb.append("?");
            List paramsList = getListFromMap(params);
            sb.append(URLEncodedUtils.format(paramsList, "UTF-8"));
        }

        URI uri;
        try {
            uri = new URI(sb.toString());
        } catch (final URISyntaxException e) {
            throw new IllegalArgumentException("Invalid uri", e);
        }

        return uri;
    }

    /**
     * Build body for POST and PATCH requests.
     *
     * @param params Body properties
     * @return Body object
     */
    private StringEntity buildEntityBody(final Map params) {
        Gson gson = new Gson();
        Map> temp = new HashMap<>();

        String paramsJson = gson.toJson(params);
        try {
            return new StringEntity(paramsJson);
        } catch (final UnsupportedEncodingException e) {
            throw new IllegalArgumentException("Invalid parameters", e);
        }
    }

    /**
     * Get list of NameValuePairs from a Map.
     *
     * @param params Map to be converted
     * @return List of NameValuePairs
     */
    private ArrayList getListFromMap(Map params) {
        ArrayList paramsList = new ArrayList();
        for (Map.Entry entry : params.entrySet()) {
            NameValuePair pair = new BasicNameValuePair(entry.getKey(), (String) entry.getValue());
            paramsList.add(pair);
        }
        return paramsList;
    }

    /**
     * Convert POJO params to String params.
     *
     * @param params Params to be converted
     * @return Converted params
     */
    private Map paramsToString(Map params) {
        if (params != null) {
            Map paramsInString = new HashMap<>();
            for (Map.Entry entry : params.entrySet()) {
                paramsInString.put(entry.getKey(), entry.getValue().toString());
            }
            return paramsInString;
        }
        return null;
    }

    /**
     * Validate response by status code.
     *
     * @param response Response object to be validated
     * @return True if valid, false otherwise
     */
    private boolean validateResponse(HttpResponse response) {
        int statusCode = response.getStatusLine().getStatusCode();
        return statusCode >= 200 && statusCode < 300;
    }

    /**
     * Return endpoint of client.
     *
     * @return Endpoint url
     */
    public String getEndpoint() {
        return endpoint;
    }

    /**
     * Return http client.
     *
     * @return Http client
     */
    public HttpClient getHttpClient() {
        return httpClient;
    }

    /**
     * Set http client.
     *
     * @param httpClient Http client to be set
     */
    public void setHttpClient(HttpClient httpClient) {
        this.httpClient = httpClient;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy