Package com.dslplatform.client

Source Code of com.dslplatform.client.HttpClient$Response

package com.dslplatform.client;

import static org.apache.commons.codec.binary.Base64.encodeBase64;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;

import com.dslplatform.patterns.ServiceLocator;
import com.fasterxml.jackson.databind.JavaType;

class HttpClient {
    public static String encode(final String param) {
        try {
            return URLEncoder.encode(param, "UTF-8");
        }
        catch (final UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

// -----------------------------------------------------------------------------

    private static final SchemeRegistry schemeRegistry;
    private static final DefaultHttpClient httpClient;

    static {
        try {
            final String storeType = KeyStore.getDefaultType();
            final KeyStore truststore = KeyStore.getInstance(storeType);
            truststore.load(
                HttpClient.class.getResourceAsStream("common-cas." + storeType),
                "common-cas".toCharArray());

            schemeRegistry = new SchemeRegistry();
            schemeRegistry.register(new Scheme("https", 443, new AdditionalKeyStoresSSLSocketFactory(truststore) ));

            @SuppressWarnings("deprecation")
            final ClientConnectionManager cm =
                new org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager(schemeRegistry);

            httpClient = new DefaultHttpClient(cm);
        }
        catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }

//-----------------------------------------------------------------------------

    private final ServiceLocator locator;
    private final JsonSerialization json;
    private final Logger logger;
    private final ExecutorService executorService;

    private final String domainPrefix;
    private final int domainPrefixLength;


    public HttpClient(
            final ProjectSettings project,
            final ServiceLocator locator,
            final JsonSerialization json,
            final Logger logger,
            final ExecutorService executorService) throws IOException {
        this.locator = locator;
        this.json = json;
        this.logger = logger;
        this.executorService = executorService;

        this.remoteUrl = project.get("api-url");
        this.domainPrefix = project.get("package-name");
        this.domainPrefixLength = domainPrefix.length() + 1;

        if (logger.isDebugEnabled()) {
            logger.debug("Initialized with: \n    username [{}] \n    api: [{}] \n    pid: [{}]"
                , project.get("username")
                , project.get("api-url")
                , project.get("project-id")
                );
        }

        final String token = project.get("username") + ':' + project.get("project-id");
        basicAuth = "Basic " + new String(encodeBase64(token.getBytes("UTF-8")));
    }

    private final String remoteUrl;
    private final String basicAuth;
    private static final String MIME_TYPE = "application/json";

    static class Response {
        public final int code;
        public final byte[] body;

        public Response(final int code, final byte[] body) {
            this.code = code;
            this.body = body;
        }

        public String bodyToString() {
            return (body == null) ? "" : new String(body, java.nio.charset.Charset.forName("UTF-8"));
        }
    }

    private Response transmit(
            final String service,
            final Map<String, String> headers,
            final String method,
            final byte[] payload) throws IOException {

        final String url = remoteUrl + service;
        if (logger.isDebugEnabled()) {
            logger.debug("{} to URL: [{}]", method, url);
        }

        final HttpRequestBase req;
        if (method.equals("POST")) {
            final HttpPost post = new HttpPost(url);
            if(payload != null) {
                post.setEntity(new ByteArrayEntity(payload));
                if (logger.isTraceEnabled()) {
                    logger.trace("payload: [{}]", IOUtils.toString(post.getEntity().getContent()));
                }
            }
            req = post;
        } else if (method.equals("PUT")){
            final HttpPut put = new HttpPut(url);
            if(payload != null) {
                put.setEntity(new ByteArrayEntity(payload));
                if (logger.isTraceEnabled()) {
                    logger.trace("payload: [{}]", IOUtils.toString(put.getEntity().getContent()));
                }
            }
            req = put;
        } else if (method.equals("DELETE")) {
            req = new HttpDelete(url);
        } else {
            req = new HttpGet(url);
        }

        req.setHeader("Accept", MIME_TYPE);
        req.setHeader("Content-Type", MIME_TYPE);
        req.setHeader("Authorization", basicAuth);

        for (final Map.Entry<String, String> h : headers.entrySet()) {
          req.setHeader(h.getKey(), h.getValue());
        }

        if (logger.isTraceEnabled()) {
            for (final Header h : req.getAllHeaders()) {
                logger.trace("header:{}:{}", h.getName(), h.getValue());
            }
        }

        try {
            final HttpResponse response = httpClient.execute(req);

            final int code = response.getStatusLine().getStatusCode();
            final byte[] body = EntityUtils.toByteArray(response.getEntity());

            return new Response(code, body);
        }
        catch (final IOException e) {
            logger.error("{} to URL: [{}]", method, url);

            for (final Header h : req.getAllHeaders()) {
                logger.error("header:{}:{}", h.getName(), h.getValue());
            }

            if (req instanceof HttpEntityEnclosingRequest) {
                final HttpEntityEnclosingRequest heer = (HttpEntityEnclosingRequest)req;
                logger.error("payload:{}", EntityUtils.toString(heer.getEntity()));
            }
            throw e;
        }
        catch (final RuntimeException e) {
            logger.error("A runtime exception has occured while executing request", e);
            req.abort();
            throw e;
        }
        finally {
            req.releaseConnection();
        }
    }

    public String getDslName(final Class<?> clazz) {
        final String domainObjectName = clazz.getName();
        if(domainObjectName.startsWith(domainPrefix))
            return domainObjectName.substring(domainPrefixLength);
        throw new RuntimeException(domainObjectName + " is not defined for package " + domainPrefix);
    }

    private static boolean contains(final int[] array, final int v) {
        for (final int e : array) if (e == v) return true;
        return false;
    }
  //-----------------------------------------------------------------------------

    private <TArgument> Response doRawRequest(
            final String service,
            final Map<String, String> headers,
            final String method,
            final TArgument content,
            final int[] expected,
            final long start) throws UnsupportedEncodingException, IOException {

        final byte[] body;
        if (content == null) {
            body = null;

            if (logger.isDebugEnabled()) {
                logger.debug("Sending request [{}]: {}, no content", method, service);
            }
        }
        else {
            final String jsonBody = json.serialize(content);
            body = jsonBody.getBytes("UTF-8");

            if (logger.isDebugEnabled()) {
                logger.debug("Sending request [{}]: {}, content size: {} bytes", method, service, jsonBody.length());
            }
        }

        final Response response = transmit(service, headers, method, body);

        if (logger.isDebugEnabled()) {
            final long time = System.currentTimeMillis() - start;
            logger.debug("Received response [{}, {} bytes] in {} ms", response.code, response.body.length, time);

            if (logger.isTraceEnabled()) {
                logger.trace("Received response body: {}", response.bodyToString());
            }
        }

        if (expected != null && !contains(expected, response.code)) {
            throw new IOException("Unexpected return code: " + response.code + ", response: " + response.bodyToString());
        }
        else if(expected == null && response.code >= 300) {
            throw new IOException(response.bodyToString());
        }

        return response;
    }

    private static final Map<String, String> emptyHeaders = new java.util.HashMap<String, String>();

    public <TArgument> Future<byte[]> sendRawRequest(
            final String service,
            final String method,
            final TArgument content,
            final Map<String, String> headers,
            final int[] expected) {

        final long start = System.currentTimeMillis();

        return
            executorService.submit(new Callable<byte[]>() {
                @Override
                public byte[] call() throws IOException {
                    return doRawRequest(service, headers, method, content, expected, start).body;
                }
            });
    }

    public <TArgument, TResult> Future<TResult> sendRequest(
            final JavaType type,
            final String service,
            final String method,
            final TArgument content,
            final int[] expected) {

        final long start = System.currentTimeMillis();

        return
            executorService.submit(new Callable<TResult>() {
                @SuppressWarnings("unchecked")
                @Override
                public TResult call() throws IOException {
                    final Response response = doRawRequest(service, emptyHeaders, method, content, expected, start);

                    return type != null
                        ? (TResult)json.deserialize(type, response.bodyToString(), locator)
                        : null;
                }
            });
    }
}
TOP

Related Classes of com.dslplatform.client.HttpClient$Response

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.