Package com.groupon.odo.client

Source Code of com.groupon.odo.client.Client

/*
Copyright 2014 Groupon, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.groupon.odo.client;

import com.groupon.odo.client.models.History;
import com.groupon.odo.client.models.ServerGroup;
import com.groupon.odo.client.models.ServerRedirect;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
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.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Client {
    protected String ODO_HOST = "localhost";
    protected String BASE_URL = "http://localhost:8090/testproxy/api/";
    protected int API_PORT = 8090;

    protected static String DEFAULT_BASE_URL = "http://localhost:8090/testproxy/api/";
    public static int DEFAULT_API_PORT = 8090;

    // API Paths
    protected static String API_BASE = "testproxy/api";
    protected static String BASE_PATH = "path/";
    protected static String BASE_PROFILE = "profile/";
    protected static String BASE_METHOD = "method/";
    protected static String BASE_CLIENTS = "clients";
    protected static String HISTORY = "history/";
    protected static String BASE_SERVER = "edit/server";
    protected static String BASE_SERVERGROUP = "servergroup";

    protected String _profileName = null;
    protected int _profileId;
    protected String _clientId = null;
    protected int _timeout = 60000;

    protected static int REQUEST_TYPE_ALL = 0;
    protected static int REQUEST_TYPE_GET = 1;
    protected static int REQUEST_TYPE_PUT = 2;
    protected static int REQUEST_TYPE_POST = 3;
    protected static int REQUEST_TYPE_DELETE = 4;
    protected History[] history;

    /**
     * Create a new client instance
     *
     * @param profileName
     * @param useClient   - create a new client id(false means use the default client)
     * @throws Exception
     */
    public Client(String profileName, boolean useClient) throws Exception {
        this._profileName = profileName;

        if (useClient) {
            this.createNewClientId();
        } else {
            this._clientId = "-1";
        }
    }

    /**
     * Call when you are done with the client
     */
    public void destroy() throws Exception {
        if (_clientId == null)
            return;

        // delete the clientId here
        String uri = BASE_PROFILE + uriEncode(_profileName) + "/" + BASE_CLIENTS + "/" + _clientId;
        try {
            doDelete(uri, null);
        } catch (Exception e) {
            // some sort of error
            throw new Exception("Could not delete a proxy client");
        }
    }

    /**
     * Get the connection timeout value in ms
     * @return
     */
    public int getTimeout() {
        return _timeout;
    }

    /**
     * Set the connection timeout value in ms
     * @param timeout
     */
    public void setTimeout(int timeout) {
        _timeout = timeout;
    }

    protected void createNewClientId() throws Exception {
        String uri = BASE_PROFILE + uriEncode(_profileName) + "/" + BASE_CLIENTS;
        try {
            JSONObject response = new JSONObject(doPost(uri, null));
            _clientId = response.getJSONObject("client").getString("uuid");
            toggleProfile(true);
        } catch (Exception e) {
            // some sort of error
            throw new Exception("Could not create a proxy client");
        }
    }

    /**
     * Set the host running the Odo instance to configure
     * @param hostName
     */
    public void setHostName(String hostName) {
        if(hostName == null || hostName.contains(":")) {
            return;
        }
        ODO_HOST = hostName;
        BASE_URL = "http://" + ODO_HOST + ":" + API_PORT + "/" + API_BASE + "/";
    }

    /**
     * Set the default host running the Odo instance to configure. Allows default profile methods and PathValueClient to
     * operate on remote hosts
     */
    public static void setDefaultHostName(String hostName) {
        if(hostName == null || hostName.contains(":")) {
            return;
        }
        DEFAULT_BASE_URL = "http://" + hostName + ":" + DEFAULT_API_PORT + "/" + API_BASE + "/";
    }

    /**
     * Retrieve the request History based on the specified filters.
     * If no filter is specified, return the default size history.
     *
     * @param filters - filters to be applied
     * @return
     * @throws Exception
     */
    public History[] filterHistory(String... filters) throws Exception {
        BasicNameValuePair[] params;
        if (filters.length > 0) {
            params = new BasicNameValuePair[filters.length];
            for (int i = 0; i < filters.length; i++) {
                params[i] = new BasicNameValuePair("source_uri[]", filters[i]);
            }
        } else {
            return refreshHistory();
        }

        return constructHistory(params);
    }

    /**
     * Construct the history array based on the given parameters
     *
     * @param params - parameters applied
     * @return
     * @throws Exception
     */
    protected History[] constructHistory(BasicNameValuePair[] params) throws Exception {
        String uri = HISTORY + uriEncode(_profileName);

        try {
            JSONObject response = new JSONObject(doGet(uri, params));
            JSONArray historyArray = response.getJSONArray("history");
            history = new History[historyArray.length()];


            for (int i = 0; i < historyArray.length(); i++) {
                history[i] = new History();
                JSONObject jsonHistory = historyArray.getJSONObject(i);
                if (jsonHistory == null) {
                    continue;
                }

                if (!jsonHistory.isNull("id"))
                    history[i].setId(jsonHistory.getInt("id"));
                if (!jsonHistory.isNull("profileId"))
                    history[i].setProfileId(jsonHistory.getInt("profileId"));
                if (!jsonHistory.isNull("clientUUID"))
                    history[i].setClientUUID(jsonHistory.getString("clientUUID"));
                if (!jsonHistory.isNull("createdAt"))
                    history[i].setCreatedAt(jsonHistory.getString("createdAt"));
                if (!jsonHistory.isNull("requestType"))
                    history[i].setRequestType(jsonHistory.getString("requestType"));
                if (!jsonHistory.isNull("requestURL"))
                    history[i].setRequestURL(jsonHistory.getString("requestURL"));
                if (!jsonHistory.isNull("requestParams"))
                    history[i].setRequestParams(jsonHistory.getString("requestParams"));
                if (!jsonHistory.isNull("requestPostData"))
                    history[i].setRequestPostData(jsonHistory.getString("requestPostData"));
                if (!jsonHistory.isNull("requestHeaders"))
                    history[i].setRequestHeaders(jsonHistory.getString("requestHeaders"));
                if (!jsonHistory.isNull("responseCode"))
                    history[i].setResponseCode(jsonHistory.getString("responseCode"));
                if (!jsonHistory.isNull("responseHeaders"))
                    history[i].setResponseHeaders(jsonHistory.getString("responseHeaders"));
                if (!jsonHistory.isNull("responseContentType"))
                    history[i].setResponseContentType(jsonHistory.getString("responseContentType"));
                if (!jsonHistory.isNull("originalRequestURL"))
                    history[i].setOriginalRequestURL(jsonHistory.getString("originalRequestURL"));
                if (!jsonHistory.isNull("originalRequestParams"))
                    history[i].setOriginalRequestParams(jsonHistory.getString("originalRequestParams"));
                if (!jsonHistory.isNull("originalRequestPostData"))
                    history[i].setOriginalRequestPostData(jsonHistory.getString("originalRequestPostData"));
                if (!jsonHistory.isNull("originalRequestHeaders"))
                    history[i].setOriginalRequestHeaders(jsonHistory.getString("originalRequestHeaders"));
                if (!jsonHistory.isNull("originalResponseCode"))
                    history[i].setOriginalResponseCode(jsonHistory.getString("originalResponseCode"));
                if (!jsonHistory.isNull("originalResponseHeaders"))
                    history[i].setOriginalResponseHeaders(jsonHistory.getString("originalResponseHeaders"));
                if (!jsonHistory.isNull("originalResponseContentType"))
                    history[i].setResponseContentType(jsonHistory.getString("originalResponseContentType"));
                if (!jsonHistory.isNull("modified"))
                    history[i].setModified(jsonHistory.getBoolean("modified"));
                if (!jsonHistory.isNull("requestBodyDecoded"))
                    history[i].setRequestBodyDecoded(jsonHistory.getBoolean("requestBodyDecoded"));
                if (!jsonHistory.isNull("responseBodyDecoded"))
                    history[i].setResponseBodyDecoded(jsonHistory.getBoolean("responseBodyDecoded"));
                /**
                 * To get the json responseData make a call specifically using the id
                 */

                int id = history[i].getId();
                String idUri = uri + "/" + id;
                JSONObject historyId = new JSONObject(doGet(idUri, null));

                String responseData = historyId.getJSONObject("history").getString("responseData");
                history[i].setResponseData(responseData);
                String originalResponseData = historyId.getJSONObject("history").getString("originalResponseData");
                history[i].setOriginalResponseData(originalResponseData);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return history;
    }

    /**
     * refresh the most recent history entries
     *
     * @return populated history entries
     * @throws Exception
     */
    public History[] refreshHistory() throws Exception {
        return refreshHistory(15, 0);
    }

    /**
     * refresh the most recent history entries
     *
     * @param limit  - number of entries to populate
     * @param offset - number of most recent entries to skip
     * @return populated history entries
     * @throws Exception
     */
    public History[] refreshHistory(int limit, int offset) throws Exception {
        BasicNameValuePair[] params = {
                new BasicNameValuePair("limit", String.valueOf(limit)),
                new BasicNameValuePair("offset", String.valueOf(offset))
        };
        return constructHistory(params);
    }

    /**
     * Delete the proxy history for the active profile
     *
     * @throws Exception
     */
    public void clearHistory() throws Exception {
        String uri;
        try {
            uri = HISTORY + uriEncode(_profileName);
            doDelete(uri, null);
        } catch (Exception e) {
            throw new Exception("Could not delete proxy history");
        }
    }

    public String getClientUUID() {
        return _clientId;
    }

    /**
     * Turn this profile on or off
     *
     * @param enabled - true or false
     * @return
     */
    public boolean toggleProfile(Boolean enabled) {
        // TODO: make this return values properly
        BasicNameValuePair[] params = {
                new BasicNameValuePair("active", enabled.toString())
        };
        try {
            String uri = BASE_PROFILE + uriEncode(this._profileName) + "/" + BASE_CLIENTS + "/";
            if (_clientId == null) {
                uri += "-1";
            } else {
                uri += _clientId;
            }
            JSONObject response = new JSONObject(doPost(uri, params));
        } catch (Exception e) {
            // some sort of error
            System.out.println(e.getMessage());
            return false;
        }
        return true;
    }


    /**
     * Reset all overrrides
     *
     * @param
     * @return
     */
    public boolean resetProfile() {
        Boolean enabled = new Boolean(true);
        BasicNameValuePair[] params = {
                new BasicNameValuePair("reset", enabled.toString())
        };

        try {
            String uri = BASE_PROFILE + uriEncode(this._profileName) + "/" + BASE_CLIENTS + "/";
            if (_clientId == null) {
                uri += "-1";
            } else {
                uri += _clientId;
            }
            JSONObject response = new JSONObject(doPost(uri, params));
        } catch (Exception e) {
            // some sort of error
            System.out.println(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * Enable/disable request overrides for a path
     *
     * @param pathName
     * @param enabled  - true or false
     * @return
     */
    public boolean toggleRequestOverride(String pathName, Boolean enabled) {
        return toggleOverride(pathName, "requestEnabled", enabled);
    }

    /**
     * Enable/disable response overrides for a path
     *
     * @param pathName
     * @param enabled  - true or false
     * @return
     */
    public boolean toggleResponseOverride(String pathName, Boolean enabled) {
        return toggleOverride(pathName, "responseEnabled", enabled);
    }

    protected boolean toggleOverride(String pathName, String type, Boolean enabled) {
        BasicNameValuePair[] params = {
                new BasicNameValuePair(type, enabled.toString()),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_PATH + uriEncode(pathName), params));
            if (response.getBoolean(type) == enabled) {
                return true;
            }
        } catch (Exception e) {
            // some sort of error
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Reset all request override information for a path
     *
     * @param pathName
     * @return
     */
    public boolean resetRequestOverride(String pathName) {
        return togglePathReset(pathName, "resetRequest");
    }

    /**
     * Reset all response override information for a path
     *
     * @param pathName
     * @return
     */
    public boolean resetResponseOverride(String pathName) {
        return togglePathReset(pathName, "resetResponse");
    }

    protected boolean togglePathReset(String pathName, String type) {
        BasicNameValuePair[] params = {
                new BasicNameValuePair(type, "true"),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_PATH + uriEncode(pathName), params));
            return true;
        } catch (Exception e) {
            // some sort of error
            e.printStackTrace();
        }
        return false;
    }

    protected boolean setCustom(Boolean isResponse, String pathName, String custom) {
        // first remove the custom entry for this path if it is the custom request
        if (!isResponse) {
            this.removeCustomRequest(pathName);
        }

        // now add it(-1 is the custom response identifier)
        if (isResponse) {
            this.addMethodToResponseOverride(pathName, "-1");
        } else {
            this.addMethodToResponseOverride(pathName, "-2");
        }

        // now set the string
        String command = "customResponse";
        if (!isResponse)
            command = "customRequest";

        try {
            BasicNameValuePair[] params = {
                    new BasicNameValuePair(command, custom),
                    new BasicNameValuePair("profileIdentifier", this._profileName)
            };

            JSONObject response = new JSONObject(doPost(BASE_PATH + uriEncode(pathName), params));

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * Set a custom response for this path
     *
     * @param pathName
     * @param customResponse
     * @return
     */
    public boolean setCustomResponse(String pathName, String customResponse) throws Exception {
        // figure out the new ordinal
        int nextOrdinal = this.getNextOrdinalForMethodId(-1, pathName);

        // add override
        this.addMethodToResponseOverride(pathName, "-1");

        // set argument
        return this.setMethodArguments(pathName, "-1", nextOrdinal, customResponse);
    }

    /**
     * Set a custom request for this path
     *
     * @param pathName
     * @param customRequest
     * @return
     */
    public boolean setCustomRequest(String pathName, String customRequest) {
        return this.setCustom(true, pathName, customRequest);
    }

    /**
     * Remove a custom response for a path
     *
     * @param pathName
     * @return
     */
    public boolean removeCustomResponse(String pathName) {
        return this.removeMethodFromResponseOverride(pathName, "-1");
    }

    /**
     * Remove a custom request for a path
     *
     * @param pathName
     * @return
     */
    public boolean removeCustomRequest(String pathName) {
        return this.removeMethodFromResponseOverride(pathName, "-2");
    }

    /**
     * Add a method to the enabled response overrides for a path
     *
     * @param pathName
     * @param methodName
     * @return
     */
    public boolean addMethodToResponseOverride(String pathName, String methodName) {
        // need to find out the ID for the method
        // TODO: change api for adding methods to take the name instead of ID
        try {
            Integer overrideId = getOverrideIdForMethodName(methodName);

            // now post to path api to add this is a selected override
            BasicNameValuePair[] params = {
                    new BasicNameValuePair("addOverride", overrideId.toString()),
                    new BasicNameValuePair("profileIdentifier", uriEncode(this._profileName))
            };
            JSONObject response = new JSONObject(doPost(BASE_PATH + uriEncode(pathName), params));
            // check enabled endpoints array to see if this overrideID exists
            JSONArray enabled = response.getJSONArray("enabledEndpoints");
            for (int x = 0; x < enabled.length(); x++) {
                if (enabled.getJSONObject(x).getInt("overrideId") == overrideId)
                    return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * Set the repeat count of an override at ordinal index
     *
     * @param pathName    - Path name
     * @param methodName  - Fully qualified method name
     * @param ordinal     - 1-based index of the override within the overrides of type methodName
     * @param repeatCount - new repeat count to set
     * @return
     */
    public boolean setOverrideRepeatCount(String pathName, String methodName, Integer ordinal, Integer repeatCount) {
        try {
            String methodId = getOverrideIdForMethodName(methodName).toString();
            BasicNameValuePair[] params = {
                    new BasicNameValuePair("profileIdentifier", uriEncode(this._profileName)),
                    new BasicNameValuePair("ordinal", ordinal.toString()),
                    new BasicNameValuePair("repeatNumber", repeatCount.toString())
            };

            JSONObject response = new JSONObject(doPost(BASE_PATH + uriEncode(pathName), params));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Set the method arguments for an enabled method override
     *
     * @param pathName   - Path name
     * @param methodName - Fully qualified method name
     * @param ordinal    TODO
     * @param arguments  - Array of arguments to set(specify all arguments)
     * @return
     */
    public boolean setMethodArguments(String pathName, String methodName, Integer ordinal, Object... arguments) {
        try {
            BasicNameValuePair[] params = new BasicNameValuePair[arguments.length + 2];
            int x = 0;
            for (Object argument : arguments) {
                params[x] = new BasicNameValuePair("arguments[]", argument.toString());
                x++;
            }
            params[x] = new BasicNameValuePair("profileIdentifier", this._profileName);
            params[x + 1] = new BasicNameValuePair("ordinal", ordinal.toString());

            JSONObject response = new JSONObject(doPost(BASE_PATH + uriEncode(pathName) + "/" + methodName, params));

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * Add a method to the enabled response overrides for a path
     *
     * @param pathName
     * @param methodName
     * @return
     */
    public boolean removeMethodFromResponseOverride(String pathName, String methodName) {
        // need to find out the ID for the method
        try {
            Integer overrideId = getOverrideIdForMethodName(methodName);

            // now post to path api to add this is a selected override
            BasicNameValuePair[] params = {
                    new BasicNameValuePair("removeOverride", overrideId.toString()),
                    new BasicNameValuePair("profileIdentifier", this._profileName)
            };

            JSONObject response = new JSONObject(doPost(BASE_PATH + uriEncode(pathName), params));
            // check enabled endpoints array to see if this overrideID exists
            JSONArray enabled = response.getJSONArray("enabledEndpoints");
            for (int x = 0; x < enabled.length(); x++) {
                if (enabled.getJSONObject(x).getInt("overrideId") == overrideId)
                    return false;
            }

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * Create a new path
     *
     * @param pathName    - friendly name of path
     * @param pathValue   - path value or regex
     * @param requestType - path request type. "GET", "POST", etc
     */
    public void createPath(String pathName, String pathValue, String requestType) {
        try {
            int type = getRequestTypeFromString(requestType);
            String url = BASE_PATH;
            BasicNameValuePair[] params = {
                    new BasicNameValuePair("pathName", pathName),
                    new BasicNameValuePair("path", pathValue),
                    new BasicNameValuePair("requestType", String.valueOf(type)),
                    new BasicNameValuePair("profileIdentifier", this._profileName)
            };

            JSONObject response = new JSONObject(doPost(BASE_PATH, params));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * set custom response or request for a profile's default client, ensures profile and path are enabled
     *
     * @param profileName - profileName to modift, default client is used
     * @param pathName    - friendly name of path
     * @param isResponse
     * @param customData  - custom response/request data
     * @return
     */
    protected static boolean setCustomForDefaultClient(String profileName, String pathName, Boolean isResponse, String customData) {
        try {
            Client client = new Client(profileName, false);
            client.toggleProfile(true);
            client.setCustom(isResponse, pathName, customData);
            if (isResponse) {
                client.toggleResponseOverride(pathName, true);
            } else {
                client.toggleRequestOverride(pathName, true);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * set custom request for profile's default client
     *
     * @param profileName - profileName to modify
     * @param pathName    - friendly name of path
     * @param customData  - custom request data
     * @return
     */
    public static boolean setCustomRequestForDefaultClient(String profileName, String pathName, String customData) {
        try {
            return setCustomForDefaultClient(profileName, pathName, false, customData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * set custom response for profile's default client
     *
     * @param profileName - profileName to modify
     * @param pathName    - friendly name of path
     * @param customData  - custom request data
     * @return
     */
    public static boolean setCustomResponseForDefaultClient(String profileName, String pathName, String customData) {
        try {
            return setCustomForDefaultClient(profileName, pathName, true, customData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * set custom request/response for the default profile's default client
     *
     * @param pathName   - friendly name of path
     * @param isResponse
     * @param customData - custom response/request data
     * @return
     */
    protected static boolean setCustomForDefaultProfile(String pathName, Boolean isResponse, String customData) {
        try {
            JSONObject profile = getDefaultProfile();
            String profileName = profile.getString("name");
            Client client = new Client(profileName, false);
            return client.setCustom(isResponse, pathName, customData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * set custom request for the default profile's default client
     *
     * @param pathName   - friendly name of path
     * @param customData - custom response/request data
     * @return
     */
    public static boolean setCustomRequestForDefaultProfile(String pathName, String customData) {
        try {
            return setCustomForDefaultProfile(pathName, false, customData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * set custom response for the default profile's default client
     *
     * @param pathName   - friendly name of path
     * @param customData - custom response/request data
     * @return
     */
    public static boolean setCustomResponseForDefaultProfile(String pathName, String customData) {
        try {
            return setCustomForDefaultProfile(pathName, true, customData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * get the default profile
     *
     * @return
     * @throws Exception
     */
    protected static JSONObject getDefaultProfile() throws Exception {
        String uri = DEFAULT_BASE_URL + BASE_PROFILE;
        try {
            JSONObject response = new JSONObject(doGet(uri, 60000));
            JSONArray profiles = response.getJSONArray("profiles");

            if (profiles.length() > 0) {
                return profiles.getJSONObject(0);
            }
        } catch (Exception e) {
            // some sort of error
            throw new Exception("Could not create a proxy client");
        }

        return null;
    }

    protected Integer getOverrideIdForMethodName(String methodName) throws Exception {
        String methodInfo = doGet(BASE_METHOD + methodName, new BasicNameValuePair[0]);
        JSONObject methodJson = new JSONObject(methodInfo);
        return methodJson.getJSONObject("method").getInt("id");
    }

    /**
     * Get the next available ordinal for a method ID
     *
     * @param methodId
     * @return
     * @throws Exception
     */
    private Integer getNextOrdinalForMethodId(int methodId, String pathName) throws Exception {
        String pathInfo = doGet(BASE_PATH + uriEncode(pathName), new BasicNameValuePair[0]);
        JSONObject pathResponse = new JSONObject(pathInfo);

        JSONArray enabledEndpoints = pathResponse.getJSONArray("enabledEndpoints");
        int lastOrdinal = 0;
        for (int x = 0; x < enabledEndpoints.length(); x++) {
            if (enabledEndpoints.getJSONObject(x).getInt("overrideId") == methodId) {
                lastOrdinal++;
            }
        }
        return lastOrdinal + 1;
    }

    // helper functions
    protected String uriEncode(String input) throws Exception {
        return URLEncoder.encode(input, "UTF-8").replace("+", "%20");
    }

    /**
     * Convert a request type string to value
     *
     * @param requestType
     * @return Matching REQUEST_TYPE
     */
    protected int getRequestTypeFromString(String requestType) {
        if ("GET".equals(requestType)) {
            return REQUEST_TYPE_GET;
        }
        if ("POST".equals(requestType)) {
            return REQUEST_TYPE_POST;
        }
        if ("PUT".equals(requestType)) {
            return REQUEST_TYPE_PUT;
        }
        if ("DELETE".equals(requestType)) {
            return REQUEST_TYPE_DELETE;
        }
        return REQUEST_TYPE_ALL;
    }

    protected ServerRedirect getServerRedirectFromJSON(JSONObject jsonServer) {
        ServerRedirect redirect = new ServerRedirect();
        if (jsonServer == null) {
            return null;
        }

        try {
            if (!jsonServer.isNull("id"))
                redirect.setId(jsonServer.getInt("id"));
            if (!jsonServer.isNull("srcUrl"))
                redirect.setSourceHost(jsonServer.getString("srcUrl"));
            if (!jsonServer.isNull("destUrl"))
                redirect.setDestinationHost(jsonServer.getString("destUrl"));
            if (!jsonServer.isNull("hostHeader"))
                redirect.setHostHeader(jsonServer.getString("hostHeader"));
            if (!jsonServer.isNull("profileId"))
                redirect.setProfileId(jsonServer.getInt("profileId"));
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }

        return redirect;
    }

    /**
     * Add a new server mapping to current profile
     *
     * @param sourceHost
     * @param destinationHost
     * @param hostHeader
     * @return
     */
    public ServerRedirect addServerMapping(String sourceHost, String destinationHost, String hostHeader) {
        JSONObject response = null;

        ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
        params.add(new BasicNameValuePair("srcUrl", sourceHost));
        params.add(new BasicNameValuePair("destUrl", destinationHost));
        params.add(new BasicNameValuePair("profileIdentifier", this._profileName));
        if (hostHeader != null) {
            params.add(new BasicNameValuePair("hostHeader", hostHeader));
        }

        try {
            BasicNameValuePair paramArray[] = new BasicNameValuePair[params.size()];
            params.toArray(paramArray);
            response = new JSONObject(doPost(BASE_SERVER, paramArray));

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return getServerRedirectFromJSON(response);
    }

    /**
     * Remove a server mapping from current profile by ID
     *
     * @param serverMappingId
     * @return
     */
    public List<ServerRedirect> deleteServerMapping(int serverMappingId) {
        ArrayList<ServerRedirect> servers = new ArrayList<ServerRedirect>();
        try {
            JSONArray serverArray = new JSONArray(doDelete(BASE_SERVER + "/" + serverMappingId, null));
            for (int i = 0; i < serverArray.length(); i++) {
                JSONObject jsonServer = serverArray.getJSONObject(i);
                ServerRedirect server = getServerRedirectFromJSON(jsonServer);
                if (server != null) {
                    servers.add(server);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        return servers;
    }

    /**
     * Get a list of all active server mappings defined for current profile
     *
     * @return
     */
    public List<ServerRedirect> getServerMappings() {
        ArrayList<ServerRedirect> servers = new ArrayList<ServerRedirect>();
        try {
            JSONObject response = new JSONObject(doGet(BASE_SERVER, null));
            JSONArray serverArray = response.getJSONArray("servers");

            for (int i = 0; i < serverArray.length(); i++) {
                JSONObject jsonServer = serverArray.getJSONObject(i);
                ServerRedirect server = getServerRedirectFromJSON(jsonServer);
                if (server != null) {
                    servers.add(server);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return servers;
    }

    /**
     * Enable/disable a server mapping
     *
     * @param serverMappingId
     * @param enabled
     * @return
     */
    public ServerRedirect enableServerMapping(int serverMappingId, Boolean enabled) {
        ServerRedirect redirect = new ServerRedirect();
        BasicNameValuePair[] params = {
                new BasicNameValuePair("enabled", enabled.toString()),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVER + "/" + serverMappingId, params));
            redirect = getServerRedirectFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return redirect;
    }

    /**
     * Update server mapping's source host
     *
     * @param serverMappingId
     * @param sourceHost
     * @return
     */
    public ServerRedirect updateServerRedirectSrc(int serverMappingId, String sourceHost) {
        ServerRedirect redirect = new ServerRedirect();
        BasicNameValuePair[] params = {
                new BasicNameValuePair("srcUrl", sourceHost),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVER + "/" + serverMappingId + "/src", params));
            redirect = getServerRedirectFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return redirect;
    }

    /**
     * Update server mapping's destination host
     *
     * @param serverMappingId
     * @param destinationHost
     * @return
     */
    public ServerRedirect updateServerRedirectDest(int serverMappingId, String destinationHost) {
        ServerRedirect redirect = new ServerRedirect();
        BasicNameValuePair[] params = {
                new BasicNameValuePair("destUrl", destinationHost),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVER + "/" + serverMappingId + "/dest", params));
            redirect = getServerRedirectFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return redirect;
    }

    /**
     * Update server mapping's host header
     *
     * @param serverMappingId
     * @param hostHeader
     * @return
     */
    public ServerRedirect updateServerRedirectHost(int serverMappingId, String hostHeader) {
        ServerRedirect redirect = new ServerRedirect();
        BasicNameValuePair[] params = {
                new BasicNameValuePair("hostHeader", hostHeader),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVER + "/" + serverMappingId + "/host", params));
            redirect = getServerRedirectFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return redirect;
    }


    protected ServerGroup getServerGroupFromJSON(JSONObject jsonServerGroup) {
        ServerGroup group = new ServerGroup();
        try {
            if (jsonServerGroup == null) {
                return null;
            }

            if (!jsonServerGroup.isNull("id"))
                group.setId(jsonServerGroup.getInt("id"));
            if (!jsonServerGroup.isNull("name"))
                group.setName(jsonServerGroup.getString("name"));
            if (!jsonServerGroup.isNull("profileId"))
                group.setProfileId(jsonServerGroup.getInt("profileId"));
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }

        return group;
    }

    /**
     * Create a new server group
     *
     * @param groupName
     * @return
     */
    public ServerGroup addServerGroup(String groupName) {
        ServerGroup group = new ServerGroup();

        BasicNameValuePair[] params = {
                new BasicNameValuePair("name", groupName),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVERGROUP, params));
            group = getServerGroupFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return group;
    }

    /**
     * Delete a server group
     *
     * @param serverGroupId
     * @return
     */
    public List<ServerGroup> deleteServerGroup(int serverGroupId) {
        ArrayList<ServerGroup> groups = new ArrayList<ServerGroup>();
        try {
            JSONArray serverArray = new JSONArray(doDelete(BASE_SERVERGROUP + "/" + serverGroupId, null));
            for (int i = 0; i < serverArray.length(); i++) {
                JSONObject jsonServerGroup = serverArray.getJSONObject(i);
                ServerGroup group = getServerGroupFromJSON(jsonServerGroup);
                groups.add(group);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return groups;
    }

    /**
     * Get the collection of the server groups
     *
     * @return
     */
    public List<ServerGroup> getServerGroups() {
        ArrayList<ServerGroup> groups = new ArrayList<ServerGroup>();
        try {
            JSONObject response = new JSONObject(doGet(BASE_SERVERGROUP, null));
            JSONArray serverArray = response.getJSONArray("servergroups");

            for (int i = 0; i < serverArray.length(); i++) {
                JSONObject jsonServerGroup = serverArray.getJSONObject(i);
                ServerGroup group = getServerGroupFromJSON(jsonServerGroup);
                groups.add(group);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return groups;
    }

    /**
     * Update the server group's name
     *
     * @param serverGroupId
     * @param name
     * @return
     */
    public ServerGroup updateServerGroupName(int serverGroupId, String name) {
        ServerGroup serverGroup = null;
        BasicNameValuePair[] params = {
                new BasicNameValuePair("name", name),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVERGROUP + "/" + serverGroupId, params));
            serverGroup = getServerGroupFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return serverGroup;
    }

    /**
     * Activate a server group
     *
     * @param serverGroupId
     * @return
     */
    public ServerGroup activateServerGroup(int serverGroupId) {
        ServerGroup serverGroup = null;
        BasicNameValuePair[] params = {
                new BasicNameValuePair("activate", String.valueOf(true)),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };
        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVERGROUP + "/" + serverGroupId, params));
            serverGroup = getServerGroupFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return serverGroup;
    }

    /**
     * Activate a server group
     *
     * @param groupName
     * @return
     */
    public ServerGroup activateServerGroup(String groupName) {
        ServerGroup serverGroup = null;
        BasicNameValuePair[] params = {
                new BasicNameValuePair("activate", String.valueOf(true)),
                new BasicNameValuePair("profileIdentifier", this._profileName)
        };

        int serverGroupId = getServerGroupId(groupName);
        if(serverGroupId == -1) {
            return null;
        }

        try {
            JSONObject response = new JSONObject(doPost(BASE_SERVERGROUP + "/" + serverGroupId, params));
            serverGroup = getServerGroupFromJSON(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return serverGroup;
    }


    protected int getServerGroupId(String groupName) {
        List<ServerGroup> groups = getServerGroups();
        for(ServerGroup group: groups) {
            if(groupName.compareTo(group.getName()) == 0) {
                return group.getId();
            }
        }
        return -1;
    }

    protected static String doGet(String fullUrl, int timeout) throws Exception {
        HttpGet get = new HttpGet(fullUrl);

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), timeout);
        HttpConnectionParams.setSoTimeout(client.getParams(), timeout);

        HttpResponse response = client.execute(get);

        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        String accumulator = "";
        String line = "";
        while ((line = rd.readLine()) != null) {
            accumulator += line;
            accumulator += "\n";
        }
        return accumulator;
    }

    protected String doGet(String apiUrl, BasicNameValuePair[] data) throws Exception {
        String fullUrl = BASE_URL + apiUrl;

        if (data != null) {
            if (data.length > 0)
                fullUrl += "?";

            for (BasicNameValuePair bnvp : data) {
                fullUrl += bnvp.getName() + "=" + uriEncode(bnvp.getValue()) + "&";
            }
        }

        // add clientUUID if necessary
        if (_clientId != null) {
            if (data == null || data.length == 0) {
                fullUrl += "?";
            }
            fullUrl += "clientUUID=" + _clientId;
        }

        fullUrl += "&profileIdentifier=" + uriEncode(this._profileName);

        HttpGet get = new HttpGet(fullUrl);

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), _timeout);
        HttpConnectionParams.setSoTimeout(client.getParams(), _timeout);

        HttpResponse response = client.execute(get);

        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        String accumulator = "";
        String line = "";
        while ((line = rd.readLine()) != null) {
            accumulator += line;
            accumulator += "\n";
        }
        return accumulator;
    }

    protected String doDelete(String apiUrl, BasicNameValuePair[] data) throws Exception {
        String fullUrl = BASE_URL + apiUrl;

        if (data != null) {
            if (data.length > 0)
                fullUrl += "?";

            for (BasicNameValuePair bnvp : data) {
                fullUrl += bnvp.getName() + "=" + uriEncode(bnvp.getValue()) + "&";
            }
        }

        // add clientUUID if necessary
        if (_clientId != null) {
            if (data == null || data.length == 0) {
                fullUrl += "?";
            }
            fullUrl += "clientUUID=" + _clientId;
        }

        fullUrl += "&profileIdentifier=" + uriEncode(this._profileName);

        HttpDelete get = new HttpDelete(fullUrl);

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), _timeout);
        HttpConnectionParams.setSoTimeout(client.getParams(), _timeout);

        HttpResponse response = client.execute(get);

        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        String accumulator = "";
        String line = "";
        while ((line = rd.readLine()) != null) {
            accumulator += line;
            accumulator += "\n";
        }
        return accumulator;
    }

    protected String doPost(String apiUrl, BasicNameValuePair[] data) throws Exception {
        String fullUrl = BASE_URL + apiUrl;
        HttpPost post = new HttpPost(fullUrl);

        post.setHeader("Content-Type", "application/x-www-form-urlencoded");
        ArrayList<BasicNameValuePair> dataList = new ArrayList<BasicNameValuePair>();
        if (data != null) {
            dataList.addAll(Arrays.asList(data));
        }

        // add clientUUID if necessary
        if (_clientId != null) {
            BasicNameValuePair clientPair = new BasicNameValuePair("clientUUID", _clientId);
            dataList.add(clientPair);
        }

        if (dataList.size() > 0) {
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(dataList);
            urlEncodedFormEntity.setContentEncoding(HTTP.UTF_8);
            post.setEntity(urlEncodedFormEntity);
        }

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), _timeout);
        HttpConnectionParams.setSoTimeout(client.getParams(), _timeout);

        HttpResponse response = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        String accumulator = "";
        String line = "";
        while ((line = rd.readLine()) != null) {
            accumulator += line;
            accumulator += "\n";
        }
        return accumulator;
    }

}
TOP

Related Classes of com.groupon.odo.client.Client

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.