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.udp;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.MuleException;
11  import org.mule.api.construct.FlowConstruct;
12  import org.mule.api.endpoint.ImmutableEndpoint;
13  import org.mule.api.endpoint.InboundEndpoint;
14  import org.mule.api.lifecycle.InitialisationException;
15  import org.mule.transport.AbstractConnector;
16  
17  import java.net.DatagramSocket;
18  
19  import org.apache.commons.pool.impl.GenericKeyedObjectPool;
20  
21  /**
22   * <code>UdpConnector</code> can send and receive Mule events as Datagram packets.
23   */
24  public class UdpConnector extends AbstractConnector
25  {
26      public static final String UDP = "udp";
27      public static final int DEFAULT_SOCKET_TIMEOUT = INT_VALUE_NOT_SET;
28      public static final int DEFAULT_BUFFER_SIZE = 1024 * 16;
29      public static final String KEEP_SEND_SOCKET_OPEN_PROPERTY = "keepSendSocketOpen";
30      public static final String ADDRESS_PROPERTY = "packet.address";
31      public static final String PORT_PROPERTY = "packet.port";
32  
33      protected int timeout = DEFAULT_SOCKET_TIMEOUT;
34      protected int sendBufferSize = DEFAULT_BUFFER_SIZE;
35      protected int receiveBufferSize = DEFAULT_BUFFER_SIZE;
36      protected boolean keepSendSocketOpen = true;
37      protected boolean broadcast;
38      protected GenericKeyedObjectPool dispatcherSocketsPool = new GenericKeyedObjectPool();
39      protected UdpSocketFactory socketFactory;
40  
41      public UdpConnector(MuleContext context)
42      {
43          super(context);
44      }
45  
46      @Override
47      protected void doInitialise() throws InitialisationException
48      {
49          socketFactory = new UdpSocketFactory();
50          dispatcherSocketsPool.setFactory(socketFactory);
51          dispatcherSocketsPool.setTestOnBorrow(true);
52          dispatcherSocketsPool.setTestOnReturn(true);
53          //There should only be one pooled instance per socket (key)
54          dispatcherSocketsPool.setMaxActive(1);
55      }
56  
57      @Override
58      protected void doDispose()
59      {
60          try
61          {
62              dispatcherSocketsPool.close();
63          }
64          catch (Exception e)
65          {
66              logger.warn("Failed to close dispatcher socket pool: " + e.getMessage());
67          }
68      }
69  
70      @Override
71      protected void doConnect() throws Exception
72      {
73          // template method
74      }
75  
76      @Override
77      protected void doDisconnect() throws Exception
78      {
79          dispatcherSocketsPool.clear();
80      }
81  
82      @Override
83      protected void doStart() throws MuleException
84      {
85          // template method
86      }
87  
88      @Override
89      protected void doStop() throws MuleException
90      {
91          // template method
92      }
93  
94      public String getProtocol()
95      {
96          return UDP;
97      }
98  
99      public int getTimeout()
100     {
101         return this.timeout;
102     }
103 
104     /**
105      * @deprecated use #setTimeout(int) instead. This method is kept for
106      *             compatibility with older schemas. Remove this for 3.2
107      */
108     @Deprecated
109     public void setSendTimeout(int timeout)
110     {
111         if (timeout < 0)
112         {
113             timeout = DEFAULT_SOCKET_TIMEOUT;
114         }
115         this.timeout = timeout;
116     }
117 
118     /**
119      * @deprecated use #setTimeout(int) instead. This method is kept for
120      *             compatibility with older schemas. Remove this for 3.2
121      */
122     @Deprecated
123     public void setReceiveTimeout(int timeout)
124     {
125         if (timeout < 0)
126         {
127             timeout = DEFAULT_SOCKET_TIMEOUT;
128         }
129         this.timeout = timeout;
130     }
131 
132     public void setTimeout(int timeout)
133     {
134         if (timeout < 0)
135         {
136             timeout = DEFAULT_SOCKET_TIMEOUT;
137         }
138         this.timeout = timeout;
139     }
140 
141     public int getSendBufferSize()
142     {
143         return sendBufferSize;
144     }
145 
146     public void setSendBufferSize(int sendBufferSize)
147     {
148         if (sendBufferSize < 1)
149         {
150             sendBufferSize = DEFAULT_BUFFER_SIZE;
151         }
152         this.sendBufferSize = sendBufferSize;
153     }
154 
155     public int getReceiveBufferSize()
156     {
157         return receiveBufferSize;
158     }
159 
160     public void setReceiveBufferSize(int receiveBufferSize)
161     {
162         if (receiveBufferSize < 1)
163         {
164             receiveBufferSize = DEFAULT_BUFFER_SIZE;
165         }
166         this.receiveBufferSize = receiveBufferSize;
167     }
168 
169     public boolean isBroadcast()
170     {
171         return broadcast;
172     }
173 
174     public void setBroadcast(boolean broadcast)
175     {
176         this.broadcast = broadcast;
177     }
178 
179 
180     public boolean isKeepSendSocketOpen()
181     {
182         return keepSendSocketOpen;
183     }
184 
185     public void setKeepSendSocketOpen(boolean keepSendSocketOpen)
186     {
187         this.keepSendSocketOpen = keepSendSocketOpen;
188     }
189 
190     /**
191      * Lookup a socket in the list of dispatcher sockets but don't create a new
192      * socket
193      *
194      * @param endpoint
195      */
196     DatagramSocket getSocket(ImmutableEndpoint endpoint) throws Exception
197     {
198         return (DatagramSocket) dispatcherSocketsPool.borrowObject(endpoint);
199     }
200 
201     DatagramSocket getServerSocket(ImmutableEndpoint endpoint) throws Exception
202     {
203         return (DatagramSocket) socketFactory.makeObject(endpoint);
204     }
205 
206     void releaseSocket(DatagramSocket socket, ImmutableEndpoint endpoint) throws Exception
207     {
208         // Sockets can't be recycled if we close them at the end...
209         if (!keepSendSocketOpen)
210         {
211             dispatcherSocketsPool.clear(endpoint);
212         }
213         else
214         {
215             dispatcherSocketsPool.returnObject(endpoint, socket);
216         }
217     }
218 
219 
220     @Override
221     protected Object getReceiverKey(FlowConstruct flowConstruct, InboundEndpoint endpoint)
222     {
223         return endpoint.getEndpointURI().getAddress() + "/" + flowConstruct.getName();
224     }
225 }