Coverage Report - org.mule.transport.udp.UdpMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
UdpMessageReceiver
0%
0/66
0%
0/22
0
UdpMessageReceiver$UdpWorker
0%
0/38
0%
0/16
0
 
 1  
 /*
 2  
  * $Id: UdpMessageReceiver.java 19400 2010-09-07 20:20:09Z mike.schilling $
 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.MuleEvent;
 14  
 import org.mule.api.MuleException;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.config.MuleProperties;
 17  
 import org.mule.api.construct.FlowConstruct;
 18  
 import org.mule.api.endpoint.InboundEndpoint;
 19  
 import org.mule.api.lifecycle.CreateException;
 20  
 import org.mule.api.lifecycle.Disposable;
 21  
 import org.mule.api.transport.Connector;
 22  
 import org.mule.api.transport.PropertyScope;
 23  
 import org.mule.config.i18n.CoreMessages;
 24  
 import org.mule.transport.AbstractMessageReceiver;
 25  
 import org.mule.transport.ConnectException;
 26  
 import org.mule.transport.udp.i18n.UdpMessages;
 27  
 
 28  
 import java.io.IOException;
 29  
 import java.net.DatagramPacket;
 30  
 import java.net.DatagramSocket;
 31  
 import java.net.InetAddress;
 32  
 import java.net.SocketAddress;
 33  
 import java.net.SocketTimeoutException;
 34  
 import java.net.URI;
 35  
 import java.net.UnknownHostException;
 36  
 import java.util.List;
 37  
 
 38  
 import javax.resource.spi.work.Work;
 39  
 import javax.resource.spi.work.WorkException;
 40  
 import javax.resource.spi.work.WorkManager;
 41  
 
 42  
 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
 43  
 
 44  
 /** <code>UdpMessageReceiver</code> receives UDP message packets. */
 45  0
 public class UdpMessageReceiver extends AbstractMessageReceiver implements Work
 46  
 {
 47  0
     protected DatagramSocket socket = null;
 48  
     protected InetAddress inetAddress;
 49  
     protected int bufferSize;
 50  
     private URI uri;
 51  0
     protected List responseTransformers = null;
 52  
 
 53  0
     protected final AtomicBoolean disposing = new AtomicBoolean(false);
 54  
 
 55  
     public UdpMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
 56  
             throws CreateException
 57  
     {
 58  
 
 59  0
         super(connector, flowConstruct, endpoint);
 60  
 
 61  0
         bufferSize = ((UdpConnector) connector).getReceiveBufferSize();
 62  
 
 63  0
         uri = endpoint.getEndpointURI().getUri();
 64  
 
 65  
         try
 66  
         {
 67  0
             if (!"null".equalsIgnoreCase(uri.getHost()))
 68  
             {
 69  0
                 inetAddress = InetAddress.getByName(uri.getHost());
 70  
             }
 71  
         }
 72  0
         catch (UnknownHostException e)
 73  
         {
 74  0
             throw new CreateException(UdpMessages.failedToLocateHost(uri), e, this);
 75  0
         }
 76  
 
 77  0
         responseTransformers = getResponseTransformers();
 78  0
     }
 79  
 
 80  
     @Override
 81  
     protected void doConnect() throws Exception
 82  
     {
 83  
         try
 84  
         {
 85  0
             socket = ((UdpConnector) connector).getServerSocket(endpoint);
 86  
         }
 87  0
         catch (Exception e)
 88  
         {
 89  0
             throw new ConnectException(UdpMessages.failedToBind(uri), e, this);
 90  0
         }
 91  
 
 92  
         try
 93  
         {
 94  0
             getWorkManager().scheduleWork(this, WorkManager.INDEFINITE, null, connector);
 95  
         }
 96  0
         catch (WorkException e)
 97  
         {
 98  0
             throw new ConnectException(CoreMessages.failedToScheduleWork(), e, this);
 99  0
         }
 100  0
     }
 101  
 
 102  
     @Override
 103  
     protected void doDisconnect() throws Exception
 104  
     {
 105  
         // this will cause the server thread to quit
 106  0
         disposing.set(true);
 107  0
         if (socket != null)
 108  
         {
 109  0
             socket.close();
 110  
         }
 111  
 
 112  0
     }
 113  
 
 114  
     @Override
 115  
     protected void doStart() throws MuleException
 116  
     {
 117  
         // nothing to do
 118  0
     }
 119  
 
 120  
     @Override
 121  
     protected void doStop() throws MuleException
 122  
     {
 123  
         // nothing to do
 124  0
     }
 125  
 
 126  
     protected List getResponseTransformers()
 127  
     {
 128  0
         List transformers = endpoint.getResponseTransformers();
 129  0
         if (transformers == null)
 130  
         {
 131  0
             return connector.getDefaultResponseTransformers(endpoint);
 132  
         }
 133  0
         return transformers;
 134  
     }
 135  
 
 136  
     protected DatagramSocket createSocket(URI uri, InetAddress inetAddress) throws IOException
 137  
     {
 138  0
         return new DatagramSocket(uri.getPort(), inetAddress);
 139  
     }
 140  
 
 141  
     /** Obtain the serverSocket */
 142  
     public DatagramSocket getSocket()
 143  
     {
 144  0
         return socket;
 145  
     }
 146  
 
 147  
     protected DatagramPacket createPacket()
 148  
     {
 149  0
         DatagramPacket packet = new DatagramPacket(new byte[bufferSize], bufferSize);
 150  
 //        if (uri.getPort() > 0)
 151  
 //        {
 152  
 //            packet.setPort(uri.getPort());
 153  
 //        }
 154  
 //        packet.setAddress(inetAddress);
 155  0
         return packet;
 156  
     }
 157  
 
 158  
     public void run()
 159  
     {
 160  0
         while (!disposing.get())
 161  
         {
 162  0
             if (connector.isStarted())
 163  
             {
 164  
 
 165  
                 try
 166  
                 {
 167  0
                     DatagramPacket packet = createPacket();
 168  
                     try
 169  
                     {
 170  0
                         if (logger.isDebugEnabled())
 171  
                         {
 172  0
                             logger.debug("Receiving packet on " + uri);
 173  
                         }
 174  0
                         socket.receive(packet);
 175  
 
 176  0
                         if (logger.isTraceEnabled())
 177  
                         {
 178  0
                             logger.trace("Received packet on: " + uri);
 179  
                         }
 180  
 
 181  0
                         Work work = createWork(packet);
 182  
                         try
 183  
                         {
 184  0
                             getWorkManager().scheduleWork(work, WorkManager.INDEFINITE, null, connector);
 185  
                         }
 186  0
                         catch (WorkException e)
 187  
                         {
 188  0
                             logger.error("Udp receiver interrupted: " + e.getMessage(), e);
 189  0
                         }
 190  
                     }
 191  0
                     catch (SocketTimeoutException e)
 192  
                     {
 193  
                         // ignore
 194  0
                     }
 195  
 
 196  
                 }
 197  0
                 catch (Exception e)
 198  
                 {
 199  0
                     if (!connector.isDisposed() && !disposing.get())
 200  
                     {
 201  0
                         logger.debug("Accept failed on socket: " + e, e);
 202  0
                         getConnector().getMuleContext().getExceptionListener().handleException(e);
 203  
                     }
 204  0
                 }
 205  
             }
 206  
         }
 207  0
     }
 208  
 
 209  
     public void release()
 210  
     {
 211  0
         dispose();
 212  0
     }
 213  
 
 214  
     @Override
 215  
     protected void doDispose()
 216  
     {
 217  0
         if (socket != null && !socket.isClosed())
 218  
         {
 219  0
             logger.debug("Closing Udp connection: " + uri);
 220  0
             socket.close();
 221  0
             logger.info("Closed Udp connection: " + uri);
 222  
         }
 223  0
     }
 224  
 
 225  
     protected Work createWork(DatagramPacket packet) throws IOException
 226  
     {
 227  0
         return new UdpWorker(new DatagramSocket(0), packet);
 228  
     }
 229  
 
 230  
     protected class UdpWorker implements Work, Disposable
 231  
     {
 232  0
         private DatagramSocket socket = null;
 233  
         private DatagramPacket packet;
 234  
 
 235  
         public UdpWorker(DatagramSocket socket, DatagramPacket packet)
 236  0
         {
 237  0
             this.socket = socket;
 238  0
             this.packet = packet;
 239  0
         }
 240  
 
 241  
         public void release()
 242  
         {
 243  0
             dispose();
 244  0
         }
 245  
 
 246  
         public void dispose()
 247  
         {
 248  0
             if (socket != null && !socket.isClosed())
 249  
             {
 250  
                 try
 251  
                 {
 252  0
                     socket.close();
 253  
                 }
 254  0
                 catch (Exception e)
 255  
                 {
 256  0
                     logger.error("Socket close failed", e);
 257  0
                 }
 258  
             }
 259  0
             socket = null;
 260  0
         }
 261  
 
 262  
         /** Accept requests from a given Udp address */
 263  
         public void run()
 264  
         {
 265  0
             MuleMessage returnMessage = null;
 266  
             try
 267  
             {
 268  0
                 MuleMessage message = createMuleMessage(packet, endpoint.getEncoding());
 269  0
                 final SocketAddress clientAddress = socket.getRemoteSocketAddress();
 270  0
                 if (clientAddress != null)
 271  
                 {
 272  0
                     message.setProperty(MuleProperties.MULE_REMOTE_CLIENT_ADDRESS, clientAddress, PropertyScope.INBOUND);
 273  
                 }
 274  0
                 MuleEvent event = routeMessage(message);
 275  0
                 returnMessage = event == null ? null : event.getMessage();
 276  
 
 277  0
                 if (returnMessage != null)
 278  
                 {
 279  
                     byte[] data;
 280  0
                     if (responseTransformers != null)
 281  
                     {
 282  0
                         returnMessage.applyTransformers(event, responseTransformers);
 283  0
                         Object response = returnMessage.getPayload();
 284  0
                         if (response instanceof byte[])
 285  
                         {
 286  0
                             data = (byte[]) response;
 287  
                         }
 288  
                         else
 289  
                         {
 290  0
                             data = response.toString().getBytes();
 291  
                         }
 292  0
                     }
 293  
                     else
 294  
                     {
 295  0
                         data = returnMessage.getPayloadAsBytes();
 296  
                     }
 297  0
                     DatagramPacket result = new DatagramPacket(data, data.length, packet.getAddress(),
 298  
                             packet.getPort());
 299  0
                     socket.send(result);
 300  
                 }
 301  
             }
 302  0
             catch (Exception e)
 303  
             {
 304  0
                 if (!disposing.get())
 305  
                 {
 306  0
                     getConnector().getMuleContext().getExceptionListener().handleException(e);
 307  
                 }
 308  
             }
 309  
             finally
 310  
             {
 311  0
                 dispose();
 312  0
             }
 313  0
         }
 314  
     }
 315  
 }