An Abstract Model for Module Processing

Mark A. Jones, AT&T Labs -- Research

W3C XML Protocol Working Group, Abstract Model subgroup

Concepts [and comparison with SOAP 1.1]

The XML Protocol abstract model for module processing borrows heavily from the SOAP model.  If we go with the current XML Protocol terminology, I would recommend substituting the term "module" for the SOAP term "actor" in the prose below.  I stuck with "actor" here to maintain familiarity with SOAP.

  1. An XML Protocol Message consists of zero or more header blocks and one body block.  The main distinction between the header blocks and body block is that the module that processes the body block has the responsibility of generating responses if necessary for the message.

    SOAP:  Same.
  2. Each header has an optional associated id (identifier), an optional actor and an optional mustUnderstand flag.  The body has an optional associated id (identifier) and an optional actor.  The body must be understood.  The id is an ID that identifies the block for the purposes of reference by other blocks.  The actor is a URI used by the XML Protocol Processor for determining which module to apply to the block.  The mustUnderstand flag has value "1" if  the matching module must carry out the intended semantics of the block or fault and "0" (the default) if it can silently fail.

    SOAP:  SOAP is ambiguous as to whether actor URI's are to be interpreted extensionally as destinations/nodes/places or intensionally as applications/modules/capabilities.  
  3. There are reserved actor URI's with special significance:
      http://.../none        // matches no module (i.e., an untargeted header)
      http://.../next       
    // matches a default module at the next processor
      http://.../final      
    // matches a default module at the final processor
      http://.../body       
    // matches the module selected at the final processor (can be used as a target for headers)

    An empty actor defaults to http://.../body.

    SOAP:   An empty SOAP actor in a header "indicates that the recipient is the ultimate destination of the SOAP message," and a "body entry is semantically equivalent to a header entry intended for the default actor."  This is SOAP talking rather extensionally, as though there were only one reasonable default module at the destination.  This is what http://.../final designates. There is no correspondent in SOAP for none or bodynext is the same as for SOAP. It appears that the actor for a SOAP body always defaults in the receiver.  This is not as flexible as permitting the message to specify an actor (a module) for processing the body.  Since headers can be targeted to http://.../body, it might be wise syntactically to ensure that the body actor is known earlier than the body header, perhaps as an envelope attribute.
  4. When a header is selected for processing by a module at an intermediary, the header is removed from the envelope.  The process API enables a module to add zero or more headers that will replace the processed header in the same relative position in the message.

    SOAP: Similar, but SOAP doesn't specify where the new headers are to be inserted.
  5. The XML Protocol Message blocks are ordered.  By using that same ordering for processing the locally targeted blocks, a limited facility for specifying sequential constraints is provided.  An extensibility mechanism is available for more complex orderings and constraints.   Headers can function as manifests to direct further processing.  The "manifest module" associated with such a header can refer to other blocks by their id's.  The processor API allows a such a "manifest module" to access other headers by id and to process a header with a specified module.   Blocks can be shared among several modules by having these modules reference them by id.  [An open question is whether referenced blocks must be untargeted (have actor http://.../none) or whether they could also be targeted.  If a targeted block is processed by its actor and removed at an intermediary, it would create a dangling reference for any unprocessed header that linked to it.  Untargeted headers would not be subject to automatic removal.  It is another open question as to whether the processor API should permit a module to remove an untargeted header.]

    SOAP:  The SOAP spec doesn't make it clear, but apparently headers with no actor can be referenced via links from other headers and they are not removed at intermediaries which reference them.  Using that mechanism, headers can be effectively shared among modules, even at different nodes.  The body can only be processed by the ultimate recipient.
  6. The processing of a header may result in a fault or a successful evaluation.  A fault terminates processing and causes a return message containing the fault to be generated if a return path is available.  It is possible for a module that processes a header to have status information, non-fatal errors, or other results incorporated into the return value generated by the ultimate recipient.  It can accomplish this by inserting headers which are targeted to http://.../body.

    SOAP:  Similar.
  7. The composition of modules is an important property.  For example, independent modules might do decompression,  decryption, and some application-specific computation.  Let M1(M2(H)) represent the application of module M1 to the result of applying M2 to header H.  The sender wants to specify the composition of applyX(decryption(decompression(H))).

    One mechanism for accomplishing M1(M2(H)) is to have M2(H) replace H with a header H' targeted at actor M1.  This fails, however, if M1 and M2 are both implemented at the same node.  One solution is to immediately process any headers targeted at modules of the current node before continuing to process the remaining blocks.

    SOAP:  SOAP does not permit module composition at the same node.
  8. The above approach to composition suffers from requiring the cooperation of M2 for targeting M1 at its result.  M2 might not always be followed by M1.  It would be preferable to allow the original sender who knows how the header data was constructed to specify the composition.  One way to do this is via a manifest that describes the composition.