View Javadoc

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