Axis 2 Developers -
I have spent the last month and a half lurking on the mailing list and
perusing the code base for Axis 2. I recently posted a few comments
in the "Dig Into Axis 2" thread, and I would like to expand upon some
ideas in this email. In particular, I have a great interest in the
creation of a web services framework that supports a low-level
messaging model, and I have been looking at the Axis 2 project as the
deliverer for this. In the rest of this email, I will present my
areas of interest within the Axis 2 project, and some concepts that I
have been brainstorming regarding the code base. Feedback is most
welcomed by the developer community, and if the comments are favorable
I would be happy to participate in the implementation. At the very
least, I imagine that my concepts could provide a healthy debate
leading towards a better product in the long-term.
It is clear that the Axis developer community supports the notion that
asynchronous messaging has vaulted to forefront of web services
architecture. I believe I am correct in assuming that Axis 2 aims to
be a web services framework supporting the asynchronous exchange of
SOAP messages in which these messages may be combined into a variety
of exchange patterns (some of which may be defined by a service
description language such as WSDL). In addition to supporting the
exchange of messages, Axis also offers a "Pipes and Filter"
architecture implemented as the Axis Engine defining a configurable
set of SOAP intermediaries (WS-RM, WS-Security, etc) for a specified
endpoint.
It is my intent to see that Axis 2 provides a simple and elegant
programming model that may be leveraged by IT applications and systems
requiring integration following service-oriented principles.
It is my belief that Axis should support two programming models based
off of the W3C Web Services Architecture Note. The first model should
be a low-level messaging model solely focused on asynchronously
sending or receiving a SOAP message. This model should make no
assumptions regarding a particular topology (i.e. it should support
peer-to-peer and a client/server). From my perspective, when systems
integrate through messaging, they act as peers, switching between the
roles of a producer and a consumer. With the creation of such a
model, all other MEPs may be constructed on top of it. As such, I
humbly request the introduction of a "messaging" package that would
contain a "MessageProducer", a "MessageEndpoint", the SOAP envelope
classes, and potentially the WS-Addressing implementation (since web
service messaging is dependent on it). In addition to these low-level
classes, another class, "MessageClient" may be introduced representing
the interface currently adorning the Call class (built leveraging the
MessageProducer and MessageEndpoint classes). This package should
replace the current "clientapi" package that is closely tied to a
client/server topology. A fine example of this low-level messaging
approach has been implemented in Microsoft's WSE 2.0.
The "MessageProducer" class would support a single operation, send(),
that would accept a SOAP message and send it one way to a given
EndpointReference (traversing through the engine pipeline first).
The "MessageEndpoint" class would extend the "Endpoint" class (which I
will discuss more about briefly), and provide a single operation
called receive(), accepting a SOAP message. The application that
creates such an endpoint must associate a URI and register it with the
Axis framework so it in turn may listen on the appropriate port (for a
given transport protocol).
The "MessageClient" class extends "MessageProducer" offering a set of
methods that capture basic MEPs. Its implementation is
straightforward, leveraging the lower-level messaging model. I have
provided some pseudo-code below implementing sendReceiveAsync() using
an asynchronous transport:
public class MessageClient extends MessageProducer
{
public void sendReceiveAsync(SOAPEnvelope env, Callback callback) {
final long messageID = System.currentTimeMillis();
final Correlator correlator = Correlator.getInstance();
// this is only required if the transport is not bi-directional otherwise
// we can listen on the 'back channel'; as such the replyTo header should
// be set to anonymous --> use invoker to wait for results (note:
not shown belown)
// creates anonymous listener endpoint
MessageEndpoint endpoint = new MessageEndpoint() {
public void receive(SOAPEnvelope env) {
RelatesTo relatesTo = env.getAddressingHeaders().getRelatesTo();
Callback callback = correlator.getCorrelationInfo(relatesTo.getAddress(\
));
AsyncResult result = new AsyncResult();
result.setResult(env);
callback.setComplete(true);
callback.setResult(result);
callback.doComplete();
EndpointRegistry.remove(env.getAddressHeaders().getTo().getAddress());
}
};
// registers endpoint listener
// please note that the EndpointRegistry is a concept and could be
implemented in the
// Axis Engine itself
EndpointReference replyTo = getAddressingHeaders().getReplyTo();
EndpointRegistry.add(replyTo.getAddress(), endpoint);
// add correlation info
correlator.setCorrelationInfo(messageID, callback);
send(env);
}
With the axis engine core, the object model, and the messaging package
(along with some transport implementations), I could create a web
services messaging system where each application embeds Axis for its
SOAP communication stack for integration purposes.
Once the messaging model has been established, we can introduce a
higher-level service model. A service endpoint is self-describing
(using a service description language such as WSDL or perhaps Savis'
SSDL). It acts upon a set of actions (described within a message),
and may return a result. As such, it differs from a message endpoint
because it may have both a request and response channel (handler
flow). However, this request/response viewpoint is purely artificial,
and in fact may be built using the in-channel of an "endpoint" and the
out-channel of a message producer.
The service programming model should allow for the following features:
- code generation of interface and messages through a service
description (WSDL, SSDL)
- provide an *event-driven* and/or blocking interface (i think this is BIG :) )
- provide wrapped or unwrapped method signatures
- support annontations to specify modules and runtime behavior
(override in config files; this should be offered in generic message
endpoints as well)
- support pluggable OX binding technologies
Instead of the current "Dispatcher", I recommend that we introduce a
"EndpointRouter". This handler would be responsible for locating an
"Endpoint" implementation based in the wsa:To property, adding its
specific phases to the chain, as well as the implementation class.
An "Endpoint" is a simple maker interface that extends Handler. There
exists two types of endpoints, a "MessageEndpoint" and a
"ServiceEndpoint", supporting both programming models. The
"MessageEndpoint" provides an abstract receive() method that
individuals can override if they want a low-level messaging solution.
This low-level solution offers no support for action dispatching based
on wsa:Action, therefore a switch statement might be needed. The
"ServiceEndpoint" on the otherhand is represented by a service
description document (WSDL or SSDL), and offers action dispatching to
a particular method call. The "ServiceEndpoint" would enlist the help
of a "Provider" implementation to actually invoke a piece of logic.
If a response is required, the "ServiceEndpoint" would use a
"MessageProducer" to send the message to the appropriate party.
In the end, an endpoint consume messages, and a producer sends
messages. We can build all of the MEPs on top of those two concepts.
I apologize for the long-winded email. My intent was to introduce
some of my brainstorming with regards to the two programming models,
and elicit some feedback. I will start implementing the low-level
messaging model (since a line of code is worth a thousand words), and
would love to work in collaboration with all of you, if you find my
comments favorable. I will be attending the ServerSide Symposium this
week, and if any of you will be attending let me know.
Thank you for your time,
Shawn Dahlen