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>
> + <transportReceiver name="TRANSPORT_NAME"
> class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_LISTNER_CLASS">
> + <parameter name="PROPERTY_NAME"
> locked="xsd:false">PROPERTY_VALUE</parameter>
> + <parameter name="PROPERTY_NAME_2"
> locked="xsd:false">PROPERTY_VALUE_2</parameter>
> + </transportReceiver>
> + </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>
> + <transportSender name="TRANSPORT_NAME"
> class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_SENDER_CLASS">
> + <parameter name="PROPERTY_NAME"
> locked="xsd:false">PROPERTY_VALUE</parameter>
> + <parameter name="PROPERTY_NAME_2"
> locked="xsd:false">PROPERTY_VALUE_2</parameter>
> + </transportSender>
> + </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
>