~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements. See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership. The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License. You may obtain a copy of the License at
~~
~~ http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied. See the License for the
~~ specific language governing permissions and limitations
~~ under the License.

UDP Transport

* {Content}

%{toc|section=1|fromDepth=1}

* {Transport listener}

** {Listener configuration}

  The UDP transport listener is configured in <<<axis2.xml>>> using the following declaration:

+----------------------------+
<transportReceiver name="udp" class="org.apache.axis2.transport.udp.UDPListener"/>
+----------------------------+

  Depending on how the UDP transport is set up, additional parameters may be required inside the
  <<<transportReceiver>>> element (see next section).

** {Endpoint configuration}

  Endpoints can be configured both at the transport level and at the service level. Each endpoint
  opens a local UDP port for listening. UDP packets received on a port that is configured on a
  service will be pre-dispatched to that service. Packets received by a port that is configured
  at the transport level need to be dispatched using WS-Addressing or some other mechanism
  implemented by a dispatcher configured in Axis2.
  
  Endpoints are configured by adding <<<parameter>>> elements to the <<<transportReceiver>>>
  element in <<<axis2.xml>>> or to a <<<service>>> element in an <<<services.xml>>> file. The
  set of parameters is the same for both scenarios:
  
  [<<<transport.udp.port>>> (required)]
  Specifies the UDP port to bind to.
  
  [<<<transport.udp.contentType>>> (required)]
  Specifies the content type of the messages received on the endpoint. This parameter is
  necessary because in contrast to HTTP, the content type information is not part of the
  information exchanged on the wire.
  
  [<<<transport.udp.maxPacketSize>>> (optional, defaults to 1024)]
  The maximum UDP packet size.

* {Transport sender}

  The UDP transport sender can be enabled in <<<axis2.xml>>> using the following declaration:

+----------------------------+
<transportSender name="udp" class="org.apache.axis2.transport.udp.UDPSender"/>
+----------------------------+

* {Examples}

** {Enabling SOAP over UDP at the transport level}

  The following declaration in <<<axis2.xml>>> enables SOAP over UDP on port 3333 and
  allows all services (for which UDP is in the list of exposed transports) to receive
  messages over that port:
  
+----------------------------+
<transportReceiver name="udp" class="org.apache.axis2.transport.udp.UDPListener">
  <parameter name="transport.udp.port">3333</parameter>
  <parameter name="transport.udp.contentType">text/xml</parameter>
  <parameter name="transport.udp.maxPacketSize">4096</parameter>
</transportReceiver>
+----------------------------+

  For this to work, WS-Addressing must be enabled, and messages sent to port 3333 must
  have the relevant WS-Addressing headers.
  
+----------------------------+
<module ref="addressing"/>
+----------------------------+

  With the configuration shown above, the UDP transport would generate bindings with the
  following EPR:

+----------------------------+
udp://localhost:3333/axis2/services/Version?contentType=text/xml
+----------------------------+

  The following example shows a message that can be sent to the Version service over UDP:

+----------------------------+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <SOAP-ENV:Header>
        <wsa:MessageID>1234</wsa:MessageID>
        <wsa:To>udp://localhost:3333/axis2/services/Version?contentType=text/xml</wsa:To>
        <wsa:Action>urn:getVersion</wsa:Action>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
+----------------------------+

  On most Linux/Unix systems (including Mac OS X), the <<<nc>>> utility is available to send
  UDP messages and can be used to test the transport. To do this, save the message into
  <<<test-message.xml>>> and execute the following command:

+----------------------------+
nc -u 127.0.0.1 3333 < test-message.xml
+----------------------------+
