Coverage Report - org.mule.providers.vm.VMMessageDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
VMMessageDispatcher
63%
52/83
50%
22/44
4.444
VMMessageDispatcher$1
100%
3/3
N/A
4.444
VMMessageDispatcher$2
100%
2/2
N/A
4.444
 
 1  
 /*
 2  
  * $Id: VMMessageDispatcher.java 10524 2008-01-24 19:20:11Z akuzmin $
 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.providers.vm;
 12  
 
 13  
 import org.mule.MuleManager;
 14  
 import org.mule.config.i18n.CoreMessages;
 15  
 import org.mule.impl.MuleMessage;
 16  
 import org.mule.providers.AbstractMessageDispatcher;
 17  
 import org.mule.providers.vm.i18n.VMMessages;
 18  
 import org.mule.transaction.TransactionCallback;
 19  
 import org.mule.transaction.TransactionTemplate;
 20  
 import org.mule.transformers.simple.ObjectToByteArray;
 21  
 import org.mule.umo.UMOEvent;
 22  
 import org.mule.umo.UMOMessage;
 23  
 import org.mule.umo.endpoint.UMOEndpointURI;
 24  
 import org.mule.umo.endpoint.UMOImmutableEndpoint;
 25  
 import org.mule.umo.provider.DispatchException;
 26  
 import org.mule.umo.provider.NoReceiverForEndpointException;
 27  
 import org.mule.umo.provider.UMOStreamMessageAdapter;
 28  
 import org.mule.util.queue.Queue;
 29  
 import org.mule.util.queue.QueueSession;
 30  
 
 31  
 import java.io.ByteArrayInputStream;
 32  
 import java.io.InputStream;
 33  
 import java.io.PipedInputStream;
 34  
 import java.io.PipedOutputStream;
 35  
 
 36  
 /**
 37  
  * <code>VMMessageDispatcher</code> is used for providing in memory interaction
 38  
  * between components.
 39  
  */
 40  
 public class VMMessageDispatcher extends AbstractMessageDispatcher
 41  
 {
 42  
     private final VMConnector connector;
 43  
     private final ObjectToByteArray objectToByteArray;
 44  
 
 45  
     public VMMessageDispatcher(UMOImmutableEndpoint endpoint)
 46  
     {
 47  46
         super(endpoint);
 48  46
         this.connector = (VMConnector) endpoint.getConnector();
 49  46
         objectToByteArray = new ObjectToByteArray();
 50  46
     }
 51  
 
 52  
     /**
 53  
      * Make a specific request to the underlying transport
 54  
      *
 55  
      * @param timeout the maximum time the operation should block before returning.
 56  
      *                The call should return immediately if there is data available. If
 57  
      *                no data becomes available before the timeout elapses, null will be
 58  
      *                returned
 59  
      * @return the result of the request wrapped in a UMOMessage object. Null will be
 60  
      *         returned if no data was available
 61  
      * @throws Exception if the call to the underlying protocol causes an exception
 62  
      */
 63  
     protected UMOMessage doReceive(long timeout) throws Exception
 64  
     {
 65  14
         if (!connector.isQueueEvents())
 66  
         {
 67  0
             throw new UnsupportedOperationException("Receive requested on VM Connector, but queueEvents is false");
 68  
         }
 69  
 
 70  
         try
 71  
         {
 72  14
             QueueSession queueSession = connector.getQueueSession();
 73  14
             Queue queue = queueSession.getQueue(endpoint.getEndpointURI().getAddress());
 74  
 
 75  14
             if (queue == null)
 76  
             {
 77  0
                 if (logger.isDebugEnabled())
 78  
                 {
 79  0
                     logger.debug("No queue with name " + endpoint.getEndpointURI().getAddress());
 80  
                 }
 81  0
                 return null;
 82  
             }
 83  
             else
 84  
             {
 85  14
                 UMOEvent event = null;
 86  14
                 if (logger.isDebugEnabled())
 87  
                 {
 88  0
                     logger.debug("Waiting for a message on " + endpoint.getEndpointURI().getAddress());
 89  
                 }
 90  
                 try
 91  
                 {
 92  14
                     event = (UMOEvent) queue.poll(timeout);
 93  
                 }
 94  0
                 catch (InterruptedException e)
 95  
                 {
 96  0
                     logger.error("Failed to receive event from queue: " + endpoint.getEndpointURI());
 97  14
                 }
 98  14
                 if (event != null)
 99  
                 {
 100  12
                     if (logger.isDebugEnabled())
 101  
                     {
 102  0
                         logger.debug("Event received: " + event);
 103  
                     }
 104  12
                     return event.getMessage();
 105  
                 }
 106  
                 else
 107  
                 {
 108  2
                     if (logger.isDebugEnabled())
 109  
                     {
 110  0
                         logger.debug("No event received after " + timeout + " ms");
 111  
                     }
 112  2
                     return null;
 113  
                 }
 114  
             }
 115  
         }
 116  0
         catch (Exception e)
 117  
         {
 118  0
             throw e;
 119  
         }
 120  
     }
 121  
 
 122  
     protected void doDispatch(final UMOEvent event) throws Exception
 123  
     {
 124  34
         UMOEndpointURI endpointUri = event.getEndpoint().getEndpointURI();
 125  
 
 126  
         // because this is vm th emessage will not be serialized, even though it will
 127  
         // be passed to a new thread.  so we need to generate a new copy of the message
 128  
         // at this point
 129  
         //event = event.newCopy();
 130  
         // doesn't help needs to be later?
 131  
 
 132  34
         if (endpointUri == null)
 133  
         {
 134  0
             throw new DispatchException(
 135  
                     CoreMessages.objectIsNull("Endpoint"), event.getMessage(), event.getEndpoint());
 136  
         }
 137  34
         if (connector.isQueueEvents())
 138  
         {
 139  24
             QueueSession session = connector.getQueueSession();
 140  24
             Queue queue = session.getQueue(endpointUri.getAddress());
 141  24
             queue.put(event);
 142  24
         }
 143  
         else
 144  
         {
 145  10
             final VMMessageReceiver receiver = connector.getReceiver(event.getEndpoint().getEndpointURI());
 146  10
             if (receiver == null)
 147  
             {
 148  0
                 logger.warn("No receiver for endpointUri: " + event.getEndpoint().getEndpointURI());
 149  0
                 return;
 150  
             }
 151  
 
 152  10
             if (event.isStreaming())
 153  
             {
 154  0
                 PipedInputStream in = new PipedInputStream();
 155  0
                 PipedOutputStream out = new PipedOutputStream(in);
 156  0
                 UMOStreamMessageAdapter sma = connector.getStreamMessageAdapter(in, out);
 157  0
                 sma.write(event);
 158  
             }
 159  10
             TransactionTemplate tt = new TransactionTemplate(receiver.getEndpoint().getTransactionConfig(), connector
 160  
                     .getExceptionListener());
 161  
 
 162  10
             TransactionCallback cb = new TransactionCallback()
 163  
             {
 164  10
                 public Object doInTransaction() throws Exception
 165  
                 {
 166  10
                     receiver.onEvent(event);
 167  10
                     return null;
 168  
                 }
 169  
             };
 170  10
             tt.execute(cb);
 171  
         }
 172  34
         if (logger.isDebugEnabled())
 173  
         {
 174  0
             logger.debug("dispatched Event on endpointUri: " + endpointUri);
 175  
         }
 176  34
     }
 177  
 
 178  
     protected UMOMessage doSend(final UMOEvent event) throws Exception
 179  
     {
 180  8
         UMOMessage retMessage = null;
 181  8
         UMOEndpointURI endpointUri = event.getEndpoint().getEndpointURI();
 182  8
         final VMMessageReceiver receiver = connector.getReceiver(endpointUri);
 183  8
         if (receiver == null)
 184  
         {
 185  4
             if (connector.isQueueEvents())
 186  
             {
 187  4
                 if (logger.isDebugEnabled())
 188  
                 {
 189  0
                     logger.debug("Writing to queue as there is no receiver on connector: "
 190  
                                  + connector.getName() + ", for endpointUri: "
 191  
                                  + event.getEndpoint().getEndpointURI());
 192  
                 }
 193  4
                 doDispatch(event);
 194  4
                 return null;
 195  
             }
 196  
             else
 197  
             {
 198  0
                 throw new NoReceiverForEndpointException(
 199  
                         VMMessages.noReceiverForEndpoint(connector.getName(),
 200  
                                                          event.getEndpoint().getEndpointURI()));
 201  
             }
 202  
         }
 203  4
         if (event.isStreaming())
 204  
         {
 205  0
             PipedInputStream in = new PipedInputStream();
 206  0
             PipedOutputStream out = new PipedOutputStream(in);
 207  0
             UMOStreamMessageAdapter sma = connector.getStreamMessageAdapter(in, out);
 208  0
             sma.write(event);
 209  
         }
 210  
 
 211  4
         TransactionTemplate tt = new TransactionTemplate(receiver.getEndpoint().getTransactionConfig(), connector
 212  
                 .getExceptionListener());
 213  
 
 214  4
         TransactionCallback cb = new TransactionCallback()
 215  
         {
 216  4
             public Object doInTransaction() throws Exception
 217  
             {
 218  4
                 return receiver.onCall(event);
 219  
             }
 220  
         };
 221  4
         retMessage = (UMOMessage) tt.execute(cb);
 222  
 
 223  4
         if (event.isStreaming() && retMessage != null)
 224  
         {
 225  
             InputStream in;
 226  0
             if (retMessage.getPayload() instanceof InputStream)
 227  
             {
 228  0
                 in = (InputStream) retMessage.getPayload();
 229  
             }
 230  
             else
 231  
             {
 232  0
                 in = new ByteArrayInputStream((byte[]) objectToByteArray.transform(retMessage.getPayload()));
 233  
             }
 234  0
             UMOStreamMessageAdapter sma = connector.getStreamMessageAdapter(in, null);
 235  0
             retMessage = new MuleMessage(sma, retMessage);
 236  
         }
 237  
 
 238  4
         if (logger.isDebugEnabled())
 239  
         {
 240  0
             logger.debug("sent event on endpointUri: " + event.getEndpoint().getEndpointURI());
 241  
         }
 242  
 
 243  4
         return retMessage;
 244  
     }
 245  
 
 246  
     protected void doDispose()
 247  
     {
 248  
         // template method
 249  46
     }
 250  
 
 251  
     protected void doConnect() throws Exception
 252  
     {
 253  46
         if (connector.isQueueEvents())
 254  
         {
 255  
             // use the default queue profile to configure this queue.
 256  
             // Todo We may want to allow users to specify this at the connector level
 257  34
             MuleManager.getConfiguration().getQueueProfile().configureQueue(
 258  
                     endpoint.getEndpointURI().getAddress());
 259  
         }
 260  46
     }
 261  
 
 262  
     protected void doDisconnect() throws Exception
 263  
     {
 264  
         // template method
 265  46
     }
 266  
 
 267  
 }