<!--
  ~ 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.
  -->

<html>
<head>
  <meta http-equiv="content-type" content=""/>
  <title></title>
</head>

<body>
<h1>How to Write Your Own Axis2 Transport</h1>

<h2>Prologue</h2>

<p>To stop you from re-inventing the wheel, before we get started, I will
quickly list the transports that are already supported in Axis2 with a small
description.</p>

<p></p>
<ul>
  <li><b>HTTP</b> - In the HTTP transport, the transport Listener is either a
    Servlet or a Simple HTTP server provided by Axis2. The transport Sender
    uses sockets to connect and send the SOAP message. Currently we have the
    Apache Httpcomponents based HTTP Transport sender as the default
  transport.</li>
  <li><b>TCP</b> - This is the most simple transport, but needs Addressing
    support to be functional.</li>
</ul>

<p>To understand the rest of this document you will need some understanding
of the architecture of Axis2. If you are not familiar with the Axis2
architecture, please go through the <a
href="Axis2ArchitectureGuide.html">Axis2 Architecture Guide</a> before you
read any further.</p>

<h2>Introduction</h2>

<p>Broadly speaking, a transport inside Axis2 can be classified as a way of
getting messages that arrive though some channel into the Axis2 engine. The
core of Axis2 is transport independent. All data that is transport specific
is stripped out of the incoming message and inserted into the MessageContext.
In the outgoing message, all transport specific information, like headers,
are added and sent.</p>

<p>To write your own transport, you will primarily need to write two classes:
one is the TransportSender and the other is the TransportReceiver. To
register a transport with Axis2 you will need to put entries corresponding
to these two classes in the axis2.xml file. I will take you through the 
process of adding the entries in the relevant sections.</p>

<h2>Transport Receiver</h2>

<p>Any message that is coming into Axis2 needs to go through a transport
receiver. All information about how the message is received at the Axis2
server from the wire (or via an e-mail) is isolated inside the transport
receiver. It extracts the data that is coming on the wire and transforms it
into a state that the Axis2 server understands.</p>

<p>So now that we have some background information about how transports work
inside Axis2, without further delay, lets dive into some coding and start
building our own transport.</p>

<p></p>

<p>To get things stared, you will first need to extend from the
org.apache.Axis2.transport.TransportListener class and write your own
transport listener. To create an engine to process the MessageContext, we
need a configuration context. The following code fragment will do this. This
should ideally be only done once for the lifetime of the Transport
receiver.</p>

<p></p>
<pre>try {
        //Create a factory 
        ConfigurationContextFactory factory = new ConfigurationContextFactory();
        //Use the factory and an Axis2 repository to create a new Configuration Context
        configurationContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(repository_directory, 
axis2xmllocation);
} catch (Exception e) {
        log.info(e.getMessage());
}</pre>
<p>Now we need some kind of a Listener to listen to the requests that come
in. You need to implement this according to the transport that you are trying
to build. After a message is received at the Receiver, you can use the
following code to process the request and then forward the message context to
the engine using the engine.receive(msgContext) method. (The following code
is extracted from the MailListener as an example)</p>
<pre>AxisEngine engine = new AxisEngine(configurationContext);
MessageContext msgContext = null;

// create and initialize a message context
try {
        TransportInDescription transportIn =
                reg.getAxisConfiguration().getTransportIn(new QName(Constants.TRANSPORT_NAME));
        TransportOutDescription transportOut =
                reg.getAxisConfiguration().getTransportOut(new QName(Constants.TRANSPORT_NAME));
        if (transportIn != null &amp;&amp; transportOut != null) {
                //create Message Context
                
                msgContext = new MessageContext(configurationContext, transportIn, transportOut);
                msgContext.setServerSide(true);
                msgContext.setProperty(MailSrvConstants.CONTENT_TYPE, message.getContentType());
                msgContext.setProperty(MessageContext.CHARACTER_SET_ENCODING, message.getEncoding());

                String soapAction = message.getSOAPActionHeader();
                msgContext.setWSAAction(soapAction);
                msgContext.setSoapAction(soapAction);

                // Here we are trying to set the reply to if it is present in the transport information.
                msgContext.setReplyTo(new EndpointReference(message.getReplyTo());

                //Create the SOAP Message -- This code in from the mail transport and will change depending
                //on how the data is handled in each transport.
                ByteArrayInputStream bais = new ByteArrayInputStream(message.getContent().toString().getBytes());
                XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(bais);

                String soapNamespaceURI = "";
                if(message.getContentType().indexOf(SOAP12Constants.SOAP_12_CONTENT_TYPE) &gt; -1){
                        soapNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
                }else if(message.getContentType().indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) &gt; -1){
                        soapNamespaceURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
                }

                StAXBuilder builder = new StAXSOAPModelBuilder(reader, soapNamespaceURI);

                SOAPEnvelope envelope = (SOAPEnvelope) builder.getDocumentElement();
                msgContext.setEnvelope(envelope);
                engine.receive(msgContext);
        } else {
                throw new AxisFault(Messages.getMessage("unknownTransport",Constants.TRANSPORT_NAME));
        }

} catch (Exception e) {
        try {
                if (msgContext != null) {
                        MessageContext faultContext = engine.createFaultMessageContext(msgContext, e);
                        engine.sendFault(faultContext);
                } else {
                        log.error(e);
                }
        } catch (AxisFault e1) {
                log.error(e);
        }
}</pre>
<p>Now that we have the coding in place, we need to let Axis2 know about our
new transport receiver. We do this by adding an entry into the axis2.xml
file. If you need to pass any properties for the transport to operate, it can
also be done through the axis2.xml file.</p>
<pre>   &lt;transportReceiver name="TRANSPORT_NAME" class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_LISTNER_CLASS"&gt;
        &lt;parameter name="PROPERTY_NAME"&gt;PROPERTY_VALUE&lt;/parameter&gt;
        &lt;parameter name="PROPERTY_NAME_2"&gt;PROPERTY_VALUE_2&lt;/parameter&gt;
  &lt;/transportReceiver&gt;
  </pre>
<p>By using a code fragment like
<code>Utils.getParameterValue(transportOut.getParameter(MailSrvConstants.SMTP_USER))</code>
we can extract the parameters that we inserted into the axis2.xml file.</p>

<p>As you can see, getting a new transport receiver up and running is a task
that requires very little effort.</p>

<h2>Transport Sender</h2>

<p>Any message that is to be sent out of Axis2, is sent through the Transport
Sender. The Transport Sender needs to be extended from the
org.apache.Axis2.transport.AbstractTransportSender class.</p>

<p>The following bit of code from the abstract transport sender will call the
Transport Sender that you wrote.</p>
<pre>// If an EPR is present then the message is going on a different channel.
if (epr != null) {
        out = openTheConnection(epr, msgContext);
        OutputStream newOut = startSendWithToAddress(msgContext, out);
        if (newOut != null) {
                out = newOut;
        }
        writeMessage(msgContext, out);
        finalizeSendWithToAddress(msgContext, out);
        } else {
        out = (OutputStream) msgContext.getProperty(MessageContext.TRANSPORT_OUT);
        if (out != null) {
                startSendWithOutputStreamFromIncomingConnection(msgContext, out);
                writeMessage(msgContext, out);
                finalizeSendWithOutputStreamFromIncomingConnection(msgContext, out);
        } else {
                throw new AxisFault(
                        "Both the TO and Property MessageContext.TRANSPORT_WRITER is Null, No way to send response.");
        }
}</pre>
<p>Therefore, depending on whether your transport is using the same channel
to send the response or using a different channel, you will need to implement
a sub-set of the methods from the abstract class.</p>

<p>After implementing the necessary methods, you can let Axis2 know about
your new transport sender by adding an entry to the axis2.xml file, like you
did for the TransportReceiver.</p>
<pre>  &lt;transportSender name="TRANSPORT_NAME" class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_SENDER_CLASS"&gt;
        &lt;parameter name="PROPERTY_NAME"&gt;PROPERTY_VALUE&lt;/parameter&gt;
        &lt;parameter name="PROPERTY_NAME_2"&gt;PROPERTY_VALUE_2&lt;/parameter&gt;
  &lt;/transportSender&gt;
  </pre>
<p>Have a look at
org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender which is used to
send HTTP responses.</p>

<p>Once we have written our transport receiver and our transport sender, and
inserted the required entries into the axis2.xml file, we are done. It is as
simple as that!</p>
</body>
</html>
