View Javadoc

1   /*
2    * $Id: UdpMessageDispatcher.java 22156 2011-06-08 21:36:30Z dfeist $
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.udp;
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.DataType;
20  import org.mule.transport.AbstractMessageDispatcher;
21  import org.mule.transport.NullPayload;
22  
23  import java.io.IOException;
24  import java.net.DatagramPacket;
25  import java.net.DatagramSocket;
26  import java.net.InetAddress;
27  
28  /**
29   * <code>UdpMessageDispatcher</code> is responsible for dispatching MuleEvents as
30   * UDP packets on the network
31   */
32  
33  public class UdpMessageDispatcher extends AbstractMessageDispatcher
34  {
35      protected final UdpConnector connector;
36  
37      public UdpMessageDispatcher(OutboundEndpoint endpoint)
38      {
39          super(endpoint);
40          this.connector = (UdpConnector)endpoint.getConnector();
41      }
42  
43      @Override
44      public RetryContext validateConnection(RetryContext retryContext)
45      {
46          DatagramSocket socket = null;
47          try
48          {
49              socket = connector.getSocket(endpoint);
50  
51              retryContext.setOk();
52          }
53          catch (Exception ex)
54          {
55              retryContext.setFailed(ex);
56          }
57          finally
58          {
59              if (socket != null)
60              {
61                  try
62                  {
63                      connector.releaseSocket(socket, endpoint);
64                  }
65                  catch (Exception e)
66                  {
67                      if (logger.isDebugEnabled())
68                      {
69                          logger.debug("Failed to release a socket " + socket, e);
70                      }
71                  }
72              }
73          }
74  
75          return retryContext;
76  
77      }
78  
79      @Override
80      protected void doConnect() throws Exception
81      {
82          // nothing, there is an optional validation in validateConnection()
83          
84      }
85  
86      @Override
87      protected void doDisconnect() throws Exception
88      {
89          // nothing to do
90      }
91  
92  
93      @Override
94      protected synchronized void doDispatch(MuleEvent event) throws Exception
95      {
96          DatagramSocket socket = connector.getSocket(endpoint);
97          try
98          {
99              byte[] payload = event.transformMessage(DataType.BYTE_ARRAY_DATA_TYPE);
100 
101             int port = endpoint.getEndpointURI().getPort();
102             InetAddress inetAddress = null;
103             //TODO, check how expensive this operation is
104             if("null".equalsIgnoreCase(endpoint.getEndpointURI().getHost()))
105             {
106                 inetAddress = InetAddress.getLocalHost();
107             }
108             else
109             {
110                 inetAddress = InetAddress.getByName(endpoint.getEndpointURI().getHost());
111             }
112 
113             write(socket, payload, port, inetAddress);
114         }
115         finally
116         {
117             connector.releaseSocket(socket, endpoint);
118         }
119     }
120 
121     protected void write(DatagramSocket socket, byte[] data, int port, InetAddress inetAddress) throws IOException
122     {
123         DatagramPacket packet = new DatagramPacket(data, data.length);
124         if (port >= 0)
125         {
126             packet.setPort(port);
127         }
128         packet.setAddress(inetAddress);
129         socket.send(packet);
130     }
131 
132     @Override
133     protected synchronized MuleMessage doSend(MuleEvent event) throws Exception
134     {
135         doDispatch(event);
136         // If we're doing sync receive try and read return info from socket
137         if (endpoint.getExchangePattern().hasResponse())
138         {
139             DatagramSocket socket = connector.getSocket(endpoint);
140             DatagramPacket result = receive(socket, event.getTimeout());
141             if (result == null)
142             {
143                 return createNullMuleMessage();
144             }
145             return createMuleMessage(result, event.getMessage(), endpoint.getEncoding());
146         }
147         else
148         {
149             return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
150         }
151     }
152 
153     private DatagramPacket receive(DatagramSocket socket, int timeout) throws IOException
154     {
155         int origTimeout = socket.getSoTimeout();
156         try
157         {
158             DatagramPacket packet = new DatagramPacket(new byte[connector.getReceiveBufferSize()],
159                 connector.getReceiveBufferSize());
160 
161             if(timeout > 0 && timeout != socket.getSoTimeout())
162             {
163                 socket.setSoTimeout(timeout);
164             }
165             socket.receive(packet);
166             return packet;
167         }
168         finally
169         {
170             if(socket.getSoTimeout()!= origTimeout)
171             {
172                 socket.setSoTimeout(origTimeout);
173             }
174         }
175     }
176 
177     @Override
178     protected void doDispose()
179     {
180         // template method
181     }
182 }