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