org.ow2.proactive_grid_cloud_portal.cli.cmd.AbstractCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.ow2.proactive_grid_cloud_portal.cli.cmd.AbstractCommand.java

Source

/*
 * ProActive Parallel Suite(TM):
 * The Open Source library for parallel and distributed
 * Workflows & Scheduling, Orchestration, Cloud Automation
 * and Big Data Analysis on Enterprise Grids & Clouds.
 *
 * Copyright (c) 2007 - 2017 ActiveEon
 * Contact: contact@activeeon.com
 *
 * This library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation: version 3 of
 * the License.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * If needed, contact us to obtain a release under GPL Version 2 or 3
 * or a different license than the AGPL.
 */
package org.ow2.proactive_grid_cloud_portal.cli.cmd;

import static com.google.common.base.Throwables.getStackTraceAsString;
import static org.ow2.proactive_grid_cloud_portal.cli.CLIException.REASON_IO_ERROR;
import static org.ow2.proactive_grid_cloud_portal.cli.CLIException.REASON_UNAUTHORIZED_ACCESS;
import static org.ow2.proactive_grid_cloud_portal.cli.HttpResponseStatus.FORBIDDEN;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Stack;

import javax.net.ssl.SSLPeerUnverifiedException;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.codehaus.jackson.type.TypeReference;
import org.ow2.proactive.http.CommonHttpClientBuilder;
import org.ow2.proactive.http.HttpClientBuilder;
import org.ow2.proactive_grid_cloud_portal.cli.ApplicationContext;
import org.ow2.proactive_grid_cloud_portal.cli.CLIException;
import org.ow2.proactive_grid_cloud_portal.cli.CommandSet;
import org.ow2.proactive_grid_cloud_portal.cli.HttpResponseStatus;
import org.ow2.proactive_grid_cloud_portal.cli.json.ErrorView;
import org.ow2.proactive_grid_cloud_portal.cli.utils.HttpResponseWrapper;
import org.ow2.proactive_grid_cloud_portal.cli.utils.StringUtility;
import org.ow2.proactive_grid_cloud_portal.scheduler.exception.NotConnectedRestException;

public abstract class AbstractCommand implements Command {

    private static final String DEBUG_MODE_USAGE_MESSAGE_PREFIX = System.lineSeparator()
            + "You can enable debug mode for getting more information using ";

    private static final String DEBUG_MODE_USAGE_INTERACTIVE_SUFFIX = "command '" + CommandSet.DEBUG.jsCommand()
            + "'.";

    private static final String DEBUG_MODE_USAGE_NON_INTERACTIVE_SUFFIX = "-" + CommandSet.DEBUG.opt() + " or --"
            + CommandSet.DEBUG.longOpt() + " option.";

    protected int statusCode(HttpResponseStatus status) {
        return status.statusCode();
    }

    protected int statusCode(HttpResponseWrapper response) {
        return response.getStatusCode();
    }

    protected <T> T readValue(HttpResponseWrapper response, Class<T> valueType, ApplicationContext currentContext) {
        try {
            return currentContext.getObjectMapper().readValue(response.getContent(), valueType);
        } catch (IOException ioe) {
            throw new CLIException(REASON_IO_ERROR, ioe);
        }
    }

    protected <T> T readValue(HttpResponseWrapper response, TypeReference<T> valueType,
            ApplicationContext currentContext) {
        try {
            return currentContext.getObjectMapper().readValue(response.getContent(), valueType);
        } catch (IOException ioe) {
            throw new CLIException(REASON_IO_ERROR, ioe);
        }

    }

    protected char[] readPassword(ApplicationContext currentContext, String format, Object... args) {
        try {
            return currentContext.getDevice().readPassword(format, args);
        } catch (IOException ioe) {
            throw new CLIException(REASON_IO_ERROR, ioe);
        }
    }

    protected HttpResponseWrapper execute(HttpUriRequest request, ApplicationContext currentContext) {
        String sessionId = currentContext.getSessionId();
        if (sessionId != null) {
            request.setHeader("sessionid", sessionId);
        }
        CommonHttpClientBuilder httpClientBuilder = new HttpClientBuilder().useSystemProperties();
        try {
            if ("https".equals(request.getURI().getScheme()) && currentContext.canInsecureAccess()) {
                httpClientBuilder.insecure(true);
            }
            HttpResponse response = httpClientBuilder.build().execute(request);
            return new HttpResponseWrapper(response);

        } catch (SSLPeerUnverifiedException sslException) {
            throw new CLIException(CLIException.REASON_OTHER,
                    "SSL error. Perhaps HTTPS certificate could not be validated, "
                            + "you can try with -k or insecure() for insecure SSL connection.",
                    sslException);
        } catch (Exception e) {
            throw new CLIException(CLIException.REASON_OTHER, e.getMessage(), e);
        } finally {
            ((HttpRequestBase) request).releaseConnection();
        }
    }

    @SuppressWarnings("unchecked")
    protected void handleError(String errorMessage, HttpResponseWrapper response,
            ApplicationContext currentContext) {
        String responseContent = StringUtility.responseAsString(response);
        Stack resultStack = resultStack(currentContext);
        ErrorView errorView = errorView(responseContent, currentContext);
        if (errorView != null) {
            resultStack.push(errorView);
        } else {
            resultStack.push(responseContent);
        }
        if (errorView != null) {
            writeError(errorMessage, errorView, currentContext);
        } else {
            writeError(errorMessage, responseContent, currentContext);
        }
    }

    @SuppressWarnings("unchecked")
    protected void handleError(String errorMessage, Exception error, ApplicationContext currentContext) {
        Stack resultStack = resultStack(currentContext);
        resultStack.push(error);

        if (error instanceof NotConnectedRestException) {
            throw new CLIException(REASON_UNAUTHORIZED_ACCESS, errorMessage, error);
        }

        writeLine(currentContext, errorMessage);
        Throwable cause = error.getCause();

        String message = error.getMessage();

        if (cause != null) {
            message = cause.getMessage();
        }

        writeLine(currentContext, "Error message: %s", message);

        if (isDebugModeEnabled(currentContext)) {
            writeLine(currentContext, "Stack trace: %s", getStackTraceAsString((cause == null) ? error : cause));
        } else {
            writeDebugModeUsage(currentContext);
        }
    }

    public static boolean isDebugModeEnabled(ApplicationContext currentContext) {
        Boolean debug = currentContext.getProperty(SetDebugModeCommand.PROP_DEBUG_MODE, Boolean.class);
        return (debug == null) ? false : debug;
    }

    public static boolean isInteractive(ApplicationContext currentContext) {
        Boolean interactive = currentContext.getProperty(AbstractIModeCommand.IMODE, Boolean.class);
        return (interactive == null) ? false : interactive;
    }

    public static void writeDebugModeUsage(ApplicationContext currentContext) {
        writeDebugModeUsage(currentContext, false);
    }

    public static void writeDebugModeUsageWithBreakEndLine(ApplicationContext currentContext) {
        writeDebugModeUsage(currentContext, true);
    }

    private static void writeDebugModeUsage(ApplicationContext currentContext, boolean breakEndline) {
        String suffix = DEBUG_MODE_USAGE_NON_INTERACTIVE_SUFFIX;

        if (isInteractive(currentContext)) {
            suffix = DEBUG_MODE_USAGE_INTERACTIVE_SUFFIX;
        }

        String endline = "";

        if (breakEndline) {
            endline = "\n";
        }

        writeLine(currentContext, DEBUG_MODE_USAGE_MESSAGE_PREFIX + suffix + endline);
    }

    protected static void writeLine(ApplicationContext currentContext, String format, Object... args) {
        if (!currentContext.isSilent()) {
            try {
                currentContext.getDevice().writeLine(format, args);
            } catch (IOException ioe) {
                throw new CLIException(REASON_IO_ERROR, ioe);
            }
        }
    }

    protected String readLine(ApplicationContext currentContext, String format, Object... args) {
        try {
            return currentContext.getDevice().readLine(format, args);
        } catch (IOException ioe) {
            throw new CLIException(REASON_IO_ERROR, ioe);
        }
    }

    protected CLIException buildCLIException(int reason, HttpResponseWrapper response,
            ApplicationContext currentContext) {
        String responseContent = StringUtility.responseAsString(response);
        ErrorView errorView = errorView(responseContent, currentContext);
        if (errorView != null) {
            throw new CLIException(reason, errorView.getErrorMessage(), errorView.getStackTrace());
        } else {
            HttpErrorView httpErrorView = errorView(responseContent);
            throw new CLIException(reason, httpErrorView.errorMessage, httpErrorView.stackTrace);
        }
    }

    private void writeError(String errorMsg, String responseContent, ApplicationContext currentContext) {
        writeLine(currentContext, errorMsg);

        HttpErrorView errorView = errorView(responseContent);

        if (errorView.errorCode != null) {
            writeLine(currentContext, "HTTP error code: %s", errorView.errorCode);
        }

        if (errorView.errorMessage != null) {
            writeLine(currentContext, "Error message: %s", errorView.errorMessage);
        }

        if (errorView.errorCode == null && errorView.errorMessage == null) {
            writeLine(currentContext, "Error message:%n%s", responseContent);
        }

        if (isDebugModeEnabled(currentContext)) {
            writeLine(currentContext, "Stack trace: %s", errorView.stackTrace);
        } else {
            writeDebugModeUsage(currentContext);
        }
    }

    public Stack resultStack(ApplicationContext currentContext) {
        return currentContext.resultStack();
    }

    protected ErrorView errorView(String responseContent, ApplicationContext currentContext) {
        try {
            return currentContext.getObjectMapper().readValue(responseContent.getBytes(), ErrorView.class);
        } catch (Exception ignore) {
            return null;
        }
    }

    protected HttpErrorView errorView(String responseContent) {
        try {
            HttpErrorView errorView = new HttpErrorView();
            BufferedReader reader = new BufferedReader(new StringReader(responseContent));

            String line;
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("errorMessage:")) {
                    errorView.errorMessage = line.substring(line.indexOf(':')).trim();
                    break;
                }
            }

            while ((line = reader.readLine()) != null) {
                if (line.startsWith("httpErrorCode:")) {
                    errorView.errorCode = line.substring(line.indexOf(':')).trim();
                    break;
                }
            }

            while ((line = reader.readLine()) != null) {
                if (line.startsWith("stackTrace:")) {
                    StringBuilder buffer = new StringBuilder();
                    while ((line = reader.readLine()) != null) {
                        buffer.append(line);
                    }
                    errorView.stackTrace = buffer.toString();
                    break;
                }
            }

            return errorView;

        } catch (IOException ioe) {
            throw new CLIException(REASON_IO_ERROR, ioe);
        }
    }

    private void writeError(String errorMessage, ErrorView error, ApplicationContext currentContext) {
        if (statusCode(FORBIDDEN) == error.getHttpErrorCode()) {
            // this exception would be handled at an upper level ..
            throw new CLIException(REASON_UNAUTHORIZED_ACCESS, error.getErrorMessage());
        }
        writeLine(currentContext, errorMessage);
        writeLine(currentContext, "%s %s", "HTTP error code:", error.getHttpErrorCode());
        writeLine(currentContext, "%s %s", "Error message:", error.getErrorMessage());

        if (isDebugModeEnabled(currentContext)) {
            writeLine(currentContext, "%s%n%s", "Stack trace:", error.getStackTrace());
        } else {
            writeDebugModeUsage(currentContext);
        }
    }

    private class HttpErrorView {
        private String errorCode;

        private String errorMessage;

        private String stackTrace;
    }
}