View Javadoc
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.api.MuleMessage;
10  import org.mule.api.endpoint.InboundEndpoint;
11  import org.mule.api.retry.RetryContext;
12  import org.mule.transport.AbstractMessageRequester;
13  
14  import java.net.Socket;
15  import java.net.SocketTimeoutException;
16  
17  /**
18   * Request transformed Mule events from TCP.
19   */
20  public class TcpMessageRequester extends AbstractMessageRequester
21  {
22  
23      private final TcpConnector connector;
24  
25      public TcpMessageRequester(InboundEndpoint endpoint)
26      {
27          super(endpoint);
28          this.connector = (TcpConnector) endpoint.getConnector();
29      }
30  
31      /**
32       * Make a specific request to the underlying transport
33       *
34       * @param timeout the maximum time the operation should block before returning.
35       *            The call should return immediately if there is data available. If
36       *            no data becomes available before the timeout elapses, null will be
37       *            returned
38       * @return the result of the request wrapped in a MuleMessage object. Null will be
39       *         returned if no data was available
40       * @throws Exception if the call to the underlying protocal cuases an exception
41       */
42      @Override
43      protected MuleMessage doRequest(long timeout) throws Exception
44      {
45          if (timeout > Integer.MAX_VALUE || timeout < 0)
46          {
47              throw new IllegalArgumentException("Timeout incorrect: " + timeout);
48          }
49          Socket socket = connector.getSocket(endpoint);
50          try
51          {
52              Object result = TcpMessageDispatcher.receiveFromSocket(socket, (int)timeout, endpoint);
53              if (result == null)
54              {
55                  return null;
56              }
57              return createMuleMessage(result, endpoint.getEncoding());
58          }
59          catch (SocketTimeoutException e)
60          {
61              // we don't necesarily expect to receive a resonse here
62              if (logger.isDebugEnabled())
63              {
64                  logger.debug("Socket timed out normally while doing a synchronous receive on endpointUri: "
65                      + endpoint.getEndpointURI());
66              }
67              return null;
68          }
69      }
70  
71      @Override
72      protected synchronized void doDispose()
73      {
74          try
75          {
76              doDisconnect();
77          }
78          catch (Exception e)
79          {
80              logger.error("Failed to shutdown the dispatcher.", e);
81          }
82      }
83  
84      @Override
85      protected void doConnect() throws Exception
86      {
87          // nothing, there is an optional validation in validateConnection()
88      }
89  
90      @Override
91      protected void doDisconnect() throws Exception
92      {
93          //nothing to do
94      }
95  
96      @Override
97      public RetryContext validateConnection(RetryContext retryContext)
98      {
99          Socket socket = null;
100         try
101         {
102             socket = connector.getSocket(endpoint);
103 
104             retryContext.setOk();
105         }
106         catch (Exception ex)
107         {
108             retryContext.setFailed(ex);
109         }
110         finally
111         {
112             if (socket != null)
113             {
114                 try
115                 {
116                     connector.releaseSocket(socket, endpoint);
117                 }
118                 catch (Exception e)
119                 {
120                     if (logger.isDebugEnabled())
121                     {
122                         logger.debug("Failed to release a socket " + socket, e);
123                     }
124                 }
125             }
126         }
127 
128         return retryContext;
129     }
130 }