Coverage Report - org.mule.transport.tcp.TcpMessageDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
TcpMessageDispatcher
0%
0/57
0%
0/16
0
TcpMessageDispatcher$1
0%
0/10
N/A
0
 
 1  
 /*
 2  
  * $Id: TcpMessageDispatcher.java 19191 2010-08-25 21:05:23Z 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.tcp;
 12  
 
 13  
 import org.mule.DefaultMuleMessage;
 14  
 import org.mule.api.MuleEvent;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.endpoint.ImmutableEndpoint;
 17  
 import org.mule.api.endpoint.OutboundEndpoint;
 18  
 import org.mule.api.retry.RetryContext;
 19  
 import org.mule.api.transformer.TransformerException;
 20  
 import org.mule.transport.AbstractMessageDispatcher;
 21  
 import org.mule.transport.NullPayload;
 22  
 
 23  
 import java.io.BufferedInputStream;
 24  
 import java.io.BufferedOutputStream;
 25  
 import java.io.DataInputStream;
 26  
 import java.io.IOException;
 27  
 import java.net.Socket;
 28  
 import java.net.SocketTimeoutException;
 29  
 
 30  
 /**
 31  
  * Send transformed Mule events over TCP.
 32  
  */
 33  
 public class TcpMessageDispatcher extends AbstractMessageDispatcher
 34  
 {
 35  
 
 36  
     private final TcpConnector connector;
 37  
 
 38  
     public TcpMessageDispatcher(OutboundEndpoint endpoint)
 39  
     {
 40  0
         super(endpoint);
 41  0
         this.connector = (TcpConnector) endpoint.getConnector();
 42  0
     }
 43  
 
 44  
     @Override
 45  
     protected synchronized void doDispatch(MuleEvent event) throws Exception
 46  
     {
 47  0
         Socket socket = connector.getSocket(event.getEndpoint());
 48  
         try 
 49  
         {
 50  0
             dispatchToSocket(socket, event);
 51  
         }
 52  
         finally 
 53  
         {
 54  0
             connector.releaseSocket(socket, event.getEndpoint());
 55  0
         }
 56  0
     }
 57  
 
 58  
     @Override
 59  
     protected synchronized MuleMessage doSend(MuleEvent event) throws Exception
 60  
     {
 61  0
         Socket socket = connector.getSocket(event.getEndpoint());
 62  0
         dispatchToSocket(socket, event);
 63  
 
 64  
         try 
 65  
         {
 66  0
             if (returnResponse(event))
 67  
             {
 68  
                 try
 69  
                 {
 70  0
                     Object result = receiveFromSocket(socket, event.getTimeout(), endpoint);
 71  0
                     if (result == null)
 72  
                     {
 73  0
                         return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
 74  
                     }
 75  
                     
 76  0
                     if (result instanceof MuleMessage)
 77  
                     {
 78  0
                         return (MuleMessage) result;
 79  
                     }
 80  
                     
 81  0
                     return createMuleMessage(result, endpoint.getEncoding());
 82  
                 }
 83  0
                 catch (SocketTimeoutException e)
 84  
                 {
 85  
                     // we don't necessarily expect to receive a response here
 86  0
                     logger.info("Socket timed out normally while doing a synchronous receive on endpointUri: "
 87  
                         + event.getEndpoint().getEndpointURI());
 88  0
                     return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
 89  
                 }
 90  
             }
 91  
             else
 92  
             {
 93  0
                 return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
 94  
             }
 95  
         }
 96  
         finally
 97  
         {
 98  0
             if (!returnResponse(event))
 99  
             {
 100  0
                 connector.releaseSocket(socket, endpoint);
 101  
             }
 102  
         }
 103  
         
 104  
     }
 105  
 
 106  
     // Socket management (get and release) is handled outside this method
 107  
     private void dispatchToSocket(Socket socket, MuleEvent event) throws Exception
 108  
     {
 109  0
         Object payload = event.getMessage().getPayload();
 110  0
         write(socket, payload);
 111  0
     }
 112  
 
 113  
     private void write(Socket socket, Object data) throws IOException, TransformerException
 114  
     {
 115  0
         BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
 116  0
         connector.getTcpProtocol().write(bos, data);
 117  0
         bos.flush();
 118  0
     }
 119  
 
 120  
     protected static Object receiveFromSocket(final Socket socket, int timeout, final ImmutableEndpoint endpoint)
 121  
             throws IOException
 122  
     {
 123  0
         final TcpConnector connector = (TcpConnector) endpoint.getConnector();
 124  0
         DataInputStream underlyingIs = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
 125  0
         TcpInputStream tis = new TcpInputStream(underlyingIs)
 126  0
         {
 127  
             @Override
 128  
             public void close() throws IOException
 129  
             {
 130  
                 try
 131  
                 {
 132  0
                     connector.releaseSocket(socket, endpoint);
 133  
                 }
 134  0
                 catch (IOException e)
 135  
                 {
 136  0
                    throw e;
 137  
                 }
 138  0
                 catch (Exception e)
 139  
                 {
 140  0
                     IOException e2 = new IOException();
 141  0
                     e2.initCause(e);
 142  0
                     throw e2;
 143  0
                 }
 144  0
             }
 145  
 
 146  
         };
 147  
 
 148  0
         if (timeout >= 0)
 149  
         {
 150  0
             socket.setSoTimeout(timeout);
 151  
         }
 152  
 
 153  
         try
 154  
         {
 155  0
             return connector.getTcpProtocol().read(tis);
 156  
         }
 157  
         finally
 158  
         {
 159  0
             if (!tis.isStreaming())
 160  
             {
 161  0
                 tis.close();
 162  
             }
 163  
         }
 164  
     }
 165  
 
 166  
     @Override
 167  
     protected synchronized void doDispose()
 168  
     {
 169  
         try
 170  
         {
 171  0
             doDisconnect();
 172  
         }
 173  0
         catch (Exception e)
 174  
         {
 175  0
             logger.error("Failed to shutdown the dispatcher.", e);
 176  0
         }
 177  0
     }
 178  
 
 179  
     @Override
 180  
     protected void doConnect() throws Exception
 181  
     {
 182  
         // nothing, there is an optional validation in validateConnection()
 183  0
     }
 184  
 
 185  
     @Override
 186  
     protected void doDisconnect() throws Exception
 187  
     {
 188  
         //nothing to do
 189  0
     }
 190  
 
 191  
     @Override
 192  
     public RetryContext validateConnection(RetryContext retryContext)
 193  
     {
 194  0
         Socket socket = null;
 195  
         try
 196  
         {
 197  0
             socket = connector.getSocket(endpoint);
 198  
 
 199  0
             retryContext.setOk();
 200  
         }
 201  0
         catch (Exception ex)
 202  
         {
 203  0
             retryContext.setFailed(ex);
 204  
         }
 205  
         finally
 206  
         {
 207  0
             if (socket != null)
 208  
             {
 209  
                 try
 210  
                 {
 211  0
                     connector.releaseSocket(socket, endpoint);
 212  
                 }
 213  0
                 catch (Exception e)
 214  
                 {
 215  0
                     if (logger.isDebugEnabled())
 216  
                     {
 217  0
                         logger.debug("Failed to release a socket " + socket, e);
 218  
                     }
 219  0
                 }
 220  
             }
 221  
         }
 222  
         
 223  0
         return retryContext;
 224  
     }
 225  
 }