Package com.salesforce.ide.core.internal.aspects

Source Code of com.salesforce.ide.core.internal.aspects.BaseRetryAspect

/*******************************************************************************
* Copyright (c) 2014 Salesforce.com, inc..
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Salesforce.com, inc. - initial API and implementation
******************************************************************************/
package com.salesforce.ide.core.internal.aspects;

import java.util.List;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.springframework.core.Ordered;

import com.salesforce.ide.core.factories.ConnectionFactory;
import com.salesforce.ide.core.factories.MetadataFactory;
import com.salesforce.ide.core.factories.ToolingFactory;
import com.salesforce.ide.core.internal.utils.ForceExceptionUtils;
import com.salesforce.ide.core.internal.utils.Utils;
import com.salesforce.ide.core.remote.Connection;
import com.salesforce.ide.core.remote.ForceConnectionException;
import com.salesforce.ide.core.remote.ForceRemoteException;
import com.salesforce.ide.core.remote.InvalidLoginException;
import com.salesforce.ide.core.remote.MetadataStubExt;
import com.salesforce.ide.core.remote.ToolingStubExt;
import com.sforce.ws.ConnectionException;

public abstract class BaseRetryAspect implements Ordered {

    private static final Logger logger = Logger.getLogger(BaseRetryAspect.class);

    private static final int DEFAULT_MAX_RETRIES = 2;

    protected ConnectionFactory connectionFactory = null;
    protected MetadataFactory metadataFactory = null;
    protected ToolingFactory toolingFactory = null;
    protected int maxRetries = DEFAULT_MAX_RETRIES;
    protected List<Object> retryableCodes = null;
    protected List<Object> reloginCodes = null;
    protected int order = 1;

    //   M E T H O D S
    public ConnectionFactory getConnectionFactory() {
        return connectionFactory;
    }

    public void setConnectionFactory(ConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    public MetadataFactory getMetadataFactory() {
        return metadataFactory;
    }

    public void setMetadataFactory(MetadataFactory metadataFactory) {
        this.metadataFactory = metadataFactory;
    }

    public ToolingFactory getToolingFactory() {
        return toolingFactory;
    }

    public void setToolingFactory(ToolingFactory toolingFactory) {
        this.toolingFactory = toolingFactory;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public void setMaxRetries(int maxRetries) {
        this.maxRetries = maxRetries;
    }

    public void setRetryableCodes(List<Object> retryableCodes) {
        this.retryableCodes = retryableCodes;
    }

    public void setReloginCodes(List<Object> reloginCodes) {
        this.reloginCodes = reloginCodes;
    }

    public void evaluateLoginException(ForceConnectionException ex, JoinPoint joinPoint) throws InvalidLoginException,
            ForceConnectionException, ForceRemoteException {
        if (isLoginExceptionRetryable(ex, joinPoint) || isConnectionExceptionRetryable(ex, joinPoint)) {
            return;
        }

        throw ex;
    }

    private boolean isLoginExceptionRetryable(ForceConnectionException ex, JoinPoint joinPoint)
            throws InvalidLoginException {
        Throwable th = ForceExceptionUtils.getRootCause(ex);
        String message = Utils.isNotEmpty(th.getMessage()) ? th.getMessage() : ex.getMessage();

        logThrowable(th, message);

        if (th instanceof java.net.SocketException) {
            if (Utils.isNotEmpty(message) && message.contains("Connection reset")) {
                if (logger.isInfoEnabled()) {
                    logger.info("Exception deemed retry worthy");
                }
                return true;
            }
        }

        logger.warn("Login evaluation deemed exception not retry-able:\n " + th.getClass().getSimpleName() + ": "
                + message);

        return false;
    }

    public void evaluateConnectionException(ForceConnectionException ex, JoinPoint joinPoint)
            throws ForceConnectionException, ForceRemoteException {
        if (!isConnectionExceptionRetryable(ex, joinPoint)) {
            throw ex;
        }
    }

    private boolean isConnectionExceptionRetryable(ForceConnectionException ex, JoinPoint joinPoint)
            throws ForceConnectionException, ForceRemoteException {
        Throwable th = ForceExceptionUtils.getRootCause(ex);
        String message = Utils.isNotEmpty(th.getMessage()) ? th.getMessage() : ex.getMessage();

        logThrowable(th, message);

        if (th instanceof java.net.SocketException) {
            if (Utils.isNotEmpty(message) && message.contains("Connection reset")) {
                if (logger.isInfoEnabled()) {
                    logger.info("Exception deemed retry worthy");
                }
                refreshConnection(joinPoint);
                return true;
            }
        } else if (th instanceof com.sforce.soap.partner.fault.wsc.ApiFault) {
            String code = ForceExceptionUtils.getExceptionCode(th);
            if (evaluateExceptionCode(code)) {
                relogin(code, joinPoint);
                return true;
            }
        }

        logger.warn("Connection evaluation deemed exception not retry-able:\n " + th.getClass().getSimpleName() + ": "
                + message);

        return false;
    }

    public void evaluateOperationsException(ForceConnectionException ex, JoinPoint joinPoint)
            throws ForceConnectionException, ForceRemoteException {
        if (isConnectionExceptionRetryable(ex, joinPoint) || isOperationsExceptionRetryable(ex, joinPoint)) {
            return;
        }

        throw ex;
    }

    private boolean isOperationsExceptionRetryable(ForceConnectionException ex, JoinPoint joinPoint)
            throws ForceConnectionException, ForceRemoteException {
        Throwable th = ForceExceptionUtils.getRootCause(ex);
        String message = Utils.isNotEmpty(th.getMessage()) ? th.getMessage() : ex.getMessage();

        logThrowable(th, message);

        if (th instanceof java.rmi.RemoteException) {
            if (evaluateExceptionCode(message)) {
                relogin(message, joinPoint);
                return true;
            }
        }

        logger.warn("Operataions evaluation deemed exception not retry-able:\n " + th.getClass().getSimpleName() + ": "
                + message);

        return false;
    }

    public void evaluateException(Exception ex, JoinPoint joinPoint) throws Exception {
        if (!isExceptionRetryable(ex, joinPoint)) {
            throw ex;
        }
    }

    private boolean isExceptionRetryable(Exception ex, JoinPoint joinPoint) throws Exception {
        Throwable th = ForceExceptionUtils.getRootCause(ex);
        String message = Utils.isNotEmpty(th.getMessage()) ? th.getMessage() : ex.getMessage();

        logThrowable(th, message);

        if (th instanceof java.net.SocketException) {
            if (Utils.isNotEmpty(message) && message.contains("Connection reset")) {
                if (logger.isInfoEnabled()) {
                    logger.info("Exception deemed retry worthy");
                }
                refreshConnection(joinPoint);
                return true;
            }
        } else if (th instanceof com.sforce.soap.partner.fault.wsc.ApiFault) {
            String code = ForceExceptionUtils.getExceptionCode(th);
            if (evaluateExceptionCode(code)) {
                relogin(code, joinPoint);
                return true;
            }
        } else if (th instanceof java.rmi.RemoteException || th instanceof ConnectionException) {
            if (evaluateExceptionCode(message)) {
                relogin(message, joinPoint);
                return true;
            }
        }

        logger.warn("General evaluation deemed exception not retry-able:\n " + th.getClass().getSimpleName() + ": "
                + message);

        return false;
    }

    private boolean evaluateExceptionCode(String code) {
        if (Utils.isEmpty(code)) {
            return false;
        }

        for (Object retryableCode : retryableCodes) {
            if (code.equals(retryableCode.toString()) || code.contains(retryableCode.toString())) {
                if (logger.isInfoEnabled()) {
                    logger.info("Exception deemed retry worthy");
                }
                return true;
            }
        }

        return false;
    }

    private void relogin(String code, JoinPoint joinPoint) throws ForceConnectionException, ForceRemoteException {
        if (Utils.isEmpty(code)) {
            return;
        }

        for (Object reloginCode : reloginCodes) {
            if (code.equals(reloginCode.toString()) || code.contains(reloginCode.toString())) {
                if (logger.isInfoEnabled()) {
                    logger.info("Exception calls for relogin");
                }
                refreshConnection(joinPoint);
                return;
            }
        }
    }

    protected Connection getConnection(JoinPoint joinPoint) {
        Object obj = joinPoint.getTarget();
        if (obj instanceof Connection) {
            return (Connection) joinPoint;
        } else if (obj instanceof MetadataStubExt) {
            return ((MetadataStubExt) obj).getConnection();
        } else if (obj instanceof ToolingStubExt) {
            return ((ToolingStubExt) obj).getConnection();
        }

        return null;
    }

    protected void refreshConnection(JoinPoint joinPoint) throws ForceConnectionException, ForceRemoteException {
        Object obj = joinPoint.getTarget();
        try {
            if (obj instanceof Connection) {
                Connection connection = (Connection) obj;
                connection = connectionFactory.refreshConnection(connection);
            } else if (obj instanceof MetadataStubExt) {
                MetadataStubExt metadataStubExt = (MetadataStubExt) obj;
                Connection connection = metadataStubExt.getConnection();
                connection = connectionFactory.refreshConnection(connection);
                metadataStubExt = metadataFactory.refreshMetadataStubExt(connection);
            } else if (obj instanceof ToolingStubExt) {
                ToolingStubExt toolingStubExt = (ToolingStubExt) obj;
                Connection connection = toolingStubExt.getConnection();
                connection = connectionFactory.refreshConnection(connection);
                toolingStubExt = toolingFactory.refreshToolingStubExt(connection);
            }
        } catch (Exception e) {
            logger.warn("Unable to refresh connection", e);
        }
    }

    protected void logThrowable(Throwable th, String message) {
        if (logger.isDebugEnabled()) {
            logger.debug("Evaluating " + th.getClass().getSimpleName() + " for recovery and/or retry:\n " + message);
        }
    }
}
TOP

Related Classes of com.salesforce.ide.core.internal.aspects.BaseRetryAspect

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.