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

io.elastic.sailor.impl.HttpUtils Maven / Gradle / Ivy

There is a newer version: 4.0.3
Show newest version
package io.elastic.sailor.impl;

import io.elastic.api.JSON;
import io.elastic.sailor.UnexpectedStatusCodeException;
import org.apache.commons.io.IOUtils;
import org.apache.http.*;

import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.json.JsonObject;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.net.URLDecoder;

public class HttpUtils {

    private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class.getName());

    public static String postJson(String url, JsonObject body, AuthorizationHandler authorizationHandler) throws IOException {
        return postJson(url, body, authorizationHandler, 0);
    }

    public static JsonObject getJson(String url, final AuthorizationHandler authorizationHandler) {
        return getJson(url, authorizationHandler, 0);
    }

    public static JsonObject putJson(final String url,
                                     final JsonObject body,
                                     final AuthorizationHandler authorizationHandler) {
        return putJson(url, body, authorizationHandler, 0);
    }

    public static String postJson(final String url,
                                  final JsonObject body,
                                  final AuthorizationHandler authorizationHandler,
                                  final int retryCount) {


        final HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
        httpPost.setEntity(createStringEntity(body));

        final byte[] bytes = sendHttpRequest(
                httpPost, authorizationHandler, retryCount, new ByteArrayHttpEntityCallback());

        if (bytes == null) {
            throw new RuntimeException("Null response received");
        }

        logger.info("Successfully posted json {} bytes length", body.toString().length());

        return new String(bytes);
    }

    public static JsonObject post(final String url,
                              final HttpEntity body,
                              final AuthorizationHandler authorizationHandler,
                              final int retryCount) {


        final HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(body);

        final JsonObject result = sendHttpRequest(
                httpPost, authorizationHandler, retryCount, new JsonObjectParseCallback());

        if (result == null) {
            throw new RuntimeException("Null response received");
        }

        logger.info("Successfully posted content");

        return result;
    }

    public static JsonObject getJson(final String url,
                                     final AuthorizationHandler authorizationHandler,
                                     int retryCount) {

        final HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader(HTTP.USER_AGENT, "eio-sailor-java");

        final JsonObject content = sendHttpRequest(
                httpGet, authorizationHandler, retryCount, new JsonObjectParseCallback());

        if (content == null) {
            throw new RuntimeException("Null response received");
        }

        return content;
    }

    public static byte[] get(final String url,
                                 final AuthorizationHandler authorizationHandler,
                                 int retryCount) {

        final HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader(HTTP.USER_AGENT, "eio-sailor-java");

        final byte[] content = sendHttpRequest(
                httpGet, authorizationHandler, retryCount, new ByteArrayHttpEntityCallback());

        if (content == null) {
            throw new RuntimeException("Null response received");
        }

        return content;
    }


    public static JsonObject putJson(final String url,
                                     final JsonObject body,
                                     final AuthorizationHandler authorizationHandler,
                                     final int retryCount) {

        final HttpPut httpPut = new HttpPut(url);
        httpPut.addHeader(HTTP.CONTENT_TYPE, "application/json");
        httpPut.setEntity(createStringEntity(body));

        final JsonObject content = sendHttpRequest(
                httpPut, authorizationHandler, retryCount, new JsonObjectParseCallback());

        if (content == null) {
            throw new RuntimeException("Null response received");
        }

        logger.info("Successfully put json {} bytes length", body.toString().length());

        return content;
    }


    public static void delete(final String url,
                              final AuthorizationHandler authorizationHandler,
                              final int retryCount) {

        final HttpDelete httpDelete = new HttpDelete(url);
        httpDelete.addHeader(HTTP.CONTENT_TYPE, "application/json");

        sendHttpRequest(httpDelete, authorizationHandler, retryCount, null);

        logger.info("Successfully sent delete");

        return;
    }

    public static StringEntity createStringEntity(final JsonObject body) {
        return createStringEntity(JSON.stringify(body));
    }

    public static StringEntity createStringEntity(final String content) {
        try {
            return new StringEntity(content);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    private static   T sendHttpRequest(final HttpUriRequest request,
                                        final AuthorizationHandler authorizationHandler,
                                        final int retryCount,
                                        final HttpEntityCallback callback) {

        CloseableHttpClient httpClient = HttpClients.custom()
                .setRetryHandler((exception, executionCount, context) -> {
                    if (executionCount >= retryCount) {
                        // Do not retry if over max retry count
                        return false;
                    }
                    if (exception instanceof InterruptedIOException) {
                        // Timeout
                        return true;
                    }
                    if (exception instanceof SocketException) {
                        return true;
                    }

                    return false;
                })
                .build();

        logger.info("Sending {} request to {}", request.getMethod(), request.getURI().getPath());
        try {
            authorizationHandler.authorize(request);
            final CloseableHttpResponse response = httpClient.execute(request);
            final StatusLine statusLine = response.getStatusLine();
            final int statusCode = statusLine.getStatusCode();
            logger.info("Got {} response", statusCode);
            if (statusCode >= 400) {
                throw new UnexpectedStatusCodeException(statusCode);
            }

            final HttpEntity responseEntity = response.getEntity();

            if (responseEntity == null || callback == null) {
                return null;
            }

            final T result = callback.handle(responseEntity);

            EntityUtils.consume(responseEntity);

            return result;

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private interface HttpEntityCallback {
        T handle(HttpEntity entity);
    }

    private static class JsonObjectParseCallback implements HttpEntityCallback {

        @Override
        public JsonObject handle(HttpEntity entity) {
            if (entity == null) {
                throw new RuntimeException("Null response received");
            }

            return JSON.parseObject(consumeToString(entity));
        }
    }

    private static class ByteArrayHttpEntityCallback implements HttpEntityCallback {
        @Override
        public byte[] handle(HttpEntity entity) {
            try {
                return IOUtils.toByteArray(entity.getContent());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }


    private static UsernamePasswordCredentials retrieveCredentialsFromUrl(final URL url) {
        final String userInfo = url.getUserInfo();

        if (userInfo == null) {
            throw new IllegalArgumentException("User info is missing in the given url: " + url);
        }


        String decodedUserInfo = urlDecode(userInfo);

        final String[] userAndPassword = decodedUserInfo.split(":");

        if (userAndPassword.length != 2) {
            throw new IllegalArgumentException("Either username or password is missing");
        }

        return new UsernamePasswordCredentials(userAndPassword[0], userAndPassword[1]);
    }

    private static String urlDecode(final String input) {
        try {
            return URLDecoder.decode(input, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }


    private static String consumeToString(final HttpEntity entity) {
        String result;
        try {
            result = EntityUtils.toString(entity);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        consume(entity);

        return result;
    }

    public static void consume(final HttpEntity entity) {
        try {
            EntityUtils.consume(entity);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public interface AuthorizationHandler {

        void authorize(final HttpUriRequest request);
    }

    static abstract class AbstractBasicAuthorizationHandler implements AuthorizationHandler {

        abstract UsernamePasswordCredentials createCredentials(HttpUriRequest request);

        @Override
        public void authorize(HttpUriRequest request) {

            try {
                final Header header = new BasicScheme()
                        .authenticate(createCredentials(request), request, null);
                request.addHeader(header);
            } catch (AuthenticationException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static class BasicAuthorizationHandler extends AbstractBasicAuthorizationHandler {
        private UsernamePasswordCredentials credentials;

        public BasicAuthorizationHandler(final String username, final String password) {
            this.credentials = new UsernamePasswordCredentials(username, password);
        }

        @Override
        UsernamePasswordCredentials createCredentials(final HttpUriRequest request) {
            return credentials;
        }

        public String getUsername() {
            return credentials.getUserName();
        }
    }

    public static class BasicURLAuthorizationHandler extends AbstractBasicAuthorizationHandler {

        @Override
        UsernamePasswordCredentials createCredentials(final HttpUriRequest request) {
            final URL url = getRequestURL(request);
            return retrieveCredentialsFromUrl(url);
        }

        private URL getRequestURL(final HttpUriRequest request) {
            try {
                return request.getURI().toURL();
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static class BearerAuthorizationHandler implements AuthorizationHandler {
        private String token;

        public BearerAuthorizationHandler(final String token) {
            this.token = token;
        }

        @Override
        public void authorize(HttpUriRequest request) {
            request.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy