You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Chamil Thanthrimudalige <ch...@opensource.lk> on 2005/10/01 07:22:22 UTC

[Axis2] Transport howto

hi,

I written a small how to on making your own transport. Can some one with 
enough please have a look at it and then commit.

Thank You !

Best Regards,
Chamil Thantrimudalige.

Re: [Axis2] Transport howto

Posted by Deepal Jayasinghe <de...@opensource.lk>.
done

Thanks,
 Deepal
................................................................
~Future is Open~

----- Original Message ----- 
From: "Chamil Thanthrimudalige" <ch...@opensource.lk>
To: <ax...@ws.apache.org>
Sent: Saturday, October 01, 2005 11:22 AM
Subject: [Axis2] Transport howto


> hi,
>
> I written a small how to on making your own transport. Can some one with
> enough please have a look at it and then commit.
>
> Thank You !
>
> Best Regards,
> Chamil Thantrimudalige.
>


--------------------------------------------------------------------------------


> Index: xdocs/transport_howto.html
> ===================================================================
> --- xdocs/transport_howto.html (revision 0)
> +++ xdocs/transport_howto.html (revision 0)
> @@ -0,0 +1,155 @@
> +<html>
> +<body>
> +<h1>How to write your own Axis2 transport</h1>
> +
> +<h2>Prologue</h2>
> +<p>To stop you from reinventing the wheel I will quickly list the 
> transports that are already supported in Axis2 with a small description 
> before we get started.<p>
> +<ul>
> +<li><b>HTTP</b> - In the HTTP transport, the transport Listener is 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 
> commons-HTTP-client 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>
> +<li><b>SMTP</b> This can work off a single email account or a mailserver. 
> The Mail Transport Receiver is a tread that checks for emails in fixed 
> time intervals.</li>
> +</ul>
> +<p>To understand the rest of this document you will need some 
> understanding of the Architecture of Axis2. Therefor if you are not 
> familiar with the Architecture of Axis2 you will have to first read 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 a messages that arrive though some channel into the Axis2 
> engine. The core of Axis2 is a transport agnostic one. All data that is 
> transport specific is striped out of the incoming message and inserted 
> into the MessageContext and on the outgoing message all transport specific 
> information like headers are added and sent.</p>
> +
> +<p>To write your own transport you will need to primarily write two 
> classes, one is the TransportSender and the other is the 
> TransportReceiver. To register a transport with Axis2 you will need to put 
> two entries in the axis2.xml file. One for the transport receiver and the 
> other for the transport sender. We will walk though the process of adding 
> the entries in the relevent sections.</p>
> +
> +<h2>Transport Receiver</h2>
> +<p>Any message that is comming into Axis2 needs to go though a transport 
> receiver. All information about how the message is received at the Axis2 
> server from the wire [or by snail mail for that matter:)] 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 with out further delay why don't we dive into some 
> coding and start building out own transport.<p>
> +
> +<p>To get things stared you will first need to extend from the 
> org.apache.Axis2.transport.TransportListener class and write you 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>
> +<source>
> +<pre>
> +try {
> + //Create a factory
> + ConfigurationContextFactory factory = new ConfigurationContextFactory();
> + //Use the factory and an Axis2 repository to create a new Configuration 
> Context
> + configurationContext = 
> factory.buildConfigurationContext(repository_directory);
> +} catch (Exception e) {
> + log.info(e.getMessage());
> +}
> +</pre>
> +</source>
> +<p>Now we need some kind of a listener to listen to the requests that 
> come in. This you will need to implement 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 thing the engine.receive(msgContext) 
> method.</p>
> +<source>
> +<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 && 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) 
>  > -1){
> + soapNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
> + }else 
> if(message.getContentType().indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) 
>  > -1){
> + soapNamespaceURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
> + }
> +
> + StAXBuilder builder = new StAXSOAPModelBuilder(reader, 
> soapNamespaceURI);
> +
> + SOAPEnvelope envelope = (SOAPEnvelope) builder.getDocumentElement();
> + msgContext.setEnvelope(envelope);
> + if (envelope.getBody().hasFault()) {
> + engine.receiveFault(msgContext);
> + } else {
> + 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>
> +</source>
> +<p>Now we have the coding in place and we need to let Axis2 know about 
> our new transport receiver. How we do this is by addind 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>
> +
> +  <source><pre>
> +   &lt;transportReceiver name="TRANSPORT_NAME" 
> class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_LISTNER_CLASS"&gt;
> +        &lt;parameter name="PROPERTY_NAME" 
> locked="xsd:false"&gt;PROPERTY_VALUE&lt;/parameter&gt;
> +        &lt;parameter name="PROPERTY_NAME_2" 
> locked="xsd:false"&gt;PROPERTY_VALUE_2&lt;/parameter&gt;
> +  &lt;/transportReceiver&gt;
> +  </pre></source>
> +
> +<p>Using a code fragment like 
> Utils.getParameterValue(transportOut.getParameter(MailSrvConstants.SMTP_USER)) 
> we can extract the parameters that we insert into the axis2.xml file.</p>
> +
> +<p>So 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 from 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>
> +<source><pre>
> +// If an EPR is present then the message is going on a diffrent 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></source>
> +<p>So depending on whether your transport is using the same channel to 
> send the responce 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 Transport Receiver.</p>
> +
> +  <source>
> +  <pre>
> +   &lt;transportSender name="TRANSPORT_NAME" 
> class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_SENDER_CLASS"&gt;
> +        &lt;parameter name="PROPERTY_NAME" 
> locked="xsd:false"&gt;PROPERTY_VALUE&lt;/parameter&gt;
> +        &lt;parameter name="PROPERTY_NAME_2" 
> locked="xsd:false"&gt;PROPERTY_VALUE_2&lt;/parameter&gt;
> +  &lt;/transportSender&gt;
> +  </pre>
> +  </source>
> +
> +<p>Have a look at org.apache.Axis2.transport.mail.MailTransportSender for 
> a very simple Transport Sender. Also have a look at 
> org.apache.Axis2.transport.http.CommonsHTTPTransportSender which is used 
> to send HTTP responses.</p>
> +<p>Once we have written our transport receiver and our transport sender, 
> and inserted the needed entries into the axis2.xml file we are done. It is 
> as simple as that. :-)</p>
> \ No newline at end of file
>