Package org.cloudfoundry.ide.eclipse.server.core.internal

Source Code of org.cloudfoundry.ide.eclipse.server.core.internal.CloudErrorUtil

/*******************************************************************************
* Copyright (c) 2013, 2014 Pivotal Software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of 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.
*  Contributors:
*     Pivotal Software, Inc. - initial API and implementation
*     Keith Chong, IBM - Support more general branded server type IDs.   Moved isCloudFoundryServer to CloudServerUtil.
********************************************************************************/
package org.cloudfoundry.ide.eclipse.server.core.internal;

import java.io.IOException;
import java.net.UnknownHostException;

import javax.net.ssl.SSLPeerUnverifiedException;

import org.cloudfoundry.client.lib.CloudFoundryException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestClientException;

/**
* Utility to detect various types of HTTP errors, like 400 Bad Request errors.
*
*/
public class CloudErrorUtil {

  private CloudErrorUtil() {
    // Util class
  }

  /**
   * Parses a error message if and only if the error is due to a request
   * failure because of a connection error. For example, if a request failed
   * due to 401, 403, or unknown host errors. Returns null otherwise.
   * @param e error to check if it is a connection error.
   * @return User-friendly error message IFF the error is due to a connection
   * error that resulted in a failed request to the server. Return null
   * otherwise.
   */
  public static String getConnectionError(CoreException e) {

    String error = getInvalidCredentialsError(e);
    if (error == null) {
      if (isUnknownHostException(e)) {
        error = Messages.ERROR_UNABLE_TO_ESTABLISH_CONNECTION_UNKNOWN_HOST;
      }
      else if (isRestClientException(e)) {
        error = NLS.bind(Messages.ERROR_FAILED_REST_CLIENT, e.getMessage());
      }
    }

    return error;
  }

  public static CoreException checkRestException(Throwable t) {
    String error = getInvalidCredentialsError(t);
    if (error == null) {

      if (t instanceof ResourceAccessException && t.getCause() instanceof UnknownHostException) {
        error = Messages.ERROR_UNABLE_TO_ESTABLISH_CONNECTION_UNKNOWN_HOST;
      }
      else if (t instanceof RestClientException) {
        error = NLS.bind(Messages.ERROR_FAILED_REST_CLIENT, t.getMessage());
      }

    }
    return error != null ? toCoreException(error, t) : toCoreException(t);
  }

  /**
   * If the error is a server communication error, it wraps it in a
   * {@link CoreException} with user-friendly message. If the server
   * communciation error is due to {@link SSLPeerUnverifiedException}, the
   * latter is set as the cause for the wrapped CoreException. Otherwise,
   * returns the error as the cause in a CoreException. Always returns a
   * {@link CoreException}.
   * @param e
   * @return CoreException wrapper if communication error with server, or
   * otherwise return CoreException with original error as cause. Never null.
   *
   */
  public static CoreException checkServerCommunicationError(RuntimeException e) {
    if (e != null && e.getCause() instanceof IOException) {
      // Set the cause for SSL
      if ((e.getCause() instanceof SSLPeerUnverifiedException)) {
        return toCoreException(e.getCause());
      }
      else {
        // Log other IO errors.
        String errorMessage = NLS.bind(Messages.ERROR_UNABLE_TO_COMMUNICATE_SERVER, e.getMessage());
        CloudFoundryPlugin.logError(errorMessage, e);
        return new CoreException(new Status(IStatus.ERROR, CloudFoundryPlugin.PLUGIN_ID, errorMessage));
      }
    }
    else {
      return checkRestException(e);
    }
  }

  /**
   * True if a request error occurred due to connection issues. For example,
   * 401, 403, or unknown host.
   * @param e error to check if it is a connection error.
   * @return true if a request error occurred due to connection issues. False
   * otherwise
   */
  public static boolean isConnectionError(CoreException e) {
    return getConnectionError(e) != null;
  }

  /**
   * Error due to invalid credentials, typically 401 or 403 HTTP errors.
   * Returns null if the error is NOT an invalid credentials error.
   * @param t error to parse
   * @return Error message if invalid credentials error (401 or 403), or null.
   */
  public static String getInvalidCredentialsError(Throwable t) {
    if (isUnauthorisedException(t)) {
      return Messages.ERROR_WRONG_EMAIL_OR_PASSWORD_UNAUTHORISED;
    }
    else if (isForbiddenException(t)) {
      return Messages.ERROR_WRONG_EMAIL_OR_PASSWORD_FORBIDDEN;
    }
    return null;
  }

  // check if error is caused by wrong credentials
  public static boolean isWrongCredentialsException(CoreException e) {
    Throwable cause = e.getCause();
    if (cause instanceof HttpClientErrorException) {
      HttpClientErrorException httpException = (HttpClientErrorException) cause;
      HttpStatus statusCode = httpException.getStatusCode();
      if (statusCode.equals(HttpStatus.FORBIDDEN) && httpException instanceof CloudFoundryException) {
        return ((CloudFoundryException) httpException).getDescription().equals("Operation not permitted"); //$NON-NLS-1$
      }
    }
    return false;
  }

  public static boolean isAppStoppedStateError(Exception e) {
    HttpClientErrorException badRequestException = getBadRequestException(e);
    if (badRequestException != null) {
      String message = getHttpErrorMessage(badRequestException);

      if (message != null) {
        message = message.toLowerCase();
        return message.contains("state") && message.contains("stop"); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
    return false;
  }

  /**
   *
   * @param error
   * @return Error message containing description of the error. If no
   * description is found, it will return the exception error or HTTP status
   * text message, if present. May return null if no message can be resolved.
   */
  protected static String getHttpErrorMessage(HttpClientErrorException error) {
    String message = null;
    if (error instanceof CloudFoundryException) {
      message = ((CloudFoundryException) error).getDescription();
    }

    if (message == null) {
      message = error.getMessage();
      if (message == null) {
        message = error.getStatusText();
        if (message == null) {
          message = error.getResponseBodyAsString();
        }
      }
    }
    return message;
  }

  public static boolean isFileNotFoundForInstance(Exception e) {
    HttpClientErrorException badRequestException = getBadRequestException(e);
    if (badRequestException != null) {
      String message = getHttpErrorMessage(badRequestException);

      if (message != null) {
        message = message.toLowerCase();
        return message.contains("file error") && message.contains("request failed") //$NON-NLS-1$ //$NON-NLS-2$
            && message.contains("as the instance is not found"); //$NON-NLS-1$
      }
    }
    return false;
  }

  public static boolean isRequestedFileRangeNotSatisfiable(CloudFoundryException cfe) {
    return cfe != null && HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE.equals(cfe.getStatusCode());
  }

  /**
   *
   * @param e to check if it is a Bad Request 400 HTTP Error.
   * @return determines if the given exception is a Bad Request 400 Exception.
   * If so, returns it the corresponding HttpClientErrorException. Otherwise
   * returns null.
   */
  public static HttpClientErrorException getBadRequestException(Exception t) {
    HttpClientErrorException httpException = getHttpClientError(t);
    if (httpException != null) {
      HttpStatus statusCode = httpException.getStatusCode();
      if (HttpStatus.BAD_REQUEST.equals(statusCode)) {
        return httpException;
      }
    }
    return null;
  }

  protected static HttpClientErrorException getHttpClientError(Throwable t) {
    if (t == null) {
      return null;
    }
    HttpClientErrorException httpException = null;
    if (t instanceof HttpClientErrorException) {
      httpException = (HttpClientErrorException) t;
    }
    else {
      Throwable cause = t.getCause();
      if (cause instanceof HttpClientErrorException) {
        httpException = (HttpClientErrorException) cause;
      }
    }
    return httpException;

  }

  public static CoreException toCoreException(Throwable e) {
    if (e instanceof CloudFoundryException) {
      if (((CloudFoundryException) e).getDescription() != null) {
        return new CoreException(new Status(IStatus.ERROR, CloudFoundryPlugin.PLUGIN_ID, NLS.bind("{0} ({1})", //$NON-NLS-1$
            ((CloudFoundryException) e).getDescription(), e.getMessage()), e));
      }
    }
    return new CoreException(new Status(IStatus.ERROR, CloudFoundryPlugin.PLUGIN_ID, NLS.bind(
        Messages.ERROR_PERFORMING_CLOUD_FOUNDRY_OPERATION, e.getMessage()), e));
  }

  /**
   * check 403 error due to invalid credentials
   * @param t
   * @return true if 403. False otherwise
   */
  public static boolean isForbiddenException(Throwable t) {
    return isHttpException(t, HttpStatus.FORBIDDEN);
  }

  /**
   * check 401 error due to invalid credentials
   * @param t
   * @return true if 401. False otherwise
   */
  public static boolean isUnauthorisedException(Throwable t) {
    return isHttpException(t, HttpStatus.UNAUTHORIZED);
  }

  /**
   * check 404 error.
   * @param t
   * @return true if 404 error. False otherwise
   */
  public static boolean isNotFoundException(Throwable t) {
    return isHttpException(t, HttpStatus.NOT_FOUND);
  }

  public static boolean isHttpException(Throwable t, HttpStatus status) {

    HttpClientErrorException httpException = getHttpClientError(t);

    if (httpException != null) {
      HttpStatus statusCode = httpException.getStatusCode();
      return statusCode.equals(status);
    }

    return false;
  }

  public static boolean isUnknownHostException(CoreException e) {
    Throwable cause = e.getStatus().getException();
    if (cause instanceof ResourceAccessException) {
      return ((ResourceAccessException) cause).getCause() instanceof UnknownHostException;
    }
    return false;
  }

  public static boolean isRestClientException(CoreException e) {
    Throwable cause = e.getStatus().getException();
    return cause instanceof RestClientException;
  }

  public static CoreException toCoreException(String message) {
    return toCoreException(message, null);
  }

  public static CoreException toCoreException(String message, Throwable error) {
    if (message == null) {
      message = Messages.ERROR_UNKNOWN;
    }
    if (error != null) {
      if (error.getMessage() != null) {
        message += " - " + error.getMessage(); //$NON-NLS-1$
      }
      return new CoreException(CloudFoundryPlugin.getErrorStatus(message, error));
    }
    else {
      return new CoreException(CloudFoundryPlugin.getErrorStatus(message));
    }
  }

  /**
   * Wraps the given error as a {@link CoreException} under these two
   * conditions:
   *
   * <p/>
   * 1. Additional error message is provided that should be added to the
   * CoreException. If the error is already a CoreException, the cause of the
   * error will be added to the new CoreException
   * <p/>
   * 2. If no error message is provided, and the error is not a CoreException,
   * a new CoreExpception will be created with the error as the cause.
   * <p/>
   * Otherwise, if the error already is a CoreException and no additional
   * message is provided, the same CoreException is returned.
   * @param message optional. Additional message to add to the CoreException.
   * @param error must not be null
   * @param replaceMessage true if existing messages in the error should be
   * replaced by the given message. False if given message should be appended
   * to existing message
   * @return error as {@link CoreException}, with the additional error message
   * added if provided.
   */
  public static CoreException asCoreException(String message, Throwable error, boolean replaceMessage) {

    if (message != null) {

      IStatus oldStatus = error instanceof CoreException ? ((CoreException) error).getStatus() : null;

      IStatus newStatus = null;
      if (oldStatus == null) {
        newStatus = CloudFoundryPlugin.getErrorStatus(message, error);
      }
      else {
        String enhancedMessage = replaceMessage ? message : message + " - " + oldStatus.getMessage(); //$NON-NLS-1$
        newStatus = new Status(oldStatus.getSeverity(), oldStatus.getPlugin(), oldStatus.getCode(),
            enhancedMessage, oldStatus.getException());
      }

      return new CoreException(newStatus);
    }
    else {
      if (error instanceof CoreException) {
        return (CoreException) error;
      }
      else {
        return new CoreException(CloudFoundryPlugin.getErrorStatus(error));
      }
    }
  }

  public static String getCloudFoundryErrorMessage(CloudFoundryException cfe) {
    return cfe.getMessage();
  }

}
TOP

Related Classes of org.cloudfoundry.ide.eclipse.server.core.internal.CloudErrorUtil

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.