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

com.trolley.Client Maven / Gradle / Ivy

The newest version!
package com.trolley;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import com.trolley.Exceptions.DownForMaintenanceException;
import com.trolley.Exceptions.InvalidServerConnectionException;
import com.trolley.Exceptions.TooManyRequestsException;
import com.trolley.types.supporting.HttpDeleteWithBody;
import com.trolley.Exceptions.InvalidStatusCodeException;
import com.trolley.Exceptions.NotFoundException;
import com.trolley.Exceptions.AuthorizationException;
import com.trolley.Exceptions.AuthenticationException;
import com.trolley.Exceptions.MalformedException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.entity.StringEntity;
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.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;

import java.io.IOException;
import java.rmi.UnexpectedException;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Client
{
    private Configuration config;
    private String trolleySourceString = "java-sdk_"+Version.MAJOR+"."+Version.MINOR+"."+Version.PATCH;
    
    public Client(final Configuration config) {
        this.config = config;
    }

    public static Client create(final Configuration config) {
        return new Client(config);
    }

    /**
     * Get the HttpClient.
     * If you don't specify an HttpClient object, this method will create a new one.
     * If you did specify an HttpClient object in Configuration, that object will be used instead.
     * @return HttpClient
     */
    private HttpClient getHttpClient(){
        if(null != this.config.getHttpClient()){
            return this.config.getHttpClient();
        }else{
            return (HttpClient)HttpClients.createSystem();
        }
    }
    
    public String get(final String endpoint) throws Exception {
        final HttpClient httpclient = getHttpClient();
        final HttpGet httpGet = new HttpGet(this.config.getApiBase() + endpoint);

        httpGet.setHeaders(getHeaders("GET", endpoint, ""));

        // execute request
        final HttpResponse response = httpclient.execute((HttpUriRequest)httpGet);
        
        // process response
        return processResponse(response);
    }
    
    public String post(final String endpoint, final String body) throws Exception {
        final HttpClient httpclient = getHttpClient();
        final HttpPost httpPatch = new HttpPost(this.config.getApiBase() + endpoint);
        final StringEntity params = new StringEntity(body);
        httpPatch.setEntity((HttpEntity)params);

        httpPatch.setHeaders(getHeaders("POST", endpoint, body));

        // execute request
        final HttpResponse response = httpclient.execute((HttpUriRequest)httpPatch);
        
        // process response
        return processResponse(response);
    }
    
    public String post(final String endpoint) throws Exception {
        final HttpClient httpclient = getHttpClient();
        final HttpPost httpPatch = new HttpPost(this.config.getApiBase() + endpoint);
        final StringEntity params = new StringEntity("");
        httpPatch.setEntity((HttpEntity)params);

        httpPatch.setHeaders(getHeaders("POST", endpoint, ""));

        // execute request
        final HttpResponse response = httpclient.execute((HttpUriRequest)httpPatch);
        
        // process response
        return processResponse(response);
    }
    
    public String patch(final String endpoint, final String body) throws Exception {
        final HttpClient httpclient = getHttpClient();
        final HttpPatch httpPatch = new HttpPatch(this.config.getApiBase() + endpoint);
        final StringEntity params = new StringEntity(body);
        httpPatch.setEntity((HttpEntity)params);

        httpPatch.setHeaders(getHeaders("PATCH", endpoint, body));

        // execute request
        final HttpResponse response = httpclient.execute((HttpUriRequest)httpPatch);
        
        // process response
        return processResponse(response);
    }
    
    public String delete(final String endpoint) throws Exception {
        final HttpClient httpclient = getHttpClient();
        final HttpDelete httpDelete = new HttpDelete(this.config.getApiBase() + endpoint);
        httpDelete.setHeaders(getHeaders("DELETE", endpoint, ""));

        // execute request
        final HttpResponse response = httpclient.execute((HttpUriRequest)httpDelete);
        
        // process response
        return processResponse(response);
    }

    /**
     * Supports DELETE request with a body.
     * @param endpoint
     * @param body
     * @return
     * @throws Exception
     */
    public String delete(final String endpoint, final String body) throws Exception {
        final HttpClient httpclient = getHttpClient();
        final HttpDeleteWithBody httpDeleteWithBody = new HttpDeleteWithBody(this.config.getApiBase() + endpoint);
        final StringEntity params = new StringEntity(body);
        httpDeleteWithBody.setEntity((HttpEntity)params);


        httpDeleteWithBody.setHeaders(getHeaders("DELETE", endpoint, body));

        // execute request
        final HttpResponse response = httpclient.execute((HttpUriRequest)httpDeleteWithBody);
        
        // process response
        return processResponse(response);
    }
    
    private void throwStatusCodeException(final int statusCode, final String message) throws Exception {
        switch (statusCode) {
            case 400: {
                throw new MalformedException(message);
            }
            case 401: {
                throw new AuthenticationException(message);
            }
            case 403: {
                throw new AuthorizationException(message);
            }
            case 404: {
                throw new NotFoundException(statusCode + " " + message);
            }
            case 406: {
                throw new InvalidStatusCodeException(message);
            }
            case 429: {
                throw new TooManyRequestsException(message);
            }
            case 500: {
                throw new InvalidServerConnectionException(message);
            }
            case 503: {
                throw new DownForMaintenanceException(message);
            }
            default: {
                throw new com.trolley.Exceptions.UnexpectedException(message);
            }
        }
    }
    
    private String generateAuthorization(final int timeStamp, final String method, final String endPoint, final String body) {
        final String message = timeStamp + "\n" + method + "\n" + endPoint + "\n" + body + "\n";
        try {
            final String hash = this.hmacDigest(message, this.config.getPrivateKey(), "HmacSHA256");
            return "prsign " + this.config.getPublicKey() + ":" + hash;
        }
        catch (Exception e) {
            return "prsign 1:1";
        }
    }
    
    private String hmacDigest(final String msg, final String keyString, final String algo) throws Exception {
        String digest = null;
        final SecretKeySpec key = new SecretKeySpec(keyString.getBytes("UTF-8"), algo);
        final Mac mac = Mac.getInstance(algo);
        mac.init(key);
        final byte[] bytes = mac.doFinal(msg.getBytes("ASCII"));
        final StringBuffer hash = new StringBuffer();
        for (int i = 0; i < bytes.length; ++i) {
            final String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                hash.append('0');
            }
            hash.append(hex);
        }
        digest = hash.toString();
        return digest;
    }

    /**
     * Process and return the response received after the calls made with HttpClient.
     * @param response
     * @return
     * @throws Exception
     */
    String processResponse(HttpResponse response) throws Exception{
        String responseStr = "";
        try{
            final StringBuffer result = new StringBuffer();
            String line = "";
            final BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            while ((line = rd.readLine()) != null) {
                result.append(line);
            }
            responseStr = result.toString();
            final int responseCode = response.getStatusLine().getStatusCode();
            if (responseCode != 200) {
                this.throwStatusCodeException(responseCode, responseStr);
            }
        }catch (IOException e) {
            throw new UnexpectedException(responseStr);
        }

        return responseStr;
    }

    /**
     * Returns an array of type {@code Header} for different requests to use.
     * @param method
     * @param endpoint
     * @param body
     * @return
     */
    private Header[] getHeaders(String method, String endpoint, String body){
        final int timestamp = ((int)(System.currentTimeMillis() / 1000L));
        final String authorizarion = this.generateAuthorization(timestamp, method, endpoint, body);

        return new Header[]{
                new BasicHeader("Content-Type", "application/json"),
                new BasicHeader("X-PR-Timestamp", ""+timestamp),
                new BasicHeader("Authorization", authorizarion),
                new BasicHeader("Trolley-Source", trolleySourceString)
            };
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy