Coverage Report - org.mule.transport.AbstractMessageDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMessageDispatcher
0%
0/57
0%
0/36
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.transport;
 8  
 
 9  
 import org.mule.DefaultMuleEvent;
 10  
 import org.mule.DefaultMuleMessage;
 11  
 import org.mule.RequestContext;
 12  
 import org.mule.api.MuleEvent;
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.MuleMessage;
 15  
 import org.mule.api.MuleSession;
 16  
 import org.mule.api.config.MuleProperties;
 17  
 import org.mule.api.context.WorkManager;
 18  
 import org.mule.api.endpoint.OutboundEndpoint;
 19  
 import org.mule.api.service.Service;
 20  
 import org.mule.api.transformer.Transformer;
 21  
 import org.mule.api.transport.DispatchException;
 22  
 import org.mule.api.transport.MessageDispatcher;
 23  
 import org.mule.service.ServiceAsyncReplyCompositeMessageSource;
 24  
 
 25  
 import java.util.List;
 26  
 
 27  
 /**
 28  
  * Abstract implementation of an outbound channel adaptors. Outbound channel adaptors
 29  
  * send messages over over a specific transport. Different implementations may
 30  
  * support different Message Exchange Patterns.
 31  
  */
 32  0
 public abstract class AbstractMessageDispatcher extends AbstractTransportMessageHandler implements MessageDispatcher
 33  
 {
 34  
 
 35  
     protected List<Transformer> defaultOutboundTransformers;
 36  
     protected List<Transformer> defaultResponseTransformers;
 37  
 
 38  
     public AbstractMessageDispatcher(OutboundEndpoint endpoint)
 39  
     {
 40  0
         super(endpoint);
 41  0
     }
 42  
 
 43  
     @Override
 44  
     protected ConnectableLifecycleManager createLifecycleManager()
 45  
     {
 46  0
         defaultOutboundTransformers = connector.getDefaultOutboundTransformers(endpoint);       
 47  0
         defaultResponseTransformers = connector.getDefaultResponseTransformers(endpoint);       
 48  0
         return new ConnectableLifecycleManager<MessageDispatcher>(getDispatcherName(), this);
 49  
     }
 50  
 
 51  
     protected String getDispatcherName()
 52  
     {
 53  0
         return getConnector().getName() + ".dispatcher." + System.identityHashCode(this);
 54  
     }
 55  
     
 56  
 
 57  
 
 58  
     public MuleEvent process(MuleEvent event) throws MuleException
 59  
     {
 60  0
         MuleEvent resultEvent = null;
 61  
         try
 62  
         {
 63  0
             connect();
 64  
 
 65  0
             String prop = event.getMessage().getOutboundProperty(MuleProperties.MULE_DISABLE_TRANSPORT_TRANSFORMER_PROPERTY);
 66  0
             boolean disableTransportTransformer = (prop != null && Boolean.parseBoolean(prop)) || endpoint.isDisableTransportTransformer();
 67  
                         
 68  0
             if (!disableTransportTransformer)
 69  
             {
 70  0
                 applyOutboundTransformers(event);            
 71  
             }
 72  
             // TODO this is the same logic as in OptionalAsyncInterceptingMessageProcessor.  Better to have it in one place
 73  0
             Object forceSyncPropertyValue = event.getMessage().getInboundProperty(MuleProperties.MULE_FORCE_SYNC_PROPERTY);
 74  0
             boolean forceSync = Boolean.TRUE.equals(forceSyncPropertyValue);
 75  0
             boolean hasResponse = endpoint.getExchangePattern().hasResponse();
 76  0
             boolean isTransacted = endpoint.getTransactionConfig().isTransacted();
 77  0
             connector.getSessionHandler().storeSessionInfoToMessage(event.getSession(),event.getMessage());
 78  0
             if (forceSync || hasResponse || isTransacted)
 79  
             {
 80  0
                 MuleMessage resultMessage = doSend(event);
 81  0
                 if (hasResponse && resultMessage != null)
 82  
                 {
 83  0
                     MuleSession storedSession = connector.getSessionHandler().retrieveSessionInfoFromMessage(resultMessage);
 84  0
                     event.getSession().merge(storedSession);
 85  0
                     resultEvent = new DefaultMuleEvent(resultMessage, endpoint, event, event.getSession());
 86  0
                     RequestContext.setEvent(resultEvent);
 87  0
                     ((DefaultMuleMessage) resultEvent.getMessage()).copyInvocationProperties(event.getMessage());
 88  
                     // TODO It seems like this should go here but it causes unwanted behaviour and breaks test cases.
 89  
                     //if (!disableTransportTransformer)
 90  
                     //{
 91  
                     //    applyResponseTransformers(resultEvent);            
 92  
                     //}
 93  
                 }
 94  0
             }
 95  
             else
 96  
             {
 97  0
                 doDispatch(event);
 98  
             }
 99  
         }
 100  0
         catch (MuleException muleException)
 101  
         {
 102  0
             throw muleException;
 103  
         }
 104  0
         catch (Exception e)
 105  
         {
 106  0
             throw new DispatchException(event, (OutboundEndpoint) endpoint, e);
 107  0
         }
 108  0
         return resultEvent;
 109  
     }
 110  
 
 111  
     /**
 112  
      * @deprecated
 113  
      */
 114  
     @Deprecated
 115  
     protected boolean returnResponse(MuleEvent event)
 116  
     {
 117  
         // Pass through false to conserve the existing behavior of this method but
 118  
         // avoid duplication of code.
 119  0
         return returnResponse(event, false);
 120  
     }
 121  
 
 122  
     /**
 123  
      * Used to determine if the dispatcher implementation should wait for a response
 124  
      * to an event on a response channel after it sends the event. The following
 125  
      * rules apply:
 126  
      * <ol>
 127  
      * <li>The connector has to support "back-channel" response. Some transports do
 128  
      * not have the notion of a response channel.
 129  
      * <li>Check if the endpoint is synchronous (outbound synchronicity is not
 130  
      * explicit since 2.2 and does not use the remoteSync message property).
 131  
      * <li>Or, if the send() method on the dispatcher was used. (This is required
 132  
      * because the ChainingRouter uses send() with async endpoints. See MULE-4631).
 133  
      * <li>Finally, if the current service has a response router configured, that the
 134  
      * router will handle the response channel event and we should not try and
 135  
      * receive a response in the Message dispatcher If remotesync should not be used
 136  
      * we must remove the REMOTE_SYNC header Note the MuleClient will automatically
 137  
      * set the REMOTE_SYNC header when client.send(..) is called so that results are
 138  
      * returned from remote invocations too.
 139  
      * </ol>
 140  
      * 
 141  
      * @param event the current event
 142  
      * @return true if a response channel should be used to get a response from the
 143  
      *         event dispatch.
 144  
      */
 145  
     protected boolean returnResponse(MuleEvent event, boolean doSend)
 146  
     {
 147  0
         boolean remoteSync = false;
 148  0
         if (event.getEndpoint().getConnector().isResponseEnabled())
 149  
         {
 150  0
             boolean hasResponse = event.getEndpoint().getExchangePattern().hasResponse();
 151  0
             remoteSync = hasResponse || doSend;
 152  0
             if (remoteSync)
 153  
             {
 154  
                 // service will be null for client calls
 155  0
                 if (event.getFlowConstruct() != null && event.getFlowConstruct() instanceof Service)
 156  
                 {
 157  0
                     ServiceAsyncReplyCompositeMessageSource responseRouters = ((Service) event.getFlowConstruct()).getAsyncReplyMessageSource();
 158  0
                     if (responseRouters != null && responseRouters.getEndpoints().size() > 0)
 159  
                     {
 160  0
                         remoteSync = false;
 161  
                     }
 162  
                     else
 163  
                     {
 164  0
                         remoteSync = true;
 165  
                     }
 166  
                 }
 167  
             }
 168  
         }
 169  0
         if (!remoteSync)
 170  
         {
 171  0
             event.getMessage().removeProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY);
 172  
         }
 173  0
         return remoteSync;
 174  
     }
 175  
 
 176  
     @Override
 177  
     protected WorkManager getWorkManager()
 178  
     {
 179  
         try
 180  
         {
 181  0
             return connector.getDispatcherWorkManager();
 182  
         }
 183  0
         catch (MuleException e)
 184  
         {
 185  0
             logger.error(e);
 186  0
             return null;
 187  
         }
 188  
     }
 189  
 
 190  
     @Override
 191  
     public OutboundEndpoint getEndpoint()
 192  
     {
 193  0
         return (OutboundEndpoint) super.getEndpoint();
 194  
     }
 195  
     
 196  
     protected void applyOutboundTransformers(MuleEvent event) throws MuleException
 197  
     {
 198  0
         event.getMessage().applyTransformers(event, defaultOutboundTransformers);
 199  0
     }
 200  
 
 201  
     protected void applyResponseTransformers(MuleEvent event) throws MuleException
 202  
     {
 203  0
         event.getMessage().applyTransformers(event, defaultResponseTransformers);
 204  0
     }
 205  
 
 206  
     protected abstract void doDispatch(MuleEvent event) throws Exception;
 207  
 
 208  
     protected abstract MuleMessage doSend(MuleEvent event) throws Exception;
 209  
 }