You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@xml.apache.org by Jean-Noel Gadreau <jn...@activcard.com> on 2000/11/03 19:12:02 UTC

Repost of Glen's Architecture doc

I looked in the archives and I cannot find the architecture proposal
from Glen, so I am reposting it.

Email from Glen Daniels on 09/25/00 ("Engine architecture for 3.0, a
spin through the system")

=======================

Hi folks:

Here's a relatively quick description of some ways I see the "next-gen"
SOAP
engine working.  This is taken from combining my own ideas with some of
the
others that have been floating about (thanks Jean-Noel, James, Yuhichi,
Jacek...).  I have a basic engine framework which implements these ideas
written in Java, which I'll post sometime in the next week.

This message focuses on message flow through a system at the server.
Many
of the components involved (except the actual target object dispatch)
are
also available on the client.  I don't cover all the details, but I
think
some of these are important lynchpins for future discussion/work.
Please
let me know what you think.

1. Receipt at Listener

The Listener is some protocol-specific piece of code.  Its job in life
is,
first, to call out to the SOAP engine to parse the XML it receives (this
wraps the XML parsing in our APIs, which is convenient).  If there is a
MIME
binding involved, the SOAP Envelope would be extracted from the MIME
envelope (and the appropriate CID references set up) before parsing.
The
engine checks the validity of the envelope, and returns a SOAPMessage,
which
contains the parsed XML (as DOM), split up into Header and Body
sections.
The Listener then creates a SOAPContext object, which contains various
properties such as IP address, protocol headers, URL, etc. (this is so
this
information is available to anyone who needs it down the line).

2. Dispatch, part I

The Listener passes the SOAPMessage and the SOAPContext to the engine.
The
engine looks at the SOAPContext (and possibly the message Body as well)
and
creates an appropriate chain of MessageHandlers to deal with this
request by
examining its configuration and locating the appropriate
ServiceDescription.
It also obtains a collection of type mappings which are supported for
this
service, and makes those accessible (via the SOAPContext) for
deserialization.

3. The MessageHandler chain

The MessageHandler interface is used by any piece of code who wants to
do
something with a SOAPMessage, and potentially contribute to a
SOAPResponse.
Examples:

* A header processor for an authentication header.  If it's not there in
the
SOAPMessage, we need to add a "challenge" header to the Response and
ensure
that we throw a "Client" Fault instead of actually processing the
request.
If it is there, we extract the credentials and, if they're valid, add a
"securityPrincipal" property to the SOAPContext.

* A header processor that decrypts the Body data based on a public key.

* The dispatcher who calls the target object to do work.

The MessageHandler interface looks something like this:

public interface MessageHandler {
    public void handleMessage(SOAPMessage msg,
                              SOAPResponse resp,
                              SOAPContext ctx)
              throws SOAPException;
}

This is so each handler can play with the message, the response (the
server
generates a blank response at the start of handler processing), and the
context.

The first thing the server does is check to make sure all headers marked
mustUnderstand can be processed.  If there is no handler registered for
one
or more mustUnderstand="1" headers, we simply return a MustUnderstand
Fault
(see section 4 below for the mechanism with which we return a response).
Otherwise, we continue by processing the headers.

3.1 Header processing

Typically Header processing will result in either a) a change to the
message
body (decryption/decompression), b) a change to the SOAPContext (adding
security information, transaction-id, etc), or c) a side-effect (sending
a
log message, etc).

Header processing should always happen first, and in general we should
process ALL headers even if there is an error condition in one of them.
This allows us to build up the maximally informative response message in
the
case that multiple handlers each need to insert information into the
response.  If any header handler fails, however, we note the failure so
that
we don't bother trying to invoke the actual "target" MessageHandler to
do
any real work.

So for instance, let's say there were two required headers that were
missing, and the desired result is two "challenge" headers in a
SOAP-Fault:Client response.  The first header handler notices it can't
find
what it's looking for, so it adds its challenge header to the
SOAPResponse
making its way through the system, and then throws a well-defined
exception.
The engine notes the failure, then runs the second handler, which adds
its
challenge header to the response also, and throws its own exception.
Once
header handling completes, the server sends the accumulated Fault
response
(again, see section 4).

3.2.  Finding the target object

OK, now the headers have all been processed, and we arrive at the
MessageHandler whose job it is to actually call a target worker object
and
run some method.  Now we need to find the right object.

We keep a mapping of our available objects somewhere, and the
SOAPContext
includes a "destination" property which is used for final dispatch to
the
actual language object we are calling to do the work we're interested
in.
This is to allow dispatch to happen in a variety of ways.  Anyone along
the
chain can set the "destination" property in some appropriate fashion -
for
instance, in an object-per-URI system, the servlet Listener that lives
at
"http://myhost/SOAPServlet" might map the URL
"http://myhost/SOAPServlet/3FC2-845B4-701" to a particular destination
object.  Whereas in another system, a MessageHandler which processes an
<object-ID> header might set the destination instead.  Or you might
dispatch
based on the QName of the Body element.  I think it's key to leave this
flexible.

So, when the Message arrives here, if the "destination" property is not
set,
we throw an exception (I can't figure out who you want to talk to).
Otherwise, we call the target object, and merge whatever it return us
into
the Response.

4.  Responding

The Response, if there is one, needs to go somewhere.  This might be
right
back out to the Listener, as in the case of HTTP. Or it might be sending
it
asynchronously via some other protocol, depending on how the service is
configured, and potentially on some request-specific data (such as a
"reply-to" header).  To keep this flexible, we use another SOAPContext
property which follows the request - "replyTo" or somesuch.  The value
of
this property is a SOAPTransport object which has a sendMessage()
method,
which we'll use to send the response.  Anyone along the chain can set
this
up, but the response isn't actually sent until we get to this step.

For HTTP, the listener (a Servlet, say) might create a "callback
transport"
object whose purpose in life is to simply collect a response message and
store it in a local variable in the Servlet.  Then when the engine
returns,
we can just take the stored response and write it out the HTTP
connection.
For SMTP/POP, the POP listener might create an SMTPTransport object
pre-configured with the email address we received this request from, and
hand that down to the engine.  Then when we get here, the engine
automatically sends out the response to the right email address.

5.  Other stuff

* We should definitely support timeouts.

* Serialization/deserialization should deal correctly with multi-ref
accessors

* It would be nice to support "as you go" deserialization, so that when
we
ask for a particular element's language representation, we deserialize
the
necessary XML the first time, and then return the cached object
thereafter.

* We should consider passing around JDOM (www.jdom.org) or some other
lightweight DOM-esque structure, instead of full-scale DOM.

6.  That's it

That's all I have time for right now, and I've been meaning to get this
message out for ages, so I'm just going to send it now.  I hope this was
comprehensible, and I welcome any questions or comments on this
approach.

Glen Daniels
Allaire Corp
Engineering Manager
http://www.allaire.com/
                                Building cool stuff for web developers
=======================

Regards,

Jean-Noel

==============
Jean-Noel GADREAU
Software Engineer, ActivCard Inc.(http://www.activcard.com )
E-mail: jngadreau@activcard.com
Tel (main): 510-574-0100
Tel (direct): 510-574-1736