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