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