All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mule.RouteableExceptionStrategy Maven / Gradle / Ivy

There is a newer version: 3.9.0
Show newest version
/*
 * $Id: RouteableExceptionStrategy.java 21336 2011-02-22 19:11:43Z dzapata $
 * --------------------------------------------------------------------------------------
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 *
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */

package org.mule;

import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.construct.FlowConstruct;
import org.mule.api.construct.FlowConstructAware;
import org.mule.api.context.MuleContextAware;
import org.mule.api.endpoint.ImmutableEndpoint;
import org.mule.api.lifecycle.Disposable;
import org.mule.api.lifecycle.Initialisable;
import org.mule.api.lifecycle.InitialisationException;
import org.mule.api.lifecycle.Lifecycle;
import org.mule.api.lifecycle.Stoppable;
import org.mule.api.routing.OutboundRouter;
import org.mule.exception.AbstractMessagingExceptionStrategy;
import org.mule.message.DefaultExceptionPayload;
import org.mule.session.DefaultMuleSession;
import org.mule.transport.NullPayload;
import org.mule.util.ObjectUtils;

import org.apache.commons.lang.exception.ExceptionUtils;

/**
 * RouteableExceptionStrategy allows transforming and routing exceptions
 * to outbound routers. This exception strategy does not take into account any
 * defined endpoints in its instance variable.
 *
 * @author estebanroblesluna
 * @since 2.2.6
 */
public class RouteableExceptionStrategy extends AbstractMessagingExceptionStrategy implements FlowConstructAware, Lifecycle
{

    private OutboundRouter router;

    private boolean stopFurtherProcessing = true;

    /**
     * {@inheritDoc}
     */
    @Override
    public MuleEvent handleException(Exception e, MuleEvent event)
    {
        int currentRootExceptionHashCode = 0;
        int originalRootExceptionHashCode = 0;
        MuleMessage msg = null;

        StringBuffer logInfo = new StringBuffer();

        try
        {
            logInfo.append("****++******Alternate Exception Strategy******++*******\n");
            logInfo.append("Current Thread = " + Thread.currentThread().toString() + "\n");

            if (event != null && event.getFlowConstruct() != null)
            {
                String serviceName = event.getFlowConstruct().getName();
                logInfo.append("serviceName = " + serviceName + "\n");

                int eventHashCode = event.hashCode();
                logInfo.append("eventHashCode = " + eventHashCode + "\n");
            }

            if (event != null && event.isStopFurtherProcessing())
            {
                logInfo.append("MuleEvent stop further processing has been set, This is probably the same exception being routed again. no Exception routing will be performed.\n"
                            + e
                            + "\n");
                event.getMessage().setPayload(NullPayload.getInstance());
                event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
                return event;
            }

            Throwable root = ExceptionUtils.getRootCause(e);
            currentRootExceptionHashCode = root == null ? -1 : root.hashCode();

            msg = event == null ? null : event.getMessage();

            if (msg != null)
            {
                int msgHashCode = msg.hashCode();
                logInfo.append("msgHashCode = " + msgHashCode + "\n");

                if (msg.getExceptionPayload() != null)
                {
                    Throwable t = msg.getExceptionPayload().getRootException();
                    if (t != null && t.hashCode() == currentRootExceptionHashCode)
                    {
                        logInfo.append("*#*#*#*#*\n");
                        logInfo.append("This error has already been handeled, returning without doing anything: "
                                    + e.getMessage()
                                    + "\n");
                        logInfo.append("*#*#*#*#*\n");
                        originalRootExceptionHashCode = currentRootExceptionHashCode;
                        event.getMessage().setPayload(NullPayload.getInstance());
                        event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
                        return event;
                    }
                }

                originalRootExceptionHashCode = msg.getIntProperty("RootExceptionHashCode", 0);

                logInfo.append("Original RootExceptionHashCode: " + originalRootExceptionHashCode + "\n");
                logInfo.append("Current  RootExceptionHashCode: " + currentRootExceptionHashCode + "\n");

                if (originalRootExceptionHashCode == 0)
                {
                    msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
                    originalRootExceptionHashCode = currentRootExceptionHashCode;
                }
                else if (originalRootExceptionHashCode == currentRootExceptionHashCode)
                {
                    logInfo.append("*#*#*#*#*\n");
                    logInfo.append("This error has already been handeled, returning without doing anything: "
                                + e.getMessage()
                                + "\n");
                    logInfo.append("*#*#*#*#*\n");
                    event.getMessage().setPayload(NullPayload.getInstance());
                    event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
                    return event;
                }
                else
                {
                    msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
                }
            }

            logInfo.append(e.getMessage());

            StackTraceElement[] st = e.getStackTrace();
            for (int i = 0; i < st.length; i++)
            {
                if (st[i].getClassName().equals("org.mule.AlternateExceptionStrategy"))
                {
                    logger.warn("*#*#*#*#*\n"
                        + "Recursive error in AlternateExceptionStrategy "
                        + e
                        + "\n"
                        + "*#*#*#*#*");
                    event.getMessage().setPayload(NullPayload.getInstance());
                    event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
                    return event;
                }
                logger.debug(st[i].toString());
            }
            return super.handleException(e, event);
        }
        finally
        {
            if (event != null && this.stopFurtherProcessing) event.setStopFurtherProcessing(true);

            if (msg != null && currentRootExceptionHashCode != 0
                && currentRootExceptionHashCode != originalRootExceptionHashCode)
                msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);

            logInfo.append("****__******Alternate Exception Strategy******__*******\n");
            logger.debug(logInfo.toString());
        }
    }

    /**
     * {@inheritDoc}
     */
    public void handleMessagingException(MuleMessage message, Throwable t)
    {
        defaultHandler(message, t);
        routeException(getMessageFromContext(message), (ImmutableEndpoint) null, t);
    }

    public void handleRoutingException(MuleMessage message, ImmutableEndpoint endpoint, Throwable t)
    {
        defaultHandler(message, t);
        routeException(getMessageFromContext(message), endpoint, t);
    }

    /**
     * {@inheritDoc}
     */
    public void handleLifecycleException(Object component, Throwable t)
    {
        logger.error("The object that failed is: \n" + ObjectUtils.toString(component, "null"));
        handleStandardException(t);
    }

    /**
     * {@inheritDoc}
     */
    public void handleStandardException(Throwable t)
    {
        handleTransaction(t);
        if (RequestContext.getEvent() != null)
        {
            handleMessagingException(RequestContext.getEvent().getMessage(), t);
        }
        else
        {
            logger.info("There is no current event available, routing Null message with the exception");
            handleMessagingException(new DefaultMuleMessage(NullPayload.getInstance(), muleContext), t);
        }
    }

    protected void defaultHandler(MuleMessage message, Throwable t)
    {
        if (RequestContext.getEvent() != null && RequestContext.getEvent().getMessage() != null)
        {
            RequestContext.getEvent().getMessage().setExceptionPayload(new DefaultExceptionPayload(t));
        }

        if (message != null) message.setExceptionPayload(new DefaultExceptionPayload(t));
    }

    protected MuleMessage getMessageFromContext(MuleMessage message)
    {
        if (RequestContext.getEvent() != null)
        {
            return RequestContext.getEvent().getMessage();
        }
        else if (message != null)
        {
            return message;
        }
        else
        {
            return new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
        }
    }

    protected void routeException(MuleMessage msg, ImmutableEndpoint failedEndpoint, Throwable t)
    {
        MuleMessage contextMsg = null;
        MuleEvent exceptionEvent = RequestContext.getEvent();
        contextMsg = exceptionEvent == null ? msg : exceptionEvent.getMessage();

        if (contextMsg == null)
        {
            contextMsg = new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
            contextMsg.setExceptionPayload(new DefaultExceptionPayload(t));
        }

        if (exceptionEvent == null)
        {
            exceptionEvent = new DefaultMuleEvent(contextMsg, failedEndpoint, new DefaultMuleSession(muleContext));
        }

        // copy the message
        DefaultMuleMessage messageCopy = new DefaultMuleMessage(contextMsg.getPayload(), contextMsg, muleContext);

        // route the message
        try
        {
            router.process(exceptionEvent);
        }
        catch (MuleException e)
        {
            logFatal(exceptionEvent, e);
        }
    }

    public OutboundRouter getRouter()
    {
        return router;
    }

    public void setRouter(OutboundRouter router)
    {
        this.router = router;
    }

    public boolean isStopFurtherProcessing()
    {
        return stopFurtherProcessing;
    }

    public void setStopFurtherProcessing(boolean stopFurtherProcessing)
    {
        this.stopFurtherProcessing = stopFurtherProcessing;
    }

    @Override
    public void setFlowConstruct(FlowConstruct flowConstruct)
    {
        if (router instanceof FlowConstructAware)
        {
            router.setFlowConstruct(flowConstruct);
        }
    }

    @Override
    public void setMuleContext(MuleContext context)
    {
        super.setMuleContext(context);
        if (router instanceof MuleContextAware)
        {
            router.setMuleContext(context);
        }
    }

    @Override
    protected void doInitialise(MuleContext muleContext) throws InitialisationException
    {
        super.doInitialise(muleContext);
        if (router instanceof Initialisable)
        {
            router.initialise();
        }
    }

    @Override
    public void dispose()
    {
        super.dispose();
        if (router instanceof Disposable)
        {
            router.dispose();
        }
    }

    @Override
    public void stop() throws MuleException
    {
        if (router instanceof Stoppable)
        {
            router.stop();
        }
    }

    @Override
    public void start() throws MuleException
    {
        if (router instanceof Stoppable)
        {
            router.stop();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy