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

br.com.cefis.ClientCefis Maven / Gradle / Ivy

There is a newer version: 0.0.2
Show newest version
package br.com.cefis;

import br.com.cefis.authentication.Authentication;
import br.com.cefis.exception.CefisException;
import br.com.cefis.exception.UnauthorizedException;
import br.com.cefis.exception.UnexpectedException;
import br.com.cefis.exception.ValidationException;
import br.com.cefis.resource.Errors;
import br.com.cefis.ssl.SSLSupport;
import br.com.cefis.util.GsonFactory;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import static br.com.cefis.util.DataHelper.jsonToUrlEncodedString;

public class ClientCefis {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientCefis.class);
    public static final String PRODUCTION = "https://cefis.com.br";
    public static final String SANDBOX = "https://cefis.com.br.local";
    private static String USER_AGENT;

    static {
        try {
            InputStream inputStream = ClientCefis.class.getResourceAsStream("/cefisJavaSDK.properties");
            Properties properties = new Properties();
            properties.load(inputStream);

            USER_AGENT = properties.getProperty("userAgent");
        } catch (Exception e) {
            USER_AGENT = "CEFISJavaSDK/UnknownVersion (+https://bitbucket.org/cefis/cefis-sdk-java)";
        }
    }

    private final String endpoint;
    private final Authentication authentication;
    private final Gson gson;

    public ClientCefis(final String endpoint, final Authentication authentication) {
        this.endpoint = endpoint;
        this.authentication = authentication;
        this.gson = GsonFactory.gson();
    }

    public  T post(final String path, final Class type) {
        RequestProps props = RequestPropsBuilder.requestPropsBuilder().method("POST").path(path).type(type).contentType(ContentType.APPLICATION_JSON);
        return doRequest(props);
    }

    public  T post(final String path, final Object object, final Class type) {
        RequestProps props = RequestPropsBuilder.requestPropsBuilder().method("POST").path(path).object(object).type(type).contentType(ContentType.APPLICATION_JSON);
        return doRequest(props);
    }

    public  T post(final String path, final Object object, final Class type, ContentType contentType) {
        RequestProps props = RequestPropsBuilder.requestPropsBuilder().method("POST").path(path).object(object).type(type).contentType(contentType);
        return doRequest(props);
    }

    public  T put(final String path, final Object object, final Class type) {
        RequestProps props = RequestPropsBuilder.requestPropsBuilder().method("PUT").path(path).object(object).type(type).contentType(ContentType.APPLICATION_JSON);
        return doRequest(props);
    }

    public  T get(String path, Class type) {
        RequestProps props = RequestPropsBuilder.requestPropsBuilder().method("GET").path(path).type(type).contentType(ContentType.APPLICATION_JSON);
        return doRequest(props);
    }

    public  T get(String path, Class type, String acceptVersion) {
        RequestProps props = RequestPropsBuilder.requestPropsBuilder().method("GET").path(path).type(type).contentType(ContentType.APPLICATION_JSON).accept(acceptVersion);
        return doRequest(props);
    }

    public  T delete(String path, Class type) {
        RequestProps props = RequestPropsBuilder.requestPropsBuilder().method("DELETE").path(path).object(null).type(type).contentType(ContentType.APPLICATION_JSON);
        return doRequest(props);
    }

    private  T doRequest(final RequestProps requestProps) {
        try {
            URL url = new URL(endpoint + requestProps.path);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestProperty("User-Agent", USER_AGENT);
            conn.setRequestProperty("Content-type", requestProps.contentType.getMimeType());
            if (requestProps.accept != null) conn.setRequestProperty("Accept", requestProps.accept);

            conn.setRequestMethod(requestProps.method);

            // Disable TLS 1.0
            if (conn instanceof HttpsURLConnection) {
                ((HttpsURLConnection) conn).setSSLSocketFactory(new SSLSupport());
            }

            if (authentication != null) {
                authentication.authenticate(conn);
            }

            LOGGER.debug("---> {} {}", requestProps.method, conn.getURL().toString());
            logHeaders(conn.getRequestProperties().entrySet());

            if (requestProps.object != null) {
                conn.setDoOutput(true);
                String body = getBody(requestProps.object, requestProps.contentType);

                LOGGER.debug("{}", body);

                DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(wr, "UTF-8"));
                writer.write(body);
                writer.close();
                wr.flush();
                wr.close();
            }

            LOGGER.debug("---> END HTTP");

            int responseCode = conn.getResponseCode();

            LOGGER.debug("<--- {} {}", responseCode, conn.getResponseMessage());
            logHeaders(conn.getHeaderFields().entrySet());

            StringBuilder responseBody = new StringBuilder();

            responseBody = responseBodyTreatment(responseBody, responseCode, conn);

            LOGGER.debug("{}", responseBody.toString());
            LOGGER.debug("<-- END HTTP ({}-byte body)", conn.getContentLength());

            return gson.fromJson(responseBody.toString(), requestProps.getType());
        } catch (IOException | KeyManagementException | NoSuchAlgorithmException e) {
            throw new CefisException("Error occurred connecting to Cefis API: " + e.getMessage(), e);
        }
    }

    private StringBuilder responseBodyTreatment(StringBuilder responseBody, int responseCode, HttpURLConnection conn) {

        try {

            if (responseCode >= 200 && responseCode < 299) {
                responseBody = readBody(conn.getInputStream());
            }

            if (responseCode == 401) {
                throw new UnauthorizedException();
            }

            if (responseCode >= 400 && responseCode < 499) {
                responseBody = readBody(conn.getErrorStream());
                LOGGER.debug("API ERROR {}", responseBody.toString());

                Errors errors = new Errors();

                try {

                    errors = gson.fromJson(responseBody.toString(), Errors.class);

                } catch (Exception e) {

                    LOGGER.debug("There was not possible cast the JSON to object");
                }

                throw new ValidationException(responseCode, conn.getResponseMessage(), errors);
            }

            if (responseCode >= 500) {
                throw new UnexpectedException();
            }

        } catch (IOException e) {
            throw new CefisException("Error occurred connecting to Cefis API: " + e.getMessage(), e);
        }

        return responseBody;
    }

    private void logHeaders(Set>> entries) {
        for (Map.Entry> header : entries) {
            if (header.getKey() != null) {
                LOGGER.debug("{}: {}", header.getKey(), header.getValue());
            }
        }
    }

    private StringBuilder readBody(final InputStream inputStream) throws IOException {
        StringBuilder body = new StringBuilder();
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));

        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            body.append(inputLine);
        }
        in.close();

        return body;
    }

    private String getBody(Object object, ContentType contentType) {
        if (contentType == ContentType.APPLICATION_FORM_URLENCODED) {
            return jsonToUrlEncodedString((JsonObject) new JsonParser().parse(gson.toJson(object)));
        }

        return gson.toJson(object);
    }

    public Authentication getAuthentication() {
        return authentication;
    }

    public String getEndpoint() {
        return endpoint;
    }

    private static class RequestProps {

        protected String method;
        protected String path;
        protected Object object;
        protected Class type;
        protected ContentType contentType;
        protected String accept;

        public RequestProps() {}

        public String getMethod() { return method; }

        public String getPath() { return path; }

        public Object getObject() { return object; }

        public  Class getType() { return type; }

        public ContentType getContentType() { return contentType; }

        public String getAccept() { return accept; }
    }

    private static class RequestPropsBuilder extends RequestProps {

        public static RequestPropsBuilder requestPropsBuilder() {
            return new RequestPropsBuilder();
        }

        public RequestPropsBuilder method(String method) {
            this.method = method;
            return this;
        }

        public RequestPropsBuilder path(String path) {
            this.path = path;
            return this;
        }

        public RequestPropsBuilder object(Object object) {
            this.object = object;
            return this;
        }

        public RequestPropsBuilder type(Class type) {
            this.type = type;
            return this;
        }

        public RequestPropsBuilder contentType(ContentType contentType) {
            this.contentType = contentType;
            return this;
        }

        public RequestPropsBuilder accept(String acceptVersion) {
            this.accept = acceptBuilder(acceptVersion);
            return this;
        }

        public String acceptBuilder(String version) {
            String value = "application/json";
            if(version == "2.1") value += ";version=" + version;
            return value;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy