My Google Summer of Code 2006 Timeline
Today I got my acceptance letter to the Google Summer of Code ..
Finished my university exams.
Got everything set up , The Mirae Source , Axis2 Source , and Sun WTK2.2.
Built the Mirae API and got things to work in my Linux system.
I know this is not relavent to my work, but today's my B'Day , went out with some of my friends ..
Collected information about the transport architecture of Axis2, took a look at some of their transport implementations source code, the TCP transport implementation can be used as a reference to build my own transport listeners/senders.
The tranport protocols are mapped to there handlers through the properties that's in the axis2.xml xml file. It stores the complete classpath of the transportSenders and transportRecievers.
Basically the classes that I've to build are classes that extend the AbstractTransportSender class and TransportListener interface.
The SOAP message properties are stored in a instance of MessageContext , and the global settings are stored in a instance of ConfigurationContext. the SOAP envelope is set to the messageContext and a AxisEngine instance is made with the configurationContext and after that the messageContext is passed to the AxisEngine. Then after that the axisEngine takes care of processing of the SOAP message and takes appropriate actions.
These days I spent my time getting the Mirae API to work properly , the Sun's WTK alone didn't help much, as instructed by my mentor Mr.Changshin Lee I had to get the Nokia's Series 4 development kit to make it work and made a web services invocation with the Apache Axis2 server.
Started to work on the Mirae transports division. The Mirae API only supports HTTP as the transport for sending the SOAP messages. Here my task is adding more transport protocols to Mirae.
For that I've created a new package as org.apache.mirae.transport , inside that contains the classes which have the transport protocol functionality. The most important class of them is the TransportHandler class. It is the base class of all the transport handlers in Mirea. There isn't any public contructors in transport handler classes , instead the TransportHandler class gives a factory method called getTransportHandler to get the necessory transport handler. The parameters for that function contains the URL,soapAction,username and password. The TransportHandler class maps different transport handler classes by the pattern of the URL. For example if the URL starts with http:// the transport handler class would be HttpTransportHandler.
The TransportHandler class also implements the StreamConnection interface , so all the input/output operations are exposed through that object. So now with a small change of code in the Dispatch class any transport protocol could be added to the Mirae API with ease. So currently the only transport protocol available is the HttpTransportHandler. I'll be implementing the MessageTransportHandler in the coming days.
Implemented the MessageTransportHandler class. Now Mirae can send and recieve web services messages through MMS. The MessageTransportHandler class contains 2 inner classes , which are MessageInputStream [ extends InputStream class ] and MessageOutputStream [ extends OutputStream class ]. These will be instantiated by MessageTransportHander class on demand when they ask for input and output streams for communication through MMS.
A MMS Message contains a subject field, which will be used to identify the specific web service. This value will be pass as the soapAction value into the constructor of the Dispatch class.
I'm also making a small J2ME application which acts as a proxy server. This is called KProxyServer. What it does is it listens to incoming MMS web services requests and routes them to another destination. There is an internel structure to do the mapping of incoming messages to the destination. The destination most probably will be a HTTP server. So KProxyServer can be run in a J2ME enabled device and it'll act as a web services container , but the real web services will be located on some other http servers residing in the internet. So every web services container doesn't have to be MMS enabled , this program can act as the bridge between MMS and HTTP.
At the end I'm also suppose to make a module to the Apache Axis2 web services container to enable MMS transport support , untill then I can use KProxyServer to test the MMS transport on Mirae. I'm still devoloping the KProxyServer but I've done some small tests and the MMS transport seems to be working just fine :).
By the way , Nokia's series 40,60,80 SDK's doesn't have WMA 2.0 (JSR-205) support. I had to download their Nokia Prototype SDK . That's the only sdk I found that works fine with MMS and the Mirae API.
Finished the KProxyServer application. I've tested my MMS transport with KProxyServer and tomcat together with the Axis2 servlet.
First I started tomcat, KProxyServer and then mirae_tester, which is the application testing the MMS transport. First the web service invocation is initiated by mirae_tester, the request is passed on to KProxyServer via the MMS protocol. When the proxy server recieves the request it looks for the message's subject field which is mapped to a target url and others information from a data structure which is build at the initialization by data taken from an external xml file. Once the web services target url is known, the proxy server makes a request to the web service through the HTTP protocol, then if there's a reply to the web service, when the response comes from the web service that data is written back to the mirae_tester through MMS. So here KProxyServer acts as the web services container and mirae_tester the client, all communicatiion between them is done by the MMS protocol.
So I think that I'm finished with this part of the project and I've sent my mirae_tester and KProxyServer projects to my mentor for evaluation.
Started on the second phase of the project, that's implementing the Apache Axis2 MMS transport functionality. First I thought of using jWAP for using as a way of sending/receiving the MMS messages and using the Nokia library for encoding and decoding the messages, but later I found that I can't use any other code other than Apache licensed code. So I've seperated the message sending/receiving and I'll be providing some interfaces for adding that functionality, so the user have to implement those to be able to send and recieve the physical MMS messages. Then I would be writing my own library for encoding/decoding the MMS messages.
Created a new package in Axis2, the MMS protocol related classes will be in org.apache.axis2.transport.mms. Created the 2 main classes, which are MMSServer class and MMSTransportSender class. MMSServer handles the incoming webservices requests, it gets the message and pass it over to the AxisEngine. This extends the TransportListener interface, so becouse of that this class could be registered through the ListenerManager api. For axis2 to know about the new transport listener an entry in the axis2.xml should be added. The added lines are as follows,
<transportReceiver name="mms" class="org.apache.axis2.transport.mms.MMSServer"> <parameter name="app_id" locked="false">WS_MMS</parameter> <parameter name="my_address" locked="false">9477123456</parameter> <parameter name="wap_gateway" locked="false">127.0.0.1</parameter> <parameter name="wap_gateway_port" locked="false">1234</parameter> <parameter name="mms_server" locked="false">127.0.0.1</parameter> <parameter name="message_input" locked="false">org.mylib.MyInput</parameter> <parameter name="message_output" locked="false">org.mylib.MyOutput</parameter> <parameter name="message_notifier" locked="false">org.mylib.MyNotifier</parameter> </transportReceiver>
These parameters should be changed according to the configured setup.
The next class MMSTransportSender is used to handle the sending of messages to the destination. This class should implement the TransportSender interface , for that it extends the AbstractTransportSender class. Here we should provide a OutputStream for them to write the data , which is been done by the openTheConnection method. This also should be registered through the axis2.xml, here's the new lines for the transport sender,
<transportSender name="mms" class="org.apache.axis2.transport.mms.MMSTransportSender"> </transportSender>
I'll give a short explanation of how MMS works.
When a MMS message is sent by a source to a destination , the message is first sent to the mms center and when the mms center receives the message it gets the destination address and sends a special kind of SMS message to the destination. That SMS contains a URL to the original data that was sent by the source, so when the recipient receives the SMS message it must look for the URL and get that resource.
The addressing of the web service is done by the subject field of the MMS message , so the subject identifies the web service to be called , an example of a subject field would be "mms://+9477123456/TYPE=PLMN/axis2/services/version".
Here's an overview of the new classes I've made.
This class is created with the MMSServer , when the server gets an incoming request , an instance of the MMSWorker is made and executed in a different thread.
This class is used to listen to incoming requests and when a MMS incoming notification message arrives the URL for that MMS message is passed to the MessageInputConnection class to get the input stream of that.
This class is used to get the MMS message of at a given URL , it gets the message and gives out the data as a InputStream.
This class is used to send an encoded MMS message to a given MMSC , all the necessory wap gateway information is passed into this. So this creates a connection and writes the data by the inner class MessageOutputStream , when the flush method is called in the MessageOutputStream the data is written to the MMS server.
This interface represents the data input as a MMS message. The user should implement this and provide a class to handle the data input.
This interface represents the data output as a MMS Message. As the message input this should be implemented by the user.
This interface represents the listening of incoming MMS notification messages , when that message comes it will hand over the URL of the actualy MMS message.
This class is used to load the message input/output classes and the message notifier class.
The classes implementing MessageInput, MessageOutput, MessageNotifier classes will be loaded dynamically at runtime as stated in the parameters in the axis2.xml's transportReceiver element's message_input and message_output parameters.
Now I've to implement the library to encode/decode the MMS messages.
I created a new package as " org.apache.axis2.transport.mms.codec " , this contains the following clases ,
This class represents a MMS message , this can be used to set/get the subject,to,from and the data of the message.
This class contains the encoding functionality for MMS messages. The main method used here is the encode method. It takes a MMMessage to be encoded, in our case the data in the MMMessage is a soap message , it encodes the message and returns a byte as the encoded message.
Some other optional properties of the MMS messages are set internally , for example the message priority is set to the highest when encoding the message, I assumed that no one would want the message to go slowly :).
This class contains the decoding functionality. The main method used here is the decode method. It takes a byte which contains the encoded data and it returns a MMMessage after decoding.
At last to test my encoder and decoder I used the Nokia MMS library for that , so I set up 4 actions for that ,
- encode using nokia library
- encode using my library
- decode using nokia libary
- decode using my library
So after running all the possiblities everything seems to be working fine .
Finished implementing the Axis2 MMS transport. I ran a small test to make sure a web service request get processed and a response is getting out. I created 3 simple classes which implements the MessageInput, MessageOutput, MessageNotifier, and I started my MMS axis2 server and gave the paths to those classes. Here the message notifier just provides a path to a file on the local file system, and the message input class reads that file and gives it into the server , that file contains a MMS encoded soap request for the axis2 version service, and the message output class just writes the response back to a file, the response will be a MMS encoded soap reply.
So first I got the soap request as an xml file and encoded it as a mms message, and that is the file I gave as the url in my message notifier. So I ran the server and everything worked fine , the message writer wrote the response mms message to the file and I decoded it and found the proper response I was expecting , which was the axis2 version.
So everything went ok , in a real situation the one who's using the MMS transport should provide the proper input/output/notifier classes. I suggest making the input and output using jWAP , which is an open source java WAP implementation, and for the notification message from what I heard you can use Gammu for that.
Wrote a JUnit test case to test the MMS Transport , it's named MMSTransportTest , it'll be run when axis2 is being built. Then I got the latest cvn checkout of axis2 and hope to make a patch with my code and send it.
Created a new JIRA issue (AXIS2-941) on Axis2 project and sent the patch.
Last few days I've been implementing a Bluetooth protocol handler for Mirae. It's nothing much , I only had to make one class BluetoothTransportHandler in the org.apache.mirae.transport package and made a small modification in TransportHandler class to identify the bluetooth handler class. So Mirae now will use the BluetoothTransportHandler when the end-point url starts with bt://. A bluetooth service is identified by a 128 bit number represented by atmost 32 hexadecimal numbers. An example would be bt://a34b098235fc, so when someone needs to write a bluetooth web service for that, he must create bluetooth service with the service id a34b098235fc.
In the future, j2me enabled devices maybe used as web services containers , in a sitiuation like that the bluetooth transport can come in handy. In the meanwhile I added the bluetooth functionality to KProxyServer, so it could be used to access http webservices though bluetooth. Earlier I ran KProxyServer depending on the Mirae API for the XML processing of the xml file that contained the services information , and for the Base64 class. So what I did was , I made my own Base64 class and besides using an xml file , I used a simple text file that's similar to property files in java , and did the text parsing in my code. So now the proxy server can be run independently.
So if someone have 2 java bluetooth api enabled cell phones he can create a mirae client on one phone which uses the bluetooth protocol and run the proxy server on the other and try out how it works.
Created a user guide on how to use the Mirae API to build web services clients and how to use the new protocol handler that I've implemented , the guide can be found at " http://wiki.apache.org/general/AnjanaFernando/MiraeGuide ".
A link to my work
The code I've created/modified can be found as a single zip file here , http://www.box.net/public/yrzx83ovrx .