Coverage Report - org.mule.transport.AbstractMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMessageReceiver
0%
0/80
0%
0/32
0
 
 1  
 /*
 2  
  * $Id: AbstractMessageReceiver.java 19976 2010-10-21 11:06:03Z rossmason $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.transport;
 12  
 
 13  
 import org.mule.DefaultMuleEvent;
 14  
 import org.mule.MessageExchangePattern;
 15  
 import org.mule.OptimizedRequestContext;
 16  
 import org.mule.ResponseOutputStream;
 17  
 import org.mule.api.MuleEvent;
 18  
 import org.mule.api.MuleException;
 19  
 import org.mule.api.MuleMessage;
 20  
 import org.mule.api.MuleSession;
 21  
 import org.mule.api.config.MuleProperties;
 22  
 import org.mule.api.construct.FlowConstruct;
 23  
 import org.mule.api.context.WorkManager;
 24  
 import org.mule.api.endpoint.EndpointURI;
 25  
 import org.mule.api.endpoint.InboundEndpoint;
 26  
 import org.mule.api.lifecycle.CreateException;
 27  
 import org.mule.api.lifecycle.InitialisationException;
 28  
 import org.mule.api.processor.MessageProcessor;
 29  
 import org.mule.api.routing.filter.FilterUnacceptedException;
 30  
 import org.mule.api.transaction.Transaction;
 31  
 import org.mule.api.transformer.Transformer;
 32  
 import org.mule.api.transport.Connector;
 33  
 import org.mule.api.transport.MessageReceiver;
 34  
 import org.mule.api.transport.PropertyScope;
 35  
 import org.mule.session.DefaultMuleSession;
 36  
 import org.mule.session.LegacySessionHandler;
 37  
 import org.mule.transaction.TransactionCoordination;
 38  
 import org.mule.util.ClassUtils;
 39  
 import org.mule.util.ObjectUtils;
 40  
 
 41  
 import java.io.OutputStream;
 42  
 import java.util.List;
 43  
 
 44  
 import org.apache.commons.lang.SerializationException;
 45  
 
 46  
 /**
 47  
  * <code>AbstractMessageReceiver</code> provides common methods for all Message
 48  
  * Receivers provided with Mule. A message receiver enables an endpoint to receive a
 49  
  * message from an external system.
 50  
  */
 51  0
 public abstract class AbstractMessageReceiver extends AbstractConnectable implements MessageReceiver
 52  
 {
 53  
     /**
 54  
      * The Service with which this receiver is associated with
 55  
      */
 56  
     protected FlowConstruct flowConstruct;
 57  
 
 58  
     /**
 59  
      * {@link MessageProcessor} chain used to process messages once the transport
 60  
      * specific {@link MessageReceiver} has received transport message and created
 61  
      * the {@link MuleEvent}
 62  
      */
 63  
     protected MessageProcessor listener;
 64  
 
 65  
     /**
 66  
      * Stores the key to this receiver, as used by the Connector to store the
 67  
      * receiver.
 68  
      */
 69  0
     protected String receiverKey = null;
 70  
 
 71  
     /**
 72  
      * Stores the endpointUri that this receiver listens on. This enpoint can be
 73  
      * different to the endpointUri in the endpoint stored on the receiver as
 74  
      * endpoint endpointUri may get rewritten if this endpointUri is a wildcard
 75  
      * endpointUri such as jms.*
 76  
      */
 77  
     private EndpointURI endpointUri;
 78  
     
 79  
     protected List<Transformer> defaultInboundTransformers;
 80  
     protected List<Transformer> defaultResponseTransformers;
 81  
 
 82  
     /**
 83  
      * Creates the Message Receiver
 84  
      * 
 85  
      * @param connector the endpoint that created this listener
 86  
      * @param service the service to associate with the receiver. When data is
 87  
      *            received the service <code>dispatchEvent</code> or
 88  
      *            <code>sendEvent</code> is used to dispatch the data to the relevant
 89  
      *            Service.
 90  
      * @param endpoint the provider contains the endpointUri on which the receiver
 91  
      *            will listen on. The endpointUri can be anything and is specific to
 92  
      *            the receiver implementation i.e. an email address, a directory, a
 93  
      *            jms destination or port address.
 94  
      * @see flowConstruct
 95  
      * @see InboundEndpoint
 96  
      */
 97  
     public AbstractMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
 98  
         throws CreateException
 99  
     {
 100  0
         super(endpoint);
 101  
 
 102  0
         if (flowConstruct == null)
 103  
         {
 104  0
             throw new IllegalArgumentException("FlowConstruct cannot be null");
 105  
         }
 106  0
         this.flowConstruct = flowConstruct;
 107  0
     }
 108  
 
 109  
     @Override
 110  
     protected ConnectableLifecycleManager createLifecycleManager()
 111  
     {
 112  0
         return new ConnectableLifecycleManager<MessageReceiver>(getReceiverKey(), this);
 113  
     }
 114  
 
 115  
     /**
 116  
      * Method used to perform any initialisation work. If a fatal error occurs during
 117  
      * initialisation an <code>InitialisationException</code> should be thrown,
 118  
      * causing the Mule instance to shutdown. If the error is recoverable, say by
 119  
      * retrying to connect, a <code>RecoverableException</code> should be thrown.
 120  
      * There is no guarantee that by throwing a Recoverable exception that the Mule
 121  
      * instance will not shut down.
 122  
      * 
 123  
      * @throws org.mule.api.lifecycle.InitialisationException if a fatal error occurs
 124  
      *             causing the Mule instance to shutdown
 125  
      * @throws org.mule.api.lifecycle.RecoverableException if an error occurs that
 126  
      *             can be recovered from
 127  
      */
 128  
     @Override
 129  
     public final void initialise() throws InitialisationException
 130  
     {
 131  0
         endpointUri = endpoint.getEndpointURI();
 132  
         
 133  0
         defaultInboundTransformers = connector.getDefaultInboundTransformers(endpoint);       
 134  0
         defaultResponseTransformers = connector.getDefaultResponseTransformers(endpoint);
 135  
         
 136  0
         super.initialise();
 137  0
     }
 138  
 
 139  
     public FlowConstruct getFlowConstruct()
 140  
     {
 141  0
         return flowConstruct;
 142  
     }
 143  
 
 144  
     public final MuleEvent routeMessage(MuleMessage message) throws MuleException
 145  
     {
 146  0
         Transaction tx = TransactionCoordination.getInstance().getTransaction();
 147  0
         return routeMessage(message, tx, null);
 148  
     }
 149  
 
 150  
     public final MuleEvent routeMessage(MuleMessage message, Transaction trans)
 151  
         throws MuleException
 152  
     {
 153  0
         return routeMessage(message, trans, null);
 154  
     }
 155  
 
 156  
     public final MuleEvent routeMessage(MuleMessage message,
 157  
                                           Transaction trans,
 158  
                                           OutputStream outputStream) throws MuleException
 159  
     {
 160  0
         return routeMessage(message, new DefaultMuleSession(connector.getMuleContext()), trans,
 161  
             outputStream);
 162  
     }
 163  
 
 164  
     public final MuleEvent routeMessage(MuleMessage message,
 165  
                                           MuleSession session,
 166  
                                           Transaction trans,
 167  
                                           OutputStream outputStream) throws MuleException
 168  
     {
 169  
 
 170  0
         final Object o = message.getInboundProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY);
 171  0
         if (ObjectUtils.getBoolean(o, false) && !endpoint.getExchangePattern().hasResponse())
 172  
         {
 173  0
             logger.warn("MuleClient.send() was used but inbound endpoint "
 174  
                         + endpoint.getEndpointURI().getUri().toString()
 175  
                         + " is not 'request-response'.  No response will be returned.");
 176  
         }
 177  
         
 178  0
         message.removeProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, PropertyScope.INBOUND);
 179  
 
 180  0
         MuleEvent muleEvent = createMuleEvent(message, outputStream);
 181  0
         muleEvent = OptimizedRequestContext.unsafeSetEvent(muleEvent);
 182  
 
 183  0
         if (!endpoint.isDisableTransportTransformer())
 184  
         {
 185  0
             applyInboundTransformers(muleEvent);            
 186  
         }
 187  0
         MuleEvent resultEvent = listener.process(muleEvent);
 188  0
         if (resultEvent != null && resultEvent.getMessage() != null
 189  
             && resultEvent.getMessage().getExceptionPayload() != null 
 190  
             && resultEvent.getMessage().getExceptionPayload().getException() instanceof FilterUnacceptedException)
 191  
         {
 192  0
             handleUnacceptedFilter(muleEvent.getMessage());
 193  0
             return muleEvent;
 194  
         }
 195  
 
 196  0
         if (endpoint.getExchangePattern()== MessageExchangePattern.REQUEST_RESPONSE && resultEvent != null && resultEvent.getMessage() != null && !endpoint.isDisableTransportTransformer())
 197  
         {
 198  0
             applyResponseTransformers(resultEvent);
 199  
         }
 200  0
         return resultEvent;
 201  
     }
 202  
     
 203  
     protected void applyInboundTransformers(MuleEvent event) throws MuleException
 204  
     {
 205  0
         event.getMessage().applyTransformers(event, defaultInboundTransformers);
 206  0
     }
 207  
 
 208  
     protected void applyResponseTransformers(MuleEvent event) throws MuleException
 209  
     {
 210  0
         event.getMessage().applyTransformers(event, defaultResponseTransformers);
 211  0
     }
 212  
 
 213  
     protected MuleMessage handleUnacceptedFilter(MuleMessage message)
 214  
     {
 215  0
         if (logger.isDebugEnabled())
 216  
         {
 217  
             String messageId;
 218  0
             messageId = message.getUniqueId();
 219  0
             logger.debug("Message " + messageId + " failed to pass filter on endpoint: " + endpoint
 220  
                          + ". Message is being ignored");
 221  
         }
 222  0
         return message;
 223  
     }
 224  
 
 225  
     protected MuleEvent createMuleEvent(MuleMessage message, OutputStream outputStream)
 226  
         throws MuleException
 227  
     {
 228  0
         ResponseOutputStream ros = null;
 229  0
         if (outputStream != null)
 230  
         {
 231  0
             if (outputStream instanceof ResponseOutputStream)
 232  
             {
 233  0
                 ros = (ResponseOutputStream) outputStream;
 234  
             }
 235  
             else
 236  
             {
 237  0
                 ros = new ResponseOutputStream(outputStream);
 238  
             }
 239  
         }
 240  
         MuleSession session;
 241  
         try
 242  
         {
 243  0
             session = connector.getSessionHandler().retrieveSessionInfoFromMessage(message);
 244  
         }
 245  0
         catch (SerializationException e)
 246  
         {
 247  
             // EE-1820 Support message headers generated by previous Mule versions
 248  0
             session = new LegacySessionHandler().retrieveSessionInfoFromMessage(message);
 249  0
         }
 250  0
         if (session != null)
 251  
         {
 252  0
             session.setFlowConstruct(flowConstruct);
 253  
         }
 254  
         else
 255  
         {
 256  0
             session = new DefaultMuleSession(flowConstruct, connector.getMuleContext());
 257  
         }
 258  0
         return new DefaultMuleEvent(message, endpoint, session, ros);
 259  
     }
 260  
 
 261  
     public EndpointURI getEndpointURI()
 262  
     {
 263  0
         return endpointUri;
 264  
     }
 265  
 
 266  
     @Override
 267  
     public String getConnectionDescription()
 268  
     {
 269  0
         return endpoint.getEndpointURI().toString();
 270  
     }
 271  
 
 272  
     protected String getConnectEventId()
 273  
     {
 274  0
         return connector.getName() + ".receiver (" + endpoint.getEndpointURI() + ")";
 275  
     }
 276  
 
 277  
     // TODO MULE-4871 Receiver key should not be mutable
 278  
     public void setReceiverKey(String receiverKey)
 279  
     {
 280  0
         this.receiverKey = receiverKey;
 281  0
     }
 282  
 
 283  
     public String getReceiverKey()
 284  
     {
 285  0
         return receiverKey;
 286  
     }
 287  
 
 288  
     @Override
 289  
     public InboundEndpoint getEndpoint()
 290  
     {
 291  0
         return (InboundEndpoint) super.getEndpoint();
 292  
     }
 293  
 
 294  
     // TODO MULE-4871 Endpoint should not be mutable
 295  
     public void setEndpoint(InboundEndpoint endpoint)
 296  
     {
 297  0
         super.setEndpoint(endpoint);
 298  0
     }
 299  
 
 300  
     @Override
 301  
     protected WorkManager getWorkManager()
 302  
     {
 303  
         try
 304  
         {
 305  0
             return connector.getReceiverWorkManager();
 306  
         }
 307  0
         catch (MuleException e)
 308  
         {
 309  0
             logger.error(e);
 310  0
             return null;
 311  
         }
 312  
     }
 313  
 
 314  
     @Override
 315  
     public String toString()
 316  
     {
 317  0
         final StringBuffer sb = new StringBuffer(80);
 318  0
         sb.append(ClassUtils.getSimpleName(this.getClass()));
 319  0
         sb.append("{this=").append(Integer.toHexString(System.identityHashCode(this)));
 320  0
         sb.append(", receiverKey=").append(receiverKey);
 321  0
         sb.append(", endpoint=").append(endpoint.getEndpointURI());
 322  0
         sb.append('}');
 323  0
         return sb.toString();
 324  
     }
 325  
 
 326  
     public void setListener(MessageProcessor processor)
 327  
     {
 328  0
         this.listener = processor;
 329  0
     }
 330  
 
 331  
     @Override
 332  
     protected void doDispose()
 333  
     {
 334  0
         this.listener = null;
 335  0
         this.flowConstruct = null;
 336  0
         super.doDispose();
 337  0
     }
 338  
 }