SOAP is an RPC mechanism running on top of the old HTTP protocol. With the popularization of SOAP and Web Services, time has come to redefine the underlying protocol. The protocol we are talking about is WSAP (Web Services Access Protocol). Aspects like RPC and RPC callbacks, Method Discovery, Object Management and Deployment are the main issues of this protocol. The Firestorm Server is an experimental WSAP server. This document contains the design of the WSAP Server Firestorm. It can be used as a guide to understanding the sourcecode of the server. It is recommended to have familiarity with the WSAP protocol before reading this document.
The Firestorm Web Server is not only an implementation of the WSAP protocol. In fact the protocol does not specify anything on how to write web objects. This project defines a technology for mapping Java classes to web objects and provides the necessary tools for developing those objects. The Java classes representing web objects are called Java Web Objects (JWO). The server provides a framework for developing and running JWOs.
The server project consists of three packages: server, wsap and soap. Each of them provides a different type of functionality. The wsap and soap packages can be also reused in different contexts. The soap package provides means to manage SOAP messages. It has classes representing SOAP messages and SOAP parameters. These classes are serializable in the standard XML SOAP format and are able to parse XML files in order to read SOAP messages. The wsap package contains classes used for the WSAP protocol like WSAP specific sockets that parse input and generate classes representing WSAP messages, wich can, like the ones representing SOAP messages, serialize themselves. Finally the server package contains the server itself, and depends on the other two packages. It uses the wsap package to parse requests, and the soap package to interpret the request contents.
As most servers in Java, the Firestorm server is based on two classes that extend the Thread class. Theese two classes are Server and ConnectionHandler. The Server class accepts new connections on a specified port and for each new connection it creates a new ConnectionHandler. The ConnectionHandler accepts incoming requests on that connection and processes them. When the connection gets closed, the associated ConnectionHandler is discarded.
The Server class can be started as an application from the command line or created from another class. There are some parameters that control the behavior of the server like the port on which to listen to or the base directory (basedir) where to store and look for web objects. These parameters can be set from the command line or by the methods provided by the Server class.
A ServerGUI class has been developed to facilitate the usage of the Server. It provides a graphical interface to the Server class. It is responsible for starting and stopping the server and for controlling the server parameters. It also handles the server log output by providing an implementation of the Logger interface.
The interface Logger has been defined for a generic logger. The Server logs all messages using the log() method of the Logger class. The Server inner class DefaultLogger implements this interface and puts all the log messages on standard output. If no Logger is specified to the Server, it uses it’s own DefaultLogger. ServerGUI defines another implementation of the Logger interface called GUILogger. This one logs all messages into the ServerGUI’s main window.
The wsap package provides classes for the WSAP protocol. The main class is WSAPServerConnection. It represents a WSAP connection from the side of the server. The construcor of this class requires an open socket Usually there’s the client on the other side of the socket. This class listens for requestson this socket. When another class calls the method getRequest() of the WSAPServerConnection, it parses the request from the socket and returns a new WSAPRequest object. The getRequest() is a blocking method, so if no input is presenti it will wait untill a request has arrived. The WSAPRequest class represents a request and has fields for all the values of a request like type of request (method), resource, headers and contents. The WSAPServerConnection has also the method send() that is used to send the response back to the client. This send() method accepts a WSAPResponse object. The WSAPResponse class represents a wsap response and like the WSAPRequest it has fields for all the needed values like code, headers and content.
The soap package contains the classes for creating and handling SOAP messages. In fact, the main class of this package is SOAPMessage. This class has three constructors. One creates an empty SOAPMessage and requires no parameters. The second constructor takes a string, representing a soap message. The contructor parses the string and sets the appropriate fields. The third constructor is like the second but it accepts a byte array instead of a string. The method toString() of this class returns the soap message represented by this class. It has fields representing the name of the method being called and the URI used for that service.
The SOAPMessage class also holds a vector of SOAPParameter-s. The SOAPParameter class at the moment can only represent two types of parameters: int and string. The constructor of the SOAPParameter accepts a DOM Element. The method toString() of the SOAPParameter class returns the string representing the fragment of the soap message corresponding to this parameter. The toString() method of the SOAPParameter is used by the toString() method of SOAPMessage.
The JWOs are a new technology defined for representing web objects as Java classes. Each web object is represented by one Java class on the server’s local file system. These classes are stored in a directory structure resembling the structure of the site.
All JWOs are extensions of the WebObject class from the server package. This class provides the basic functionality a WebObject must have (like event handling).
In order to load the WebObjects from the file system and to access it’s functionality, another class has been defined. This class is called WebObjectUtility. This works like a stub for the WebObject class. This class is used by the ConnectionHandler to load the object, invoke it’s methods, open and close the object, view it’s methods and handle events. It’s like a wrapper class for the WebObject.
New web objects can be added to the server runtime, as existing Web Objects can be deleted. Because web objects can’t be added to the classpath on runtime, they cannot be accessed from other web objects. The WebObjectUtility class does the class loading for web objects.
…something on Xerces XML parser…
When the Server starts it creates an instance ot it’s inner class Scanner, responsible for loading and unloading web objects. When started the Scanner looks for all web objects present on the file system and loads them. A list of loaded web objects is kept in the Array webObjects. The webObjects list is a field of the Server class. It actually contains WebObjectUtility (from now on WOU) classes, each wrapping a Web Object. The WebObjectUtility, when created, loads the class of the specified object and instantiates it. Because we can’t add new web objects to the classpath on runtime, the WebObjectUtility uses the internal class FileClassLoader to load the web object. The FileClassLoader is a reimplementation of the ClassLoader. This class loader is capable of loading a class from anywhere on the file system, even if it’s not in the classpath.
The Scanner class periodically scans the file system for new or deleted web objects, or new versions of existing web objects, and updates the webObjects list accordingly. The scanner also updates, the webObjects list when a new Web Object is uploaded, or deleted from a client.
…wich methods get published…
…how do we find methods…
Let’s see how does JWO’s method invocation work in detail. When the ConnectionHandler receives a CALL request it gets the appropriate WebObjectUtility from webObjects and calls the invoke() method on it. The WOU (WebObjectUtility) calls the specified method of the WebObject and if it’s a method returning void it returns null.
…this mechanism has to be reimplemented…
When an object gets OPEN-ed, the server calls the open() Method of the WOU, wich calls the Web Object’s open() method. A unique seession identifier is generated for that connection with the Web Object (not the connection with the server) and the identifier is put into the openObjects list. The indentifier is sent to the client in the Interface-ID header.
When a client sends a CLOSE request it has to specify the Interface-ID of the session it wishes to close (assuming that a client can have multiple open sessions with the same Web Object). The ConnectionHandler finds the WOU relative to that identifier in the openObjects list and invokes a close() method on it. The WOU calls the close() method of the Web Object.
…how to implement open() and close() on a WebObject…