View Javadoc

1   /*
2    * $Id: UdpMessageDispatcher.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.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          ImmutableEndpoint ep = event.getEndpoint();
97  
98          DatagramSocket socket = connector.getSocket(ep);
99          try
100         {
101             byte[] payload = event.transformMessage(DataType.BYTE_ARRAY_DATA_TYPE);
102 
103             int port = ep.getEndpointURI().getPort();
104             InetAddress inetAddress = null;
105             //TODO, check how expensive this operation is
106             if("null".equalsIgnoreCase(ep.getEndpointURI().getHost()))
107             {
108                 inetAddress = InetAddress.getLocalHost();
109             }
110             else
111             {
112                 inetAddress = InetAddress.getByName(ep.getEndpointURI().getHost());
113             }
114 
115             write(socket, payload, port, inetAddress);
116         }
117         finally
118         {
119             connector.releaseSocket(socket, ep);
120         }
121     }
122 
123     protected void write(DatagramSocket socket, byte[] data, int port, InetAddress inetAddress) throws IOException
124     {
125         DatagramPacket packet = new DatagramPacket(data, data.length);
126         if (port >= 0)
127         {
128             packet.setPort(port);
129         }
130         packet.setAddress(inetAddress);
131         socket.send(packet);
132     }
133 
134     @Override
135     protected synchronized MuleMessage doSend(MuleEvent event) throws Exception
136     {
137         doDispatch(event);
138         // If we're doing sync receive try and read return info from socket
139         if (event.getEndpoint().getExchangePattern().hasResponse())
140         {
141             DatagramSocket socket = connector.getSocket(event.getEndpoint());
142             DatagramPacket result = receive(socket, event.getTimeout());
143             if (result == null)
144             {
145                 return createNullMuleMessage();
146             }
147             return createMuleMessage(result, event.getMessage(), endpoint.getEncoding());
148         }
149         else
150         {
151             return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
152         }
153     }
154 
155     private DatagramPacket receive(DatagramSocket socket, int timeout) throws IOException
156     {
157         int origTimeout = socket.getSoTimeout();
158         try
159         {
160             DatagramPacket packet = new DatagramPacket(new byte[connector.getReceiveBufferSize()],
161                 connector.getReceiveBufferSize());
162 
163             if(timeout > 0 && timeout != socket.getSoTimeout())
164             {
165                 socket.setSoTimeout(timeout);
166             }
167             socket.receive(packet);
168             return packet;
169         }
170         finally
171         {
172             if(socket.getSoTimeout()!= origTimeout)
173             {
174                 socket.setSoTimeout(origTimeout);
175             }
176         }
177     }
178 
179     @Override
180     protected void doDispose()
181     {
182         // template method
183     }
184 }