View Javadoc

1   /*
2    * $Id: LocalSocketTcpMessageDispatcher.java 21943 2011-05-18 14:23:26Z aperepel $
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.OutboundEndpoint;
17  import org.mule.api.retry.RetryContext;
18  import org.mule.api.transformer.TransformerException;
19  import org.mule.transport.NullPayload;
20  
21  import java.io.BufferedOutputStream;
22  import java.io.IOException;
23  import java.net.Socket;
24  import java.net.SocketTimeoutException;
25  
26  /**
27   * <code>LocalSocketTcpMessageDispatcher</code> will send transformed Mule events
28   * over TCP. It contains a local socket that reuses on each message dispatch
29   * 
30   * @since 2.2.6
31   */
32  public class LocalSocketTcpMessageDispatcher extends TcpMessageDispatcher
33  {
34      private AbstractTcpSocketFactory socketFactory;
35  
36      private Socket socket;
37  
38      public LocalSocketTcpMessageDispatcher(OutboundEndpoint endpoint)
39      {
40          super(endpoint);
41          this.socketFactory = this.getConnector().getSocketFactory();
42      }
43  
44      @Override
45      public TcpConnector getConnector()
46      {
47          return (TcpConnector) super.getConnector();
48      }
49  
50      @Override
51      protected void doDispatch(MuleEvent event) throws Exception
52      {
53          dispatchToSocket(event);
54      }
55  
56      @Override
57      protected synchronized MuleMessage doSend(MuleEvent event) throws Exception
58      {
59          try
60          {
61              dispatchToSocket(event);
62              if (returnResponse(event))
63              {
64                  try
65                  {
66                      Object result = receiveFromSocket(socket, event.getTimeout(), endpoint);
67                      if (result == null)
68                      {
69                          return new DefaultMuleMessage(NullPayload.getInstance(), this.getConnector().getMuleContext());
70                      }
71  
72                      if (result instanceof MuleMessage)
73                      {
74                          return (MuleMessage) result;
75                      }
76  
77                      return new DefaultMuleMessage(result, this.getConnector()
78                              .getMuleContext());
79                  }
80                  catch (Exception ex)
81                  {
82                      if (logger.isInfoEnabled())
83                      {
84                          logger.info("Error occurred while Reading; Message: " + ex.getMessage(), ex);
85                      }
86                      closeSocket();
87                      throw ex;
88                  }
89  
90              }
91              else
92              {
93                  return event.getMessage();
94              }
95          }
96          finally
97          {
98              if (!this.getConnector().isKeepSendSocketOpen())
99              {
100                 closeSocket();
101             }
102         }
103     }
104 
105     private void closeSocket()
106     {
107         try
108         {
109             socket.close();
110             socket = null;
111         }
112         catch (Exception ex)
113         {
114             logger.info("Error occurred while closing socket; Message: " + ex.getMessage());
115         }
116     }
117 
118     protected void dispatchToSocket(MuleEvent event) throws Exception
119     {
120         if (socket == null || socket.isClosed())
121         {
122             if (logger.isDebugEnabled())
123             {
124                 logger.debug("Socket is null; Creating... ");
125             }
126             TcpSocketKey socketKey = new TcpSocketKey(endpoint);
127             socket = (Socket) socketFactory.makeObject(socketKey); // connector.getSocket(event.getEndpoint());
128         }
129         if (logger.isDebugEnabled())
130         {
131             logger.debug("Is socket closed? " + (socket != null && socket.isClosed()));
132         }
133         try
134         {
135             Object payload = event.getMessage().getPayload();// getTransformedMessage();
136             // following line was added set the payload in the threadlocal
137             // so that a protocol class can use the thread local and pick the
138             // transformed
139             // message.
140             event.getMessage().setPayload(payload);
141             // OptimizedRequestContext.unsafeRewriteEvent(new DefaultMuleMessage(
142             // payload));
143             write(payload);
144             return;
145         }
146         catch (IOException ioEx)
147         {
148             closeSocket();
149             if (logger.isInfoEnabled())
150             {
151                 logger.info("Error occurred while Writing; Message: " + ioEx.getMessage(), ioEx);
152             }
153             if (ioEx instanceof SocketTimeoutException)
154             {
155                 throw ioEx;
156             }
157         }
158         catch (Exception ex)
159         {
160             logger.info("Unknown Error occurred while Writing; Message: " + ex.getMessage(), ex);
161         }
162     }
163 
164     private void write(Object data) throws IOException, TransformerException
165     {
166         BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
167         this.getConnector().getTcpProtocol().write(bos, data);
168         bos.flush();
169     }
170 
171     @Override
172     public RetryContext validateConnection(RetryContext retryContext)
173     {
174         try
175         {
176             retryContext.setOk();
177         }
178         catch (Exception ex)
179         {
180             retryContext.setFailed(ex);
181         }
182         return retryContext;
183     }
184 }