Coverage Report - org.mule.routing.outbound.ExceptionBasedRouter
 
Classes in this File Line Coverage Branch Coverage Complexity
ExceptionBasedRouter
94%
44/47
74%
25/34
7
 
 1  
 /*
 2  
  * $Id: ExceptionBasedRouter.java 12181 2008-06-26 20:05:55Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.routing.outbound;
 12  
 
 13  
 import org.mule.api.ExceptionPayload;
 14  
 import org.mule.api.MuleException;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.MuleSession;
 17  
 import org.mule.api.endpoint.ImmutableEndpoint;
 18  
 import org.mule.api.endpoint.OutboundEndpoint;
 19  
 import org.mule.api.routing.CouldNotRouteOutboundMessageException;
 20  
 import org.mule.api.routing.RoutePathNotFoundException;
 21  
 import org.mule.api.routing.RoutingException;
 22  
 import org.mule.config.ExceptionHelper;
 23  
 import org.mule.config.i18n.CoreMessages;
 24  
 import org.mule.transaction.TransactionTemplate;
 25  
 
 26  
 /**
 27  
  * <code>ExceptionBasedRouter</code> Will send the current event to the first
 28  
  * endpoint that doesn't throw an exception. If all attempted endpoints fail then an
 29  
  * exception is thrown. <p/> The router will override the sync/async mode of the
 30  
  * endpoint and force the sync mode for all endpoints except the last one.
 31  
  * <code>remoteSync</code> is also enforced.
 32  
  */
 33  
 
 34  10
 public class ExceptionBasedRouter extends FilteringOutboundRouter
 35  
 {
 36  
 
 37  
     public MuleMessage route(MuleMessage message, MuleSession session, boolean synchronous)
 38  
         throws RoutingException
 39  
     {
 40  12
         if (endpoints == null || endpoints.size() == 0)
 41  
         {
 42  0
             throw new RoutePathNotFoundException(CoreMessages.noEndpointsForRouter(), message, null);
 43  
         }
 44  
 
 45  12
         final int endpointsCount = endpoints.size();
 46  
 
 47  12
         if (enableCorrelation != ENABLE_CORRELATION_NEVER)
 48  
         {
 49  12
             boolean correlationSet = message.getCorrelationId() != null;
 50  12
             if (correlationSet && (enableCorrelation == ENABLE_CORRELATION_IF_NOT_SET))
 51  
             {
 52  0
                 logger.debug("CorrelationId is already set, not setting Correlation group size");
 53  
             }
 54  
             else
 55  
             {
 56  
                 // the correlationId will be set by the AbstractOutboundRouter
 57  12
                 message.setCorrelationGroupSize(endpointsCount);
 58  
             }
 59  
         }
 60  
 
 61  12
         MuleMessage result = null;
 62  
         // need that ref for an error message
 63  12
         OutboundEndpoint endpoint = null;
 64  12
         boolean success = false;
 65  
 
 66  12
         synchronized (endpoints)
 67  
         {
 68  22
             for (int i = 0; i < endpointsCount; i++)
 69  
             {
 70  
                 // apply endpoint URI templates if any
 71  20
                 endpoint = getEndpoint(i, message);
 72  20
                 boolean lastEndpoint = (i == endpointsCount - 1);
 73  
 
 74  20
                 if (!lastEndpoint)
 75  
                 {
 76  12
                     logger.info("Sync mode will be forced for " + endpoint.getEndpointURI()
 77  
                                 + ", as there are more endpoints available.");
 78  
                 }
 79  
 
 80  20
                 if (!lastEndpoint || synchronous)
 81  
                 {
 82  
                     try
 83  
                     {
 84  16
                         result = send(session, message, endpoint);
 85  10
                         if (!exceptionPayloadAvailable(result))
 86  
                         {
 87  8
                             if (logger.isDebugEnabled())
 88  
                             {
 89  0
                                 logger.debug("Successful invocation detected, stopping further processing.");
 90  
                             }
 91  8
                             success = true;
 92  8
                             break;
 93  
                         }
 94  
                     }
 95  6
                     catch (MuleException e)
 96  
                     {
 97  6
                         if(logger.isWarnEnabled())
 98  
                         {
 99  6
                             Throwable t = ExceptionHelper.getRootException(e);
 100  6
                             logger.warn("Failed to send to endpoint: " + endpoint.getEndpointURI().toString()
 101  
                                     + ". Error was: " + t + ". Trying next endpoint", t);
 102  
                         }
 103  8
                     }
 104  
                 }
 105  
                 else
 106  
                 {
 107  
                     try
 108  
                     {
 109  4
                         dispatch(session, message, endpoint);
 110  2
                         success = true;
 111  2
                         break;
 112  
                     }
 113  2
                     catch (MuleException e)
 114  
                     {
 115  2
                         logger.info("Failed to dispatch to endpoint: " + endpoint.getEndpointURI().toString()
 116  
                                     + ". Error was: " + e.getMessage() + ". Trying next endpoint");
 117  
                     }
 118  
                 }
 119  
             }
 120  12
         }
 121  
 
 122  12
         if (!success)
 123  
         {
 124  2
             throw new CouldNotRouteOutboundMessageException(message, endpoint);
 125  
         }
 126  
 
 127  10
         return result;
 128  
     }
 129  
 
 130  
 //    public void addEndpoint(Endpoint endpoint)
 131  
 //    {
 132  
 //        if (!endpoint.isRemoteSync())
 133  
 //        {
 134  
 //            logger.debug("Endpoint: "
 135  
 //                         + endpoint.getEndpointURI()
 136  
 //                         + " registered on ExceptionBasedRouter needs to be RemoteSync enabled. Setting this property now.");
 137  
 //            endpoint.setRemoteSync(true);
 138  
 //        }
 139  
 //        super.addEndpoint(endpoint);
 140  
 //    }
 141  
 
 142  
     /**
 143  
      * @param message message to check
 144  
      * @return true if there was an exception payload set
 145  
      */
 146  
     protected boolean exceptionPayloadAvailable(MuleMessage message)
 147  
     {
 148  10
         if (message == null)
 149  
         {
 150  2
             return false;
 151  
         }
 152  
 
 153  8
         final ExceptionPayload exceptionPayload = message.getExceptionPayload();
 154  8
         if (exceptionPayload != null)
 155  
         {
 156  2
             logger.info("Failure returned, will try next endpoint. Exception payload is: " + exceptionPayload);
 157  2
             return true;
 158  
         }
 159  
         else
 160  
         {
 161  6
             return false;
 162  
         }
 163  
     }
 164  
     
 165  
     protected TransactionTemplate createTransactionTemplate(MuleSession session, ImmutableEndpoint endpoint)
 166  
     {
 167  20
         return new TransactionTemplate(endpoint.getTransactionConfig(), null, muleContext);
 168  
     }
 169  
 }