org.alfresco.dataprep.AlfrescoHttpClient.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.dataprep.AlfrescoHttpClient.java

Source

/*
 * Copyright (C) 2005-2015 Alfresco Software Limited.
 * This file is part of Alfresco
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 */
package org.alfresco.dataprep;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
 * Helper class that provides HttpClient.
 * 
 * @author Michael Suzuki
 */
public class AlfrescoHttpClient {
    private static Log logger = LogFactory.getLog(AlfrescoHttpClient.class);
    public static final String UTF_8_ENCODING = "UTF-8";
    public static final String MIME_TYPE_JSON = "application/json";
    public static String ALFRESCO_API_PATH = "alfresco/service/api/";
    public static String ALFRESCO_API_VERSION = "-default-/public/alfresco/versions/1/";
    private CloseableHttpClient client;
    private String scheme;
    private String host;
    private int port;
    private int sharePort;
    private String apiUrl;
    private String alfrescoUrl;

    public AlfrescoHttpClient(final String scheme, final String host, final int port, final int sharePort) {
        this.scheme = scheme;
        this.host = host;
        this.port = port;
        this.sharePort = sharePort;
        apiUrl = String.format("%s://%s:%d/%s", scheme, host, port, ALFRESCO_API_PATH);
        client = HttpClientBuilder.create().build();
    }

    public String getApiVersionUrl() {
        String versionApi = getApiUrl().replace("/service", "");
        return versionApi + ALFRESCO_API_VERSION;
    }

    /**
     * Generates an Alfresco Authentication Ticket based on the user name and password passed in.
     * @param username user identifier
     * @param password user password
     * @return String authentication ticket
     */
    public String getAlfTicket(String username, String password) {
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            throw new IllegalArgumentException("Username and password are required");
        }
        String targetUrl = apiUrl + "login?u=" + username + "&pw=" + password + "&format=json";
        try {
            URL url = new URL(apiUrl + "login?u=" + username + "&pw=" + password + "&format=json");
            URLConnection con = url.openConnection();
            InputStream in = con.getInputStream();
            String encoding = con.getContentEncoding();
            encoding = encoding == null ? UTF_8_ENCODING : encoding;
            String json = IOUtils.toString(in, encoding);
            JSONParser parser = new JSONParser();
            JSONObject obj = (JSONObject) parser.parse(json);
            JSONObject data = (JSONObject) obj.get("data");
            return (String) data.get("ticket");
        } catch (IOException | ParseException e) {
            logger.error(String.format("Unable to generate ticket, url: %s", targetUrl), e);
        }
        throw new RuntimeException("Unable to get ticket");
    }

    /**
     * Get the alfresco version
     * @return String version of alfresco
     */
    public String getAlfrescoVersion() {
        String url = apiUrl + "server";
        HttpGet get = new HttpGet(url);
        HttpResponse response = execute("", "", get);
        if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
            try {
                String json_string = EntityUtils.toString(response.getEntity());
                JSONParser parser = new JSONParser();
                JSONObject obj = (JSONObject) parser.parse(json_string);
                JSONObject data = (JSONObject) obj.get("data");
                return (String) data.get("version");
            } catch (IOException | ParseException e) {
                return "";
            }
        }
        return "";
    }

    /**
     * Populate HTTP message call with given content.
     * @param json {@link JSONObject} content
     * @return {@link StringEntity} content.
     */
    public StringEntity setMessageBody(final JSONObject json) {
        if (json == null || json.toString().isEmpty()) {
            throw new IllegalArgumentException("JSON Content is required.");
        }
        StringEntity se = new StringEntity(json.toString(), UTF_8_ENCODING);
        se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, MIME_TYPE_JSON));
        if (logger.isDebugEnabled()) {
            logger.debug("Json string value: " + se);
        }
        return se;
    }

    /**
    * @deprecated
    * Execute HttpClient request.
    * @param request to send 
    * @return {@link HttpResponse} response
    */
    public HttpResponse executeRequest(HttpRequestBase request) {
        HttpResponse response = null;
        try {
            response = client.execute(request);
            if (logger.isTraceEnabled()) {
                logger.trace("Status Received:" + response.getStatusLine());
            }
            return response;
        } catch (IOException e) {
            logger.error(response);
            throw new RuntimeException("Error while executing request", e);
        }
    }

    /**
     * Execute HttpClient request without releasing the connection
     * @param userName user name
     * @param password password
     * @param request to send 
     * @return {@link HttpResponse} response
     */
    public HttpResponse execute(final String userName, final String password, HttpRequestBase request) {
        HttpResponse response = null;
        if (!StringUtils.isEmpty(userName) || !StringUtils.isEmpty(password)) {
            client = getHttpClientWithBasicAuth(userName, password);
        }
        try {
            response = client.execute(request);
            if (logger.isTraceEnabled()) {
                logger.trace("Status Received:" + response.getStatusLine());
            }
            return response;
        } catch (IOException e) {
            logger.error(response);
            throw new RuntimeException("Error while executing request", e);
        }
    }

    /**
     * Execute HttpClient request.
     * @param userName String user name 
     * @param password String password
     * @param request HttpRequestBase the request
     * @return {@link HttpResponse} response
     */
    public HttpResponse executeRequest(final String userName, final String password, HttpRequestBase request) {
        HttpResponse response = null;
        client = getHttpClientWithBasicAuth(userName, password);
        try {
            response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
                throw new RuntimeException("Invalid user name or password");
            }
        } catch (IOException e) {
            logger.error(response);
            throw new RuntimeException("Error while executing request", e);
        } finally {
            request.releaseConnection();
            close();
        }
        return response;
    }

    /**
     * Execute HttpClient POST OR PUT
     * @param userName String user name 
     * @param password String password
     * @param body JSONObject body of the request
     * @param request HttpEntityEnclosingRequestBase the request
     * @return {@link HttpResponse} response
     */
    public HttpResponse executeRequest(final String userName, final String password, final JSONObject body,
            HttpEntityEnclosingRequestBase request) {
        HttpResponse response = null;
        client = getHttpClientWithBasicAuth(userName, password);
        request.setEntity(setMessageBody(body));
        try {
            response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
                throw new RuntimeException("Invalid user name or password");
            }
        } catch (IOException e) {
            logger.error(response);
            throw new RuntimeException("Error while executing request", e);
        } finally {
            request.releaseConnection();
            close();
        }
        return response;
    }

    /**
     * Get basic http client with basic credential.
     * @param username String username 
     * @param password String password
     * @return {@link CloseableHttpClient} client
     */
    public CloseableHttpClient getHttpClientWithBasicAuth(String username, String password) {
        CredentialsProvider provider = new BasicCredentialsProvider();
        UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
        provider.setCredentials(AuthScope.ANY, credentials);
        CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
        return client;
    }

    /**
     * Parses http response stream into a {@link JSONObject}.
     * @param entity Http response entity
     * @return {@link JSONObject} response
     */
    public JSONObject readStream(final HttpEntity entity) {
        String rsp = null;
        try {
            rsp = EntityUtils.toString(entity, UTF_8_ENCODING);
        } catch (Throwable ex) {
            throw new RuntimeException("Failed to read HTTP entity stream.", ex);
        } finally {
            EntityUtils.consumeQuietly(entity);
        }
        try {
            JSONParser parser = new JSONParser();
            JSONObject result = (JSONObject) parser.parse(rsp);
            return result;
        } catch (Throwable e) {
            throw new RuntimeException("Failed to convert response to JSON: \n" + "   Response: \r\n" + rsp, e);
        }
    }

    private String getParameterFromJSON(boolean httpResp, String stringResponse, HttpResponse response,
            String parameter, String... jsonObjs) {
        String strResponse = "";
        Object obj = null;
        if (httpResp) {
            strResponse = readStream(response.getEntity()).toJSONString();
            obj = JSONValue.parse(strResponse);
        } else {
            obj = JSONValue.parse(stringResponse);
        }
        JSONObject jObj = (JSONObject) obj;
        if (!StringUtils.isEmpty(jsonObjs[0])) {
            //JSONObject entry = null;
            for (int i = 0; i < jsonObjs.length; i++) {
                jObj = (JSONObject) jObj.get(jsonObjs[i]);
            }
            return (String) jObj.get(parameter).toString();
        } else {
            return (String) jObj.get(parameter);
        }

    }

    /**
     * Get an element from HttpResponse
     * 
     * @param response response
     * @param parameter wanted parameter
     * @param jsonObjs json objects to reach the parameter
     * @return
     */
    public String getParameterFromJSON(HttpResponse response, String parameter, String... jsonObjs) {
        return getParameterFromJSON(true, null, response, parameter, jsonObjs);
    }

    /**
     * Get an element from a string HttpResponse
     * 
     * @param response String response 
     * @param parameter String wanted parameter
     * @param jsonObjs String json objects to reach the parameter
     * @return
     */
    public String getParameterFromJSON(String response, String parameter, String... jsonObjs) {
        return getParameterFromJSON(false, response, null, parameter, jsonObjs);
    }

    /**
     * Get the elements from a JSONArray
     * @param response HttpResponse response
     * @param array String the name of the array
     * @param elementFromArray element from array
     * @return List<String> elements found in the array
     */
    public List<String> getElementsFromJsonArray(HttpResponse response, String objAbove, String array,
            String elementFromArray) {
        List<String> elements = new ArrayList<String>();
        HttpEntity entity = response.getEntity();
        String responseString = "";
        try {
            responseString = EntityUtils.toString(entity, "UTF-8");
        } catch (IOException e) {
            throw new RuntimeException("Failed to read the response", e);
        }
        Object obj = JSONValue.parse(responseString);
        JSONObject jsonObject;
        if (StringUtils.isEmpty(objAbove)) {
            jsonObject = (JSONObject) obj;
        } else {
            jsonObject = (JSONObject) obj;
            jsonObject = (JSONObject) jsonObject.get(objAbove);
        }
        JSONArray jArray = (JSONArray) jsonObject.get(array);
        for (Object item : jArray) {
            JSONObject jobject = (JSONObject) item;
            elements.add(jobject.get(elementFromArray).toString());
        }
        return elements;
    }

    public String getSpecificElementFromJArray(HttpResponse response, String firstParam, String array,
            String itemName, String itemParameter, String requiredElement) {
        JSONArray jArray = getJSONArray(response, firstParam, array);
        for (Object item : jArray) {
            JSONObject jobject = (JSONObject) item;
            if (jobject.get(itemParameter).toString().equals(itemName)) {
                return (String) jobject.get(requiredElement);
            }
        }
        return "";
    }

    /**
     * Get JSONArray from HttpResponse
     * @param response HttpResponse the request response
     * @param firstParam String parameter that has the array
     * @param arrayName String array name
     * @return JSONArray the array
     */
    public JSONArray getJSONArray(HttpResponse response, String firstParam, String arrayName) {
        HttpEntity entity = response.getEntity();
        String responseString = "";
        try {
            responseString = EntityUtils.toString(entity, "UTF-8");
        } catch (IOException e) {
            throw new RuntimeException("Failed to read the response", e);
        }
        Object obj = JSONValue.parse(responseString);
        JSONObject jsonObject = (JSONObject) obj;
        if (!StringUtils.isEmpty(firstParam)) {
            jsonObject = (JSONObject) jsonObject.get(firstParam);
        }
        return (JSONArray) jsonObject.get(arrayName);
    }

    /**
     * Closes the HttpClient. 
     * @throws IOException if error
     */
    public void close() {
        try {
            client.close();
        } catch (IOException e) {
            logger.error("Unable to close http client", e);
        }
    }

    /**
     * Closes the HttpClient.
     * @param client CloseableHttpClient the client
     * @throws IOException if error
     */
    public void close(CloseableHttpClient client) {
        try {
            client.close();
        } catch (IOException e) {
            logger.error("Unable to close http client", e);
        }
    }

    public HttpClient getClient() {
        return client;
    }

    public String getScheme() {
        return scheme;
    }

    public String getHost() {
        return host;
    }

    public int getPort() {
        return port;
    }

    public int getSharePort() {
        return sharePort;
    }

    public String getApiUrl() {
        return apiUrl;
    }

    public String getAlfrescoUrl() {
        alfrescoUrl = String.format("%s://%s:%d/", scheme, host, port);
        return alfrescoUrl;
    }

    public String getShareUrl() {
        return String.format("%s://%s:%d/", scheme, host, sharePort);
    }
}